diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index c0ffaedaf..62f0c7275 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -6,6 +6,8 @@ on: jobs: Build: env: + V3_SUBGRAPH: https://api.studio.thegraph.com/proxy/31386/balancer-v3-sepolia/version/latest + V3_POOLS_SUBGRAPH: https://api.studio.thegraph.com/proxy/31386/balancer-pools-v3-sepolia/version/latest BALANCER_SUBGRAPH: https://api.thegraph.com/subgraphs/name/beethovenxfi/beethovenx MASTERCHEF_SUBGRAPH: https://api.thegraph.com/subgraphs/name/beethovenxfi/masterchefv2 BLOCKS_SUBGRAPH: https://api.thegraph.com/subgraphs/name/danielmkm/optimism-blocks diff --git a/app-architecture.excalidraw b/app-architecture.excalidraw new file mode 100644 index 000000000..16cc41d47 --- /dev/null +++ b/app-architecture.excalidraw @@ -0,0 +1,1832 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "rectangle", + "version": 865, + "versionNonce": 618847347, + "isDeleted": false, + "id": "0rCUkN1a2gY5msly4lPoJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 626.0769073589, + "y": 1234.8874532379957, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 805.0668571070347, + "height": 339.28462450621436, + "seed": 485198810, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "9Dx_1COVEMPVHccffiLwH" + }, + { + "id": "VboAKrgz851OORtW9No3h", + "type": "arrow" + }, + { + "id": "y_uM2fFfpaEi9hwrpZBqP", + "type": "arrow" + }, + { + "id": "614vaW_3XHnGgPUnoYSFE", + "type": "arrow" + } + ], + "updated": 1707940476825, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 574, + "versionNonce": 412435485, + "isDeleted": false, + "id": "9Dx_1COVEMPVHccffiLwH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 631.0769073589, + "y": 1239.8874532379957, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 286.9158935546875, + "height": 70, + "seed": 1498115654, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707940454699, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 1, + "text": "\n Configured context", + "textAlign": "left", + "verticalAlign": "top", + "containerId": "0rCUkN1a2gY5msly4lPoJ", + "originalText": "\n Configured context", + "lineHeight": 1.25, + "baseline": 60 + }, + { + "type": "text", + "version": 168, + "versionNonce": 1333760326, + "isDeleted": false, + "id": "l9lNn3ZlV1VxxGrVFqyBr", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 512.3144110597245, + "y": 84.15771359161883, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 504.25177001953125, + "height": 45, + "seed": 1343185222, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707925076170, + "link": null, + "locked": false, + "fontSize": 36, + "fontFamily": 1, + "text": "API application architecture", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "API application architecture", + "lineHeight": 1.25, + "baseline": 32 + }, + { + "type": "rectangle", + "version": 374, + "versionNonce": 1338218266, + "isDeleted": false, + "id": "rtyvvejqKNEkFQQW0oda0", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 629.7265182237195, + "y": 261.2164066662183, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 219.95703124999997, + "height": 103.03515625, + "seed": 700003270, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "95gidIyH9fC5A3lmczIdh" + }, + { + "id": "vg6-l8Xznua-BCWboSEs4", + "type": "arrow" + }, + { + "id": "j-VKbIqAdLxV6NjHu9da1", + "type": "arrow" + } + ], + "updated": 1707925098341, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 472, + "versionNonce": 2083890138, + "isDeleted": false, + "id": "95gidIyH9fC5A3lmczIdh", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 680.255090306239, + "y": 300.2339847912183, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 118.89988708496094, + "height": 25, + "seed": 728430426, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707925098341, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Express app", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "rtyvvejqKNEkFQQW0oda0", + "originalText": "Express app", + "lineHeight": 1.25, + "baseline": 18 + }, + { + "type": "rectangle", + "version": 498, + "versionNonce": 226062170, + "isDeleted": false, + "id": "bvxjwWJEryYTp1hXvIEk5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 358.6028636353002, + "y": 478.09765624999994, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 308.3359375, + "height": 119.9765625, + "seed": 547445830, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "0lVehAIjpyAIvWJF1OD0o" + }, + { + "id": "vg6-l8Xznua-BCWboSEs4", + "type": "arrow" + }, + { + "id": "uj7GcQ_fyBRff70WrSx4w", + "type": "arrow" + } + ], + "updated": 1707925337870, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 643, + "versionNonce": 2126256518, + "isDeleted": false, + "id": "0lVehAIjpyAIvWJF1OD0o", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 389.77093919682363, + "y": 513.0859375, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 245.99978637695312, + "height": 50, + "seed": 905569158, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707925104984, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "POST /jobs\nruns the background jobs", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "bvxjwWJEryYTp1hXvIEk5", + "originalText": "POST /jobs\nruns the background jobs", + "lineHeight": 1.25, + "baseline": 43 + }, + { + "type": "rectangle", + "version": 506, + "versionNonce": 1183149210, + "isDeleted": false, + "id": "BI0s-hG2xUwjQmFAhFfn0", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 838.9249916537059, + "y": 480.9868795587057, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 308.3359375, + "height": 119.9765625, + "seed": 427759302, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "vmTgASKFvWEof8L2w_UmV" + }, + { + "id": "j-VKbIqAdLxV6NjHu9da1", + "type": "arrow" + }, + { + "id": "4x-jVg3VAfW0rFQzP402V", + "type": "arrow" + } + ], + "updated": 1707926250651, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 689, + "versionNonce": 887754886, + "isDeleted": false, + "id": "vmTgASKFvWEof8L2w_UmV", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 921.1630135042918, + "y": 515.9751608087057, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 143.85989379882812, + "height": 50, + "seed": 1883000326, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707926247787, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "POST /graphql\nApollo server", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "BI0s-hG2xUwjQmFAhFfn0", + "originalText": "POST /graphql\nApollo server", + "lineHeight": 1.25, + "baseline": 43 + }, + { + "type": "rectangle", + "version": 670, + "versionNonce": 1661281715, + "isDeleted": false, + "id": "b5Ml9fkgIPa8v2fp9Kt9d", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1811.227829284344, + "y": 267.40536771482607, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 308.3359375, + "height": 119.9765625, + "seed": 2112226522, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "wN-cyeOs1s97VjXdqlN1_" + } + ], + "updated": 1707940527608, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 687, + "versionNonce": 224130899, + "isDeleted": false, + "id": "wN-cyeOs1s97VjXdqlN1_", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1920.115845031414, + "y": 314.89364896482607, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 90.55990600585938, + "height": 25, + "seed": 524573082, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707940527608, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Scheduler", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "b5Ml9fkgIPa8v2fp9Kt9d", + "originalText": "Scheduler", + "lineHeight": 1.25, + "baseline": 18 + }, + { + "type": "arrow", + "version": 110, + "versionNonce": 725348358, + "isDeleted": false, + "id": "vg6-l8Xznua-BCWboSEs4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 731.8248229331246, + "y": 367.0552833346115, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 212.6538719242776, + "height": 109.48671833378177, + "seed": 37291354, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1707925104984, + "link": null, + "locked": false, + "startBinding": { + "elementId": "rtyvvejqKNEkFQQW0oda0", + "focus": -0.4644458004203634, + "gap": 2.8037204183931976 + }, + "endBinding": { + "elementId": "bvxjwWJEryYTp1hXvIEk5", + "focus": -0.4179643889919988, + "gap": 1.555654581606774 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -212.6538719242776, + 109.48671833378177 + ] + ] + }, + { + "type": "arrow", + "version": 87, + "versionNonce": 1234708230, + "isDeleted": false, + "id": "j-VKbIqAdLxV6NjHu9da1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 740.7665820910862, + "y": 367.1177833346115, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 251.76652049132224, + "height": 104.89156664248742, + "seed": 370382342, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1707926247787, + "link": null, + "locked": false, + "startBinding": { + "elementId": "rtyvvejqKNEkFQQW0oda0", + "focus": 0.5530999063539602, + "gap": 2.8662204183931976 + }, + "endBinding": { + "elementId": "BI0s-hG2xUwjQmFAhFfn0", + "focus": 0.5533215980667758, + "gap": 8.977529581606802 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 251.76652049132224, + 104.89156664248742 + ] + ] + }, + { + "type": "rectangle", + "version": 563, + "versionNonce": 1271079898, + "isDeleted": false, + "id": "PQ8zJtBlZuvNesoG3T0A0", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 358.7075006737633, + "y": 777.2549019291434, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 308.3359375, + "height": 119.9765625, + "seed": 474475738, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "yhshF7mYuuI1NENOq7m0w" + }, + { + "id": "p04FjRC7bFzLdr2STyCnI", + "type": "arrow" + }, + { + "id": "gAkm6uT_7wSXCu95CFn8U", + "type": "arrow" + }, + { + "id": "uj7GcQ_fyBRff70WrSx4w", + "type": "arrow" + }, + { + "id": "RHVw0U5boLMcrEmQQbDqj", + "type": "arrow" + } + ], + "updated": 1707925770470, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 803, + "versionNonce": 1709529242, + "isDeleted": false, + "id": "yhshF7mYuuI1NENOq7m0w", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 419.78553412102895, + "y": 812.2431831791434, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 186.17987060546875, + "height": 50, + "seed": 1764311450, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707925572928, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Handler\nknows what to call", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "PQ8zJtBlZuvNesoG3T0A0", + "originalText": "Handler\nknows what to call", + "lineHeight": 1.25, + "baseline": 43 + }, + { + "type": "rectangle", + "version": 705, + "versionNonce": 1945243354, + "isDeleted": false, + "id": "vRh35_WImTNMpdlYPHt7E", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -145.3083445419249, + "y": 771.9810153460681, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 308.3359375, + "height": 119.9765625, + "seed": 2077206278, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "Yq8uvKvWpUrW3aM02foeq" + }, + { + "id": "p04FjRC7bFzLdr2STyCnI", + "type": "arrow" + } + ], + "updated": 1707925776969, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 965, + "versionNonce": 950901574, + "isDeleted": false, + "id": "Yq8uvKvWpUrW3aM02foeq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -136.04026287688583, + "y": 794.4692965960681, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 289.7997741699219, + "height": 75, + "seed": 311481926, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707926212942, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Execution logic\n(concurrency, tracing, alerts, \nmonitoring)", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "vRh35_WImTNMpdlYPHt7E", + "originalText": "Execution logic\n(concurrency, tracing, alerts, monitoring)", + "lineHeight": 1.25, + "baseline": 68 + }, + { + "type": "arrow", + "version": 242, + "versionNonce": 420593478, + "isDeleted": false, + "id": "p04FjRC7bFzLdr2STyCnI", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 170.329589698084, + "y": 834.1066579326716, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 183.46155436416043, + "height": 2.9490252402465558, + "seed": 2046748442, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1707925779844, + "link": null, + "locked": false, + "startBinding": { + "elementId": "vRh35_WImTNMpdlYPHt7E", + "focus": -0.007334553906602865, + "gap": 7.301996740008889 + }, + "endBinding": { + "elementId": "PQ8zJtBlZuvNesoG3T0A0", + "focus": -0.037935209026344924, + "gap": 4.916356611518893 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 183.46155436416043, + 2.9490252402465558 + ] + ] + }, + { + "type": "rectangle", + "version": 795, + "versionNonce": 1475902086, + "isDeleted": false, + "id": "mGeAjrKYThqTz6OROStTH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -133.90378372517483, + "y": 1009.1715495169069, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 308.3359375, + "height": 119.9765625, + "seed": 2079939782, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "UNrJfhn0S00DQ2x_Tglun" + }, + { + "id": "gAkm6uT_7wSXCu95CFn8U", + "type": "arrow" + } + ], + "updated": 1707925805653, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1043, + "versionNonce": 693320134, + "isDeleted": false, + "id": "UNrJfhn0S00DQ2x_Tglun", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": -43.14574997273343, + "y": 1056.659830766907, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 126.81986999511719, + "height": 25, + "seed": 1467864070, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707925805653, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Configuration", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "mGeAjrKYThqTz6OROStTH", + "originalText": "Configuration", + "lineHeight": 1.25, + "baseline": 18 + }, + { + "type": "arrow", + "version": 441, + "versionNonce": 1436774598, + "isDeleted": false, + "id": "gAkm6uT_7wSXCu95CFn8U", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 181.09991116802735, + "y": 1079.4842931952699, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 163.93625108134245, + "height": 2.4055138321657523, + "seed": 757321606, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1707926019123, + "link": null, + "locked": false, + "startBinding": { + "elementId": "mGeAjrKYThqTz6OROStTH", + "focus": 0.20699809207901113, + "gap": 6.6677573932022085 + }, + "endBinding": { + "elementId": "nplU0SHojzsk4FXPETiYF", + "focus": -0.01742985684773468, + "gap": 6.50532555727159 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 163.93625108134245, + -2.4055138321657523 + ] + ] + }, + { + "type": "rectangle", + "version": 799, + "versionNonce": 546811709, + "isDeleted": false, + "id": "nplU0SHojzsk4FXPETiYF", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 351.5414878066414, + "y": 1013.6478465678853, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 308.3359375, + "height": 119.9765625, + "seed": 1382588294, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "OQu_Hxf7mq-UU4hUK9caz" + }, + { + "id": "gAkm6uT_7wSXCu95CFn8U", + "type": "arrow" + }, + { + "id": "RHVw0U5boLMcrEmQQbDqj", + "type": "arrow" + }, + { + "id": "614vaW_3XHnGgPUnoYSFE", + "type": "arrow" + }, + { + "id": "zwnghJfQIHaTc7m3J2hIg", + "type": "arrow" + } + ], + "updated": 1707940418860, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1026, + "versionNonce": 1668187078, + "isDeleted": false, + "id": "OQu_Hxf7mq-UU4hUK9caz", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 395.399550550782, + "y": 1036.1361278178854, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 220.61981201171875, + "height": 75, + "seed": 209108678, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707926019123, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Controllers\nknows how to execute,\ncreates context", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "nplU0SHojzsk4FXPETiYF", + "originalText": "Controllers\nknows how to execute,\ncreates context", + "lineHeight": 1.25, + "baseline": 68 + }, + { + "type": "arrow", + "version": 97, + "versionNonce": 1740671834, + "isDeleted": false, + "id": "uj7GcQ_fyBRff70WrSx4w", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 513.779012861997, + "y": 600.8473679154308, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 3.2527582283347556, + "height": 173.37700981947967, + "seed": 472969158, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1707925514888, + "link": null, + "locked": false, + "startBinding": { + "elementId": "bvxjwWJEryYTp1hXvIEk5", + "focus": -0.01362000814081663, + "gap": 2.7731491654307945 + }, + "endBinding": { + "elementId": "PQ8zJtBlZuvNesoG3T0A0", + "focus": -0.022740965350795648, + "gap": 3.030524194232953 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -3.2527582283347556, + 173.37700981947967 + ] + ] + }, + { + "type": "rectangle", + "version": 974, + "versionNonce": 488162301, + "isDeleted": false, + "id": "z1P6dAwrnt95XQLJrTDlz", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 349.3956006344352, + "y": 1678.7191717521068, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 308.3359375, + "height": 119.9765625, + "seed": 1145436550, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "jqXGGNGzRN3ai7m8gvJpq" + }, + { + "id": "Pp3cnjDdYnCjvNGio5jzA", + "type": "arrow" + }, + { + "id": "ObWGMI7bb4fMOA7infU3T", + "type": "arrow" + }, + { + "id": "y_uM2fFfpaEi9hwrpZBqP", + "type": "arrow" + }, + { + "id": "zwnghJfQIHaTc7m3J2hIg", + "type": "arrow" + } + ], + "updated": 1707940418860, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1294, + "versionNonce": 1908571526, + "isDeleted": false, + "id": "jqXGGNGzRN3ai7m8gvJpq", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 358.7736829098258, + "y": 1713.7074530021068, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 289.57977294921875, + "height": 50, + "seed": 1301862598, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707926052057, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Actions\nknows what needs to be done", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "z1P6dAwrnt95XQLJrTDlz", + "originalText": "Actions\nknows what needs to be done", + "lineHeight": 1.25, + "baseline": 43 + }, + { + "type": "rectangle", + "version": 1494, + "versionNonce": 859913693, + "isDeleted": false, + "id": "SF-Ct3jvdbXrlXmM5qhTu", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1068.067252614944, + "y": 1378.9330618856036, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 308.3359375, + "height": 119.9765625, + "seed": 1492098714, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "2759MoHnFvyuXdinx-RFE" + }, + { + "id": "VboAKrgz851OORtW9No3h", + "type": "arrow" + } + ], + "updated": 1707940458158, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1887, + "versionNonce": 1227366621, + "isDeleted": false, + "id": "2759MoHnFvyuXdinx-RFE", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1171.0752634792018, + "y": 1413.9213431356036, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 102.31991577148438, + "height": 50, + "seed": 561298266, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707940509638, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Stores\nDB models", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "SF-Ct3jvdbXrlXmM5qhTu", + "originalText": "Stores\nDB models", + "lineHeight": 1.25, + "baseline": 43 + }, + { + "type": "rectangle", + "version": 1544, + "versionNonce": 386015357, + "isDeleted": false, + "id": "4IzITRueridnIqiLKsGi1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 678.2142338689831, + "y": 1379.9813732445514, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 308.3359375, + "height": 119.9765625, + "seed": 1345582426, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "O3yNoHaKP0LBUhiIm84ii" + } + ], + "updated": 1707940408758, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1973, + "versionNonce": 37947613, + "isDeleted": false, + "id": "O3yNoHaKP0LBUhiIm84ii", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 714.0723042425183, + "y": 1414.9696544945514, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 236.6197967529297, + "height": 50, + "seed": 1132476954, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707940408758, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Data sources\nsubgraph, contract, logs", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "4IzITRueridnIqiLKsGi1", + "originalText": "Data sources\nsubgraph, contract, logs", + "lineHeight": 1.25, + "baseline": 43 + }, + { + "type": "rectangle", + "version": 1256, + "versionNonce": 686864070, + "isDeleted": false, + "id": "tO4GEy8oBl6piCMtE5BYt", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 342.27168157891697, + "y": 1957.431911454487, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 308.3359375, + "height": 119.9765625, + "seed": 2022345670, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "M-6U6BUI39ixWdxUNP_YS" + }, + { + "id": "ObWGMI7bb4fMOA7infU3T", + "type": "arrow" + } + ], + "updated": 1707926030524, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1756, + "versionNonce": 1618603526, + "isDeleted": false, + "id": "M-6U6BUI39ixWdxUNP_YS", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 364.42976263360447, + "y": 1992.420192704487, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 264.019775390625, + "height": 50, + "seed": 672211718, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707926030524, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Transformers\nprepares data for the DB", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tO4GEy8oBl6piCMtE5BYt", + "originalText": "Transformers\nprepares data for the DB", + "lineHeight": 1.25, + "baseline": 43 + }, + { + "type": "arrow", + "version": 933, + "versionNonce": 541887110, + "isDeleted": false, + "id": "ObWGMI7bb4fMOA7infU3T", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 503.1177388531386, + "y": 1951.683528736298, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.20933401772674642, + "height": 146.81350481066056, + "seed": 1088990726, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1707926052057, + "link": null, + "locked": false, + "startBinding": { + "elementId": "tO4GEy8oBl6piCMtE5BYt", + "focus": 0.0438986464455738, + "gap": 5.74838271818885 + }, + "endBinding": { + "elementId": "z1P6dAwrnt95XQLJrTDlz", + "focus": 0.004858900627053375, + "gap": 6.174289673530666 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -0.20933401772674642, + -146.81350481066056 + ] + ] + }, + { + "type": "arrow", + "version": 38, + "versionNonce": 791050054, + "isDeleted": false, + "id": "RHVw0U5boLMcrEmQQbDqj", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 508.9348937747624, + "y": 901.1234252897526, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 1.693399649831008, + "height": 108.88017912269822, + "seed": 1922867462, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1707926019124, + "link": null, + "locked": false, + "startBinding": { + "elementId": "PQ8zJtBlZuvNesoG3T0A0", + "focus": 0.03183082197404965, + "gap": 3.8919608606090605 + }, + "endBinding": { + "elementId": "nplU0SHojzsk4FXPETiYF", + "focus": 0.03809457720533805, + "gap": 3.644242155434256 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 1.693399649831008, + 108.88017912269822 + ] + ] + }, + { + "type": "text", + "version": 144, + "versionNonce": 615599130, + "isDeleted": false, + "id": "MCju5oeR-thaF0t-6Co6C", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 167.47715758645728, + "y": 302.51959011572853, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 140.47592163085938, + "height": 35, + "seed": 2043388314, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707926152525, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 1, + "text": "DB writing", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "DB writing", + "lineHeight": 1.25, + "baseline": 25 + }, + { + "type": "text", + "version": 209, + "versionNonce": 371194694, + "isDeleted": false, + "id": "q375xvuA_Vs7J6Gglhqrz", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1223.9749075834748, + "y": 304.1284151646575, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 151.39593505859375, + "height": 35, + "seed": 1599926554, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707926164810, + "link": null, + "locked": false, + "fontSize": 28, + "fontFamily": 1, + "text": "DB reading", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "DB reading", + "lineHeight": 1.25, + "baseline": 25 + }, + { + "type": "rectangle", + "version": 542, + "versionNonce": 709293715, + "isDeleted": false, + "id": "6uYVJb4hhqsXKen0kvDn9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 849.9003831051311, + "y": 781.7174259605832, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 308.3359375, + "height": 119.9765625, + "seed": 201315334, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "3I468xPZ0ZRZtcCurgeWT" + }, + { + "id": "4x-jVg3VAfW0rFQzP402V", + "type": "arrow" + }, + { + "id": "VboAKrgz851OORtW9No3h", + "type": "arrow" + } + ], + "updated": 1707940286790, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 743, + "versionNonce": 83141318, + "isDeleted": false, + "id": "3I468xPZ0ZRZtcCurgeWT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 968.3383866451702, + "y": 829.2057072105832, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 71.45993041992188, + "height": 25, + "seed": 1714643782, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1707926244620, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "loaders", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "6uYVJb4hhqsXKen0kvDn9", + "originalText": "loaders", + "lineHeight": 1.25, + "baseline": 18 + }, + { + "type": "arrow", + "version": 28, + "versionNonce": 2133703386, + "isDeleted": false, + "id": "4x-jVg3VAfW0rFQzP402V", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 991.4503747299802, + "y": 611.2276276530748, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 6.781409869044637, + "height": 164.65368709275606, + "seed": 1167236486, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1707926252727, + "link": null, + "locked": false, + "startBinding": { + "elementId": "BI0s-hG2xUwjQmFAhFfn0", + "focus": 0.028958350055107673, + "gap": 10.26418559436911 + }, + "endBinding": { + "elementId": "6uYVJb4hhqsXKen0kvDn9", + "focus": -0.01995376479451029, + "gap": 5.83611121475235 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 6.781409869044637, + 164.65368709275606 + ] + ] + }, + { + "id": "VboAKrgz851OORtW9No3h", + "type": "arrow", + "x": 999.3729793068529, + "y": 1210.1039915799047, + "width": 3.842047300777608, + "height": 282.1120384916244, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1530990877, + "version": 1580, + "versionNonce": 160865203, + "isDeleted": false, + "boundElements": null, + "updated": 1707940476825, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -3.842047300777608, + -282.1120384916244 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "0rCUkN1a2gY5msly4lPoJ", + "gap": 24.7834616580908, + "focus": -0.06567990475367153 + }, + "endBinding": { + "elementId": "6uYVJb4hhqsXKen0kvDn9", + "gap": 26.297964627696956, + "focus": 0.06266764348604946 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "y_uM2fFfpaEi9hwrpZBqP", + "type": "arrow", + "x": 708.0096168316634, + "y": 1590.571541415734, + "width": 103.06612005250531, + "height": 77.30992844466846, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 420217171, + "version": 954, + "versionNonce": 290687731, + "isDeleted": false, + "boundElements": null, + "updated": 1707940476825, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -103.06612005250531, + 77.30992844466846 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "0rCUkN1a2gY5msly4lPoJ", + "gap": 16.39946367152379, + "focus": 0.11499207460118326 + }, + "endBinding": { + "elementId": "z1P6dAwrnt95XQLJrTDlz", + "gap": 10.837701891704455, + "focus": 0.02971667668683233 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "614vaW_3XHnGgPUnoYSFE", + "type": "arrow", + "x": 710.4007569205448, + "y": 1220.377265850082, + "width": 95.30409985136987, + "height": 69.33891056634707, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 336140285, + "version": 983, + "versionNonce": 260942387, + "isDeleted": false, + "boundElements": null, + "updated": 1707940476825, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -95.30409985136987, + -69.33891056634707 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "0rCUkN1a2gY5msly4lPoJ", + "gap": 14.510187387913447, + "focus": -0.10312430370153185 + }, + "endBinding": { + "elementId": "nplU0SHojzsk4FXPETiYF", + "gap": 17.41394621584965, + "focus": -0.012679959910820856 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "zwnghJfQIHaTc7m3J2hIg", + "type": "arrow", + "x": 499.119442701254, + "y": 1150.4231809452544, + "width": 4.174397296830875, + "height": 507.8264164155132, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1578221843, + "version": 49, + "versionNonce": 1203290013, + "isDeleted": false, + "boundElements": null, + "updated": 1707940418860, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -4.174397296830875, + 507.8264164155132 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "nplU0SHojzsk4FXPETiYF", + "focus": 0.038528210058637914, + "gap": 16.798771877369347 + }, + "endBinding": { + "elementId": "z1P6dAwrnt95XQLJrTDlz", + "focus": -0.06000150598742052, + "gap": 20.469574391339165 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/buildspec.yml b/buildspec.yml index 3b9a1e090..2672c08a7 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -1,6 +1,8 @@ version: 0.2 env: variables: + V3_SUBGRAPH: 'https://api.studio.thegraph.com/proxy/31386/balancer-v3-sepolia/version/latest/graphql' + V3_POOLS_SUBGRAPH: 'https://api.studio.thegraph.com/proxy/31386/balancer-pools-v3-sepolia/version/latest/graphql' BALANCER_SUBGRAPH: 'https://api.thegraph.com/subgraphs/name/beethovenxfi/beethovenx-v2-optimism' MASTERCHEF_SUBGRAPH: 'https://api.thegraph.com/subgraphs/name/beethovenxfi/masterchefv2' RELIQUARY_SUBGRAPH: 'https://api.thegraph.com/subgraphs/name/beethovenxfi/reliquary' diff --git a/codegen.yml b/codegen.yml index b6d7a4a77..e87c909af 100644 --- a/codegen.yml +++ b/codegen.yml @@ -3,6 +3,40 @@ hooks: afterAllFileWrite: - prettier --write generates: + modules/subgraphs/balancer-v3-vault/generated/types.ts: + schema: ${V3_SUBGRAPH} + documents: 'modules/subgraphs/balancer-v3-vault/*.graphql' + plugins: + - typescript + - typescript-operations + - typescript-graphql-request + config: + skipTypename: true + scalars: + BigInt: string + Bytes: string + BigDecimal: string + modules/subgraphs/balancer-v3-vault/generated/balancer-v3-schema.graphql: + schema: ${V3_SUBGRAPH} + plugins: + - schema-ast + modules/subgraphs/balancer-v3-pools/generated/types.ts: + schema: ${V3_POOLS_SUBGRAPH} + documents: 'modules/subgraphs/balancer-v3-pools/*.graphql' + plugins: + - typescript + - typescript-operations + - typescript-graphql-request + config: + skipTypename: true + scalars: + BigInt: string + Bytes: string + BigDecimal: string + modules/subgraphs/balancer-v3-pools/generated/balancer-v3-pools-schema.graphql: + schema: ${V3_POOLS_SUBGRAPH} + plugins: + - schema-ast modules/subgraphs/balancer-subgraph/generated/balancer-subgraph-types.ts: schema: ${BALANCER_SUBGRAPH} documents: 'modules/subgraphs/balancer-subgraph/balancer-subgraph-queries.graphql' diff --git a/config/index.ts b/config/index.ts new file mode 100644 index 000000000..384c7b540 --- /dev/null +++ b/config/index.ts @@ -0,0 +1,16 @@ +import { Chain } from '@prisma/client'; +import { sepoliaConfig } from './sepolia'; +import { NetworkData } from '../modules/network/network-config-types'; + +export default { + [Chain.ARBITRUM]: {} as NetworkData, + [Chain.AVALANCHE]: {} as NetworkData, + [Chain.BASE]: {} as NetworkData, + [Chain.FANTOM]: {} as NetworkData, + [Chain.GNOSIS]: {} as NetworkData, + [Chain.MAINNET]: {} as NetworkData, + [Chain.OPTIMISM]: {} as NetworkData, + [Chain.POLYGON]: {} as NetworkData, + [Chain.SEPOLIA]: sepoliaConfig, + [Chain.ZKEVM]: {} as NetworkData, +}; diff --git a/config/sepolia.ts b/config/sepolia.ts new file mode 100644 index 000000000..954990207 --- /dev/null +++ b/config/sepolia.ts @@ -0,0 +1,113 @@ +import { BigNumber } from 'ethers'; +import { env } from '../app/env'; +import { NetworkData } from '../modules/network/network-config-types'; + +export const sepoliaConfig: NetworkData = { + chain: { + slug: 'sepolia', + id: 11155111, + nativeAssetAddress: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + wrappedNativeAssetAddress: '0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9', + prismaId: 'SEPOLIA', + gqlId: 'SEPOLIA', + }, + subgraphs: { + startDate: '2023-05-03', + balancer: 'https://api.studio.thegraph.com/query/24660/balancer-sepolia-v2/version/latest', + balancerV3: 'https://api.studio.thegraph.com/proxy/31386/balancer-v3-sepolia/version/latest', + balancerPoolsV3: 'https://api.studio.thegraph.com/proxy/31386/balancer-pools-v3-sepolia/version/latest', + beetsBar: 'https://', + blocks: 'https://api.studio.thegraph.com/query/48427/bleu-sepolia-blocks/version/latest', + gauge: 'https://api.studio.thegraph.com/proxy/24660/balancer-gauges-sepolia/version/latest', + // veBalLocks: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges', + userBalances: 'https://', + }, + eth: { + address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', + addressFormatted: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', + symbol: 'ETH', + name: 'Ether', + }, + weth: { + address: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', + addressFormatted: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', + }, + coingecko: { + nativeAssetId: 'ethereum', + platformId: 'ethereum', + excludedTokenAddresses: [], + }, + rpcUrl: env.GROVE_CITY + ? `https://sepolia.rpc.grove.city/v1/${env.GROVE_CITY}` + : env.INFURA_API_KEY + ? `https://sepolia.infura.io/v3/${env.INFURA_API_KEY}` + : 'https://gateway.tenderly.co/public/sepolia', + rpcMaxBlockRange: 700, + protocolToken: 'bal', + bal: { + address: '0xb19382073c7A0aDdbb56Ac6AF1808Fa49e377B75', + }, + // veBal: { + // address: '0xc128a9954e6c874ea3d62ce62b468ba073093f25', + // delegationProxy: '0x81cfae226343b24ba12ec6521db2c79e7aeeb310', + // }, + balancer: { + v2: { + vaultAddress: '0xba12222222228d8ba445958a75a0704d566bf2c8', + defaultSwapFeePercentage: '0.5', + defaultYieldFeePercentage: '0.5', + balancerQueriesAddress: '0xe39b5e3b6d74016b2f6a9673d7d7493b6df549d5', + }, + v3: { + vaultAddress: '0xdaa273aeec06e9ccb7428a77e2abb1e4659b16d2', + defaultSwapFeePercentage: '0.5', + defaultYieldFeePercentage: '0.5', + }, + }, + multicall: '0x80c7dd17b01855a6d2347444a0fcc36136a314de', + multicall3: '0xca11bde05977b3631167028862be2a173976ca11', + avgBlockSpeed: 1, + sor: { + main: { + url: 'https://uu6cfghhd5lqa7py3nojxkivd40zuugb.lambda-url.ca-central-1.on.aws/', + maxPools: 8, + forceRefresh: false, + gasPrice: BigNumber.from(10), + swapGas: BigNumber.from('1000000'), + poolIdsToExclude: [], + }, + canary: { + url: 'https://ksa66wlkjbvteijxmflqjehsay0jmekw.lambda-url.eu-central-1.on.aws/', + maxPools: 8, + forceRefresh: false, + gasPrice: BigNumber.from(10), + swapGas: BigNumber.from('1000000'), + poolIdsToExclude: [], + }, + }, + ybAprConfig: {}, + datastudio: { + main: { + user: 'datafeed-service@datastudio-366113.iam.gserviceaccount.com', + sheetId: '11anHUEb9snGwvB-errb5HvO8TvoLTRJhkDdD80Gxw1Q', + databaseTabName: 'Database v2', + compositionTabName: 'Pool Composition v2', + emissionDataTabName: 'EmissionData', + }, + canary: { + user: 'datafeed-service@datastudio-366113.iam.gserviceaccount.com', + sheetId: '1HnJOuRQXGy06tNgqjYMzQNIsaCSCC01Yxe_lZhXBDpY', + databaseTabName: 'Database v2', + compositionTabName: 'Pool Composition v2', + emissionDataTabName: 'EmissionData', + }, + }, + monitoring: { + main: { + alarmTopicArn: 'arn:aws:sns:ca-central-1:118697801881:api_alarms', + }, + canary: { + alarmTopicArn: 'arn:aws:sns:eu-central-1:118697801881:api_alarms', + }, + }, +}; diff --git a/env.local b/env.local index bf4e9fc42..31d2dae37 100644 --- a/env.local +++ b/env.local @@ -20,6 +20,8 @@ WORKER_QUEUE_URL=https://# DEFAULT_CHAIN_ID=250 # Subgraph type config +V3_SUBGRAPH=https://api.studio.thegraph.com/proxy/31386/balancer-v3-sepolia/version/latest +V3_POOLS_SUBGRAPH=https://api.studio.thegraph.com/proxy/31386/balancer-pools-v3-sepolia/version/latest BALANCER_SUBGRAPH=https://api.thegraph.com/subgraphs/name/beethovenxfi/beethovenx MASTERCHEF_SUBGRAPH=https://api.thegraph.com/subgraphs/name/beethovenxfi/masterchefv2 BLOCKS_SUBGRAPH=https://api.thegraph.com/subgraphs/name/danielmkm/optimism-blocks diff --git a/jest.config.js b/jest.config.js index ab69250fa..cda9284cf 100644 --- a/jest.config.js +++ b/jest.config.js @@ -10,4 +10,9 @@ module.exports = { isolatedModules: true, }, }, + moduleNameMapper: { + '^@app/(.*)$': '/app/$1', + '^@config/(.*)$': '/config/$1', + '^@modules/(.*)$': '/modules/$1', + }, }; diff --git a/modules/actions/pool/add-pools-from-subgraph.test.ts b/modules/actions/pool/add-pools-from-subgraph.test.ts new file mode 100644 index 000000000..cf0165764 --- /dev/null +++ b/modules/actions/pool/add-pools-from-subgraph.test.ts @@ -0,0 +1,63 @@ +import { addMissingPoolsFromSubgraph } from './add-pools-from-subgraph'; +import { prisma } from '../../../prisma/prisma-client'; +import { PrismaPool } from '@prisma/client'; +import { PoolFragment as VaultSubgraphPoolFragment } from '../../subgraphs/balancer-v3-vault/generated/types'; +import { TypePoolFragment as PoolSubgraphPoolFragment } from '../../subgraphs/balancer-v3-pools/generated/types'; + +// Mock the module dependencies +jest.mock('@modules/sources/contracts', () => ({ + ...jest.requireActual('@modules/sources/contracts'), + fetchErc20Headers: jest.fn().mockResolvedValue({ '2': { name: 'name', symbol: 'symbol' } }), + fetchWeightedPoolData: jest.fn().mockResolvedValue({}), + fetchPoolTokens: jest.fn().mockResolvedValue({}), +})); + +jest.mock('../../../prisma/prisma-client', () => ({ + prisma: { + prismaPool: { + findMany: jest.fn().mockResolvedValue([{ id: '1' }] as PrismaPool[]), + create: jest.fn(), + }, + prismaToken: { + findMany: jest.fn(), + createMany: jest.fn(), + }, + prismaPoolExpandedTokens: { + createMany: jest.fn(), + }, + prismaPoolTokenDynamicData: { + createMany: jest.fn(), + }, + }, +})); + +describe('syncPools', () => { + const vaultSubgraphClient = { + Pools: jest.fn().mockResolvedValue({ pools: [{ id: '1' }, { id: '2' }] as VaultSubgraphPoolFragment[] }), + }; + const poolSubgraphClient = { + Pools: jest.fn().mockResolvedValue({ + pools: [ + { id: '1', factory: { id: '1' } }, + { id: '2', factory: { id: '1' } }, + ] as PoolSubgraphPoolFragment[], + }), + }; + + beforeEach(() => { + jest.clearAllMocks(); + return addMissingPoolsFromSubgraph(vaultSubgraphClient, poolSubgraphClient, 'SEPOLIA'); + }); + + it('should fetch pools from vault subgraph', async () => { + expect(vaultSubgraphClient.Pools).toHaveBeenCalled(); + }); + + it('should fetch pools from pools subgraph', async () => { + expect(poolSubgraphClient.Pools).toHaveBeenCalled(); + }); + + it('should store missing pools in the database', async () => { + expect(prisma.prismaPool.create).toHaveBeenCalledWith({ data: expect.objectContaining({ id: '2' }) }); + }); +}); diff --git a/modules/actions/pool/add-pools-from-subgraph.ts b/modules/actions/pool/add-pools-from-subgraph.ts new file mode 100644 index 000000000..7af60a10f --- /dev/null +++ b/modules/actions/pool/add-pools-from-subgraph.ts @@ -0,0 +1,143 @@ +import { Chain, Prisma, PrismaPoolType } from '@prisma/client'; +import { prisma } from '../../../prisma/prisma-client'; +import { + poolTransformer, + poolTokensTransformer, + poolTokensDynamicDataTransformer, + poolExpandedTokensTransformer, +} from '../../sources/transformers'; +import { V3PoolsSubgraphClient } from '../../subgraphs/balancer-v3-pools'; +import { V3SubgraphClient } from '../../subgraphs/balancer-v3-vault'; +import { PoolFragment } from '../../subgraphs/balancer-v3-vault/generated/types'; +import { PoolType, TypePoolFragment } from '../../subgraphs/balancer-v3-pools/generated/types'; +import _ from 'lodash'; + +type PoolDbEntry = { + pool: Prisma.PrismaPoolCreateInput; + poolTokenDynamicData: Prisma.PrismaPoolTokenDynamicDataCreateManyInput[]; + poolExpandedTokens: Prisma.PrismaPoolExpandedTokensCreateManyInput[]; +}; +/** + * Makes sure that all pools are synced in the database + * + * @param vaultSubgraphClient + * @param poolSubgraphClient + * @param chain + * @returns syncedPools - the pools that were synced + */ +export async function addMissingPoolsFromSubgraph( + vaultSubgraphClient: Pick, + poolSubgraphClient: V3PoolsSubgraphClient, + // viemClient: ViemClient, + // vaultAddress: string, + chain = 'SEPOLIA' as Chain, +): Promise { + // Fetch pools from subgraph + // TODO this needs paging + const { pools: vaultSubgraphPools } = await vaultSubgraphClient.Pools(); + const { pools: poolSubgraphPools } = await poolSubgraphClient.Pools(); + + // Find pools missing from the database + const dbPools = await prisma.prismaPool.findMany({ where: { chain, vaultVersion: 3 } }); + const dbPoolIds = new Set(dbPools.map((pool) => pool.id.toLowerCase())); + const missingPools = vaultSubgraphPools.filter((pool) => !dbPoolIds.has(pool.id)); + + // Store pool tokens and BPT in the tokens table before creating the pools + try { + const allTokens: { address: string; name: string; decimals: number; symbol: string; chain: Chain }[] = []; + missingPools.forEach((pool) => { + allTokens.push({ + address: pool.address, + decimals: 18, + name: pool.name, + symbol: pool.symbol, + chain: chain, + }); + if (pool.tokens) { + for (const poolToken of pool.tokens) { + allTokens.push({ + address: poolToken.address, + decimals: poolToken.decimals, + name: poolToken.name, + symbol: poolToken.symbol, + chain: chain, + }); + } + } + }); + + await prisma.prismaToken.createMany({ + data: allTokens, + skipDuplicates: true, + }); + } catch (e) { + console.error('Error creating tokens', e); + } + + // Transform pool data for the database + const dbEntries: PoolDbEntry[] = []; + + missingPools.forEach((missingPool) => { + const vaultSubgraphPool = vaultSubgraphPools.find((pool) => pool.id === missingPool.id); + const poolSubgraphPool = poolSubgraphPools.find((pool) => pool.id === missingPool.id); + if (!vaultSubgraphPool || !poolSubgraphPool) { + // That won't happen, but TS doesn't know that + return null; + } + const dbEntry: PoolDbEntry = { + pool: { + ...poolTransformer(vaultSubgraphPool, poolSubgraphPool, chain), + typeData: JSON.stringify({}), + tokens: { + createMany: { + // TODO: Will be great to create all the token data here, including dynamic data + // but for now we can only store static data, because prisma doesn't support nested createMany + // to create dynamic data tabels as well. One solution is to move "dynamicData" to the tokens table + data: poolTokensTransformer(vaultSubgraphPool), + }, + }, + // placeholder data, will be updated with onchain values + dynamicData: { + create: { + id: vaultSubgraphPool.id, + swapFee: '0', + blockNumber: Number(vaultSubgraphPool.blockNumber), + swapEnabled: true, + totalLiquidity: 1, + totalShares: vaultSubgraphPool.totalShares, + totalSharesNum: parseFloat(vaultSubgraphPool.totalShares), + }, + }, + }, + poolTokenDynamicData: poolTokensDynamicDataTransformer(vaultSubgraphPool, poolSubgraphPool, chain), + poolExpandedTokens: poolExpandedTokensTransformer(vaultSubgraphPool, chain), + }; + dbEntries.push(dbEntry); + }); + + // Store missing pools in the database + const added: string[] = []; + for (const entry of dbEntries) { + try { + await prisma.prismaPool.create({ data: entry.pool }); + + await prisma.prismaPoolTokenDynamicData.createMany({ + skipDuplicates: true, + data: entry.poolTokenDynamicData, + }); + + // TODO deal with nested pools + await prisma.prismaPoolExpandedTokens.createMany({ + skipDuplicates: true, + data: entry.poolExpandedTokens, + }); + + added.push(entry.pool.id); + } catch (e) { + // TODO: handle errors + console.error(`Error creating pool ${entry.pool.id}`, e); + } + } + + return added; +} diff --git a/modules/actions/pool/get-changed-pools.ts b/modules/actions/pool/get-changed-pools.ts new file mode 100644 index 000000000..b19423b1d --- /dev/null +++ b/modules/actions/pool/get-changed-pools.ts @@ -0,0 +1,52 @@ +import { Chain, Prisma, PrismaLastBlockSyncedCategory, PrismaPoolType } from '@prisma/client'; +import { prisma } from '../../../prisma/prisma-client'; +import { tokenService } from '../../token/token.service'; +import { fetchPoolTokenInfo, fetchPoolTokenRates } from '../../sources/contracts'; +import { ViemClient } from '../../sources/viem-client'; +import { fetchPoolData } from '../../sources/contracts/fetch-pool-data'; +import { formatEther, formatUnits, parseUnits } from 'viem'; +import { isSameAddress } from '@balancer-labs/sdk'; +import { prismaBulkExecuteOperations } from '../../../prisma/prisma-util'; +import { getPoolBalanceChanged } from '../../sources/logs/get-pool-balance-changed'; +import { start } from 'repl'; +import { getSwaps } from '../../sources/logs'; +import _ from 'lodash'; + +/** + * Get all pool IDs of pools that have emitted a poolBalanceChanged event + * + * @param vaultAddress + * @param viemClient + * @param chain + * @returns list of changed pool IDs + */ +export async function getChangedPools( + vaultAddress: string, + viemClient: ViemClient, + blockNumber: bigint, + chain = 'SEPOLIA' as Chain, +): Promise { + let lastSync = await prisma.prismaLastBlockSynced.findUnique({ + where: { category_chain: { category: PrismaLastBlockSyncedCategory.POOLS, chain: chain } }, + }); + const lastSyncBlock = lastSync?.blockNumber ? BigInt(lastSync.blockNumber) : 0n; + const latestBlock = blockNumber; + + const startBlock = lastSyncBlock + 1n; + const endBlock = latestBlock; + + // no new blocks have been minted, needed for slow networks + if (startBlock > endBlock) { + return []; + } + + const poolBalanceChangedEvents = await getPoolBalanceChanged(vaultAddress, viemClient, startBlock, endBlock); + const poolIdsFromBalanceChangedEvents = poolBalanceChangedEvents.map((event) => event.args.pool!); + + const swapEvents = await getSwaps(vaultAddress, viemClient, startBlock, endBlock); + const poolIdsFromSwapEvents = swapEvents.map((event) => event.args.pool!); + + const changedPoolIds = _.uniq(poolIdsFromBalanceChangedEvents.concat(poolIdsFromSwapEvents)); + + return changedPoolIds; +} diff --git a/modules/actions/pool/update-on-chain-data.ts b/modules/actions/pool/update-on-chain-data.ts new file mode 100644 index 000000000..4183d2074 --- /dev/null +++ b/modules/actions/pool/update-on-chain-data.ts @@ -0,0 +1,222 @@ +import { Chain, Prisma, PrismaPoolType } from '@prisma/client'; +import { prisma } from '../../../prisma/prisma-client'; +import { tokenService } from '../../token/token.service'; +import { fetchPoolTokenInfo, fetchPoolTokenRates } from '../../sources/contracts'; +import { ViemClient } from '../../sources/viem-client'; +import { fetchPoolData } from '../../sources/contracts/fetch-pool-data'; +import { formatEther, formatUnits, parseUnits } from 'viem'; +import { isSameAddress } from '@balancer-labs/sdk'; +import { prismaBulkExecuteOperations } from '../../../prisma/prisma-util'; + +const SUPPORTED_POOL_TYPES: PrismaPoolType[] = ['WEIGHTED', 'STABLE']; + +export async function updateOnchainDataForAllPools( + vaultAddress: string, + viemClient: ViemClient, + blockNumber: bigint, + chain = 'SEPOLIA' as Chain, +): Promise { + const allPools = await prisma.prismaPool.findMany({ + where: { chain: chain, vaultVersion: 3 }, + select: { + id: true, + }, + }); + + return updateOnChainDataForPools( + vaultAddress, + '123', + allPools.map((pool) => pool.id), + viemClient, + blockNumber, + chain, + ); +} + +/** + * Makes sure that all pools are synced in the database + * + * @param vaultSubgraphClient + * @param poolSubgraphClient + * @param chain + * @returns syncedPools - the pools that were synced + */ +export async function updateOnChainDataForPools( + vaultAddress: string, + balancerQueriesAddress: string, + poolIds: string[], + viemClient: ViemClient, + blockNumber: bigint, + chain = 'SEPOLIA' as Chain, +): Promise { + if (poolIds.length === 0) { + return []; + } + const updated: string[] = []; + + const filteredPools = await prisma.prismaPool.findMany({ + where: { + id: { in: poolIds }, + chain: chain, + type: { in: SUPPORTED_POOL_TYPES }, + }, + include: { + tokens: { orderBy: { index: 'asc' }, include: { dynamicData: true, token: true } }, + dynamicData: true, + }, + }); + + const filteredPoolIds = filteredPools.map((pool) => pool.id); + const filteredPoolInputs = filteredPools.map((pool) => ({ + id: pool.id, + address: pool.address, + type: pool.type, + version: pool.version, + })); + + const tokenPricesForCurrentChain = await tokenService.getTokenPrices(chain); + const poolTokenData = await fetchPoolTokenInfo(vaultAddress, filteredPoolIds, viemClient, blockNumber); + const poolTokenRatesData = await fetchPoolTokenRates(vaultAddress, filteredPoolIds, viemClient, blockNumber); + const poolConfigData = await fetchPoolData(vaultAddress, filteredPoolInputs, viemClient, blockNumber); + + // TODO also need to add tokenPairs for SOR and calc normalized liquidity + // const tokenPairData = await fetchTokenPairData( + // filteredPools, + // balancerQueriesAddress, + // chain === 'ZKEVM' ? 190 : 1024, + // ); + + const operations = []; + for (const pool of filteredPools) { + const poolTokens = poolTokenData[pool.id]; + const poolTokenRates = poolTokenRatesData[pool.id]; + const poolConfig = poolConfigData[pool.id]; + + try { + // if (isStablePool(pool.type)) { + // if (!amp) { + // console.error(`Stable Pool Missing Amp: ${pool.id}`); + // continue; + // } + + // //only update if amp has changed + // if ((pool.typeData as StableData).amp !== amp) { + // operations.push( + // prisma.prismaPool.update({ + // where: { id_chain: { id: pool.id, chain: this.options.chain } }, + // data: { + // typeData: { + // ...(pool.typeData as StableData), + // amp, + // }, + // }, + // }), + // ); + // } + // } + + const swapFee = poolConfig.swapFee.toString(); + const totalSupply = formatEther(poolConfig.totalSupply); + const swapEnabled = !poolConfig.isPoolPaused; + const isPaused = poolConfig.isPoolPaused; + const isInRecoveryMode = poolConfig.isPoolInRecoveryMode; + + const yieldProtocolFeePercentage = '0'; // TODO + const protocolSwapFeePercentage = poolConfig.protocolSwapFeePercentage.toString(); + + if ( + pool.dynamicData && + (pool.dynamicData.swapFee !== swapFee || + pool.dynamicData.totalShares !== totalSupply || + pool.dynamicData.swapEnabled !== swapEnabled || + pool.dynamicData.protocolYieldFee !== yieldProtocolFeePercentage || + pool.dynamicData.protocolSwapFee !== protocolSwapFeePercentage || + pool.dynamicData.isInRecoveryMode !== isInRecoveryMode || + pool.dynamicData.isPaused !== isPaused) + ) { + operations.push( + prisma.prismaPoolDynamicData.update({ + where: { id_chain: { id: pool.id, chain: chain } }, + data: { + swapFee, + totalShares: totalSupply, + totalSharesNum: parseFloat(totalSupply), + swapEnabled: typeof swapEnabled !== 'undefined' ? swapEnabled : true, + isInRecoveryMode: isInRecoveryMode, + isPaused: isPaused, + protocolYieldFee: yieldProtocolFeePercentage, + protocolSwapFee: protocolSwapFeePercentage, + blockNumber: parseFloat(blockNumber.toString()), + }, + }), + ); + } + + // always update tokenPair data + // if (pool.dynamicData) { + // operations.push( + // prisma.prismaPoolDynamicData.update({ + // where: { id_chain: { id: pool.id, chain: this.options.chain } }, + // data: { + // tokenPairsData: tokenPairs, + // }, + // }), + // ); + // } + + for (let i = 0; i < poolTokens.tokens.length; i++) { + const tokenAddress = poolTokens.tokens[i]; + const poolToken = pool.tokens.find((token) => isSameAddress(token.address, tokenAddress)); + + if (!poolToken) { + throw `Pool Missing Expected Token: ${pool.id} ${tokenAddress}`; + } + + if (poolToken.index !== i) { + throw `Pooltoken index mismatch! "poolToken.index": ${poolToken.index} vs "i": ${i} on pool ${pool.id}`; + } + + const balance = formatUnits(poolTokens.balancesRaw[i], poolToken.token.decimals); + + // set token price rate for various rate types + + // top level token rates, e.g. LSTs in pools + let priceRate = formatEther(poolTokenRates[i]); + + // // bpt price rate + // if (onchainData.rate && isSameAddress(poolToken.address, pool.address)) { + // priceRate = onchainData.rate; + // } + + // TODO v3 does not contain the BPT as pool token, do we need to add it nevertheless? + + if ( + !poolToken.dynamicData || + poolToken.dynamicData.balance !== balance || + poolToken.dynamicData.priceRate !== priceRate + ) { + operations.push( + prisma.prismaPoolTokenDynamicData.update({ + where: { id_chain: { id: poolToken.id, chain: chain } }, + data: { + blockNumber: parseFloat(blockNumber.toString()), + priceRate, + balance, + balanceUSD: + poolToken.address === pool.address + ? 0 + : tokenService.getPriceForToken(tokenPricesForCurrentChain, poolToken.address) * + parseFloat(balance), + }, + }), + ); + } + } + } catch (e) { + console.log('error syncing on chain data', e); + } + } + await prismaBulkExecuteOperations(operations, false); + + return updated; +} diff --git a/modules/content/github-content.service.ts b/modules/content/github-content.service.ts index b8eecb11d..079adc6cc 100644 --- a/modules/content/github-content.service.ts +++ b/modules/content/github-content.service.ts @@ -4,7 +4,7 @@ import axios from 'axios'; import { prisma } from '../../prisma/prisma-client'; import { networkContext } from '../network/network-context.service'; import { ContentService, FeaturedPool, HomeScreenFeaturedPoolGroup, HomeScreenNewsItem } from './content-types'; -import { chainIdToChain } from '../network/network-config'; +import { chainIdToChain } from '../network/chain-id-to-chain'; import { LinearData } from '../pool/subgraph-mapper'; const POOLS_METADATA_URL = 'https://raw.githubusercontent.com/balancer/metadata/main/pools/featured.json'; diff --git a/modules/context/header-chain.ts b/modules/context/header-chain.ts index 799f9d097..55224f32b 100644 --- a/modules/context/header-chain.ts +++ b/modules/context/header-chain.ts @@ -1,6 +1,6 @@ import { getRequestScopeContextValue } from '../context/request-scoped-context'; import { Chain } from '@prisma/client'; -import { chainIdToChain } from '../network/network-config'; +import { chainIdToChain } from '../network/chain-id-to-chain'; /** * Setup to transition out from the old header-based chainIDs to the new required chain query filters. diff --git a/modules/controllers/jobs-controller.test.ts b/modules/controllers/jobs-controller.test.ts new file mode 100644 index 000000000..537d322f2 --- /dev/null +++ b/modules/controllers/jobs-controller.test.ts @@ -0,0 +1,20 @@ +import { addMissingPoolsFromSubgraph } from '../actions/pool/add-pools-from-subgraph'; +import { JobsController } from './jobs-controller'; +// Mock the actions +jest.mock('@modules/actions/jobs_actions', () => ({ + syncPools: jest.fn(), +})); + +describe('jobsController', () => { + const jobsController = JobsController(); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should call getClient with correct chain', () => { + jobsController.addMissingPoolsFromSubgraph('11155111'); + + expect(addMissingPoolsFromSubgraph).toHaveBeenCalled(); + }); +}); diff --git a/modules/controllers/jobs-controller.ts b/modules/controllers/jobs-controller.ts new file mode 100644 index 000000000..79fc608ed --- /dev/null +++ b/modules/controllers/jobs-controller.ts @@ -0,0 +1,92 @@ +import { update } from 'lodash'; +import config from '../../config'; +import { addMissingPoolsFromSubgraph } from '../actions/pool/add-pools-from-subgraph'; +import { getChangedPools } from '../actions/pool/get-changed-pools'; +import { updateOnChainDataForPools } from '../actions/pool/update-on-chain-data'; +import { chainIdToChain } from '../network/chain-id-to-chain'; +import { getViemClient } from '../sources/viem-client'; +import { getPoolsSubgraphClient } from '../subgraphs/balancer-v3-pools'; +import { getVaultSubgraphClient } from '../subgraphs/balancer-v3-vault'; + +/** + * Controller responsible for matching job requests to configured job handlers + * + * @param name - the name of the job + * @param chain - the chain to run the job on + * @returns a controller with configured job handlers + */ +export function JobsController(tracer?: any) { + // Setup tracing + // ... + return { + async addMissingPoolsFromSubgraph(chainId: string) { + const chain = chainIdToChain[chainId]; + const { + subgraphs: { balancerV3, balancerPoolsV3 }, + balancer: { + v3: { vaultAddress }, + }, + } = config[chain]; + + // Guard against unconfigured chains + if (!balancerV3) { + throw new Error(`Chain not configured: ${chain}`); + } + + const vaultSubgraphClient = getVaultSubgraphClient(balancerV3); + const poolSubgraphClient = getPoolsSubgraphClient(balancerPoolsV3!); + const viemClient = getViemClient(chain); + const latestBlock = await viemClient.getBlockNumber(); + + // TODO: add syncing v2 pools as well by splitting the poolService into separate + // actions with extracted configuration + + // find all missing pools and add them to the DB + const added = await addMissingPoolsFromSubgraph(vaultSubgraphClient, poolSubgraphClient, chain); + + // update with latest on-chain data + const updated = await updateOnChainDataForPools(vaultAddress, '123', added, viemClient, latestBlock); + + // also sync swaps and volumeAndFee values + // const poolsWithNewSwaps = await poolService.syncSwapsForLast48Hours(); + // await poolService.updateVolumeAndFeeValuesForPools(poolsWithNewSwaps); + + return updated; + }, + async updateOnChainDataChangedPools(chainId: string) { + const chain = chainIdToChain[chainId]; + const { + balancer: { + v3: { vaultAddress }, + }, + } = config[chain]; + + // Guard against unconfigured chains + if (!vaultAddress) { + throw new Error(`Chain not configured: ${chain}`); + } + const viemClient = getViemClient(chain); + + const blockNumber = await viemClient.getBlockNumber(); + + const changedPools = await getChangedPools(vaultAddress, viemClient, blockNumber, chain); + if (changedPools.length === 0) { + return []; + } + + const updated = updateOnChainDataForPools( + vaultAddress, + '123', + changedPools, + viemClient, + blockNumber, + chain, + ); + // also sync swaps and volumeAndFee values + // const poolsWithNewSwaps = await poolService.syncSwapsForLast48Hours(); + // await poolService.updateVolumeAndFeeValuesForPools(poolsWithNewSwaps); + + return updated; + }, + }; +} diff --git a/modules/controllers/pools-controller.ts b/modules/controllers/pools-controller.ts new file mode 100644 index 000000000..400d1c5e9 --- /dev/null +++ b/modules/controllers/pools-controller.ts @@ -0,0 +1,36 @@ +import config from '../../config'; +import { updateOnchainDataForAllPools } from '../actions/pool/update-on-chain-data'; +import { chainIdToChain } from '../network/chain-id-to-chain'; +import { getViemClient } from '../sources/viem-client'; + +/** + * Controller responsible for matching job requests to configured job handlers + * + * @param name - the name of the job + * @param chain - the chain to run the job on + * @returns a controller with configured job handlers + */ +export function PoolsController(tracer?: any) { + // Setup tracing + // ... + return { + async updateOnChainDataForAllPools(chainId: string) { + const chain = chainIdToChain[chainId]; + const { + balancer: { + v3: { vaultAddress }, + }, + } = config[chain]; + + // Guard against unconfigured chains + if (!vaultAddress) { + throw new Error(`Chain not configured: ${chain}`); + } + const viemClient = getViemClient(chain); + const latestBlockNumber = await viemClient.getBlockNumber(); + + const updated = updateOnchainDataForAllPools(vaultAddress, viemClient, latestBlockNumber, chain); + return updated; + }, + }; +} diff --git a/modules/network/chain-id-to-chain.ts b/modules/network/chain-id-to-chain.ts new file mode 100644 index 000000000..49cdba0ab --- /dev/null +++ b/modules/network/chain-id-to-chain.ts @@ -0,0 +1,14 @@ +import { Chain } from '@prisma/client'; + +export const chainIdToChain: { [id: string]: Chain } = { + '1': Chain.MAINNET, + '10': Chain.OPTIMISM, + '100': Chain.GNOSIS, + '137': Chain.POLYGON, + '250': Chain.FANTOM, + '1101': Chain.ZKEVM, + '8453': Chain.BASE, + '42161': Chain.ARBITRUM, + '43114': Chain.AVALANCHE, + '11155111': Chain.SEPOLIA, +}; diff --git a/modules/network/network-config-types.ts b/modules/network/network-config-types.ts index 345b484ca..595ba5269 100644 --- a/modules/network/network-config-types.ts +++ b/modules/network/network-config-types.ts @@ -65,6 +65,8 @@ export interface NetworkData { subgraphs: { startDate: string; balancer: string; + balancerV3?: string; + balancerPoolsV3?: string; blocks: string; masterchef?: string; reliquary?: string; diff --git a/modules/network/network-config.ts b/modules/network/network-config.ts index fd555b33e..1cb0c6033 100644 --- a/modules/network/network-config.ts +++ b/modules/network/network-config.ts @@ -37,19 +37,6 @@ export const AllNetworkConfigsKeyedOnChain: { [chain in Chain]: NetworkConfig } SEPOLIA: sepoliaNetworkConfig, }; -export const chainIdToChain: { [id: string]: Chain } = { - '1': Chain.MAINNET, - '10': Chain.OPTIMISM, - '100': Chain.GNOSIS, - '137': Chain.POLYGON, - '250': Chain.FANTOM, - '1101': Chain.ZKEVM, - '8453': Chain.BASE, - '42161': Chain.ARBITRUM, - '43114': Chain.AVALANCHE, - '11155111': Chain.SEPOLIA, -}; - export const BalancerChainIds = ['1', '137', '42161', '100', '1101', '43114', '8453', '11155111']; export const BeethovenChainIds = ['250', '10']; diff --git a/modules/network/sepolia.ts b/modules/network/sepolia.ts index c25dbb054..b3ae77b27 100644 --- a/modules/network/sepolia.ts +++ b/modules/network/sepolia.ts @@ -1,5 +1,5 @@ -import { BigNumber, ethers } from 'ethers'; -import { DeploymentEnv, NetworkConfig, NetworkData } from './network-config-types'; +import { ethers } from 'ethers'; +import { NetworkConfig } from './network-config-types'; import { tokenService } from '../token/token.service'; import { PhantomStableAprService } from '../pool/lib/apr-data-sources/phantom-stable-apr.service'; import { BoostedPoolAprService } from '../pool/lib/apr-data-sources/boosted-pool-apr.service'; @@ -13,117 +13,11 @@ import { UserSyncGaugeBalanceService } from '../user/lib/user-sync-gauge-balance import { every } from '../../worker/intervals'; import { GithubContentService } from '../content/github-content.service'; import { gaugeSubgraphService } from '../subgraphs/gauge-subgraph/gauge-subgraph.service'; -import { CoingeckoPriceHandlerService } from '../token/lib/token-price-handlers/coingecko-price-handler.service'; -import { coingeckoService } from '../coingecko/coingecko.service'; import { YbTokensAprService } from '../pool/lib/apr-data-sources/yb-tokens-apr.service'; -import { env } from '../../app/env'; import { BalancerSubgraphService } from '../subgraphs/balancer-subgraph/balancer-subgraph.service'; +import { sepoliaConfig as sepoliaNetworkData } from '../../config/sepolia'; -export const sepoliaNetworkData: NetworkData = { - chain: { - slug: 'sepolia', - id: 11155111, - nativeAssetAddress: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - wrappedNativeAssetAddress: '0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9', - prismaId: 'SEPOLIA', - gqlId: 'SEPOLIA', - }, - subgraphs: { - startDate: '2023-05-03', - balancer: 'https://api.studio.thegraph.com/query/24660/balancer-sepolia-v2/version/latest', - beetsBar: 'https://', - blocks: 'https://api.studio.thegraph.com/query/48427/bleu-sepolia-blocks/version/latest', - gauge: 'https://api.studio.thegraph.com/proxy/24660/balancer-gauges-sepolia/version/latest', - // veBalLocks: 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges', - userBalances: 'https://', - }, - eth: { - address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', - addressFormatted: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', - symbol: 'ETH', - name: 'Ether', - }, - weth: { - address: '0x82af49447d8a07e3bd95bd0d56f35241523fbab1', - addressFormatted: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', - }, - coingecko: { - nativeAssetId: 'ethereum', - platformId: 'ethereum', - excludedTokenAddresses: [], - }, - rpcUrl: env.INFURA_API_KEY - ? `https://sepolia.infura.io/v3/${env.INFURA_API_KEY}` - : 'https://gateway.tenderly.co/public/sepolia', - rpcMaxBlockRange: 700, - protocolToken: 'bal', - bal: { - address: '0xb19382073c7A0aDdbb56Ac6AF1808Fa49e377B75', - }, - // veBal: { - // address: '0xc128a9954e6c874ea3d62ce62b468ba073093f25', - // delegationProxy: '0x81cfae226343b24ba12ec6521db2c79e7aeeb310', - // }, - balancer: { - v2: { - vaultAddress: '0xba12222222228d8ba445958a75a0704d566bf2c8', - defaultSwapFeePercentage: '0.5', - defaultYieldFeePercentage: '0.5', - balancerQueriesAddress: '0xe39b5e3b6d74016b2f6a9673d7d7493b6df549d5', - }, - v3: { - vaultAddress: '0x816e90DC85bF016455017a76Bc09CC0451Eeb308', - defaultSwapFeePercentage: '0.5', - defaultYieldFeePercentage: '0.5', - }, - }, - multicall: '0x80c7dd17b01855a6d2347444a0fcc36136a314de', - multicall3: '0xca11bde05977b3631167028862be2a173976ca11', - avgBlockSpeed: 1, - sor: { - main: { - url: 'https://uu6cfghhd5lqa7py3nojxkivd40zuugb.lambda-url.ca-central-1.on.aws/', - maxPools: 8, - forceRefresh: false, - gasPrice: BigNumber.from(10), - swapGas: BigNumber.from('1000000'), - poolIdsToExclude: [], - }, - canary: { - url: 'https://ksa66wlkjbvteijxmflqjehsay0jmekw.lambda-url.eu-central-1.on.aws/', - maxPools: 8, - forceRefresh: false, - gasPrice: BigNumber.from(10), - swapGas: BigNumber.from('1000000'), - poolIdsToExclude: [], - }, - }, - ybAprConfig: {}, - datastudio: { - main: { - user: 'datafeed-service@datastudio-366113.iam.gserviceaccount.com', - sheetId: '11anHUEb9snGwvB-errb5HvO8TvoLTRJhkDdD80Gxw1Q', - databaseTabName: 'Database v2', - compositionTabName: 'Pool Composition v2', - emissionDataTabName: 'EmissionData', - }, - canary: { - user: 'datafeed-service@datastudio-366113.iam.gserviceaccount.com', - sheetId: '1HnJOuRQXGy06tNgqjYMzQNIsaCSCC01Yxe_lZhXBDpY', - databaseTabName: 'Database v2', - compositionTabName: 'Pool Composition v2', - emissionDataTabName: 'EmissionData', - }, - }, - monitoring: { - main: { - alarmTopicArn: 'arn:aws:sns:ca-central-1:118697801881:api_alarms', - }, - canary: { - alarmTopicArn: 'arn:aws:sns:eu-central-1:118697801881:api_alarms', - }, - }, -}; +export { sepoliaNetworkData }; export const sepoliaNetworkConfig: NetworkConfig = { data: sepoliaNetworkData, @@ -220,25 +114,17 @@ export const sepoliaNetworkConfig: NetworkConfig = { name: 'user-sync-staked-balances', interval: every(5, 'minutes'), }, - // { - // name: 'sync-coingecko-coinids', - // interval: every(2, 'hours'), - // }, { name: 'update-fee-volume-yield-all-pools', interval: every(1, 'hours'), }, - // { - // name: 'sync-vebal-balances', - // interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(9, 'minutes') : every(3, 'minutes'), - // }, - // { - // name: 'sync-vebal-totalSupply', - // interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(10, 'minutes') : every(5, 'minutes'), - // }, - // { - // name: 'feed-data-to-datastudio', - // interval: (env.DEPLOYMENT_ENV as DeploymentEnv) === 'canary' ? every(5, 'minutes') : every(5, 'minutes'), - // }, + { + name: 'sync-changed-pools-v3', + interval: every(15, 'minutes'), + }, + { + name: 'sync-new-pools-from-subgraph-v3', + interval: every(20, 'minutes'), + }, ], }; diff --git a/modules/pool/abi/VaultV3.json b/modules/pool/abi/VaultV3.json deleted file mode 100644 index 2e0ae17c0..000000000 --- a/modules/pool/abi/VaultV3.json +++ /dev/null @@ -1,3401 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "contract IVaultExtension", - "name": "vaultExtension", - "type": "address" - }, - { - "internalType": "contract IAuthorizer", - "name": "authorizer", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "target", - "type": "address" - } - ], - "name": "AddressEmptyCode", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "AddressInsufficientBalance", - "type": "error" - }, - { - "inputs": [], - "name": "AllZeroInputs", - "type": "error" - }, - { - "inputs": [], - "name": "AmountGivenZero", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limit", - "type": "uint256" - } - ], - "name": "AmountInAboveMax", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limit", - "type": "uint256" - } - ], - "name": "AmountOutBelowMin", - "type": "error" - }, - { - "inputs": [], - "name": "BalanceNotSettled", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limit", - "type": "uint256" - } - ], - "name": "BptAmountInAboveMax", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limit", - "type": "uint256" - } - ], - "name": "BptAmountOutBelowMin", - "type": "error" - }, - { - "inputs": [], - "name": "CallbackFailed", - "type": "error" - }, - { - "inputs": [], - "name": "CannotReceiveEth", - "type": "error" - }, - { - "inputs": [], - "name": "CannotSwapSameToken", - "type": "error" - }, - { - "inputs": [], - "name": "DoesNotSupportAddLiquidityCustom", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "allowance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "needed", - "type": "uint256" - } - ], - "name": "ERC20InsufficientAllowance", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "needed", - "type": "uint256" - } - ], - "name": "ERC20InsufficientBalance", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "approver", - "type": "address" - } - ], - "name": "ERC20InvalidApprover", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "receiver", - "type": "address" - } - ], - "name": "ERC20InvalidReceiver", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "ERC20InvalidSender", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - } - ], - "name": "ERC20InvalidSpender", - "type": "error" - }, - { - "inputs": [], - "name": "FailedInnerCall", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "HandlerOutOfBounds", - "type": "error" - }, - { - "inputs": [], - "name": "InputLengthMismatch", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidAddLiquidityKind", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidRemoveLiquidityKind", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidToken", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidTokenConfiguration", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidTokenType", - "type": "error" - }, - { - "inputs": [], - "name": "MaxTokens", - "type": "error" - }, - { - "inputs": [], - "name": "MinTokens", - "type": "error" - }, - { - "inputs": [], - "name": "MultipleNonZeroInputs", - "type": "error" - }, - { - "inputs": [], - "name": "NoHandler", - "type": "error" - }, - { - "inputs": [], - "name": "NotStaticCall", - "type": "error" - }, - { - "inputs": [], - "name": "NotVaultDelegateCall", - "type": "error" - }, - { - "inputs": [], - "name": "PauseBufferPeriodDurationTooLarge", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolAlreadyInitialized", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolAlreadyRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolInRecoveryMode", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolNotInRecoveryMode", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolNotInitialized", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolNotPaused", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolNotRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolPauseWindowExpired", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolPaused", - "type": "error" - }, - { - "inputs": [], - "name": "ProtocolSwapFeePercentageTooHigh", - "type": "error" - }, - { - "inputs": [], - "name": "QueriesDisabled", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrancyGuardReentrantCall", - "type": "error" - }, - { - "inputs": [], - "name": "RouterNotTrusted", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint8", - "name": "bits", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "SafeCastOverflowedUintDowncast", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "SafeCastOverflowedUintToInt", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - } - ], - "name": "SafeERC20FailedOperation", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "SenderIsNotPauseManager", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "SenderIsNotVault", - "type": "error" - }, - { - "inputs": [], - "name": "SwapFeePercentageTooHigh", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - } - ], - "name": "TokenAlreadyRegistered", - "type": "error" - }, - { - "inputs": [], - "name": "TokenNotRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "address", - "name": "expectedToken", - "type": "address" - }, - { - "internalType": "address", - "name": "actualToken", - "type": "address" - } - ], - "name": "TokensMismatch", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limit", - "type": "uint256" - } - ], - "name": "TotalSupplyTooLow", - "type": "error" - }, - { - "inputs": [], - "name": "UserDataNotSupported", - "type": "error" - }, - { - "inputs": [], - "name": "VaultNotPaused", - "type": "error" - }, - { - "inputs": [], - "name": "VaultPauseWindowDurationTooLarge", - "type": "error" - }, - { - "inputs": [], - "name": "VaultPauseWindowExpired", - "type": "error" - }, - { - "inputs": [], - "name": "VaultPaused", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "handler", - "type": "address" - }, - { - "internalType": "address", - "name": "caller", - "type": "address" - } - ], - "name": "WrongHandler", - "type": "error" - }, - { - "inputs": [], - "name": "WrongVaultExtensionDeployment", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroDivision", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "contract IAuthorizer", - "name": "newAuthorizer", - "type": "address" - } - ], - "name": "AuthorizerChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "liquidityProvider", - "type": "address" - }, - { - "indexed": false, - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "int256[]", - "name": "deltas", - "type": "int256[]" - } - ], - "name": "PoolBalanceChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolInitialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "paused", - "type": "bool" - } - ], - "name": "PoolPausedStateChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "recoveryMode", - "type": "bool" - } - ], - "name": "PoolRecoveryModeStateChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "factory", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "internalType": "enum TokenType", - "name": "tokenType", - "type": "uint8" - }, - { - "internalType": "contract IRateProvider", - "name": "rateProvider", - "type": "address" - }, - { - "internalType": "bool", - "name": "yieldFeeExempt", - "type": "bool" - } - ], - "indexed": false, - "internalType": "struct TokenConfig[]", - "name": "tokenConfig", - "type": "tuple[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "pauseWindowEndTime", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "pauseManager", - "type": "address" - }, - { - "components": [ - { - "internalType": "bool", - "name": "shouldCallBeforeInitialize", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterInitialize", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallBeforeSwap", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterSwap", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallBeforeAddLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterAddLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallBeforeRemoveLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterRemoveLiquidity", - "type": "bool" - } - ], - "indexed": false, - "internalType": "struct PoolCallbacks", - "name": "callbacks", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "bool", - "name": "supportsAddLiquidityCustom", - "type": "bool" - }, - { - "internalType": "bool", - "name": "supportsRemoveLiquidityCustom", - "type": "bool" - } - ], - "indexed": false, - "internalType": "struct LiquidityManagement", - "name": "liquidityManagement", - "type": "tuple" - } - ], - "name": "PoolRegistered", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "ProtocolFeeCollected", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "swapFeePercentage", - "type": "uint256" - } - ], - "name": "ProtocolSwapFeePercentageChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "indexed": true, - "internalType": "contract IERC20", - "name": "tokenIn", - "type": "address" - }, - { - "indexed": true, - "internalType": "contract IERC20", - "name": "tokenOut", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "swapFeeAmount", - "type": "uint256" - } - ], - "name": "Swap", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bool", - "name": "paused", - "type": "bool" - } - ], - "name": "VaultPausedStateChanged", - "type": "event" - }, - { - "stateMutability": "payable", - "type": "fallback" - }, - { - "inputs": [], - "name": "MAX_BUFFER_PERIOD_DURATION", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MAX_PAUSE_WINDOW_DURATION", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256[]", - "name": "maxAmountsIn", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "minBptAmountOut", - "type": "uint256" - }, - { - "internalType": "enum AddLiquidityKind", - "name": "kind", - "type": "uint8" - }, - { - "internalType": "bytes", - "name": "userData", - "type": "bytes" - } - ], - "internalType": "struct AddLiquidityParams", - "name": "params", - "type": "tuple" - } - ], - "name": "addLiquidity", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amountsIn", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "bptAmountOut", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "returnData", - "type": "bytes" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getVaultExtension", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "invoke", - "outputs": [ - { - "internalType": "bytes", - "name": "result", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxBptAmountIn", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "minAmountsOut", - "type": "uint256[]" - }, - { - "internalType": "enum RemoveLiquidityKind", - "name": "kind", - "type": "uint8" - }, - { - "internalType": "bytes", - "name": "userData", - "type": "bytes" - } - ], - "internalType": "struct RemoveLiquidityParams", - "name": "params", - "type": "tuple" - } - ], - "name": "removeLiquidity", - "outputs": [ - { - "internalType": "uint256", - "name": "bptAmountIn", - "type": "uint256" - }, - { - "internalType": "uint256[]", - "name": "amountsOut", - "type": "uint256[]" - }, - { - "internalType": "bytes", - "name": "returnData", - "type": "bytes" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "exactBptAmountIn", - "type": "uint256" - } - ], - "name": "removeLiquidityRecovery", - "outputs": [ - { - "internalType": "uint256[]", - "name": "amountsOutRaw", - "type": "uint256[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "retrieve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - } - ], - "name": "settle", - "outputs": [ - { - "internalType": "uint256", - "name": "paid", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "enum SwapKind", - "name": "kind", - "type": "uint8" - }, - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "contract IERC20", - "name": "tokenIn", - "type": "address" - }, - { - "internalType": "contract IERC20", - "name": "tokenOut", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amountGivenRaw", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "userData", - "type": "bytes" - } - ], - "internalType": "struct SwapParams", - "name": "params", - "type": "tuple" - } - ], - "name": "swap", - "outputs": [ - { - "internalType": "uint256", - "name": "amountCalculated", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountIn", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "amountOut", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "wire", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" - }, - - "inputs": [ - { - "internalType": "contract IVault", - "name": "mainVault", - "type": "address" - }, - { - "internalType": "uint256", - "name": "pauseWindowDuration", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "bufferPeriodDuration", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "target", - "type": "address" - } - ], - "name": "AddressEmptyCode", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "AddressInsufficientBalance", - "type": "error" - }, - { - "inputs": [], - "name": "AmountGivenZero", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limit", - "type": "uint256" - } - ], - "name": "AmountInAboveMax", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limit", - "type": "uint256" - } - ], - "name": "AmountOutBelowMin", - "type": "error" - }, - { - "inputs": [], - "name": "BalanceNotSettled", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limit", - "type": "uint256" - } - ], - "name": "BptAmountInAboveMax", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limit", - "type": "uint256" - } - ], - "name": "BptAmountOutBelowMin", - "type": "error" - }, - { - "inputs": [], - "name": "CallbackFailed", - "type": "error" - }, - { - "inputs": [], - "name": "CannotReceiveEth", - "type": "error" - }, - { - "inputs": [], - "name": "CannotSwapSameToken", - "type": "error" - }, - { - "inputs": [], - "name": "CodecOverflow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "allowance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "needed", - "type": "uint256" - } - ], - "name": "ERC20InsufficientAllowance", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "needed", - "type": "uint256" - } - ], - "name": "ERC20InsufficientBalance", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "approver", - "type": "address" - } - ], - "name": "ERC20InvalidApprover", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "receiver", - "type": "address" - } - ], - "name": "ERC20InvalidReceiver", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "ERC20InvalidSender", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - } - ], - "name": "ERC20InvalidSpender", - "type": "error" - }, - { - "inputs": [], - "name": "FailedInnerCall", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "HandlerOutOfBounds", - "type": "error" - }, - { - "inputs": [], - "name": "InputLengthMismatch", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidAddLiquidityKind", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidRemoveLiquidityKind", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidToken", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidTokenConfiguration", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidTokenType", - "type": "error" - }, - { - "inputs": [], - "name": "MaxTokens", - "type": "error" - }, - { - "inputs": [], - "name": "MinTokens", - "type": "error" - }, - { - "inputs": [], - "name": "NoHandler", - "type": "error" - }, - { - "inputs": [], - "name": "NotStaticCall", - "type": "error" - }, - { - "inputs": [], - "name": "NotVaultDelegateCall", - "type": "error" - }, - { - "inputs": [], - "name": "OutOfBounds", - "type": "error" - }, - { - "inputs": [], - "name": "PauseBufferPeriodDurationTooLarge", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolAlreadyInitialized", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolAlreadyRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolInRecoveryMode", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolNotInRecoveryMode", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolNotInitialized", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolNotPaused", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolNotRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolPauseWindowExpired", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolPaused", - "type": "error" - }, - { - "inputs": [], - "name": "ProtocolSwapFeePercentageTooHigh", - "type": "error" - }, - { - "inputs": [], - "name": "QueriesDisabled", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrancyGuardReentrantCall", - "type": "error" - }, - { - "inputs": [], - "name": "RouterNotTrusted", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint8", - "name": "bits", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "SafeCastOverflowedUintDowncast", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "SafeCastOverflowedUintToInt", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - } - ], - "name": "SafeERC20FailedOperation", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "SenderIsNotPauseManager", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "SenderIsNotVault", - "type": "error" - }, - { - "inputs": [], - "name": "SenderNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "SwapFeePercentageTooHigh", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - } - ], - "name": "TokenAlreadyRegistered", - "type": "error" - }, - { - "inputs": [], - "name": "TokenNotRegistered", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "address", - "name": "expectedToken", - "type": "address" - }, - { - "internalType": "address", - "name": "actualToken", - "type": "address" - } - ], - "name": "TokensMismatch", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "limit", - "type": "uint256" - } - ], - "name": "TotalSupplyTooLow", - "type": "error" - }, - { - "inputs": [], - "name": "UserDataNotSupported", - "type": "error" - }, - { - "inputs": [], - "name": "VaultNotPaused", - "type": "error" - }, - { - "inputs": [], - "name": "VaultPauseWindowDurationTooLarge", - "type": "error" - }, - { - "inputs": [], - "name": "VaultPauseWindowExpired", - "type": "error" - }, - { - "inputs": [], - "name": "VaultPaused", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "handler", - "type": "address" - }, - { - "internalType": "address", - "name": "caller", - "type": "address" - } - ], - "name": "WrongHandler", - "type": "error" - }, - { - "inputs": [], - "name": "WrongVaultExtensionDeployment", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "contract IAuthorizer", - "name": "newAuthorizer", - "type": "address" - } - ], - "name": "AuthorizerChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "liquidityProvider", - "type": "address" - }, - { - "indexed": false, - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - }, - { - "indexed": false, - "internalType": "int256[]", - "name": "deltas", - "type": "int256[]" - } - ], - "name": "PoolBalanceChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolInitialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "paused", - "type": "bool" - } - ], - "name": "PoolPausedStateChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "recoveryMode", - "type": "bool" - } - ], - "name": "PoolRecoveryModeStateChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "factory", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "internalType": "enum TokenType", - "name": "tokenType", - "type": "uint8" - }, - { - "internalType": "contract IRateProvider", - "name": "rateProvider", - "type": "address" - }, - { - "internalType": "bool", - "name": "yieldFeeExempt", - "type": "bool" - } - ], - "indexed": false, - "internalType": "struct TokenConfig[]", - "name": "tokenConfig", - "type": "tuple[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "pauseWindowEndTime", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "pauseManager", - "type": "address" - }, - { - "components": [ - { - "internalType": "bool", - "name": "shouldCallBeforeInitialize", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterInitialize", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallBeforeSwap", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterSwap", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallBeforeAddLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterAddLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallBeforeRemoveLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterRemoveLiquidity", - "type": "bool" - } - ], - "indexed": false, - "internalType": "struct PoolCallbacks", - "name": "callbacks", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "bool", - "name": "supportsAddLiquidityCustom", - "type": "bool" - }, - { - "internalType": "bool", - "name": "supportsRemoveLiquidityCustom", - "type": "bool" - } - ], - "indexed": false, - "internalType": "struct LiquidityManagement", - "name": "liquidityManagement", - "type": "tuple" - } - ], - "name": "PoolRegistered", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "ProtocolFeeCollected", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "swapFeePercentage", - "type": "uint256" - } - ], - "name": "ProtocolSwapFeePercentageChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "swapFeePercentage", - "type": "uint256" - } - ], - "name": "SwapFeePercentageChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bool", - "name": "paused", - "type": "bool" - } - ], - "name": "VaultPausedStateChanged", - "type": "event" - }, - { - "inputs": [], - "name": "MAX_BUFFER_PERIOD_DURATION", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "MAX_PAUSE_WINDOW_DURATION", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - } - ], - "name": "collectProtocolFees", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "disableQuery", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "disableRecoveryMode", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "enableRecoveryMode", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "selector", - "type": "bytes4" - } - ], - "name": "getActionId", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getAuthorizer", - "outputs": [ - { - "internalType": "contract IAuthorizer", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getBufferPeriodDuration", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getBufferPeriodEndTime", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "getHandler", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getHandlersCount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getMaximumPoolTokens", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "getMinimumPoolTokens", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "getNonzeroDeltaCount", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getPauseWindowEndTime", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "getPoolConfig", - "outputs": [ - { - "components": [ - { - "internalType": "bool", - "name": "isPoolRegistered", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isPoolInitialized", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isPoolPaused", - "type": "bool" - }, - { - "internalType": "bool", - "name": "isPoolInRecoveryMode", - "type": "bool" - }, - { - "internalType": "bool", - "name": "hasDynamicSwapFee", - "type": "bool" - }, - { - "internalType": "uint64", - "name": "staticSwapFeePercentage", - "type": "uint64" - }, - { - "internalType": "uint24", - "name": "tokenDecimalDiffs", - "type": "uint24" - }, - { - "internalType": "uint32", - "name": "pauseWindowEndTime", - "type": "uint32" - }, - { - "components": [ - { - "internalType": "bool", - "name": "shouldCallBeforeInitialize", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterInitialize", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallBeforeSwap", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterSwap", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallBeforeAddLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterAddLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallBeforeRemoveLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterRemoveLiquidity", - "type": "bool" - } - ], - "internalType": "struct PoolCallbacks", - "name": "callbacks", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "bool", - "name": "supportsAddLiquidityCustom", - "type": "bool" - }, - { - "internalType": "bool", - "name": "supportsRemoveLiquidityCustom", - "type": "bool" - } - ], - "internalType": "struct LiquidityManagement", - "name": "liquidityManagement", - "type": "tuple" - } - ], - "internalType": "struct PoolConfig", - "name": "", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "getPoolPausedState", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - } - ], - "name": "getPoolTokenCountAndIndexOfToken", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "getPoolTokenInfo", - "outputs": [ - { - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - }, - { - "internalType": "enum TokenType[]", - "name": "tokenTypes", - "type": "uint8[]" - }, - { - "internalType": "uint256[]", - "name": "balancesRaw", - "type": "uint256[]" - }, - { - "internalType": "uint256[]", - "name": "decimalScalingFactors", - "type": "uint256[]" - }, - { - "internalType": "contract IRateProvider[]", - "name": "rateProviders", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "getPoolTokenRates", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "getPoolTokens", - "outputs": [ - { - "internalType": "contract IERC20[]", - "name": "", - "type": "address[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - } - ], - "name": "getProtocolSwapFee", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getProtocolSwapFeePercentage", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "getStaticSwapFeePercentage", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "user", - "type": "address" - }, - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - } - ], - "name": "getTokenDelta", - "outputs": [ - { - "internalType": "int256", - "name": "", - "type": "int256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - } - ], - "name": "getTokenReserve", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getVaultPausedState", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "contract IERC20[]", - "name": "tokens", - "type": "address[]" - }, - { - "internalType": "uint256[]", - "name": "exactAmountsIn", - "type": "uint256[]" - }, - { - "internalType": "uint256", - "name": "minBptAmountOut", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "userData", - "type": "bytes" - } - ], - "name": "initialize", - "outputs": [ - { - "internalType": "uint256", - "name": "bptAmountOut", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "isPoolInRecoveryMode", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "isPoolInitialized", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "isPoolPaused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "isPoolRegistered", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isQueryDisabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isVaultPaused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "pausePool", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "pauseVault", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "quote", - "outputs": [ - { - "internalType": "bytes", - "name": "result", - "type": "bytes" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "internalType": "enum TokenType", - "name": "tokenType", - "type": "uint8" - }, - { - "internalType": "contract IRateProvider", - "name": "rateProvider", - "type": "address" - }, - { - "internalType": "bool", - "name": "yieldFeeExempt", - "type": "bool" - } - ], - "internalType": "struct TokenConfig[]", - "name": "tokenConfig", - "type": "tuple[]" - }, - { - "internalType": "uint256", - "name": "pauseWindowEndTime", - "type": "uint256" - }, - { - "internalType": "address", - "name": "pauseManager", - "type": "address" - }, - { - "components": [ - { - "internalType": "bool", - "name": "shouldCallBeforeInitialize", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterInitialize", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallBeforeSwap", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterSwap", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallBeforeAddLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterAddLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallBeforeRemoveLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "shouldCallAfterRemoveLiquidity", - "type": "bool" - } - ], - "internalType": "struct PoolCallbacks", - "name": "poolCallbacks", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "bool", - "name": "supportsAddLiquidityCustom", - "type": "bool" - }, - { - "internalType": "bool", - "name": "supportsRemoveLiquidityCustom", - "type": "bool" - } - ], - "internalType": "struct LiquidityManagement", - "name": "liquidityManagement", - "type": "tuple" - } - ], - "name": "registerPool", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IAuthorizer", - "name": "newAuthorizer", - "type": "address" - } - ], - "name": "setAuthorizer", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "newProtocolSwapFeePercentage", - "type": "uint256" - } - ], - "name": "setProtocolSwapFeePercentage", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - }, - { - "internalType": "uint256", - "name": "swapFeePercentage", - "type": "uint256" - } - ], - "name": "setStaticSwapFeePercentage", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "token", - "type": "address" - } - ], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "unpausePool", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "unpauseVault", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "vault", - "outputs": [ - { - "internalType": "contract IVault", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } -] \ No newline at end of file diff --git a/modules/sources/contracts/abis/VaultV3.ts b/modules/sources/contracts/abis/VaultV3.ts new file mode 100644 index 000000000..dcf38d114 --- /dev/null +++ b/modules/sources/contracts/abis/VaultV3.ts @@ -0,0 +1,3622 @@ +export const vaultV3Abi = [ + { + inputs: [ + { + internalType: 'contract IVaultExtension', + name: 'vaultExtension', + type: 'address', + }, + { + internalType: 'contract IAuthorizer', + name: 'authorizer', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [ + { + internalType: 'address', + name: 'target', + type: 'address', + }, + ], + name: 'AddressEmptyCode', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'AddressInsufficientBalance', + type: 'error', + }, + { + inputs: [], + name: 'AllZeroInputs', + type: 'error', + }, + { + inputs: [], + name: 'AmountGivenZero', + type: 'error', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + name: 'AmountInAboveMax', + type: 'error', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + name: 'AmountOutBelowMin', + type: 'error', + }, + { + inputs: [], + name: 'BalanceNotSettled', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + name: 'BptAmountInAboveMax', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + name: 'BptAmountOutBelowMin', + type: 'error', + }, + { + inputs: [], + name: 'CannotReceiveEth', + type: 'error', + }, + { + inputs: [], + name: 'CannotSwapSameToken', + type: 'error', + }, + { + inputs: [], + name: 'DoesNotSupportAddLiquidityCustom', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'allowance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'needed', + type: 'uint256', + }, + ], + name: 'ERC20InsufficientAllowance', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'balance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'needed', + type: 'uint256', + }, + ], + name: 'ERC20InsufficientBalance', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'approver', + type: 'address', + }, + ], + name: 'ERC20InvalidApprover', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + ], + name: 'ERC20InvalidReceiver', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'ERC20InvalidSender', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + name: 'ERC20InvalidSpender', + type: 'error', + }, + { + inputs: [], + name: 'FailedInnerCall', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + ], + name: 'HandlerOutOfBounds', + type: 'error', + }, + { + inputs: [], + name: 'HookFailed', + type: 'error', + }, + { + inputs: [], + name: 'InputLengthMismatch', + type: 'error', + }, + { + inputs: [], + name: 'InvalidAddLiquidityKind', + type: 'error', + }, + { + inputs: [], + name: 'InvalidRemoveLiquidityKind', + type: 'error', + }, + { + inputs: [], + name: 'InvalidToken', + type: 'error', + }, + { + inputs: [], + name: 'InvalidTokenConfiguration', + type: 'error', + }, + { + inputs: [], + name: 'InvalidTokenType', + type: 'error', + }, + { + inputs: [], + name: 'MaxTokens', + type: 'error', + }, + { + inputs: [], + name: 'MinTokens', + type: 'error', + }, + { + inputs: [], + name: 'MultipleNonZeroInputs', + type: 'error', + }, + { + inputs: [], + name: 'NoHandler', + type: 'error', + }, + { + inputs: [], + name: 'NotStaticCall', + type: 'error', + }, + { + inputs: [], + name: 'NotVaultDelegateCall', + type: 'error', + }, + { + inputs: [], + name: 'PauseBufferPeriodDurationTooLarge', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolAlreadyInitialized', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolAlreadyRegistered', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolInRecoveryMode', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolNotInRecoveryMode', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolNotInitialized', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolNotPaused', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolNotRegistered', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolPauseWindowExpired', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolPaused', + type: 'error', + }, + { + inputs: [], + name: 'ProtocolSwapFeePercentageTooHigh', + type: 'error', + }, + { + inputs: [], + name: 'ProtocolYieldFeePercentageTooHigh', + type: 'error', + }, + { + inputs: [], + name: 'QueriesDisabled', + type: 'error', + }, + { + inputs: [], + name: 'ReentrancyGuardReentrantCall', + type: 'error', + }, + { + inputs: [], + name: 'RouterNotTrusted', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint8', + name: 'bits', + type: 'uint8', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'SafeCastOverflowedUintDowncast', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'SafeCastOverflowedUintToInt', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + ], + name: 'SafeERC20FailedOperation', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'SenderIsNotPauseManager', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'SenderIsNotVault', + type: 'error', + }, + { + inputs: [], + name: 'SwapFeePercentageTooHigh', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + name: 'SwapLimit', + type: 'error', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + ], + name: 'TokenAlreadyRegistered', + type: 'error', + }, + { + inputs: [], + name: 'TokenNotRegistered', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + internalType: 'address', + name: 'expectedToken', + type: 'address', + }, + { + internalType: 'address', + name: 'actualToken', + type: 'address', + }, + ], + name: 'TokensMismatch', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + name: 'TotalSupplyTooLow', + type: 'error', + }, + { + inputs: [], + name: 'UserDataNotSupported', + type: 'error', + }, + { + inputs: [], + name: 'VaultNotPaused', + type: 'error', + }, + { + inputs: [], + name: 'VaultPauseWindowDurationTooLarge', + type: 'error', + }, + { + inputs: [], + name: 'VaultPauseWindowExpired', + type: 'error', + }, + { + inputs: [], + name: 'VaultPaused', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'handler', + type: 'address', + }, + { + internalType: 'address', + name: 'caller', + type: 'address', + }, + ], + name: 'WrongHandler', + type: 'error', + }, + { + inputs: [], + name: 'WrongVaultExtensionDeployment', + type: 'error', + }, + { + inputs: [], + name: 'ZeroDivision', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract IAuthorizer', + name: 'newAuthorizer', + type: 'address', + }, + ], + name: 'AuthorizerChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'liquidityProvider', + type: 'address', + }, + { + indexed: false, + internalType: 'contract IERC20[]', + name: 'tokens', + type: 'address[]', + }, + { + indexed: false, + internalType: 'int256[]', + name: 'deltas', + type: 'int256[]', + }, + ], + name: 'PoolBalanceChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolInitialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'paused', + type: 'bool', + }, + ], + name: 'PoolPausedStateChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'recoveryMode', + type: 'bool', + }, + ], + name: 'PoolRecoveryModeStateChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'factory', + type: 'address', + }, + { + components: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'enum TokenType', + name: 'tokenType', + type: 'uint8', + }, + { + internalType: 'contract IRateProvider', + name: 'rateProvider', + type: 'address', + }, + { + internalType: 'bool', + name: 'yieldFeeExempt', + type: 'bool', + }, + ], + indexed: false, + internalType: 'struct TokenConfig[]', + name: 'tokenConfig', + type: 'tuple[]', + }, + { + indexed: false, + internalType: 'uint256', + name: 'pauseWindowEndTime', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'pauseManager', + type: 'address', + }, + { + components: [ + { + internalType: 'bool', + name: 'shouldCallBeforeInitialize', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterInitialize', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeSwap', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterSwap', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeAddLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterAddLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeRemoveLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterRemoveLiquidity', + type: 'bool', + }, + ], + indexed: false, + internalType: 'struct PoolHooks', + name: 'hooks', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'supportsAddLiquidityCustom', + type: 'bool', + }, + { + internalType: 'bool', + name: 'supportsRemoveLiquidityCustom', + type: 'bool', + }, + ], + indexed: false, + internalType: 'struct LiquidityManagement', + name: 'liquidityManagement', + type: 'tuple', + }, + ], + name: 'PoolRegistered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ProtocolFeeCollected', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ProtocolSwapFeeCharged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'swapFeePercentage', + type: 'uint256', + }, + ], + name: 'ProtocolSwapFeePercentageChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ProtocolYieldFeeCharged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'yieldFeePercentage', + type: 'uint256', + }, + ], + name: 'ProtocolYieldFeePercentageChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'tokenIn', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'tokenOut', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amountIn', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amountOut', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'swapFeeAmount', + type: 'uint256', + }, + ], + name: 'Swap', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'paused', + type: 'bool', + }, + ], + name: 'VaultPausedStateChanged', + type: 'event', + }, + { + stateMutability: 'payable', + type: 'fallback', + }, + { + inputs: [], + name: 'MAX_BUFFER_PERIOD_DURATION', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_PAUSE_WINDOW_DURATION', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256[]', + name: 'maxAmountsIn', + type: 'uint256[]', + }, + { + internalType: 'uint256', + name: 'minBptAmountOut', + type: 'uint256', + }, + { + internalType: 'enum AddLiquidityKind', + name: 'kind', + type: 'uint8', + }, + { + internalType: 'bytes', + name: 'userData', + type: 'bytes', + }, + ], + internalType: 'struct AddLiquidityParams', + name: 'params', + type: 'tuple', + }, + ], + name: 'addLiquidity', + outputs: [ + { + internalType: 'uint256[]', + name: 'amountsIn', + type: 'uint256[]', + }, + { + internalType: 'uint256', + name: 'bptAmountOut', + type: 'uint256', + }, + { + internalType: 'bytes', + name: 'returnData', + type: 'bytes', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + ], + name: 'getPoolTokenCountAndIndexOfToken', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getVaultExtension', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + name: 'invoke', + outputs: [ + { + internalType: 'bytes', + name: 'result', + type: 'bytes', + }, + ], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'reentrancyGuardEntered', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'uint256', + name: 'maxBptAmountIn', + type: 'uint256', + }, + { + internalType: 'uint256[]', + name: 'minAmountsOut', + type: 'uint256[]', + }, + { + internalType: 'enum RemoveLiquidityKind', + name: 'kind', + type: 'uint8', + }, + { + internalType: 'bytes', + name: 'userData', + type: 'bytes', + }, + ], + internalType: 'struct RemoveLiquidityParams', + name: 'params', + type: 'tuple', + }, + ], + name: 'removeLiquidity', + outputs: [ + { + internalType: 'uint256', + name: 'bptAmountIn', + type: 'uint256', + }, + { + internalType: 'uint256[]', + name: 'amountsOut', + type: 'uint256[]', + }, + { + internalType: 'bytes', + name: 'returnData', + type: 'bytes', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'uint256', + name: 'exactBptAmountIn', + type: 'uint256', + }, + ], + name: 'removeLiquidityRecovery', + outputs: [ + { + internalType: 'uint256[]', + name: 'amountsOutRaw', + type: 'uint256[]', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'retrieve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + ], + name: 'settle', + outputs: [ + { + internalType: 'uint256', + name: 'paid', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + components: [ + { + internalType: 'enum SwapKind', + name: 'kind', + type: 'uint8', + }, + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + internalType: 'contract IERC20', + name: 'tokenIn', + type: 'address', + }, + { + internalType: 'contract IERC20', + name: 'tokenOut', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amountGivenRaw', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limitRaw', + type: 'uint256', + }, + { + internalType: 'bytes', + name: 'userData', + type: 'bytes', + }, + ], + internalType: 'struct SwapParams', + name: 'params', + type: 'tuple', + }, + ], + name: 'swap', + outputs: [ + { + internalType: 'uint256', + name: 'amountCalculated', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amountIn', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'amountOut', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'wire', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IVault', + name: 'mainVault', + type: 'address', + }, + { + internalType: 'uint256', + name: 'pauseWindowDuration', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'bufferPeriodDuration', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [ + { + internalType: 'address', + name: 'target', + type: 'address', + }, + ], + name: 'AddressEmptyCode', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'AddressInsufficientBalance', + type: 'error', + }, + { + inputs: [], + name: 'AmountGivenZero', + type: 'error', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + name: 'AmountInAboveMax', + type: 'error', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + name: 'AmountOutBelowMin', + type: 'error', + }, + { + inputs: [], + name: 'BalanceNotSettled', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + name: 'BptAmountInAboveMax', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + name: 'BptAmountOutBelowMin', + type: 'error', + }, + { + inputs: [], + name: 'CannotReceiveEth', + type: 'error', + }, + { + inputs: [], + name: 'CannotSwapSameToken', + type: 'error', + }, + { + inputs: [], + name: 'CodecOverflow', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'allowance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'needed', + type: 'uint256', + }, + ], + name: 'ERC20InsufficientAllowance', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'balance', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'needed', + type: 'uint256', + }, + ], + name: 'ERC20InsufficientBalance', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'approver', + type: 'address', + }, + ], + name: 'ERC20InvalidApprover', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'receiver', + type: 'address', + }, + ], + name: 'ERC20InvalidReceiver', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'ERC20InvalidSender', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + name: 'ERC20InvalidSpender', + type: 'error', + }, + { + inputs: [], + name: 'FailedInnerCall', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + ], + name: 'HandlerOutOfBounds', + type: 'error', + }, + { + inputs: [], + name: 'HookFailed', + type: 'error', + }, + { + inputs: [], + name: 'InputLengthMismatch', + type: 'error', + }, + { + inputs: [], + name: 'InvalidAddLiquidityKind', + type: 'error', + }, + { + inputs: [], + name: 'InvalidRemoveLiquidityKind', + type: 'error', + }, + { + inputs: [], + name: 'InvalidToken', + type: 'error', + }, + { + inputs: [], + name: 'InvalidTokenConfiguration', + type: 'error', + }, + { + inputs: [], + name: 'InvalidTokenType', + type: 'error', + }, + { + inputs: [], + name: 'MaxTokens', + type: 'error', + }, + { + inputs: [], + name: 'MinTokens', + type: 'error', + }, + { + inputs: [], + name: 'NoHandler', + type: 'error', + }, + { + inputs: [], + name: 'NotStaticCall', + type: 'error', + }, + { + inputs: [], + name: 'NotVaultDelegateCall', + type: 'error', + }, + { + inputs: [], + name: 'OutOfBounds', + type: 'error', + }, + { + inputs: [], + name: 'PauseBufferPeriodDurationTooLarge', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolAlreadyInitialized', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolAlreadyRegistered', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolInRecoveryMode', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolNotInRecoveryMode', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolNotInitialized', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolNotPaused', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolNotRegistered', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolPauseWindowExpired', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolPaused', + type: 'error', + }, + { + inputs: [], + name: 'ProtocolSwapFeePercentageTooHigh', + type: 'error', + }, + { + inputs: [], + name: 'ProtocolYieldFeePercentageTooHigh', + type: 'error', + }, + { + inputs: [], + name: 'QueriesDisabled', + type: 'error', + }, + { + inputs: [], + name: 'ReentrancyGuardReentrantCall', + type: 'error', + }, + { + inputs: [], + name: 'RouterNotTrusted', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint8', + name: 'bits', + type: 'uint8', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'SafeCastOverflowedUintDowncast', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'SafeCastOverflowedUintToInt', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + ], + name: 'SafeERC20FailedOperation', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'SenderIsNotPauseManager', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'SenderIsNotVault', + type: 'error', + }, + { + inputs: [], + name: 'SenderNotAllowed', + type: 'error', + }, + { + inputs: [], + name: 'SwapFeePercentageTooHigh', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + name: 'SwapLimit', + type: 'error', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + ], + name: 'TokenAlreadyRegistered', + type: 'error', + }, + { + inputs: [], + name: 'TokenNotRegistered', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + internalType: 'address', + name: 'expectedToken', + type: 'address', + }, + { + internalType: 'address', + name: 'actualToken', + type: 'address', + }, + ], + name: 'TokensMismatch', + type: 'error', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + { + internalType: 'uint256', + name: 'limit', + type: 'uint256', + }, + ], + name: 'TotalSupplyTooLow', + type: 'error', + }, + { + inputs: [], + name: 'UserDataNotSupported', + type: 'error', + }, + { + inputs: [], + name: 'VaultNotPaused', + type: 'error', + }, + { + inputs: [], + name: 'VaultPauseWindowDurationTooLarge', + type: 'error', + }, + { + inputs: [], + name: 'VaultPauseWindowExpired', + type: 'error', + }, + { + inputs: [], + name: 'VaultPaused', + type: 'error', + }, + { + inputs: [ + { + internalType: 'address', + name: 'handler', + type: 'address', + }, + { + internalType: 'address', + name: 'caller', + type: 'address', + }, + ], + name: 'WrongHandler', + type: 'error', + }, + { + inputs: [], + name: 'WrongVaultExtensionDeployment', + type: 'error', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract IAuthorizer', + name: 'newAuthorizer', + type: 'address', + }, + ], + name: 'AuthorizerChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'liquidityProvider', + type: 'address', + }, + { + indexed: false, + internalType: 'contract IERC20[]', + name: 'tokens', + type: 'address[]', + }, + { + indexed: false, + internalType: 'int256[]', + name: 'deltas', + type: 'int256[]', + }, + ], + name: 'PoolBalanceChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'PoolInitialized', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'paused', + type: 'bool', + }, + ], + name: 'PoolPausedStateChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: false, + internalType: 'bool', + name: 'recoveryMode', + type: 'bool', + }, + ], + name: 'PoolRecoveryModeStateChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'factory', + type: 'address', + }, + { + components: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'enum TokenType', + name: 'tokenType', + type: 'uint8', + }, + { + internalType: 'contract IRateProvider', + name: 'rateProvider', + type: 'address', + }, + { + internalType: 'bool', + name: 'yieldFeeExempt', + type: 'bool', + }, + ], + indexed: false, + internalType: 'struct TokenConfig[]', + name: 'tokenConfig', + type: 'tuple[]', + }, + { + indexed: false, + internalType: 'uint256', + name: 'pauseWindowEndTime', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'pauseManager', + type: 'address', + }, + { + components: [ + { + internalType: 'bool', + name: 'shouldCallBeforeInitialize', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterInitialize', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeSwap', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterSwap', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeAddLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterAddLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeRemoveLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterRemoveLiquidity', + type: 'bool', + }, + ], + indexed: false, + internalType: 'struct PoolHooks', + name: 'hooks', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'supportsAddLiquidityCustom', + type: 'bool', + }, + { + internalType: 'bool', + name: 'supportsRemoveLiquidityCustom', + type: 'bool', + }, + ], + indexed: false, + internalType: 'struct LiquidityManagement', + name: 'liquidityManagement', + type: 'tuple', + }, + ], + name: 'PoolRegistered', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ProtocolFeeCollected', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ProtocolSwapFeeCharged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'swapFeePercentage', + type: 'uint256', + }, + ], + name: 'ProtocolSwapFeePercentageChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'ProtocolYieldFeeCharged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'uint256', + name: 'yieldFeePercentage', + type: 'uint256', + }, + ], + name: 'ProtocolYieldFeePercentageChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'uint256', + name: 'swapFeePercentage', + type: 'uint256', + }, + ], + name: 'SwapFeePercentageChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bool', + name: 'paused', + type: 'bool', + }, + ], + name: 'VaultPausedStateChanged', + type: 'event', + }, + { + inputs: [], + name: 'MAX_BUFFER_PERIOD_DURATION', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MAX_PAUSE_WINDOW_DURATION', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + { + internalType: 'address', + name: 'account', + type: 'address', + }, + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20[]', + name: 'tokens', + type: 'address[]', + }, + ], + name: 'collectProtocolFees', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'disableQuery', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'disableRecoveryMode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'enableRecoveryMode', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes4', + name: 'selector', + type: 'bytes4', + }, + ], + name: 'getActionId', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getAuthorizer', + outputs: [ + { + internalType: 'contract IAuthorizer', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getBufferPeriodDuration', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getBufferPeriodEndTime', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'index', + type: 'uint256', + }, + ], + name: 'getHandler', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getHandlersCount', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getMaximumPoolTokens', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'getMinimumPoolTokens', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'getNonzeroDeltaCount', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getPauseWindowEndTime', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'getPoolConfig', + outputs: [ + { + components: [ + { + internalType: 'bool', + name: 'isPoolRegistered', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isPoolInitialized', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isPoolPaused', + type: 'bool', + }, + { + internalType: 'bool', + name: 'isPoolInRecoveryMode', + type: 'bool', + }, + { + internalType: 'bool', + name: 'hasDynamicSwapFee', + type: 'bool', + }, + { + internalType: 'uint64', + name: 'staticSwapFeePercentage', + type: 'uint64', + }, + { + internalType: 'uint24', + name: 'tokenDecimalDiffs', + type: 'uint24', + }, + { + internalType: 'uint32', + name: 'pauseWindowEndTime', + type: 'uint32', + }, + { + components: [ + { + internalType: 'bool', + name: 'shouldCallBeforeInitialize', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterInitialize', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeSwap', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterSwap', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeAddLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterAddLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeRemoveLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterRemoveLiquidity', + type: 'bool', + }, + ], + internalType: 'struct PoolHooks', + name: 'hooks', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'supportsAddLiquidityCustom', + type: 'bool', + }, + { + internalType: 'bool', + name: 'supportsRemoveLiquidityCustom', + type: 'bool', + }, + ], + internalType: 'struct LiquidityManagement', + name: 'liquidityManagement', + type: 'tuple', + }, + ], + internalType: 'struct PoolConfig', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'getPoolPausedState', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'getPoolTokenInfo', + outputs: [ + { + internalType: 'contract IERC20[]', + name: 'tokens', + type: 'address[]', + }, + { + internalType: 'enum TokenType[]', + name: 'tokenTypes', + type: 'uint8[]', + }, + { + internalType: 'uint256[]', + name: 'balancesRaw', + type: 'uint256[]', + }, + { + internalType: 'uint256[]', + name: 'decimalScalingFactors', + type: 'uint256[]', + }, + { + internalType: 'contract IRateProvider[]', + name: 'rateProviders', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'getPoolTokenRates', + outputs: [ + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'getPoolTokens', + outputs: [ + { + internalType: 'contract IERC20[]', + name: '', + type: 'address[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + ], + name: 'getProtocolFees', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getProtocolSwapFeePercentage', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getProtocolYieldFeePercentage', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'getStaticSwapFeePercentage', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'user', + type: 'address', + }, + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + ], + name: 'getTokenDelta', + outputs: [ + { + internalType: 'int256', + name: '', + type: 'int256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + ], + name: 'getTokenReserve', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getVaultPausedState', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'contract IERC20[]', + name: 'tokens', + type: 'address[]', + }, + { + internalType: 'uint256[]', + name: 'exactAmountsIn', + type: 'uint256[]', + }, + { + internalType: 'uint256', + name: 'minBptAmountOut', + type: 'uint256', + }, + { + internalType: 'bytes', + name: 'userData', + type: 'bytes', + }, + ], + name: 'initialize', + outputs: [ + { + internalType: 'uint256', + name: 'bptAmountOut', + type: 'uint256', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'isPoolInRecoveryMode', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'isPoolInitialized', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'isPoolPaused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'isPoolRegistered', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isQueryDisabled', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'isVaultPaused', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'pausePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'pauseVault', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'bytes', + name: 'data', + type: 'bytes', + }, + ], + name: 'quote', + outputs: [ + { + internalType: 'bytes', + name: 'result', + type: 'bytes', + }, + ], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'reentrancyGuardEntered', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + components: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'enum TokenType', + name: 'tokenType', + type: 'uint8', + }, + { + internalType: 'contract IRateProvider', + name: 'rateProvider', + type: 'address', + }, + { + internalType: 'bool', + name: 'yieldFeeExempt', + type: 'bool', + }, + ], + internalType: 'struct TokenConfig[]', + name: 'tokenConfig', + type: 'tuple[]', + }, + { + internalType: 'uint256', + name: 'pauseWindowEndTime', + type: 'uint256', + }, + { + internalType: 'address', + name: 'pauseManager', + type: 'address', + }, + { + components: [ + { + internalType: 'bool', + name: 'shouldCallBeforeInitialize', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterInitialize', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeSwap', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterSwap', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeAddLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterAddLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeRemoveLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterRemoveLiquidity', + type: 'bool', + }, + ], + internalType: 'struct PoolHooks', + name: 'poolHooks', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'supportsAddLiquidityCustom', + type: 'bool', + }, + { + internalType: 'bool', + name: 'supportsRemoveLiquidityCustom', + type: 'bool', + }, + ], + internalType: 'struct LiquidityManagement', + name: 'liquidityManagement', + type: 'tuple', + }, + ], + name: 'registerPool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'contract IAuthorizer', + name: 'newAuthorizer', + type: 'address', + }, + ], + name: 'setAuthorizer', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newProtocolSwapFeePercentage', + type: 'uint256', + }, + ], + name: 'setProtocolSwapFeePercentage', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'newProtocolYieldFeePercentage', + type: 'uint256', + }, + ], + name: 'setProtocolYieldFeePercentage', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + internalType: 'uint256', + name: 'swapFeePercentage', + type: 'uint256', + }, + ], + name: 'setStaticSwapFeePercentage', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'token', + type: 'address', + }, + ], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transfer', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address', + }, + { + internalType: 'address', + name: 'from', + type: 'address', + }, + { + internalType: 'address', + name: 'to', + type: 'address', + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { + internalType: 'address', + name: 'pool', + type: 'address', + }, + ], + name: 'unpausePool', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'unpauseVault', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'vault', + outputs: [ + { + internalType: 'contract IVault', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +] as const; diff --git a/modules/sources/contracts/abis/VaultV3JSON.json b/modules/sources/contracts/abis/VaultV3JSON.json new file mode 100644 index 000000000..cee6a2f2e --- /dev/null +++ b/modules/sources/contracts/abis/VaultV3JSON.json @@ -0,0 +1,3622 @@ +[ + { + "inputs": [ + { + "internalType": "contract IVaultExtension", + "name": "vaultExtension", + "type": "address" + }, + { + "internalType": "contract IAuthorizer", + "name": "authorizer", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "AllZeroInputs", + "type": "error" + }, + { + "inputs": [], + "name": "AmountGivenZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "AmountInAboveMax", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "AmountOutBelowMin", + "type": "error" + }, + { + "inputs": [], + "name": "BalanceNotSettled", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "BptAmountInAboveMax", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "BptAmountOutBelowMin", + "type": "error" + }, + { + "inputs": [], + "name": "CannotReceiveEth", + "type": "error" + }, + { + "inputs": [], + "name": "CannotSwapSameToken", + "type": "error" + }, + { + "inputs": [], + "name": "DoesNotSupportAddLiquidityCustom", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "HandlerOutOfBounds", + "type": "error" + }, + { + "inputs": [], + "name": "HookFailed", + "type": "error" + }, + { + "inputs": [], + "name": "InputLengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAddLiquidityKind", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRemoveLiquidityKind", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidToken", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTokenConfiguration", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTokenType", + "type": "error" + }, + { + "inputs": [], + "name": "MaxTokens", + "type": "error" + }, + { + "inputs": [], + "name": "MinTokens", + "type": "error" + }, + { + "inputs": [], + "name": "MultipleNonZeroInputs", + "type": "error" + }, + { + "inputs": [], + "name": "NoHandler", + "type": "error" + }, + { + "inputs": [], + "name": "NotStaticCall", + "type": "error" + }, + { + "inputs": [], + "name": "NotVaultDelegateCall", + "type": "error" + }, + { + "inputs": [], + "name": "PauseBufferPeriodDurationTooLarge", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolAlreadyInitialized", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolAlreadyRegistered", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolInRecoveryMode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolNotInRecoveryMode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolNotInitialized", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolNotPaused", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolNotRegistered", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolPauseWindowExpired", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolPaused", + "type": "error" + }, + { + "inputs": [], + "name": "ProtocolSwapFeePercentageTooHigh", + "type": "error" + }, + { + "inputs": [], + "name": "ProtocolYieldFeePercentageTooHigh", + "type": "error" + }, + { + "inputs": [], + "name": "QueriesDisabled", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyGuardReentrantCall", + "type": "error" + }, + { + "inputs": [], + "name": "RouterNotTrusted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "bits", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintDowncast", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintToInt", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "SenderIsNotPauseManager", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "SenderIsNotVault", + "type": "error" + }, + { + "inputs": [], + "name": "SwapFeePercentageTooHigh", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "SwapLimit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "TokenAlreadyRegistered", + "type": "error" + }, + { + "inputs": [], + "name": "TokenNotRegistered", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "expectedToken", + "type": "address" + }, + { + "internalType": "address", + "name": "actualToken", + "type": "address" + } + ], + "name": "TokensMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "TotalSupplyTooLow", + "type": "error" + }, + { + "inputs": [], + "name": "UserDataNotSupported", + "type": "error" + }, + { + "inputs": [], + "name": "VaultNotPaused", + "type": "error" + }, + { + "inputs": [], + "name": "VaultPauseWindowDurationTooLarge", + "type": "error" + }, + { + "inputs": [], + "name": "VaultPauseWindowExpired", + "type": "error" + }, + { + "inputs": [], + "name": "VaultPaused", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "handler", + "type": "address" + }, + { + "internalType": "address", + "name": "caller", + "type": "address" + } + ], + "name": "WrongHandler", + "type": "error" + }, + { + "inputs": [], + "name": "WrongVaultExtensionDeployment", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroDivision", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IAuthorizer", + "name": "newAuthorizer", + "type": "address" + } + ], + "name": "AuthorizerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "liquidityProvider", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "int256[]", + "name": "deltas", + "type": "int256[]" + } + ], + "name": "PoolBalanceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "PoolPausedStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "recoveryMode", + "type": "bool" + } + ], + "name": "PoolRecoveryModeStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "factory", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "enum TokenType", + "name": "tokenType", + "type": "uint8" + }, + { + "internalType": "contract IRateProvider", + "name": "rateProvider", + "type": "address" + }, + { + "internalType": "bool", + "name": "yieldFeeExempt", + "type": "bool" + } + ], + "indexed": false, + "internalType": "struct TokenConfig[]", + "name": "tokenConfig", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pauseWindowEndTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "pauseManager", + "type": "address" + }, + { + "components": [ + { + "internalType": "bool", + "name": "shouldCallBeforeInitialize", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterInitialize", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallBeforeSwap", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterSwap", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallBeforeAddLiquidity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterAddLiquidity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallBeforeRemoveLiquidity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterRemoveLiquidity", + "type": "bool" + } + ], + "indexed": false, + "internalType": "struct PoolHooks", + "name": "hooks", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bool", + "name": "supportsAddLiquidityCustom", + "type": "bool" + }, + { + "internalType": "bool", + "name": "supportsRemoveLiquidityCustom", + "type": "bool" + } + ], + "indexed": false, + "internalType": "struct LiquidityManagement", + "name": "liquidityManagement", + "type": "tuple" + } + ], + "name": "PoolRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ProtocolFeeCollected", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ProtocolSwapFeeCharged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "swapFeePercentage", + "type": "uint256" + } + ], + "name": "ProtocolSwapFeePercentageChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ProtocolYieldFeeCharged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "yieldFeePercentage", + "type": "uint256" + } + ], + "name": "ProtocolYieldFeePercentageChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "tokenIn", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "tokenOut", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "swapFeeAmount", + "type": "uint256" + } + ], + "name": "Swap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "VaultPausedStateChanged", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "MAX_BUFFER_PERIOD_DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_PAUSE_WINDOW_DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "maxAmountsIn", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "minBptAmountOut", + "type": "uint256" + }, + { + "internalType": "enum AddLiquidityKind", + "name": "kind", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "internalType": "struct AddLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "addLiquidity", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amountsIn", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "bptAmountOut", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "getPoolTokenCountAndIndexOfToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVaultExtension", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "invoke", + "outputs": [ + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "reentrancyGuardEntered", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxBptAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "minAmountsOut", + "type": "uint256[]" + }, + { + "internalType": "enum RemoveLiquidityKind", + "name": "kind", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "internalType": "struct RemoveLiquidityParams", + "name": "params", + "type": "tuple" + } + ], + "name": "removeLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "bptAmountIn", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "amountsOut", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "returnData", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "exactBptAmountIn", + "type": "uint256" + } + ], + "name": "removeLiquidityRecovery", + "outputs": [ + { + "internalType": "uint256[]", + "name": "amountsOutRaw", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "retrieve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "settle", + "outputs": [ + { + "internalType": "uint256", + "name": "paid", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "enum SwapKind", + "name": "kind", + "type": "uint8" + }, + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountGivenRaw", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limitRaw", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "internalType": "struct SwapParams", + "name": "params", + "type": "tuple" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "uint256", + "name": "amountCalculated", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "wire", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IVault", + "name": "mainVault", + "type": "address" + }, + { + "internalType": "uint256", + "name": "pauseWindowDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "bufferPeriodDuration", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { + "inputs": [], + "name": "AmountGivenZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "AmountInAboveMax", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "AmountOutBelowMin", + "type": "error" + }, + { + "inputs": [], + "name": "BalanceNotSettled", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "BptAmountInAboveMax", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "BptAmountOutBelowMin", + "type": "error" + }, + { + "inputs": [], + "name": "CannotReceiveEth", + "type": "error" + }, + { + "inputs": [], + "name": "CannotSwapSameToken", + "type": "error" + }, + { + "inputs": [], + "name": "CodecOverflow", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "needed", + "type": "uint256" + } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "approver", + "type": "address" + } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [], + "name": "FailedInnerCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "HandlerOutOfBounds", + "type": "error" + }, + { + "inputs": [], + "name": "HookFailed", + "type": "error" + }, + { + "inputs": [], + "name": "InputLengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAddLiquidityKind", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRemoveLiquidityKind", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidToken", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTokenConfiguration", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTokenType", + "type": "error" + }, + { + "inputs": [], + "name": "MaxTokens", + "type": "error" + }, + { + "inputs": [], + "name": "MinTokens", + "type": "error" + }, + { + "inputs": [], + "name": "NoHandler", + "type": "error" + }, + { + "inputs": [], + "name": "NotStaticCall", + "type": "error" + }, + { + "inputs": [], + "name": "NotVaultDelegateCall", + "type": "error" + }, + { + "inputs": [], + "name": "OutOfBounds", + "type": "error" + }, + { + "inputs": [], + "name": "PauseBufferPeriodDurationTooLarge", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolAlreadyInitialized", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolAlreadyRegistered", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolInRecoveryMode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolNotInRecoveryMode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolNotInitialized", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolNotPaused", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolNotRegistered", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolPauseWindowExpired", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolPaused", + "type": "error" + }, + { + "inputs": [], + "name": "ProtocolSwapFeePercentageTooHigh", + "type": "error" + }, + { + "inputs": [], + "name": "ProtocolYieldFeePercentageTooHigh", + "type": "error" + }, + { + "inputs": [], + "name": "QueriesDisabled", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyGuardReentrantCall", + "type": "error" + }, + { + "inputs": [], + "name": "RouterNotTrusted", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "bits", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintDowncast", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "SafeCastOverflowedUintToInt", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "SenderIsNotPauseManager", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "SenderIsNotVault", + "type": "error" + }, + { + "inputs": [], + "name": "SenderNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "SwapFeePercentageTooHigh", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "SwapLimit", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "TokenAlreadyRegistered", + "type": "error" + }, + { + "inputs": [], + "name": "TokenNotRegistered", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "expectedToken", + "type": "address" + }, + { + "internalType": "address", + "name": "actualToken", + "type": "address" + } + ], + "name": "TokensMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "TotalSupplyTooLow", + "type": "error" + }, + { + "inputs": [], + "name": "UserDataNotSupported", + "type": "error" + }, + { + "inputs": [], + "name": "VaultNotPaused", + "type": "error" + }, + { + "inputs": [], + "name": "VaultPauseWindowDurationTooLarge", + "type": "error" + }, + { + "inputs": [], + "name": "VaultPauseWindowExpired", + "type": "error" + }, + { + "inputs": [], + "name": "VaultPaused", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "handler", + "type": "address" + }, + { + "internalType": "address", + "name": "caller", + "type": "address" + } + ], + "name": "WrongHandler", + "type": "error" + }, + { + "inputs": [], + "name": "WrongVaultExtensionDeployment", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IAuthorizer", + "name": "newAuthorizer", + "type": "address" + } + ], + "name": "AuthorizerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "liquidityProvider", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "int256[]", + "name": "deltas", + "type": "int256[]" + } + ], + "name": "PoolBalanceChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "PoolPausedStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "recoveryMode", + "type": "bool" + } + ], + "name": "PoolRecoveryModeStateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "factory", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "enum TokenType", + "name": "tokenType", + "type": "uint8" + }, + { + "internalType": "contract IRateProvider", + "name": "rateProvider", + "type": "address" + }, + { + "internalType": "bool", + "name": "yieldFeeExempt", + "type": "bool" + } + ], + "indexed": false, + "internalType": "struct TokenConfig[]", + "name": "tokenConfig", + "type": "tuple[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pauseWindowEndTime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "pauseManager", + "type": "address" + }, + { + "components": [ + { + "internalType": "bool", + "name": "shouldCallBeforeInitialize", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterInitialize", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallBeforeSwap", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterSwap", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallBeforeAddLiquidity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterAddLiquidity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallBeforeRemoveLiquidity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterRemoveLiquidity", + "type": "bool" + } + ], + "indexed": false, + "internalType": "struct PoolHooks", + "name": "hooks", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bool", + "name": "supportsAddLiquidityCustom", + "type": "bool" + }, + { + "internalType": "bool", + "name": "supportsRemoveLiquidityCustom", + "type": "bool" + } + ], + "indexed": false, + "internalType": "struct LiquidityManagement", + "name": "liquidityManagement", + "type": "tuple" + } + ], + "name": "PoolRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ProtocolFeeCollected", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ProtocolSwapFeeCharged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "swapFeePercentage", + "type": "uint256" + } + ], + "name": "ProtocolSwapFeePercentageChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ProtocolYieldFeeCharged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "yieldFeePercentage", + "type": "uint256" + } + ], + "name": "ProtocolYieldFeePercentageChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "swapFeePercentage", + "type": "uint256" + } + ], + "name": "SwapFeePercentageChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "VaultPausedStateChanged", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_BUFFER_PERIOD_DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_PAUSE_WINDOW_DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "collectProtocolFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "disableQuery", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "disableRecoveryMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "enableRecoveryMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + } + ], + "name": "getActionId", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAuthorizer", + "outputs": [ + { + "internalType": "contract IAuthorizer", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBufferPeriodDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getBufferPeriodEndTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getHandler", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getHandlersCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getMaximumPoolTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getMinimumPoolTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getNonzeroDeltaCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getPauseWindowEndTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "getPoolConfig", + "outputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "isPoolRegistered", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isPoolInitialized", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isPoolPaused", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isPoolInRecoveryMode", + "type": "bool" + }, + { + "internalType": "bool", + "name": "hasDynamicSwapFee", + "type": "bool" + }, + { + "internalType": "uint64", + "name": "staticSwapFeePercentage", + "type": "uint64" + }, + { + "internalType": "uint24", + "name": "tokenDecimalDiffs", + "type": "uint24" + }, + { + "internalType": "uint32", + "name": "pauseWindowEndTime", + "type": "uint32" + }, + { + "components": [ + { + "internalType": "bool", + "name": "shouldCallBeforeInitialize", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterInitialize", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallBeforeSwap", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterSwap", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallBeforeAddLiquidity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterAddLiquidity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallBeforeRemoveLiquidity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterRemoveLiquidity", + "type": "bool" + } + ], + "internalType": "struct PoolHooks", + "name": "hooks", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bool", + "name": "supportsAddLiquidityCustom", + "type": "bool" + }, + { + "internalType": "bool", + "name": "supportsRemoveLiquidityCustom", + "type": "bool" + } + ], + "internalType": "struct LiquidityManagement", + "name": "liquidityManagement", + "type": "tuple" + } + ], + "internalType": "struct PoolConfig", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "getPoolPausedState", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "getPoolTokenInfo", + "outputs": [ + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "enum TokenType[]", + "name": "tokenTypes", + "type": "uint8[]" + }, + { + "internalType": "uint256[]", + "name": "balancesRaw", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "decimalScalingFactors", + "type": "uint256[]" + }, + { + "internalType": "contract IRateProvider[]", + "name": "rateProviders", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "getPoolTokenRates", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "getPoolTokens", + "outputs": [ + { + "internalType": "contract IERC20[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "getProtocolFees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProtocolSwapFeePercentage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getProtocolYieldFeePercentage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "getStaticSwapFeePercentage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "getTokenDelta", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "getTokenReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getVaultPausedState", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "contract IERC20[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "exactAmountsIn", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "minBptAmountOut", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "name": "initialize", + "outputs": [ + { + "internalType": "uint256", + "name": "bptAmountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "isPoolInRecoveryMode", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "isPoolInitialized", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "isPoolPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "isPoolRegistered", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isQueryDisabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isVaultPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "pausePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pauseVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "quote", + "outputs": [ + { + "internalType": "bytes", + "name": "result", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "reentrancyGuardEntered", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { + "internalType": "enum TokenType", + "name": "tokenType", + "type": "uint8" + }, + { + "internalType": "contract IRateProvider", + "name": "rateProvider", + "type": "address" + }, + { + "internalType": "bool", + "name": "yieldFeeExempt", + "type": "bool" + } + ], + "internalType": "struct TokenConfig[]", + "name": "tokenConfig", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "pauseWindowEndTime", + "type": "uint256" + }, + { + "internalType": "address", + "name": "pauseManager", + "type": "address" + }, + { + "components": [ + { + "internalType": "bool", + "name": "shouldCallBeforeInitialize", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterInitialize", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallBeforeSwap", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterSwap", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallBeforeAddLiquidity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterAddLiquidity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallBeforeRemoveLiquidity", + "type": "bool" + }, + { + "internalType": "bool", + "name": "shouldCallAfterRemoveLiquidity", + "type": "bool" + } + ], + "internalType": "struct PoolHooks", + "name": "poolHooks", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bool", + "name": "supportsAddLiquidityCustom", + "type": "bool" + }, + { + "internalType": "bool", + "name": "supportsRemoveLiquidityCustom", + "type": "bool" + } + ], + "internalType": "struct LiquidityManagement", + "name": "liquidityManagement", + "type": "tuple" + } + ], + "name": "registerPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IAuthorizer", + "name": "newAuthorizer", + "type": "address" + } + ], + "name": "setAuthorizer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newProtocolSwapFeePercentage", + "type": "uint256" + } + ], + "name": "setProtocolSwapFeePercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newProtocolYieldFeePercentage", + "type": "uint256" + } + ], + "name": "setProtocolYieldFeePercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "internalType": "uint256", + "name": "swapFeePercentage", + "type": "uint256" + } + ], + "name": "setStaticSwapFeePercentage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "unpausePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpauseVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vault", + "outputs": [ + { + "internalType": "contract IVault", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/modules/sources/contracts/abis/weighted_pool.abi b/modules/sources/contracts/abis/weighted_pool.abi new file mode 100644 index 000000000..e69de29bb diff --git a/modules/sources/contracts/fetch-erc20-headers.ts b/modules/sources/contracts/fetch-erc20-headers.ts new file mode 100644 index 000000000..8ea18a97b --- /dev/null +++ b/modules/sources/contracts/fetch-erc20-headers.ts @@ -0,0 +1,54 @@ +import { parseAbi } from 'viem'; +import type { ViemClient } from '../types'; + +const poolAbi = [ + 'function name() view returns (string)', + 'function symbol() view returns (string)', + 'function decimals() view returns (uint8)', +]; + +const abi = parseAbi(poolAbi); + +export async function fetchErc20Headers(addresses: `0x${string}`[], client: ViemClient) { + const contracts = addresses + .map((address) => [ + { + address, + abi, + functionName: 'name', + }, + { + address, + abi, + functionName: 'symbol', + }, + { + address, + abi, + functionName: 'decimals', + }, + ]) + .flat(); + + const results = await client.multicall({ contracts }); + + // Parse the results + const parsedResults = results.map((result) => { + if (result.status === 'success' && result.result !== undefined) { + return result.result as string; + } + // Handle the error + return undefined; + }); + + return Object.fromEntries( + addresses.map((address, i) => [ + address, + { + name: String(parsedResults[i * 3]), + symbol: String(parsedResults[i * 3 + 1]), + decimals: Number(parsedResults[i * 3 + 2]), + }, + ]), + ); +} diff --git a/modules/sources/contracts/fetch-pool-data.ts b/modules/sources/contracts/fetch-pool-data.ts new file mode 100644 index 000000000..bafe1627e --- /dev/null +++ b/modules/sources/contracts/fetch-pool-data.ts @@ -0,0 +1,95 @@ +import { PrismaPoolType } from '@prisma/client'; +import { ViemClient } from '../types'; +import { vaultV3Abi } from './abis/VaultV3'; +import { fetchPoolTokenInfo } from './fetch-pool-tokens'; + +interface PoolInput { + id: string; + address: string; + type: PrismaPoolType; + version: number; +} + +interface PoolData { + totalSupply: bigint; + swapFee: bigint; + protocolSwapFeePercentage: bigint; + // protocolYieldFeePercentage: bigint; + // rate?: bigint; + // amp?: [bigint, boolean, bigint]; + isPoolPaused: boolean; + isPoolInRecoveryMode: boolean; +} + +export async function fetchPoolData( + vault: string, + pools: PoolInput[], + client: ViemClient, + blockNumber: bigint, +): Promise> { + const totalSupplyContracts = pools + .map((pool) => [ + { + address: vault as `0x${string}`, + abi: vaultV3Abi, + functionName: 'totalSupply', + args: [pool.address as `0x${string}`], + } as const, + ]) + .flat(); + + const configContracts = pools + .map((pool) => [ + { + address: vault as `0x${string}`, + abi: vaultV3Abi, + functionName: 'getPoolConfig', + args: [pool.address as `0x${string}`], + } as const, + ]) + .flat(); + + const protocolSwapFeeContracts = pools + .map((pool) => [ + { + address: vault as `0x${string}`, + abi: vaultV3Abi, + functionName: 'getProtocolSwapFeePercentage', + } as const, + ]) + .flat(); + + // TODO combine into one call + const totalSupplyResult = await client.multicall({ contracts: totalSupplyContracts, blockNumber: blockNumber }); + const configResult = await client.multicall({ contracts: configContracts, blockNumber: blockNumber }); + const protocolSwapFeeResult = await client.multicall({ + contracts: protocolSwapFeeContracts, + blockNumber: blockNumber, + }); + + // Parse the results + const parsedResults: Record = {}; + pools.forEach((result, i) => { + if ( + totalSupplyResult[i].status === 'success' && + totalSupplyResult[i].result !== undefined && + configResult[i].status === 'success' && + configResult[i].result !== undefined && + protocolSwapFeeResult[i].status === 'success' && + protocolSwapFeeResult[i].result !== undefined + ) { + // parse the result here using the abi + const poolData = { + totalSupply: totalSupplyResult[i].result!, + swapFee: configResult[i].result!.staticSwapFeePercentage, + protocolSwapFeePercentage: 0n, // TODO can this be added to config? + isPoolPaused: configResult[i].result!.isPoolPaused, + isPoolInRecoveryMode: configResult[i].result!.isPoolInRecoveryMode, + } as PoolData; + + parsedResults[result.id] = poolData; + } + // Handle the error + }); + return parsedResults; +} diff --git a/modules/sources/contracts/fetch-pool-tokens.ts b/modules/sources/contracts/fetch-pool-tokens.ts new file mode 100644 index 000000000..ad5cf87ee --- /dev/null +++ b/modules/sources/contracts/fetch-pool-tokens.ts @@ -0,0 +1,90 @@ +import { ViemClient } from '../types'; +import { vaultV3Abi } from './abis/VaultV3'; + +type PoolTokenInfo = { + tokens: `0x${string}`[]; + tokenTypes: number[]; + balancesRaw: bigint[]; + decimalScalingFactors: bigint[]; + rateProviders: `0x${string}`[]; +}; + +type PoolTokenRates = { + tokenRates: bigint[]; +}; + +export async function fetchPoolTokenInfo( + vault: string, + pools: string[], + client: ViemClient, + blockNumber: bigint, +): Promise> { + const contracts = pools + .map((pool) => [ + { + address: vault as `0x${string}`, + abi: vaultV3Abi, + functionName: 'getPoolTokenInfo', + args: [pool as `0x${string}`], + } as const, + ]) + .flat(); + + const results = await client.multicall({ contracts, blockNumber: blockNumber }); + + // Parse the results + const parsedResults = results + .map((result, i) => { + if (result.status === 'success' && result.result !== undefined) { + // parse the result here using the abi + const poolTokens = { + tokens: result.result[0], + tokenTypes: result.result[1], + balancesRaw: result.result[2], + decimalScalingFactors: result.result[3], + rateProviders: result.result[4], + } as PoolTokenInfo; + + return [pools[i], poolTokens]; + } + // Handle the error + return undefined; + }) + .filter((result): result is NonNullable => result !== undefined); + + return Object.fromEntries(parsedResults) as Record; +} + +export async function fetchPoolTokenRates( + vault: string, + pools: string[], + client: ViemClient, + blockNumber: bigint, +): Promise> { + const contracts = pools + .map((pool) => [ + { + address: vault as `0x${string}`, + abi: vaultV3Abi, + functionName: 'getPoolTokenRates', + args: [pool as `0x${string}`], + } as const, + ]) + .flat(); + + const results = await client.multicall({ contracts, blockNumber: blockNumber }); + + // Parse the results + const parsedResults = results + .map((result, i) => { + if (result.status === 'success' && result.result !== undefined) { + // parse the result here using the abi + return [pools[i], result.result]; + } + // Handle the error + return undefined; + }) + .filter((result): result is NonNullable => result !== undefined); + + return Object.fromEntries(parsedResults) as Record; +} diff --git a/modules/sources/contracts/fetch-weighted-pools-data.ts b/modules/sources/contracts/fetch-weighted-pools-data.ts new file mode 100644 index 000000000..d79c7868e --- /dev/null +++ b/modules/sources/contracts/fetch-weighted-pools-data.ts @@ -0,0 +1,41 @@ +import { parseAbi, formatEther } from 'viem'; +import { ViemClient } from '../types'; + +const abi = parseAbi(['function getNormalizedWeights() view returns (uint[] weights)']); + +interface WeightedPoolData { + weights: string[]; +} + +export async function fetchWeightedPoolData(pools: string[], client: ViemClient) { + const contracts = pools + .map((pool) => [ + { + address: pool as `0x${string}`, + abi, + args: [], + functionName: 'getNormalizedWeights', + }, + ]) + .flat(); + + const results = await client.multicall({ contracts }); + + // Parse the results + const parsedResults = results + .map((result, i) => { + if (result.status === 'success' && result.result !== undefined) { + return [ + pools[i], + { + weights: result.result.map((weight) => formatEther(weight)), + }, + ]; + } + // Handle the error + return undefined; + }) + .filter((result): result is NonNullable => result !== undefined); + + return Object.fromEntries(parsedResults) as Record; +} diff --git a/modules/sources/contracts/index.ts b/modules/sources/contracts/index.ts new file mode 100644 index 000000000..1347526f8 --- /dev/null +++ b/modules/sources/contracts/index.ts @@ -0,0 +1,3 @@ +export * from './fetch-erc20-headers'; +export * from './fetch-pool-tokens'; +export * from './fetch-weighted-pools-data'; diff --git a/modules/sources/logs/get-new-pools.ts b/modules/sources/logs/get-new-pools.ts new file mode 100644 index 000000000..5ef6dc038 --- /dev/null +++ b/modules/sources/logs/get-new-pools.ts @@ -0,0 +1,142 @@ +import { ViemClient } from '../types'; + +const event = { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'factory', + type: 'address', + }, + { + components: [ + { + internalType: 'contract IERC20', + name: 'token', + type: 'address', + }, + { + internalType: 'enum TokenType', + name: 'tokenType', + type: 'uint8', + }, + { + internalType: 'contract IRateProvider', + name: 'rateProvider', + type: 'address', + }, + { + internalType: 'bool', + name: 'yieldFeeExempt', + type: 'bool', + }, + ], + indexed: false, + internalType: 'struct TokenConfig[]', + name: 'tokenConfig', + type: 'tuple[]', + }, + { + indexed: false, + internalType: 'uint256', + name: 'pauseWindowEndTime', + type: 'uint256', + }, + { + indexed: false, + internalType: 'address', + name: 'pauseManager', + type: 'address', + }, + { + components: [ + { + internalType: 'bool', + name: 'shouldCallBeforeInitialize', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterInitialize', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeSwap', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterSwap', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeAddLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterAddLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallBeforeRemoveLiquidity', + type: 'bool', + }, + { + internalType: 'bool', + name: 'shouldCallAfterRemoveLiquidity', + type: 'bool', + }, + ], + indexed: false, + internalType: 'struct PoolCallbacks', + name: 'callbacks', + type: 'tuple', + }, + { + components: [ + { + internalType: 'bool', + name: 'supportsAddLiquidityCustom', + type: 'bool', + }, + { + internalType: 'bool', + name: 'supportsRemoveLiquidityCustom', + type: 'bool', + }, + ], + indexed: false, + internalType: 'struct LiquidityManagement', + name: 'liquidityManagement', + type: 'tuple', + }, + ], + name: 'PoolRegistered', + type: 'event', +} as const; + +/** + * Extract balances from the contract + */ +export const getNewPools = async (vaultAddress: string, client: ViemClient, fromBlock: bigint) => { + // Get Transfer logs from the vault + const logs = await client.getLogs({ + address: vaultAddress as `0x${string}`, + event, + fromBlock, + }); + + // Parse the logs + return logs; +}; diff --git a/modules/sources/logs/get-pool-balance-changed.ts b/modules/sources/logs/get-pool-balance-changed.ts new file mode 100644 index 000000000..5140d1d41 --- /dev/null +++ b/modules/sources/logs/get-pool-balance-changed.ts @@ -0,0 +1,49 @@ +import { ViemClient } from '../types'; + +const event = { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'liquidityProvider', + type: 'address', + }, + { + indexed: false, + internalType: 'contract IERC20[]', + name: 'tokens', + type: 'address[]', + }, + { + indexed: false, + internalType: 'int256[]', + name: 'deltas', + type: 'int256[]', + }, + ], + name: 'PoolBalanceChanged', + type: 'event', +} as const; + +export const getPoolBalanceChanged = async ( + vaultAddress: string, + client: ViemClient, + fromBlock: bigint, + toBlock: bigint | undefined = undefined, +) => { + const logs = await client.getLogs({ + address: vaultAddress as `0x${string}`, + event, + fromBlock, + toBlock, + }); + + return logs; +}; diff --git a/modules/sources/logs/get-swaps.ts b/modules/sources/logs/get-swaps.ts new file mode 100644 index 000000000..b63773e33 --- /dev/null +++ b/modules/sources/logs/get-swaps.ts @@ -0,0 +1,64 @@ +import { ViemClient } from '../types'; + +const event = { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'pool', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'tokenIn', + type: 'address', + }, + { + indexed: true, + internalType: 'contract IERC20', + name: 'tokenOut', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amountIn', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amountOut', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'swapFeeAmount', + type: 'uint256', + }, + ], + name: 'Swap', + type: 'event', +} as const; + +/** + * Extract balances from the contract + */ +export const getSwaps = async ( + vaultAddress: string, + client: ViemClient, + fromBlock: bigint, + toBlock: bigint | undefined = undefined, +) => { + const logs = await client.getLogs({ + address: vaultAddress as `0x${string}`, + event, + fromBlock, + toBlock, + }); + + return logs; +}; diff --git a/modules/sources/logs/get-transfers.ts b/modules/sources/logs/get-transfers.ts new file mode 100644 index 000000000..7396b4f38 --- /dev/null +++ b/modules/sources/logs/get-transfers.ts @@ -0,0 +1,48 @@ +import { ViemClient } from '../types'; + +const event = { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', +} as const; + +/** + * Extract balances from the contract + */ +export const getTransfers = async (vaultAddress: string, client: ViemClient, fromBlock: bigint) => { + // Get Transfer logs from the vault + const logs = await client.getLogs({ + address: vaultAddress as `0x${string}`, + event, + fromBlock, + }); + + // Parse the logs + return logs; +}; diff --git a/modules/sources/logs/index.ts b/modules/sources/logs/index.ts new file mode 100644 index 000000000..7bdec8277 --- /dev/null +++ b/modules/sources/logs/index.ts @@ -0,0 +1,3 @@ +export * from './get-swaps'; +export * from './get-transfers'; +export * from './get-new-pools'; diff --git a/modules/sources/transformers/index.ts b/modules/sources/transformers/index.ts new file mode 100644 index 000000000..ca74df49e --- /dev/null +++ b/modules/sources/transformers/index.ts @@ -0,0 +1,2 @@ +export * from './pool-transformer'; +export * from './pool-tokens-transformer'; diff --git a/modules/sources/transformers/pool-tokens-transformer.ts b/modules/sources/transformers/pool-tokens-transformer.ts new file mode 100644 index 000000000..30a2ee535 --- /dev/null +++ b/modules/sources/transformers/pool-tokens-transformer.ts @@ -0,0 +1,50 @@ +import { PoolFragment as VaultSubgraphPoolFragment } from '../../subgraphs/balancer-v3-vault/generated/types'; +import { TypePoolFragment as PoolSubgraphPoolFragment } from '../../subgraphs/balancer-v3-pools/generated/types'; +import { Chain, Prisma } from '@prisma/client'; + +export function poolTokensTransformer( + vaultSubgraphPool: VaultSubgraphPoolFragment, +): Prisma.PrismaPoolTokenCreateManyPoolInput[] { + const tokens = vaultSubgraphPool.tokens ?? []; + return tokens.map((token, i) => ({ + id: `${vaultSubgraphPool.id}-${token.address}`.toLowerCase(), + address: token.address.toLowerCase(), + index: token.index, + nestedPoolId: null, + priceRateProvider: vaultSubgraphPool.rateProviders![i].address.toLowerCase(), + exemptFromProtocolYieldFee: token.totalProtocolYieldFee === '0' ? true : false, + })); +} + +export function poolTokensDynamicDataTransformer( + vaultSubgraphPool: VaultSubgraphPoolFragment, + poolSubgraphPool: PoolSubgraphPoolFragment, + chain: Chain, +): Prisma.PrismaPoolTokenDynamicDataCreateManyInput[] { + const tokens = vaultSubgraphPool.tokens ?? []; + return tokens.map((token, i) => ({ + id: `${vaultSubgraphPool.id}-${token.address}`.toLowerCase(), + poolTokenId: `${vaultSubgraphPool.id}-${token.address}`.toLowerCase(), + chain, + blockNumber: parseFloat(vaultSubgraphPool.blockNumber), + balance: token.balance, + balanceUSD: 0, + priceRate: '0', + weight: poolSubgraphPool.weights[token.index] ?? null, + // latestFxPrice: poolSubgraphPool.latestFxPrice, + })); +} + +// TODO deal with nested pools +export function poolExpandedTokensTransformer( + vaultSubgraphPool: VaultSubgraphPoolFragment, + chain: Chain, +): Prisma.PrismaPoolExpandedTokensCreateManyInput[] { + const tokens = vaultSubgraphPool.tokens ?? []; + return tokens.map((token, i) => ({ + poolId: vaultSubgraphPool.id, + chain: chain, + tokenAddress: token.address, + nestedPoolId: null, + })); +} diff --git a/modules/sources/transformers/pool-transformer.ts b/modules/sources/transformers/pool-transformer.ts new file mode 100644 index 000000000..69830e328 --- /dev/null +++ b/modules/sources/transformers/pool-transformer.ts @@ -0,0 +1,46 @@ +import { Chain, PrismaPool, PrismaPoolType } from '@prisma/client'; +import { PoolFragment as VaultSubgraphPoolFragment } from '../../subgraphs/balancer-v3-vault/generated/types'; +import { + TypePoolFragment as PoolSubgraphPoolFragment, + PoolType, +} from '../../subgraphs/balancer-v3-pools/generated/types'; +import { StableData } from '../../pool/subgraph-mapper'; + +export const poolTransformer = ( + vaultSubgraphPool: VaultSubgraphPoolFragment, + poolSubgraphPool: PoolSubgraphPoolFragment, + chain: Chain, +): PrismaPool => { + let type: PrismaPoolType; + let typeData = {}; + + switch (poolSubgraphPool.factory.type) { + case PoolType.Weighted: + type = PrismaPoolType.WEIGHTED; + break; + case PoolType.Stable: + type = PrismaPoolType.STABLE; + typeData = { + amp: '10', // TODO just a place holder + } as StableData; + break; + default: + type = PrismaPoolType.UNKNOWN; + } + + return { + id: vaultSubgraphPool.id.toLowerCase(), + chain: chain, + vaultVersion: 3, + address: vaultSubgraphPool.id.toLowerCase(), + decimals: 18, + symbol: vaultSubgraphPool.symbol, + name: vaultSubgraphPool.name, + owner: '', + factory: poolSubgraphPool.factory.id.toLowerCase(), + type: type, + typeData: typeData, + version: poolSubgraphPool.factory.version, + createTime: Number(vaultSubgraphPool.blockTimestamp), + }; +}; diff --git a/modules/sources/types.ts b/modules/sources/types.ts new file mode 100644 index 000000000..489287794 --- /dev/null +++ b/modules/sources/types.ts @@ -0,0 +1 @@ +export type { ViemClient } from './viem-client'; diff --git a/modules/sources/viem-client.ts b/modules/sources/viem-client.ts new file mode 100644 index 000000000..5d268d9e7 --- /dev/null +++ b/modules/sources/viem-client.ts @@ -0,0 +1,37 @@ +import { createPublicClient, http } from 'viem'; +import { + arbitrum, + avalanche, + base, + fantom, + gnosis, + mainnet, + optimism, + polygon, + polygonZkEvm, + sepolia, +} from 'viem/chains'; +import { Chain } from '@prisma/client'; +import config from '../../config'; + +export type ViemClient = ReturnType; + +const chain2ViemChain = { + [Chain.MAINNET]: mainnet, + [Chain.SEPOLIA]: sepolia, + [Chain.ARBITRUM]: arbitrum, + [Chain.AVALANCHE]: avalanche, + [Chain.BASE]: base, + [Chain.FANTOM]: fantom, + [Chain.GNOSIS]: gnosis, + [Chain.OPTIMISM]: optimism, + [Chain.POLYGON]: polygon, + [Chain.ZKEVM]: polygonZkEvm, +}; + +export const getViemClient = (chain: Chain) => { + return createPublicClient({ + chain: chain2ViemChain[chain], + transport: http(config[chain]?.rpcUrl), + }); +}; diff --git a/modules/subgraphs/balancer-v3-pools/index.ts b/modules/subgraphs/balancer-v3-pools/index.ts new file mode 100644 index 000000000..7d0e78052 --- /dev/null +++ b/modules/subgraphs/balancer-v3-pools/index.ts @@ -0,0 +1,17 @@ +import { GraphQLClient } from 'graphql-request'; +import { getSdk } from './generated/types'; + +/** + * Builds a client based on subgraph URL. + * + * @param subgraphUrl - url of the subgraph + * @returns sdk - generated sdk for the subgraph + */ +export const getPoolsSubgraphClient = (subgraphUrl: string) => { + const client = new GraphQLClient(subgraphUrl); + const sdk = getSdk(client); + + return sdk; +}; + +export type V3PoolsSubgraphClient = ReturnType; diff --git a/modules/subgraphs/balancer-v3-pools/pools.graphql b/modules/subgraphs/balancer-v3-pools/pools.graphql new file mode 100644 index 000000000..c9417d1c0 --- /dev/null +++ b/modules/subgraphs/balancer-v3-pools/pools.graphql @@ -0,0 +1,42 @@ +fragment Factory on Factory { + id + type + version + pools { + id + address + weights + } +} + +fragment TypePool on Pool { + id + address + factory { + id + # address + type + version + } + weights +} + +query Pools( + $skip: Int + $first: Int + $orderBy: Pool_orderBy + $orderDirection: OrderDirection + $where: Pool_filter + $block: Block_height +) { + pools( + skip: $skip + first: $first + orderBy: $orderBy + orderDirection: $orderDirection + where: $where + block: $block + ) { + ...TypePool + } +} diff --git a/modules/subgraphs/balancer-v3-vault/index.ts b/modules/subgraphs/balancer-v3-vault/index.ts new file mode 100644 index 000000000..c3f2b1c96 --- /dev/null +++ b/modules/subgraphs/balancer-v3-vault/index.ts @@ -0,0 +1,17 @@ +import { GraphQLClient } from 'graphql-request'; +import { getSdk } from './generated/types'; + +/** + * Builds a client based on subgraph URL. + * + * @param subgraphUrl - url of the subgraph + * @returns sdk - generated sdk for the subgraph + */ +export const getVaultSubgraphClient = (subgraphUrl: string) => { + const client = new GraphQLClient(subgraphUrl); + const sdk = getSdk(client); + + return sdk; +}; + +export type V3SubgraphClient = ReturnType; diff --git a/modules/subgraphs/balancer-v3-vault/join-exits.graphql b/modules/subgraphs/balancer-v3-vault/join-exits.graphql new file mode 100644 index 000000000..25c3c07f3 --- /dev/null +++ b/modules/subgraphs/balancer-v3-vault/join-exits.graphql @@ -0,0 +1,38 @@ +fragment JoinExit on JoinExit { + id + type + sender + amounts + pool { + id + tokens { + address + } + } + user { + id + } + blockNumber + blockTimestamp + transactionHash +} + +query JoinExits( + $skip: Int + $first: Int + $orderBy: JoinExit_orderBy + $orderDirection: OrderDirection + $where: JoinExit_filter + $block: Block_height +) { + joinExits( + skip: $skip + first: $first + orderBy: $orderBy + orderDirection: $orderDirection + where: $where + block: $block + ) { + ...JoinExit + } +} diff --git a/modules/subgraphs/balancer-v3-vault/pool-snapshots.graphql b/modules/subgraphs/balancer-v3-vault/pool-snapshots.graphql new file mode 100644 index 000000000..cadf3ac3f --- /dev/null +++ b/modules/subgraphs/balancer-v3-vault/pool-snapshots.graphql @@ -0,0 +1,32 @@ +fragment PoolSnapshot on PoolSnapshot { + id + pool { + id + tokens { + address + } + } + timestamp + balances + totalShares +} + +query PoolSnapshots( + $skip: Int + $first: Int + $orderBy: PoolSnapshot_orderBy + $orderDirection: OrderDirection + $where: PoolSnapshot_filter + $block: Block_height +) { + poolSnapshots( + skip: $skip + first: $first + orderBy: $orderBy + orderDirection: $orderDirection + where: $where + block: $block + ) { + ...PoolSnapshot + } +} diff --git a/modules/subgraphs/balancer-v3-vault/pools.graphql b/modules/subgraphs/balancer-v3-vault/pools.graphql new file mode 100644 index 000000000..786e1ffcf --- /dev/null +++ b/modules/subgraphs/balancer-v3-vault/pools.graphql @@ -0,0 +1,50 @@ +fragment Pool on Pool { + id + factory + address + name + symbol + totalShares + pauseWindowEndTime + pauseManager + blockNumber + blockTimestamp + transactionHash + tokens { + id + address + index + name + symbol + decimals + balance + totalProtocolSwapFee + totalProtocolYieldFee + } + rateProviders { + address + token { + address + } + } +} + +query Pools( + $skip: Int + $first: Int + $orderBy: Pool_orderBy + $orderDirection: OrderDirection + $where: Pool_filter + $block: Block_height +) { + pools( + skip: $skip + first: $first + orderBy: $orderBy + orderDirection: $orderDirection + where: $where + block: $block + ) { + ...Pool + } +} diff --git a/modules/subgraphs/balancer-v3-vault/swaps.graphql b/modules/subgraphs/balancer-v3-vault/swaps.graphql new file mode 100644 index 000000000..89f72ef63 --- /dev/null +++ b/modules/subgraphs/balancer-v3-vault/swaps.graphql @@ -0,0 +1,35 @@ +fragment Swap on Swap { + id + pool + tokenIn + tokenOut + tokenAmountIn + tokenAmountOut + swapFeeAmount + user { + id + } + blockNumber + blockTimestamp + transactionHash +} + +query Swaps( + $skip: Int + $first: Int + $orderBy: Swap_orderBy + $orderDirection: OrderDirection + $where: Swap_filter + $block: Block_height +) { + swaps( + skip: $skip + first: $first + orderBy: $orderBy + orderDirection: $orderDirection + where: $where + block: $block + ) { + ...Swap + } +} diff --git a/modules/subgraphs/balancer-v3-vault/users.graphql b/modules/subgraphs/balancer-v3-vault/users.graphql new file mode 100644 index 000000000..15fd08d5b --- /dev/null +++ b/modules/subgraphs/balancer-v3-vault/users.graphql @@ -0,0 +1,42 @@ +fragment User on User { + id + swaps(first: 1000) { + id + pool + tokenIn + tokenOut + tokenAmountIn + tokenAmountOut + swapFeeAmount + blockNumber + blockTimestamp + transactionHash + } + shares(first: 1000) { + id + pool { + id + } + balance + } +} + +query Users( + $skip: Int + $first: Int + $orderBy: User_orderBy + $orderDirection: OrderDirection + $where: User_filter + $block: Block_height +) { + users( + skip: $skip + first: $first + orderBy: $orderBy + orderDirection: $orderDirection + where: $where + block: $block + ) { + ...User + } +} diff --git a/modules/v3/README.md b/modules/v3/README.md new file mode 100644 index 000000000..75bd94b86 --- /dev/null +++ b/modules/v3/README.md @@ -0,0 +1,34 @@ +### Architecture + +The API is a monolith designed to cover 2 main functions: + +1. Serve graphql API with cached onchain state of pool and user data designed around frontend needs. It has 3 components: + - Jobs queue scheduler – is pushing jobs to the queue on cron schedule + - Jobs handler – executes ETL actions + - Server – serves graphql schema for reading +2. Provide SOR for liquidity on Balancer. It's route finding is based on BSF on the pools directed graph where nodes are the tokens and edges are triads: [pool.id, tokenIn, tokenOut]. + +#### Structural Layers + +Excalidraw diagram: app-architecture.excalidraw + +**/modules/controllers** +Controllers are resposible for creating context from configuration, eg: setting up external data sources or passing required configs to the actions. It's the entry point for executing logic based on the users / cron requests. + +**/modules/actions** +This directory contains the code that orchestrates the ETL process, calling the appropriate functions from the sources, transformers, and stores directories. This is the main logic of the ETL process. + +**/modules/sources** +Sources is the external data access layer, it's responsible for extracting data from 3 main sources: + +1. Subgraph – responsible for static data with low frequency updates +2. Contracts – used for quering real time data +3. Logs – extracting events for direct indexing skipping subgraph + +The extracted data is then passed on to the transform functions for DB format mapping. + +**/modules/sources/transformers** +Transformers are responsible for converting the extracted data format into DB expected one. This could involve cleaning the data, filtering it, aggregating it, or applying business rules. The transformed data is then passed on to the Stores for loading into the DB. + +**Application data access layer** +Prisma ORM to abstract the DB. diff --git a/package.json b/package.json index cab372b3d..98b667b9e 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,14 @@ "private": true, "scripts": { "start": "node dist/app.js", - "start:local": "ts-node -r dotenv/config app", + "start:local": "ts-node -r dotenv/config -r tsconfig-paths/register app", "watch": "concurrently \"nodemon app\" \"yarn generate --watch\"", - "build": "tsc", + "build": "tsc -p tsconfig.build.json", "generate": "graphql-codegen --config codegen.yml -r dotenv/config", "prisma-merge": "ts-node prisma/prisma-merge.ts", "test": "jest", - "vitest": "vitest" + "vitest": "vitest", + "task": "ts-node -r tsconfig-paths/register -r dotenv/config tasks/index.ts" }, "dependencies": { "@aws-sdk/client-cloudwatch": "^3.388.0", @@ -33,6 +34,7 @@ "@sentry/node": "^7.0.0", "@sentry/profiling-node": "^1.2.6", "@sentry/tracing": "^7.56.0", + "abitype": "^1.0.0", "apollo-server-core": "^3.5.0", "apollo-server-express": "^3.5.0", "axios": "^0.24.0", @@ -92,6 +94,7 @@ "testcontainers": "^8.0.0", "ts-jest": "^28.0.7", "ts-node": "^10.4.0", + "tsconfig-paths": "^4.2.0", "typescript": "^5.3.3", "vitest": "^0.32.4", "vitest-mock-extended": "^1.1.3" diff --git a/tasks/index.ts b/tasks/index.ts new file mode 100644 index 000000000..49ace8c83 --- /dev/null +++ b/tasks/index.ts @@ -0,0 +1,19 @@ +import { JobsController } from '../modules/controllers/jobs-controller'; + +// TODO needed? +const jobsController = JobsController(); + +async function run(job: string = process.argv[2], chain: string = process.argv[3]) { + console.log('Running job', job, chain); + + if (job === 'sync-changed-pools-v3') { + return jobsController.addMissingPoolsFromSubgraph(chain); + } + + return Promise.reject(new Error(`Unknown job: ${job}`)); +} + +run() + .then((r) => console.log) + .then(() => process.exit(0)) + .catch((e) => console.error); diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 000000000..d92252c64 --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["node_modules", "debug", "**/*.spec.ts", "**/*.test.ts"] +} diff --git a/worker/job-handlers.ts b/worker/job-handlers.ts index 06a54a168..1eccf9932 100644 --- a/worker/job-handlers.ts +++ b/worker/job-handlers.ts @@ -17,9 +17,12 @@ import { cronsDurationMetricPublisher } from '../modules/metrics/cron-duration-m import { syncLatestFXPrices } from '../modules/token/latest-fx-price'; import { AllNetworkConfigs } from '../modules/network/network-config'; import { sftmxService } from '../modules/sftmx/sftmx.service'; +import { JobsController } from '../modules/controllers/jobs-controller'; const runningJobs: Set = new Set(); +const jobsController = JobsController(); + async function runIfNotAlreadyRunning( id: string, chainId: string, @@ -105,7 +108,13 @@ export function configureWorkerRoutes(app: Express) { break; case 'sync-changed-pools-v3': - await runIfNotAlreadyRunning(job.name, chainId, () => poolService.syncChangedPoolsV3(), res, next); + await runIfNotAlreadyRunning( + job.name, + chainId, + () => jobsController.updateOnChainDataChangedPools(chainId), + res, + next, + ); break; case 'user-sync-wallet-balances-for-all-pools': await runIfNotAlreadyRunning( @@ -180,7 +189,7 @@ export function configureWorkerRoutes(app: Express) { await runIfNotAlreadyRunning( job.name, chainId, - () => poolService.syncNewPoolsFromSubgraphV3(), + () => jobsController.addMissingPoolsFromSubgraph(chainId), res, next, ); diff --git a/yarn.lock b/yarn.lock index 5b741e11f..5ae87b4a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5084,7 +5084,7 @@ abitype@0.9.8: resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.9.8.tgz#1f120b6b717459deafd213dfbf3a3dd1bf10ae8c" integrity sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ== -abitype@1.0.0: +abitype@1.0.0, abitype@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.0.tgz#237176dace81d90d018bebf3a45cb42f2a2d9e97" integrity sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ== @@ -9037,6 +9037,11 @@ json5@^2.2.1: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +json5@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + jsonc-parser@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" @@ -9575,6 +9580,11 @@ minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + minipass-collect@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" @@ -11283,6 +11293,11 @@ strip-ansi@^7.0.1: dependencies: ansi-regex "^6.0.1" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + strip-bom@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" @@ -11611,6 +11626,15 @@ ts-node@^9: source-map-support "^0.5.17" yn "3.1.1" +tsconfig-paths@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" + integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== + dependencies: + json5 "^2.2.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + tslib@^1.11.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"