From 956a8954679fccf4b080c1ea864662cb7552acf3 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Thu, 21 Dec 2023 14:02:30 +0100
Subject: [PATCH 01/23] docker-compose setup

---
 README.md          | 9 +++------
 docker-compose.yml | 9 ++++++++-
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md
index 828d6e766..f638248cd 100644
--- a/README.md
+++ b/README.md
@@ -47,14 +47,11 @@ userInitStakedBalances
 ### Setup database & Prisma from backup
 
 Retrieve the current pg_dump file under `https://api-db-dump.s3.eu-central-1.amazonaws.com/canary/api-dump.YYYYMMDD`.
-Database dumps are kept for the previous 7 days, replace YYYYMMDD in the URL above (ie: 20230317)  to download a db dump.
+Database dumps are kept for the previous 7 days, replace YYYYMMDD in the URL above (ie: 20230317) to download a db dump.
 
 Run `docker-compose up -d` to start the database via docker compose.
 
-Retrieve the docker container ID through `docker ps`.
-
-Run `docker exec -i <container-ID> /bin/bash -c "PGPASSWORD=let-me-in psql --username backend database" < /path/on/your/machine/dump`
-with the container-ID from the step before.
+Run `docker exec -i $(docker ps -qf "name=balancer-backend") /bin/bash -c "PGPASSWORD=let-me-in psql --username backend database" < /path/on/your/machine/dump`
 
 The output at the very end saying `ERROR: role "rdsadmin" does not exist` is normal and can be ignored.
 
@@ -90,4 +87,4 @@ To contribute, branch from `v2-canary` (which is our development branch) and ope
 
 ### Database Updates
 
-If you make any changes to the database schema be sure to run `yarn prisma migrate dev --name <change_name>` which will create a new file in `prisma/migrations` that contains all the database changes you've made as an SQL update script. 
\ No newline at end of file
+If you make any changes to the database schema be sure to run `yarn prisma migrate dev --name <change_name>` which will create a new file in `prisma/migrations` that contains all the database changes you've made as an SQL update script.
diff --git a/docker-compose.yml b/docker-compose.yml
index 91766dccb..05ae87ada 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,10 +2,17 @@ version: '3'
 
 services:
     postgres:
-        image: postgres
+        container_name: balancer-backend
+        image: postgres:14-alpine
         ports:
             - '5431:5432'
         environment:
             POSTGRES_USER: backend
             POSTGRES_PASSWORD: let-me-in
             POSTGRES_DB: database
+        networks:
+            - balancer
+
+networks:
+    balancer:
+        name: balancer

From dcfd0d206027accbb2e63eb44b4d8b0a28f24a78 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Thu, 21 Dec 2023 15:12:18 +0100
Subject: [PATCH 02/23] more tests

---
 package.json                         |  1 +
 test/factories/index.ts              |  2 ++
 test/factories/pool.factory.ts       | 50 ++++++++++++++++++++++++++++
 test/factories/pool_token.factory.ts | 17 ++++++++++
 yarn.lock                            | 12 +++++++
 5 files changed, 82 insertions(+)
 create mode 100644 test/factories/index.ts
 create mode 100644 test/factories/pool.factory.ts
 create mode 100644 test/factories/pool_token.factory.ts

diff --git a/package.json b/package.json
index ce3785b5f..8165f0df3 100644
--- a/package.json
+++ b/package.json
@@ -82,6 +82,7 @@
         "@types/uuid": "^8.0.0",
         "concurrently": "^6.4.0",
         "execa": "^4.1.0",
+        "fishery": "^2.2.2",
         "jest": "^28.1.3",
         "jest-watch-typeahead": "^1.0.0",
         "msw": "^0.47.3",
diff --git a/test/factories/index.ts b/test/factories/index.ts
new file mode 100644
index 000000000..6706ad5bc
--- /dev/null
+++ b/test/factories/index.ts
@@ -0,0 +1,2 @@
+export * from './pool.factory';
+export * from './pool_token.factory';
diff --git a/test/factories/pool.factory.ts b/test/factories/pool.factory.ts
new file mode 100644
index 000000000..a64270533
--- /dev/null
+++ b/test/factories/pool.factory.ts
@@ -0,0 +1,50 @@
+import { Factory } from 'fishery';
+import { BalancerPoolFragment } from '../../modules/subgraphs/balancer-subgraph/generated/balancer-subgraph-types';
+
+export const poolFactory = Factory.define<BalancerPoolFragment>(() => ({
+    id: '123',
+    poolType: 'A',
+    address: '0x123456789',
+    swapFee: '0.01',
+    totalSwapVolume: '1000',
+    totalSwapFee: '10',
+    totalLiquidity: '10000',
+    totalShares: '100',
+    swapsCount: '5',
+    holdersCount: '10',
+    createTime: 1234567890, // Add createTime property as a number
+    swapEnabled: true, // Add swapEnabled property
+    tokensList: ['token1', 'token2'], // Add tokensList property
+    tokens: [
+        {
+            id: 'token1',
+            symbol: 'T1',
+            name: 'Token 1',
+            decimals: 18,
+            address: 'token1',
+            balance: '100',
+            weight: '0.5',
+            priceRate: '1',
+            index: 0,
+            token: {
+                // token properties...
+            },
+        },
+        {
+            id: 'token2',
+            symbol: 'T2',
+            name: 'Token 2',
+            decimals: 18,
+            address: 'token2',
+            balance: '200',
+            weight: '0.5',
+            priceRate: '1',
+            index: 1,
+            token: {
+                // token properties...
+            },
+        },
+    ],
+
+    // Add other required properties...
+}));
diff --git a/test/factories/pool_token.factory.ts b/test/factories/pool_token.factory.ts
new file mode 100644
index 000000000..50c03cc75
--- /dev/null
+++ b/test/factories/pool_token.factory.ts
@@ -0,0 +1,17 @@
+import { Factory } from 'fishery';
+import { BalancerPoolTokenFragment } from '../../modules/subgraphs/balancer-subgraph/generated/balancer-subgraph-types';
+
+export const poolTokenFactory = Factory.define<BalancerPoolTokenFragment>(() => ({
+    id: 'token1',
+    symbol: 'T1',
+    name: 'Token 1',
+    decimals: 18,
+    address: 'token1',
+    balance: '100',
+    weight: '0.5',
+    priceRate: '1',
+    index: 0,
+    token: {
+        // token properties...
+    },
+}));
diff --git a/yarn.lock b/yarn.lock
index 1f593b651..830c56f46 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7280,6 +7280,13 @@ find-up@^4.0.0, find-up@^4.1.0:
     locate-path "^5.0.0"
     path-exists "^4.0.0"
 
+fishery@^2.2.2:
+  version "2.2.2"
+  resolved "https://registry.yarnpkg.com/fishery/-/fishery-2.2.2.tgz#94d3d9380295dd3ce555021e9353c5348b8beb77"
+  integrity sha512-jeU0nDhPHJkupmjX+r9niKgVMTBDB8X+U/pktoGHAiWOSyNlMd0HhmqnjrpjUOCDPJYaSSu4Ze16h6dZOKSp2w==
+  dependencies:
+    lodash.mergewith "^4.6.2"
+
 follow-redirects@^1.0.0:
   version "1.15.3"
   resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a"
@@ -9263,6 +9270,11 @@ lodash.memoize@4.x:
   resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
   integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
 
+lodash.mergewith@^4.6.2:
+  version "4.6.2"
+  resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
+  integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
+
 lodash.once@^4.0.0:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"

From ee6e0e71bc1d46b3a283a6f165476de1e4361593 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Thu, 21 Dec 2023 16:36:18 +0100
Subject: [PATCH 03/23] allow deleting pools with associations

---
 modules/pool/pool.prisma                      |  36 ++---
 modules/user/user.prisma                      |   6 +-
 modules/vebal/vebal.prisma                    |   2 +-
 .../migration.sql                             | 131 ++++++++++++++++++
 prisma/schema.prisma                          |  44 +++---
 5 files changed, 175 insertions(+), 44 deletions(-)
 create mode 100644 prisma/migrations/20231221153955_allow_deleting_pools_with_associations/migration.sql

diff --git a/modules/pool/pool.prisma b/modules/pool/pool.prisma
index 9b16b15c2..a152af46b 100644
--- a/modules/pool/pool.prisma
+++ b/modules/pool/pool.prisma
@@ -65,7 +65,7 @@ model PrismaPoolLinearData {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     mainIndex           Int
@@ -78,7 +78,7 @@ model PrismaPoolElementData {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     unitSeconds         String
@@ -92,7 +92,7 @@ model PrismaPoolGyroData{
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     alpha               String
@@ -120,7 +120,7 @@ model PrismaPoolDynamicData {
 
     id                      String
     poolId                  String
-    pool                    PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                    PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain                   Chain
     blockNumber             Int
     updatedAt               DateTime            @updatedAt
@@ -174,7 +174,7 @@ model PrismaPoolStableDynamicData {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
     blockNumber         Int
     updatedAt           DateTime            @updatedAt
@@ -188,7 +188,7 @@ model PrismaPoolLinearDynamicData {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
     blockNumber         Int
     updatedAt           DateTime            @updatedAt
@@ -202,7 +202,7 @@ model PrismaPoolToken {
 
     id                          String
     poolId                      String
-    pool                        PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                        PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain                       Chain
 
     address                     String
@@ -224,7 +224,7 @@ model PrismaPoolTokenDynamicData {
 
     id                  String
     poolTokenId         String
-    poolToken           PrismaPoolToken     @relation(fields:[poolTokenId, chain], references: [id, chain])
+    poolToken           PrismaPoolToken     @relation(fields:[poolTokenId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
     blockNumber         Int
     updatedAt           DateTime            @updatedAt
@@ -241,7 +241,7 @@ model PrismaPoolSwap {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     userAddress         String
@@ -284,7 +284,7 @@ model PrismaPoolAprItem {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
     title               String
     apr                 Float
@@ -301,7 +301,7 @@ model PrismaPoolAprRange {
     id                  String
     chain               Chain
     aprItemId           String
-    aprItem             PrismaPoolAprItem   @relation(fields:[aprItemId, chain], references: [id, chain])
+    aprItem             PrismaPoolAprItem   @relation(fields:[aprItemId, chain], references: [id, chain], onDelete: Cascade)
     min                 Float
     max                 Float
 }
@@ -355,11 +355,11 @@ model PrismaPoolExpandedTokens {
     tokenAddress        String
     token               PrismaToken         @relation(fields:[tokenAddress, chain], references: [address, chain])
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     nestedPoolId        String?
-    nestedPool          PrismaPool?         @relation(name: "NestedPoolForAllToken", fields:[nestedPoolId, chain], references: [id, chain])
+    nestedPool          PrismaPool?         @relation(name: "NestedPoolForAllToken", fields:[nestedPoolId, chain], references: [id, chain], onDelete: Cascade)
 }
 
 
@@ -381,7 +381,7 @@ model PrismaPoolFilterMap {
     filterId            String
     filter              PrismaPoolFilter    @relation(fields:[filterId, chain], references: [id, chain])
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
 }
 
 model PrismaPoolStaking {
@@ -389,7 +389,7 @@ model PrismaPoolStaking {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
     type                PrismaPoolStakingType
     address             String
@@ -439,7 +439,7 @@ model PrismaPoolStakingGauge {
 
     id                  String
     stakingId           String
-    staking             PrismaPoolStaking   @relation(fields:[stakingId, chain], references: [id, chain])
+    staking             PrismaPoolStaking   @relation(fields:[stakingId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     gaugeAddress        String
@@ -463,7 +463,7 @@ model PrismaPoolStakingGaugeReward{
 
     id                  String
     gaugeId             String
-    gauge               PrismaPoolStakingGauge @relation(fields:[gaugeId, chain], references: [id, chain])
+    gauge               PrismaPoolStakingGauge @relation(fields:[gaugeId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     tokenAddress        String
@@ -510,7 +510,7 @@ model PrismaPoolSnapshot {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
     timestamp           Int
 
diff --git a/modules/user/user.prisma b/modules/user/user.prisma
index 69746e651..11cdd6c6e 100644
--- a/modules/user/user.prisma
+++ b/modules/user/user.prisma
@@ -26,7 +26,7 @@ model PrismaUserWalletBalance {
     user                    PrismaUser          @relation(fields:[userAddress], references: [address])
 
     poolId                  String?
-    pool                    PrismaPool?         @relation(fields:[poolId, chain], references: [id, chain])
+    pool                    PrismaPool?         @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
 
     tokenAddress            String
     token                   PrismaToken         @relation(fields:[tokenAddress, chain], references: [address, chain])
@@ -46,13 +46,13 @@ model PrismaUserStakedBalance {
     user                    PrismaUser          @relation(fields:[userAddress], references: [address])
 
     poolId                  String?
-    pool                    PrismaPool?          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                    PrismaPool?          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
 
     tokenAddress            String
     token                   PrismaToken         @relation(fields:[tokenAddress, chain], references: [address, chain])
 
     stakingId               String
-    staking                 PrismaPoolStaking   @relation(fields:[stakingId, chain], references: [id, chain])
+    staking                 PrismaPoolStaking   @relation(fields:[stakingId, chain], references: [id, chain], onDelete: Cascade)
 }
 
 model PrismaUserBalanceSyncStatus {
diff --git a/modules/vebal/vebal.prisma b/modules/vebal/vebal.prisma
index df28431b5..3ea981dc9 100644
--- a/modules/vebal/vebal.prisma
+++ b/modules/vebal/vebal.prisma
@@ -31,7 +31,7 @@ model PrismaVotingGauge {
   id      String
   chain   Chain
 
-  stakingGauge      PrismaPoolStakingGauge? @relation(fields: [stakingGaugeId, chain], references: [id, chain])
+  stakingGauge      PrismaPoolStakingGauge? @relation(fields: [stakingGaugeId, chain], references: [id, chain], onDelete: Cascade)
   status            PrismaVotingGaugeStatus @default(ACTIVE)
   gaugeAddress      String
   stakingGaugeId    String?
diff --git a/prisma/migrations/20231221153955_allow_deleting_pools_with_associations/migration.sql b/prisma/migrations/20231221153955_allow_deleting_pools_with_associations/migration.sql
new file mode 100644
index 000000000..7160564a4
--- /dev/null
+++ b/prisma/migrations/20231221153955_allow_deleting_pools_with_associations/migration.sql
@@ -0,0 +1,131 @@
+-- DropForeignKey
+ALTER TABLE "PrismaPoolAprItem" DROP CONSTRAINT "PrismaPoolAprItem_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolAprRange" DROP CONSTRAINT "PrismaPoolAprRange_aprItemId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolDynamicData" DROP CONSTRAINT "PrismaPoolDynamicData_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolElementData" DROP CONSTRAINT "PrismaPoolElementData_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolExpandedTokens" DROP CONSTRAINT "PrismaPoolExpandedTokens_nestedPoolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolExpandedTokens" DROP CONSTRAINT "PrismaPoolExpandedTokens_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolFilterMap" DROP CONSTRAINT "PrismaPoolFilterMap_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolGyroData" DROP CONSTRAINT "PrismaPoolGyroData_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolLinearData" DROP CONSTRAINT "PrismaPoolLinearData_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolLinearDynamicData" DROP CONSTRAINT "PrismaPoolLinearDynamicData_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolSnapshot" DROP CONSTRAINT "PrismaPoolSnapshot_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolStableDynamicData" DROP CONSTRAINT "PrismaPoolStableDynamicData_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolStaking" DROP CONSTRAINT "PrismaPoolStaking_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolStakingGauge" DROP CONSTRAINT "PrismaPoolStakingGauge_stakingId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolStakingGaugeReward" DROP CONSTRAINT "PrismaPoolStakingGaugeReward_gaugeId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolSwap" DROP CONSTRAINT "PrismaPoolSwap_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolToken" DROP CONSTRAINT "PrismaPoolToken_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaPoolTokenDynamicData" DROP CONSTRAINT "PrismaPoolTokenDynamicData_poolTokenId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaUserStakedBalance" DROP CONSTRAINT "PrismaUserStakedBalance_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaUserStakedBalance" DROP CONSTRAINT "PrismaUserStakedBalance_stakingId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaUserWalletBalance" DROP CONSTRAINT "PrismaUserWalletBalance_poolId_chain_fkey";
+
+-- DropForeignKey
+ALTER TABLE "PrismaVotingGauge" DROP CONSTRAINT "PrismaVotingGauge_stakingGaugeId_chain_fkey";
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolLinearData" ADD CONSTRAINT "PrismaPoolLinearData_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolElementData" ADD CONSTRAINT "PrismaPoolElementData_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolGyroData" ADD CONSTRAINT "PrismaPoolGyroData_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolDynamicData" ADD CONSTRAINT "PrismaPoolDynamicData_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolStableDynamicData" ADD CONSTRAINT "PrismaPoolStableDynamicData_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolLinearDynamicData" ADD CONSTRAINT "PrismaPoolLinearDynamicData_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolToken" ADD CONSTRAINT "PrismaPoolToken_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolTokenDynamicData" ADD CONSTRAINT "PrismaPoolTokenDynamicData_poolTokenId_chain_fkey" FOREIGN KEY ("poolTokenId", "chain") REFERENCES "PrismaPoolToken"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolSwap" ADD CONSTRAINT "PrismaPoolSwap_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolAprItem" ADD CONSTRAINT "PrismaPoolAprItem_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolAprRange" ADD CONSTRAINT "PrismaPoolAprRange_aprItemId_chain_fkey" FOREIGN KEY ("aprItemId", "chain") REFERENCES "PrismaPoolAprItem"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolExpandedTokens" ADD CONSTRAINT "PrismaPoolExpandedTokens_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolExpandedTokens" ADD CONSTRAINT "PrismaPoolExpandedTokens_nestedPoolId_chain_fkey" FOREIGN KEY ("nestedPoolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolFilterMap" ADD CONSTRAINT "PrismaPoolFilterMap_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolStaking" ADD CONSTRAINT "PrismaPoolStaking_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolStakingGauge" ADD CONSTRAINT "PrismaPoolStakingGauge_stakingId_chain_fkey" FOREIGN KEY ("stakingId", "chain") REFERENCES "PrismaPoolStaking"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolStakingGaugeReward" ADD CONSTRAINT "PrismaPoolStakingGaugeReward_gaugeId_chain_fkey" FOREIGN KEY ("gaugeId", "chain") REFERENCES "PrismaPoolStakingGauge"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaPoolSnapshot" ADD CONSTRAINT "PrismaPoolSnapshot_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaUserWalletBalance" ADD CONSTRAINT "PrismaUserWalletBalance_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaUserStakedBalance" ADD CONSTRAINT "PrismaUserStakedBalance_poolId_chain_fkey" FOREIGN KEY ("poolId", "chain") REFERENCES "PrismaPool"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaUserStakedBalance" ADD CONSTRAINT "PrismaUserStakedBalance_stakingId_chain_fkey" FOREIGN KEY ("stakingId", "chain") REFERENCES "PrismaPoolStaking"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PrismaVotingGauge" ADD CONSTRAINT "PrismaVotingGauge_stakingGaugeId_chain_fkey" FOREIGN KEY ("stakingGaugeId", "chain") REFERENCES "PrismaPoolStakingGauge"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE;
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 186f5c992..4868e2afd 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -111,7 +111,7 @@ model PrismaPoolLinearData {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     mainIndex           Int
@@ -124,7 +124,7 @@ model PrismaPoolElementData {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     unitSeconds         String
@@ -138,7 +138,7 @@ model PrismaPoolGyroData{
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     alpha               String
@@ -166,7 +166,7 @@ model PrismaPoolDynamicData {
 
     id                      String
     poolId                  String
-    pool                    PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                    PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain                   Chain
     blockNumber             Int
     updatedAt               DateTime            @updatedAt
@@ -220,7 +220,7 @@ model PrismaPoolStableDynamicData {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
     blockNumber         Int
     updatedAt           DateTime            @updatedAt
@@ -234,7 +234,7 @@ model PrismaPoolLinearDynamicData {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
     blockNumber         Int
     updatedAt           DateTime            @updatedAt
@@ -248,7 +248,7 @@ model PrismaPoolToken {
 
     id                          String
     poolId                      String
-    pool                        PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                        PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain                       Chain
 
     address                     String
@@ -270,7 +270,7 @@ model PrismaPoolTokenDynamicData {
 
     id                  String
     poolTokenId         String
-    poolToken           PrismaPoolToken     @relation(fields:[poolTokenId, chain], references: [id, chain])
+    poolToken           PrismaPoolToken     @relation(fields:[poolTokenId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
     blockNumber         Int
     updatedAt           DateTime            @updatedAt
@@ -287,7 +287,7 @@ model PrismaPoolSwap {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     userAddress         String
@@ -330,7 +330,7 @@ model PrismaPoolAprItem {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
     title               String
     apr                 Float
@@ -347,7 +347,7 @@ model PrismaPoolAprRange {
     id                  String
     chain               Chain
     aprItemId           String
-    aprItem             PrismaPoolAprItem   @relation(fields:[aprItemId, chain], references: [id, chain])
+    aprItem             PrismaPoolAprItem   @relation(fields:[aprItemId, chain], references: [id, chain], onDelete: Cascade)
     min                 Float
     max                 Float
 }
@@ -401,11 +401,11 @@ model PrismaPoolExpandedTokens {
     tokenAddress        String
     token               PrismaToken         @relation(fields:[tokenAddress, chain], references: [address, chain])
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     nestedPoolId        String?
-    nestedPool          PrismaPool?         @relation(name: "NestedPoolForAllToken", fields:[nestedPoolId, chain], references: [id, chain])
+    nestedPool          PrismaPool?         @relation(name: "NestedPoolForAllToken", fields:[nestedPoolId, chain], references: [id, chain], onDelete: Cascade)
 }
 
 
@@ -427,7 +427,7 @@ model PrismaPoolFilterMap {
     filterId            String
     filter              PrismaPoolFilter    @relation(fields:[filterId, chain], references: [id, chain])
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
 }
 
 model PrismaPoolStaking {
@@ -435,7 +435,7 @@ model PrismaPoolStaking {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
     type                PrismaPoolStakingType
     address             String
@@ -485,7 +485,7 @@ model PrismaPoolStakingGauge {
 
     id                  String
     stakingId           String
-    staking             PrismaPoolStaking   @relation(fields:[stakingId, chain], references: [id, chain])
+    staking             PrismaPoolStaking   @relation(fields:[stakingId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     gaugeAddress        String
@@ -509,7 +509,7 @@ model PrismaPoolStakingGaugeReward{
 
     id                  String
     gaugeId             String
-    gauge               PrismaPoolStakingGauge @relation(fields:[gaugeId, chain], references: [id, chain])
+    gauge               PrismaPoolStakingGauge @relation(fields:[gaugeId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
 
     tokenAddress        String
@@ -556,7 +556,7 @@ model PrismaPoolSnapshot {
 
     id                  String
     poolId              String
-    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                PrismaPool          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
     chain               Chain
     timestamp           Int
 
@@ -787,7 +787,7 @@ model PrismaUserWalletBalance {
     user                    PrismaUser          @relation(fields:[userAddress], references: [address])
 
     poolId                  String?
-    pool                    PrismaPool?         @relation(fields:[poolId, chain], references: [id, chain])
+    pool                    PrismaPool?         @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
 
     tokenAddress            String
     token                   PrismaToken         @relation(fields:[tokenAddress, chain], references: [address, chain])
@@ -807,13 +807,13 @@ model PrismaUserStakedBalance {
     user                    PrismaUser          @relation(fields:[userAddress], references: [address])
 
     poolId                  String?
-    pool                    PrismaPool?          @relation(fields:[poolId, chain], references: [id, chain])
+    pool                    PrismaPool?          @relation(fields:[poolId, chain], references: [id, chain], onDelete: Cascade)
 
     tokenAddress            String
     token                   PrismaToken         @relation(fields:[tokenAddress, chain], references: [address, chain])
 
     stakingId               String
-    staking                 PrismaPoolStaking   @relation(fields:[stakingId, chain], references: [id, chain])
+    staking                 PrismaPoolStaking   @relation(fields:[stakingId, chain], references: [id, chain], onDelete: Cascade)
 }
 
 model PrismaUserBalanceSyncStatus {
@@ -903,7 +903,7 @@ model PrismaVotingGauge {
   id      String
   chain   Chain
 
-  stakingGauge      PrismaPoolStakingGauge? @relation(fields: [stakingGaugeId, chain], references: [id, chain])
+  stakingGauge      PrismaPoolStakingGauge? @relation(fields: [stakingGaugeId, chain], references: [id, chain], onDelete: Cascade)
   status            PrismaVotingGaugeStatus @default(ACTIVE)
   gaugeAddress      String
   stakingGaugeId    String?

From 001d1df90c0c617f6eaecf27e01314e3dac90a73 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Thu, 21 Dec 2023 16:40:56 +0100
Subject: [PATCH 04/23] pool defaults for 24h volume and fees

---
 modules/pool/pool.prisma                                      | 4 ++--
 .../20231221154038_more_pool_defaults/migration.sql           | 3 +++
 prisma/schema.prisma                                          | 4 ++--
 3 files changed, 7 insertions(+), 4 deletions(-)
 create mode 100644 prisma/migrations/20231221154038_more_pool_defaults/migration.sql

diff --git a/modules/pool/pool.prisma b/modules/pool/pool.prisma
index a152af46b..a3c234f40 100644
--- a/modules/pool/pool.prisma
+++ b/modules/pool/pool.prisma
@@ -133,8 +133,8 @@ model PrismaPoolDynamicData {
     totalShares             String
     totalSharesNum          Float               @default(0)
     totalLiquidity          Float
-    volume24h               Float
-    fees24h                 Float
+    volume24h               Float               @default(0)
+    fees24h                 Float               @default(0)
     yieldCapture24h         Float               @default(0)
     apr                     Float               @default(0)
     volume48h               Float               @default(0)
diff --git a/prisma/migrations/20231221154038_more_pool_defaults/migration.sql b/prisma/migrations/20231221154038_more_pool_defaults/migration.sql
new file mode 100644
index 000000000..56c17b3ad
--- /dev/null
+++ b/prisma/migrations/20231221154038_more_pool_defaults/migration.sql
@@ -0,0 +1,3 @@
+-- AlterTable
+ALTER TABLE "PrismaPoolDynamicData" ALTER COLUMN "volume24h" SET DEFAULT 0,
+ALTER COLUMN "fees24h" SET DEFAULT 0;
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 4868e2afd..425e860c7 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -179,8 +179,8 @@ model PrismaPoolDynamicData {
     totalShares             String
     totalSharesNum          Float               @default(0)
     totalLiquidity          Float
-    volume24h               Float
-    fees24h                 Float
+    volume24h               Float               @default(0)
+    fees24h                 Float               @default(0)
     yieldCapture24h         Float               @default(0)
     apr                     Float               @default(0)
     volume48h               Float               @default(0)

From 9d5c936100fa9e25318ff1a139e36b1265baf3d0 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Thu, 21 Dec 2023 16:41:26 +0100
Subject: [PATCH 05/23] pools data json column

---
 modules/pool/pool.prisma                                        | 1 +
 .../20231221154118_pools_data_json_column/migration.sql         | 2 ++
 prisma/schema.prisma                                            | 1 +
 3 files changed, 4 insertions(+)
 create mode 100644 prisma/migrations/20231221154118_pools_data_json_column/migration.sql

diff --git a/modules/pool/pool.prisma b/modules/pool/pool.prisma
index a3c234f40..8bb8816ac 100644
--- a/modules/pool/pool.prisma
+++ b/modules/pool/pool.prisma
@@ -18,6 +18,7 @@ model PrismaPool {
     linearData          PrismaPoolLinearData?
     elementData         PrismaPoolElementData?
     gyroData            PrismaPoolGyroData?
+    data                Json @default("{}")
 
     tokens              PrismaPoolToken[]
 
diff --git a/prisma/migrations/20231221154118_pools_data_json_column/migration.sql b/prisma/migrations/20231221154118_pools_data_json_column/migration.sql
new file mode 100644
index 000000000..c08b112b7
--- /dev/null
+++ b/prisma/migrations/20231221154118_pools_data_json_column/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "PrismaPool" ADD COLUMN     "data" JSONB NOT NULL DEFAULT '{}';
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 425e860c7..ad5882758 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -64,6 +64,7 @@ model PrismaPool {
     linearData          PrismaPoolLinearData?
     elementData         PrismaPoolElementData?
     gyroData            PrismaPoolGyroData?
+    data                Json @default("{}")
 
     tokens              PrismaPoolToken[]
 

From b5af3e5f91f7fd3be4a3dca8e333ea53229c1435 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Thu, 21 Dec 2023 14:07:44 +0100
Subject: [PATCH 06/23] add fx data to subgraph

---
 .../balancer-subgraph/balancer-subgraph-queries.graphql        | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/modules/subgraphs/balancer-subgraph/balancer-subgraph-queries.graphql b/modules/subgraphs/balancer-subgraph/balancer-subgraph-queries.graphql
index 5469dc094..faa6bd405 100644
--- a/modules/subgraphs/balancer-subgraph/balancer-subgraph-queries.graphql
+++ b/modules/subgraphs/balancer-subgraph/balancer-subgraph-queries.graphql
@@ -198,6 +198,9 @@ fragment BalancerPool on Pool {
     w
     z
     dSq
+    delta
+    epsilon
+
     priceRateProviders {
         address
         token {

From 827943ccd95e6e21341e4d81eb779cde4c01c16f Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Thu, 21 Dec 2023 16:43:47 +0100
Subject: [PATCH 07/23] subgraph to DB mappers

---
 modules/pool/lib/pool-creator.service.ts | 132 +-------------
 modules/pool/pool-data/element.ts        |   9 +
 modules/pool/pool-data/fx.ts             |  11 ++
 modules/pool/pool-data/gyro.ts           |  23 +++
 modules/pool/pool-data/index.ts          |   5 +
 modules/pool/pool-data/linear.ts         |  16 ++
 modules/pool/pool-data/stable.ts         |   8 +
 modules/pool/subgraph-mapper.test.ts     |  91 ++++++++++
 modules/pool/subgraph-mapper.ts          | 221 +++++++++++++++++++++++
 9 files changed, 387 insertions(+), 129 deletions(-)
 create mode 100644 modules/pool/pool-data/element.ts
 create mode 100644 modules/pool/pool-data/fx.ts
 create mode 100644 modules/pool/pool-data/gyro.ts
 create mode 100644 modules/pool/pool-data/index.ts
 create mode 100644 modules/pool/pool-data/linear.ts
 create mode 100644 modules/pool/pool-data/stable.ts
 create mode 100644 modules/pool/subgraph-mapper.test.ts
 create mode 100644 modules/pool/subgraph-mapper.ts

diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts
index b138ea03b..ebe49f0dc 100644
--- a/modules/pool/lib/pool-creator.service.ts
+++ b/modules/pool/lib/pool-creator.service.ts
@@ -7,6 +7,7 @@ import { prismaPoolWithExpandedNesting } from '../../../prisma/prisma-types';
 import { UserService } from '../../user/user.service';
 import { prismaBulkExecuteOperations } from '../../../prisma/prisma-util';
 import { networkContext } from '../../network/network-context.service';
+import { subgraphToPrisma } from '../subgraph-mapper';
 
 export class PoolCreatorService {
     constructor(private readonly userService: UserService) {}
@@ -224,136 +225,9 @@ export class PoolCreatorService {
             ],
         });
 
-        // for the old phantom stable pool, we add it to the DB as type COMPOSABLE_STABLE with version 0
-        let poolTypeVersion = pool.poolTypeVersion ? pool.poolTypeVersion : 1;
-        if (pool.poolType === 'StablePhantom') {
-            poolTypeVersion = 0;
-        }
+        const prismaPoolRecordWithAssociations = subgraphToPrisma(pool, this.chain, blockNumber, allNestedTypePools);
 
-        await prisma.prismaPool.create({
-            data: {
-                id: pool.id,
-                chain: this.chain,
-                createTime: pool.createTime,
-                address: pool.address,
-                symbol: pool.symbol || '',
-                name: pool.name || '',
-                decimals: 18,
-                type: poolType,
-                version: poolTypeVersion,
-                owner: pool.owner || ZERO_ADDRESS,
-                factory: pool.factory,
-                tokens: {
-                    createMany: {
-                        data: poolTokens.map((token) => {
-                            const nestedPool = allNestedTypePools.find((nestedPool) => {
-                                return nestedPool.address === token.address;
-                            });
-
-                            let priceRateProvider;
-                            if (pool.priceRateProviders) {
-                                const data = pool.priceRateProviders.find(
-                                    (provider) => provider.token.address === token.address,
-                                );
-                                priceRateProvider = data?.address;
-                            }
-
-                            return {
-                                id: token.id,
-                                address: token.address,
-                                priceRateProvider,
-                                exemptFromProtocolYieldFee: token.isExemptFromYieldProtocolFee
-                                    ? token.isExemptFromYieldProtocolFee
-                                    : false,
-                                nestedPoolId: nestedPool?.id,
-                                index: token.index || pool.tokensList.findIndex((address) => address === token.address),
-                            };
-                        }),
-                    },
-                },
-                linearData:
-                    poolType === 'LINEAR'
-                        ? {
-                              create: {
-                                  id: pool.id,
-                                  mainIndex: pool.mainIndex || 0,
-                                  wrappedIndex: pool.wrappedIndex || 0,
-                              },
-                          }
-                        : undefined,
-                linearDynamicData:
-                    poolType === 'LINEAR'
-                        ? {
-                              create: {
-                                  id: pool.id,
-                                  upperTarget: pool.upperTarget || '',
-                                  lowerTarget: pool.lowerTarget || '',
-                                  blockNumber,
-                              },
-                          }
-                        : undefined,
-                elementData:
-                    poolType === 'ELEMENT'
-                        ? {
-                              create: {
-                                  id: pool.id,
-                                  unitSeconds: pool.unitSeconds || '',
-                                  principalToken: pool.principalToken || '',
-                                  baseToken: pool.baseToken || '',
-                              },
-                          }
-                        : undefined,
-                gyroData: ['GYRO', 'GYRO3', 'GYROE'].includes(poolType)
-                    ? {
-                          create: {
-                              id: pool.id,
-                              alpha: pool.alpha || '',
-                              beta: pool.beta || '',
-                              sqrtAlpha: pool.sqrtAlpha || '',
-                              sqrtBeta: pool.sqrtBeta || '',
-                              root3Alpha: pool.root3Alpha || '',
-                              c: pool.c || '',
-                              s: pool.s || '',
-                              lambda: pool.lambda || '',
-                              tauAlphaX: pool.tauAlphaX || '',
-                              tauAlphaY: pool.tauAlphaY || '',
-                              tauBetaX: pool.tauBetaX || '',
-                              tauBetaY: pool.tauBetaY || '',
-                              u: pool.u || '',
-                              v: pool.v || '',
-                              w: pool.w || '',
-                              z: pool.z || '',
-                              dSq: pool.dSq || '',
-                          },
-                      }
-                    : undefined,
-                stableDynamicData:
-                    poolType === 'STABLE' || poolType === 'COMPOSABLE_STABLE' || poolType === 'META_STABLE'
-                        ? {
-                              create: {
-                                  id: pool.id,
-                                  amp: pool.amp || '',
-                                  blockNumber,
-                              },
-                          }
-                        : undefined,
-                dynamicData: {
-                    create: {
-                        id: pool.id,
-                        blockNumber,
-                        swapFee: pool.swapFee,
-                        swapEnabled: pool.swapEnabled,
-                        totalShares: pool.totalShares,
-                        totalSharesNum: parseFloat(pool.totalShares),
-                        totalLiquidity: Math.max(parseFloat(pool.totalLiquidity), 0),
-                        volume24h: 0,
-                        fees24h: 0,
-                        volume48h: 0,
-                        fees48h: 0,
-                    },
-                },
-            },
-        });
+        await prisma.prismaPool.create(prismaPoolRecordWithAssociations);
 
         await prisma.prismaPoolTokenDynamicData.createMany({
             data: poolTokens.map((token) => ({
diff --git a/modules/pool/pool-data/element.ts b/modules/pool/pool-data/element.ts
new file mode 100644
index 000000000..89c6af0ec
--- /dev/null
+++ b/modules/pool/pool-data/element.ts
@@ -0,0 +1,9 @@
+import { BalancerPoolFragment } from '../../subgraphs/balancer-subgraph/generated/balancer-subgraph-types';
+
+export const element = (pool: BalancerPoolFragment) => {
+    return {
+        unitSeconds: pool.unitSeconds || '',
+        principalToken: pool.principalToken || '',
+        baseToken: pool.baseToken || '',
+    };
+};
diff --git a/modules/pool/pool-data/fx.ts b/modules/pool/pool-data/fx.ts
new file mode 100644
index 000000000..7b1edf745
--- /dev/null
+++ b/modules/pool/pool-data/fx.ts
@@ -0,0 +1,11 @@
+import { BalancerPoolFragment } from '../../subgraphs/balancer-subgraph/generated/balancer-subgraph-types';
+
+export const fx = (pool: BalancerPoolFragment) => {
+    return {
+        alpha: pool.alpha,
+        beta: pool.beta,
+        delta: pool.delta,
+        epsilon: pool.epsilon,
+        lambda: pool.lambda,
+    };
+};
diff --git a/modules/pool/pool-data/gyro.ts b/modules/pool/pool-data/gyro.ts
new file mode 100644
index 000000000..326a3c044
--- /dev/null
+++ b/modules/pool/pool-data/gyro.ts
@@ -0,0 +1,23 @@
+import { BalancerPoolFragment } from '../../subgraphs/balancer-subgraph/generated/balancer-subgraph-types';
+
+export const gyro = (pool: BalancerPoolFragment) => {
+    return {
+        alpha: pool.alpha || '',
+        beta: pool.beta || '',
+        sqrtAlpha: pool.sqrtAlpha || '',
+        sqrtBeta: pool.sqrtBeta || '',
+        root3Alpha: pool.root3Alpha || '',
+        c: pool.c || '',
+        s: pool.s || '',
+        lambda: pool.lambda || '',
+        tauAlphaX: pool.tauAlphaX || '',
+        tauAlphaY: pool.tauAlphaY || '',
+        tauBetaX: pool.tauBetaX || '',
+        tauBetaY: pool.tauBetaY || '',
+        u: pool.u || '',
+        v: pool.v || '',
+        w: pool.w || '',
+        z: pool.z || '',
+        dSq: pool.dSq || '',
+    };
+};
diff --git a/modules/pool/pool-data/index.ts b/modules/pool/pool-data/index.ts
new file mode 100644
index 000000000..52c0b91de
--- /dev/null
+++ b/modules/pool/pool-data/index.ts
@@ -0,0 +1,5 @@
+export * from './element';
+export * from './fx';
+export * from './gyro';
+export * from './linear';
+export * from './stable';
diff --git a/modules/pool/pool-data/linear.ts b/modules/pool/pool-data/linear.ts
new file mode 100644
index 000000000..becb29a4c
--- /dev/null
+++ b/modules/pool/pool-data/linear.ts
@@ -0,0 +1,16 @@
+import { BalancerPoolFragment } from '../../subgraphs/balancer-subgraph/generated/balancer-subgraph-types';
+
+export const linear = (pool: BalancerPoolFragment) => {
+    return {
+        mainIndex: pool.mainIndex || 0,
+        wrappedIndex: pool.wrappedIndex || 0,
+    };
+};
+
+export const linearDynamic = (pool: BalancerPoolFragment, blockNumber: number) => {
+    return {
+        upperTarget: pool.upperTarget || '',
+        lowerTarget: pool.lowerTarget || '',
+        blockNumber,
+    };
+};
diff --git a/modules/pool/pool-data/stable.ts b/modules/pool/pool-data/stable.ts
new file mode 100644
index 000000000..7ac8218d8
--- /dev/null
+++ b/modules/pool/pool-data/stable.ts
@@ -0,0 +1,8 @@
+import { BalancerPoolFragment } from '../../subgraphs/balancer-subgraph/generated/balancer-subgraph-types';
+
+export const stableDynamic = (pool: BalancerPoolFragment, blockNumber: number) => {
+    return {
+        amp: pool.amp || '',
+        blockNumber,
+    };
+};
diff --git a/modules/pool/subgraph-mapper.test.ts b/modules/pool/subgraph-mapper.test.ts
new file mode 100644
index 000000000..76a5fe62c
--- /dev/null
+++ b/modules/pool/subgraph-mapper.test.ts
@@ -0,0 +1,91 @@
+import { subgraphToPrisma } from './subgraph-mapper';
+import { poolFactory, poolTokenFactory } from '../../test/factories';
+
+describe('subgraphToPrisma', () => {
+    const weightedPool = poolFactory.build({
+        poolType: 'Weighted',
+    });
+
+    const stablePool = poolFactory.build({
+        poolType: 'ComposableStable',
+        amp: '0.1',
+    });
+
+    const linearPool = poolFactory.build({
+        poolType: 'Linear',
+        wrappedIndex: 1,
+        upperTarget: '1',
+    });
+
+    const elementPool = poolFactory.build({
+        poolType: 'Element',
+        principalToken: '0x123',
+    });
+
+    const gyroPool = poolFactory.build({
+        poolType: 'GyroE',
+        alpha: '0.5',
+        tauAlphaX: '0.5',
+    });
+
+    const fxPool = poolFactory.build({
+        poolType: 'FX',
+        alpha: '0.5',
+    });
+
+    it('should return correct object for weighted pool', () => {
+        const result = subgraphToPrisma(weightedPool, 'MAINNET', 1, []);
+        expect(result.data.type).toBe('WEIGHTED');
+    });
+
+    it('should return correct object for stable pool', () => {
+        const result = subgraphToPrisma(stablePool, 'MAINNET', 1, []);
+        expect(result.data.type).toBe('COMPOSABLE_STABLE');
+        expect(result.data.stableDynamicData?.create.amp).toBe(stablePool.amp);
+    });
+
+    it('should return correct object for linear pool', () => {
+        const result = subgraphToPrisma(linearPool, 'MAINNET', 1, []);
+        expect(result.data.type).toBe('LINEAR');
+        expect(result.data.linearDynamicData?.create.upperTarget).toBe(linearPool.upperTarget);
+        expect(result.data.linearData?.create.wrappedIndex).toBe(linearPool.wrappedIndex);
+    });
+
+    it('should return correct object for element pool', () => {
+        const result = subgraphToPrisma(elementPool, 'MAINNET', 1, []);
+        expect(result.data.type).toBe('ELEMENT');
+        expect(result.data.elementData?.create.principalToken).toBe(elementPool.principalToken);
+    });
+
+    it('should return correct object for gyro pool', () => {
+        const result = subgraphToPrisma(gyroPool, 'MAINNET', 1, []);
+        expect(result.data.type).toBe('GYROE');
+        expect(result.data.gyroData?.create.alpha).toBe(gyroPool.alpha);
+        expect(result.data.gyroData?.create.tauAlphaX).toBe(gyroPool.tauAlphaX);
+    });
+
+    it('should return correct object for fx pool', () => {
+        const result = subgraphToPrisma(fxPool, 'MAINNET', 1, []);
+        expect(result.data.type).toBe('FX');
+        expect(result.data.data['alpha']).toBe(gyroPool.alpha);
+    });
+
+    describe('nested pools', () => {
+        const nestedPools = [linearPool];
+        const poolWithNestedPools = poolFactory.build({
+            poolType: 'ComposableStable',
+            tokens: [
+                poolTokenFactory.build({
+                    address: linearPool.address,
+                }),
+                poolTokenFactory.build({}),
+            ],
+        });
+
+        it('should recognise nested pools', () => {
+            const result = subgraphToPrisma(poolWithNestedPools, 'MAINNET', 1, nestedPools);
+            expect(result.data.type).toBe('COMPOSABLE_STABLE');
+            expect(result.data.tokens.createMany.data[0].nestedPoolId).toBe(linearPool.id);
+        });
+    });
+});
diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts
new file mode 100644
index 000000000..38a451555
--- /dev/null
+++ b/modules/pool/subgraph-mapper.ts
@@ -0,0 +1,221 @@
+import { Chain, PrismaPoolType } from '@prisma/client';
+import { BalancerPoolFragment } from '../subgraphs/balancer-subgraph/generated/balancer-subgraph-types';
+import { AddressZero } from '@ethersproject/constants';
+import * as dataMappers from './pool-data';
+
+export const subgraphToPrisma = (
+    pool: BalancerPoolFragment,
+    chain: Chain,
+    blockNumber: number,
+    nestedPools: { id: string; address: string }[],
+) => {
+    const dbData = subgraphMapper(pool, chain, blockNumber, nestedPools);
+
+    const prismaPoolRecordWithAssociations = {
+        data: {
+            ...dbData.base,
+            data: dbData.data, // DISCUSS: simplify DB schema by migrating from individual tables to a JSON column with types enforced on read. And same with dynamic data.
+            tokens: {
+                createMany: {
+                    data: dbData.tokens,
+                },
+            },
+            dynamicData: {
+                create: {
+                    id: dbData.base.id,
+                    ...dbData.dynamicData,
+                },
+            },
+            linearData:
+                dbData.base.type === 'LINEAR'
+                    ? {
+                          create: {
+                              id: dbData.base.id,
+                              ...(dbData.data as ReturnType<typeof dataMapper['LINEAR']>),
+                          },
+                      }
+                    : undefined,
+            elementData:
+                dbData.base.type === 'ELEMENT'
+                    ? {
+                          create: {
+                              id: dbData.base.id,
+                              ...(dbData.data as ReturnType<typeof dataMapper['ELEMENT']>),
+                          },
+                      }
+                    : undefined,
+            gyroData: ['GYRO', 'GYRO3', 'GYROE'].includes(dbData.base.type)
+                ? {
+                      create: {
+                          id: dbData.base.id,
+                          ...(dbData.data as ReturnType<typeof dataMapper['GYRO']>),
+                      },
+                  }
+                : undefined,
+            linearDynamicData:
+                dbData.base.type === 'LINEAR'
+                    ? {
+                          create: {
+                              id: dbData.base.id,
+                              ...(dbData.dynamicTypeData as ReturnType<typeof dynamicMapper['LINEAR']>),
+                          },
+                      }
+                    : undefined,
+            stableDynamicData: ['STABLE', 'COMPOSABLE_STABLE', 'META_STABLE'].includes(dbData.base.type)
+                ? {
+                      create: {
+                          id: dbData.base.id,
+                          ...(dbData.dynamicTypeData as ReturnType<typeof dynamicMapper['STABLE']>),
+                      },
+                  }
+                : undefined,
+        },
+    };
+
+    return prismaPoolRecordWithAssociations;
+};
+
+const subgraphMapper = (
+    pool: BalancerPoolFragment,
+    chain: Chain,
+    blockNumber: number,
+    nestedPools: { id: string; address: string }[],
+) => {
+    const type = mapSubgraphPoolTypeToPoolType(pool.poolType!);
+    const version = mapPoolTypeVersion(type, pool.poolTypeVersion!);
+
+    const base = {
+        id: pool.id,
+        chain: chain,
+        createTime: pool.createTime,
+        address: pool.address,
+        symbol: pool.symbol || '',
+        name: pool.name || '',
+        decimals: 18,
+        type: type,
+        version: version,
+        owner: pool.owner || AddressZero,
+        factory: pool.factory,
+    };
+
+    const dynamicData = {
+        blockNumber,
+        swapFee: pool.swapFee,
+        swapEnabled: pool.swapEnabled,
+        totalShares: pool.totalShares,
+        totalSharesNum: parseFloat(pool.totalShares),
+        totalLiquidity: Math.max(parseFloat(pool.totalLiquidity), 0),
+    };
+
+    const data: ReturnType<typeof dataMapper[keyof typeof dataMapper]> | {} = Object.keys(dataMapper).includes(type)
+        ? dataMapper[type as keyof typeof dataMapper](pool)
+        : {};
+
+    const dynamicTypeData = Object.keys(dynamicMapper).includes(type)
+        ? dynamicMapper[type as keyof typeof dynamicMapper](pool, blockNumber)
+        : {};
+
+    const tokens =
+        pool.tokens?.map((token) => {
+            const nestedPool = nestedPools.find((nestedPool) => {
+                return nestedPool.address === token.address;
+            });
+
+            let priceRateProvider;
+            if (pool.priceRateProviders) {
+                const data = pool.priceRateProviders.find((provider) => provider.token.address === token.address);
+                priceRateProvider = data?.address;
+            }
+
+            return {
+                id: token.id,
+                address: token.address,
+                priceRateProvider,
+                exemptFromProtocolYieldFee: token.isExemptFromYieldProtocolFee
+                    ? token.isExemptFromYieldProtocolFee
+                    : false,
+                nestedPoolId: nestedPool?.id,
+                index: token.index || pool.tokensList.findIndex((address) => address === token.address),
+            };
+        }) ?? [];
+
+    return {
+        base,
+        dynamicData,
+        tokens,
+        data,
+        dynamicTypeData,
+    };
+};
+
+const mapSubgraphPoolTypeToPoolType = (poolType: string): PrismaPoolType => {
+    switch (poolType) {
+        case 'Weighted':
+            return 'WEIGHTED';
+        case 'LiquidityBootstrapping':
+            return 'LIQUIDITY_BOOTSTRAPPING';
+        case 'Stable':
+            return 'STABLE';
+        case 'MetaStable':
+            return 'META_STABLE';
+        // for the old phantom stable pool, we add it to the DB as type COMPOSABLE_STABLE with version 0
+        case 'StablePhantom':
+            return 'COMPOSABLE_STABLE';
+        case 'ComposableStable':
+            return 'COMPOSABLE_STABLE';
+        case 'Linear':
+            return 'LINEAR';
+        case 'Element':
+            return 'ELEMENT';
+        case 'Investment':
+            return 'INVESTMENT';
+        case 'Gyro2':
+            return 'GYRO';
+        case 'Gyro3':
+            return 'GYRO3';
+        case 'GyroE':
+            return 'GYROE';
+        case 'FX':
+            return 'FX';
+    }
+
+    // balancer still uses AaveLinear, etc, so we account for that here
+    if (poolType.includes('Linear')) {
+        return 'LINEAR';
+    }
+
+    return 'UNKNOWN';
+};
+
+const mapPoolTypeVersion = (poolType: string, poolTypeVersion: number): number => {
+    // for the old phantom stable pool, we add it to the DB as type COMPOSABLE_STABLE with version 0
+    let version = poolTypeVersion ? poolTypeVersion : 1;
+    if (poolType === 'StablePhantom') {
+        version = 0;
+    }
+
+    return version;
+};
+
+const dataMapper = {
+    ELEMENT: dataMappers.element,
+    FX: dataMappers.fx,
+    GYRO: dataMappers.gyro,
+    GYRO3: dataMappers.gyro,
+    GYROE: dataMappers.gyro,
+    LINEAR: dataMappers.linear,
+};
+
+const dynamicMapper = {
+    STABLE: dataMappers.stableDynamic,
+    COMPOSABLE_STABLE: dataMappers.stableDynamic,
+    META_STABLE: dataMappers.stableDynamic,
+    LINEAR: dataMappers.linearDynamic,
+};
+
+export type FxData = ReturnType<typeof dataMappers['fx']>;
+export type GyroData = ReturnType<typeof dataMappers['gyro']>;
+export type LinearData = ReturnType<typeof dataMappers['linear']>;
+export type ElementData = ReturnType<typeof dataMappers['element']>;
+export type StableDynamicData = ReturnType<typeof dataMappers['stableDynamic']>;
+export type LinearDynamicData = ReturnType<typeof dataMappers['linearDynamic']>;

From 7ab4104dd5904fe1b45f703d519be7974f7cb62b Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Thu, 21 Dec 2023 16:44:22 +0100
Subject: [PATCH 08/23] FX pools parsing in SOR

---
 modules/sor/sorV2/sorV2.service.ts | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/modules/sor/sorV2/sorV2.service.ts b/modules/sor/sorV2/sorV2.service.ts
index 279c65459..8ec3a59fb 100644
--- a/modules/sor/sorV2/sorV2.service.ts
+++ b/modules/sor/sorV2/sorV2.service.ts
@@ -13,6 +13,7 @@ import {
     RawGyro2Pool,
     RawGyro3Pool,
     RawGyroEPool,
+    RawFxPool,
     HumanAmount,
     SupportedRawPoolTypes,
     SingleSwap,
@@ -44,6 +45,7 @@ import { poolsToIgnore } from '../constants';
 import { AllNetworkConfigsKeyedOnChain, chainToIdMap } from '../../network/network-config';
 import * as Sentry from '@sentry/node';
 import { getToken } from '../utils';
+import { FxData } from '../../pool/subgraph-mapper';
 
 const ALL_BASEPOOLS_CACHE_KEY = `basePools:all`;
 
@@ -377,7 +379,6 @@ export class SorV2Service implements SwapService {
                         'ELEMENT', // not supported by b-sdk
                         'UNKNOWN', // not supported by b-sdk
                         'INVESTMENT', // not supported by b-sdk
-                        'FX', // needs more data
                     ],
                 },
                 AND: {
@@ -428,6 +429,22 @@ export class SorV2Service implements SwapService {
                 inRecoveryMode: !!prismaPool.dynamicData?.isInRecoveryMode,
                 name: 'n/a',
             };
+            if (['FX'].includes(rawPool.poolType)) {
+                const data = prismaPool.data as FxData;
+                rawPool = {
+                    ...rawPool,
+                    ...data,
+                    tokens: rawPool.tokens.map((t, i) => {
+                        return {
+                            ...t,
+                            token: {
+                                latestFXPrice: prismaPool.tokens[i].dynamicData?.latestFxPrice?.toString(),
+                                fxOracleDecimals: 18,
+                            },
+                        };
+                    }),
+                } as RawFxPool;
+            }
             if (['Weighted', 'Investment', 'LiquidityBootstrapping'].includes(rawPool.poolType)) {
                 rawPool = {
                     ...rawPool,

From 64d756bcbf878b3003f29c571aa2ed91c71341d5 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Thu, 21 Dec 2023 16:45:06 +0100
Subject: [PATCH 09/23] FX pools in the graph schema

---
 modules/pool/lib/pool-gql-loader.service.ts | 24 +++++++++++++++++
 modules/pool/pool.gql                       | 30 +++++++++++++++++++++
 modules/pool/pool.resolvers.ts              | 10 +++++++
 modules/pool/pool.service.ts                |  5 ++++
 4 files changed, 69 insertions(+)

diff --git a/modules/pool/lib/pool-gql-loader.service.ts b/modules/pool/lib/pool-gql-loader.service.ts
index fac3005a0..e910344af 100644
--- a/modules/pool/lib/pool-gql-loader.service.ts
+++ b/modules/pool/lib/pool-gql-loader.service.ts
@@ -32,6 +32,7 @@ import {
     GqlPoolWithdrawConfig,
     GqlPoolWithdrawOption,
     QueryPoolGetPoolsArgs,
+    GqlPoolFx,
 } from '../../../schema';
 import { isSameAddress } from '@balancer-labs/sdk';
 import _ from 'lodash';
@@ -47,6 +48,7 @@ import { BalancerChainIds, BeethovenChainIds, chainIdToChain, chainToIdMap } fro
 import { GithubContentService } from '../../content/github-content.service';
 import { SanityContentService } from '../../content/sanity-content.service';
 import { FeaturedPool } from '../../content/content-types';
+import { FxData } from '../subgraph-mapper';
 
 export class PoolGqlLoaderService {
     public async getPool(id: string, chain: Chain, userAddress?: string): Promise<GqlPoolUnion> {
@@ -139,6 +141,16 @@ export class PoolGqlLoaderService {
         return pools.map((pool) => this.mapPoolToGqlPool(pool)) as GqlPoolGyro[];
     }
 
+    public async getFxPools(chains: Chain[]): Promise<GqlPoolFx[]> {
+        const pools = await prisma.prismaPool.findMany({
+            where: { type: { in: ['FX'] }, chain: { in: chains } },
+            orderBy: { dynamicData: { totalLiquidity: 'desc' } },
+            include: prismaPoolWithExpandedNesting.include,
+        });
+
+        return pools.map((pool) => this.mapPoolToGqlPool(pool)) as GqlPoolFx[];
+    }
+
     public mapToMinimalGqlPool(
         pool: PrismaPoolMinimal,
         userWalletbalances: PrismaUserWalletBalance[] = [],
@@ -581,6 +593,18 @@ export class PoolGqlLoaderService {
                     z: pool.gyroData?.z || '',
                     dSq: pool.gyroData?.dSq || '',
                 };
+            case 'FX':
+                const data = pool.data as FxData;
+                return {
+                    __typename: 'GqlPoolFx',
+                    ...mappedData,
+                    type: mappedData.type,
+                    alpha: data.alpha || '',
+                    beta: data.beta || '',
+                    delta: data.delta || '',
+                    epsilon: data.epsilon || '',
+                    lambda: data.lambda || '',
+                };
         }
 
         return {
diff --git a/modules/pool/pool.gql b/modules/pool/pool.gql
index f1fa5ed92..91fac31fe 100644
--- a/modules/pool/pool.gql
+++ b/modules/pool/pool.gql
@@ -24,6 +24,7 @@ extend type Query {
     poolGetSnapshots(id: String!, chain: GqlChain, range: GqlPoolSnapshotDataRange!): [GqlPoolSnapshot!]!
     poolGetLinearPools(chains: [GqlChain!]): [GqlPoolLinear!]!
     poolGetGyroPools(chains: [GqlChain!]): [GqlPoolGyro!]!
+    poolGetFxPools(chains: [GqlChain!]): [GqlPoolFx!]!
 }
 
 extend type Mutation {
@@ -282,6 +283,34 @@ type GqlPoolGyro implements GqlPoolBase {
     userBalance: GqlPoolUserBalance
 }
 
+type GqlPoolFx implements GqlPoolBase {
+    alpha: String!
+    beta: String!
+    delta: String!
+    epsilon: String!
+    lambda: String!
+
+    # Base pool
+    id: ID!
+    chain: GqlChain!
+    type: GqlPoolType!
+    version: Int!
+    name: String!
+    symbol: String!
+    address: Bytes!
+    decimals: Int!
+    owner: Bytes
+    factory: Bytes
+    createTime: Int!
+    investConfig: GqlPoolInvestConfig!
+    withdrawConfig: GqlPoolWithdrawConfig!
+    displayTokens: [GqlPoolTokenDisplay!]!
+    allTokens: [GqlPoolTokenExpanded!]!
+    dynamicData: GqlPoolDynamicData!
+    staking: GqlPoolStaking
+    userBalance: GqlPoolUserBalance
+}
+
 type GqlPoolLiquidityBootstrapping implements GqlPoolBase {
     id: ID!
     chain: GqlChain!
@@ -495,6 +524,7 @@ union GqlPoolUnion =
     | GqlPoolElement
     | GqlPoolLiquidityBootstrapping
     | GqlPoolGyro
+    | GqlPoolFx
 union GqlPoolNestedUnion = GqlPoolLinearNested | GqlPoolComposableStableNested
 
 union GqlPoolTokenUnion = GqlPoolToken | GqlPoolTokenComposableStable | GqlPoolTokenLinear
diff --git a/modules/pool/pool.resolvers.ts b/modules/pool/pool.resolvers.ts
index 9f2ff0d7e..2e3bd994e 100644
--- a/modules/pool/pool.resolvers.ts
+++ b/modules/pool/pool.resolvers.ts
@@ -94,6 +94,16 @@ const balancerResolvers: Resolvers = {
         poolGetGyroPools: async () => {
             return poolService.getGqlGyroPools();
         },
+
+        poolGetFxPools: async (parent, { chains }) => {
+            const currentChain = headerChain();
+            if (!chains && currentChain) {
+                chains = [currentChain];
+            } else if (!chains) {
+                throw new Error('poolGetLinearPools error: Provide "chains" param');
+            }
+            return poolService.getGqlFxPools(chains);
+        },
     },
     Mutation: {
         poolSyncAllPoolsFromSubgraph: async (parent, {}, context) => {
diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts
index 9461b541f..ba8e9d4de 100644
--- a/modules/pool/pool.service.ts
+++ b/modules/pool/pool.service.ts
@@ -8,6 +8,7 @@ import {
     GqlPoolBatchSwap,
     GqlPoolFeaturedPool,
     GqlPoolFeaturedPoolGroup,
+    GqlPoolFx,
     GqlPoolGyro,
     GqlPoolJoinExit,
     GqlPoolLinear,
@@ -87,6 +88,10 @@ export class PoolService {
         return this.poolGqlLoaderService.getGyroPools();
     }
 
+    public async getGqlFxPools(chains: Chain[]): Promise<GqlPoolFx[]> {
+        return this.poolGqlLoaderService.getFxPools(chains);
+    }
+
     public async getPoolsCount(args: QueryPoolGetPoolsArgs): Promise<number> {
         return this.poolGqlLoaderService.getPoolsCount(args);
     }

From 5d63418f3c09cd1566d9fd6f8ffb3d24b971aa2c Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Tue, 9 Jan 2024 17:58:52 +0100
Subject: [PATCH 10/23] subgraph pool to DB update

---
 modules/pool/lib/pool-creator.service.ts | 82 +++++++++++-------------
 modules/pool/subgraph-mapper.ts          | 57 +++++++++++++++-
 2 files changed, 92 insertions(+), 47 deletions(-)

diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts
index ebe49f0dc..6b7f0fef2 100644
--- a/modules/pool/lib/pool-creator.service.ts
+++ b/modules/pool/lib/pool-creator.service.ts
@@ -7,7 +7,7 @@ import { prismaPoolWithExpandedNesting } from '../../../prisma/prisma-types';
 import { UserService } from '../../user/user.service';
 import { prismaBulkExecuteOperations } from '../../../prisma/prisma-util';
 import { networkContext } from '../../network/network-context.service';
-import { subgraphToPrisma } from '../subgraph-mapper';
+import { subgraphToPrismaCreate, subgraphToPrismaUpdate } from '../subgraph-mapper';
 
 export class PoolCreatorService {
     constructor(private readonly userService: UserService) {}
@@ -24,6 +24,13 @@ export class PoolCreatorService {
         const existingPools = await prisma.prismaPool.findMany({ where: { chain: this.chain } });
         const subgraphPools = await this.balancerSubgraphService.getAllPools({}, false);
         const sortedSubgraphPools = this.sortSubgraphPools(subgraphPools);
+        const allNestedTypePools = await prisma.prismaPool.findMany({
+            where: {
+                chain: this.chain,
+                type: { in: [PrismaPoolType.LINEAR, PrismaPoolType.COMPOSABLE_STABLE] },
+            },
+            select: { id: true, address: true },
+        });
 
         const poolIds: string[] = [];
 
@@ -34,42 +41,11 @@ export class PoolCreatorService {
             const existsInDb = !!existingPools.find((pool) => pool.id === subgraphPool.id);
 
             if (!existsInDb) {
-                await this.createPoolRecord(subgraphPool, blockNumber);
+                await this.createPoolRecord(subgraphPool, blockNumber, allNestedTypePools);
 
                 poolIds.push(subgraphPool.id);
-            } else if (subgraphPool.poolType?.includes('Gyro')) {
-                await prisma.prismaPool.update({
-                    data: {
-                        gyroData: {
-                            update: {
-                                id: subgraphPool.id,
-                                alpha: subgraphPool.alpha || '',
-                                beta: subgraphPool.beta || '',
-                                sqrtAlpha: subgraphPool.sqrtAlpha || '',
-                                sqrtBeta: subgraphPool.sqrtBeta || '',
-                                root3Alpha: subgraphPool.root3Alpha || '',
-                                c: subgraphPool.c || '',
-                                s: subgraphPool.s || '',
-                                lambda: subgraphPool.lambda || '',
-                                tauAlphaX: subgraphPool.tauAlphaX || '',
-                                tauAlphaY: subgraphPool.tauAlphaY || '',
-                                tauBetaX: subgraphPool.tauBetaX || '',
-                                tauBetaY: subgraphPool.tauBetaY || '',
-                                u: subgraphPool.u || '',
-                                v: subgraphPool.v || '',
-                                w: subgraphPool.w || '',
-                                z: subgraphPool.z || '',
-                                dSq: subgraphPool.dSq || '',
-                            },
-                        },
-                    },
-                    where: {
-                        id_chain: {
-                            id: subgraphPool.id,
-                            chain: this.chain,
-                        },
-                    },
-                });
+            } else {
+                await this.updatePoolRecord(subgraphPool, blockNumber, allNestedTypePools);
             }
         }
 
@@ -193,18 +169,13 @@ export class PoolCreatorService {
         await prismaBulkExecuteOperations(operations);
     }
 
-    private async createPoolRecord(pool: BalancerPoolFragment, blockNumber: number) {
-        const poolType = this.mapSubgraphPoolTypeToPoolType(pool.poolType || '');
+    private async createPoolRecord(
+        pool: BalancerPoolFragment,
+        blockNumber: number,
+        nestedPools: { id: string; address: string }[] = [],
+    ) {
         const poolTokens = pool.tokens || [];
 
-        const allNestedTypePools = await prisma.prismaPool.findMany({
-            where: {
-                chain: this.chain,
-                type: { in: [PrismaPoolType.LINEAR, PrismaPoolType.COMPOSABLE_STABLE] },
-            },
-            select: { id: true, address: true },
-        });
-
         await prisma.prismaToken.createMany({
             skipDuplicates: true,
             data: [
@@ -225,7 +196,7 @@ export class PoolCreatorService {
             ],
         });
 
-        const prismaPoolRecordWithAssociations = subgraphToPrisma(pool, this.chain, blockNumber, allNestedTypePools);
+        const prismaPoolRecordWithAssociations = subgraphToPrismaCreate(pool, this.chain, blockNumber, nestedPools);
 
         await prisma.prismaPool.create(prismaPoolRecordWithAssociations);
 
@@ -246,6 +217,25 @@ export class PoolCreatorService {
         await this.userService.initWalletBalancesForPool(pool.id);
     }
 
+    private async updatePoolRecord(
+        pool: BalancerPoolFragment,
+        blockNumber: number,
+        nestedPools: { id: string; address: string }[] = [],
+    ) {
+        const prismaPoolRecordWithAssociations = subgraphToPrismaUpdate(pool, this.chain, blockNumber, nestedPools);
+
+        // Update pool record and type specific data
+        await prisma.prismaPool.update({
+            data: prismaPoolRecordWithAssociations,
+            where: {
+                id_chain: {
+                    id: pool.id,
+                    chain: this.chain,
+                },
+            },
+        });
+    }
+
     public async createAllTokensRelationshipForPool(poolId: string): Promise<void> {
         const pool = await prisma.prismaPool.findUnique({
             ...prismaPoolWithExpandedNesting,
diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts
index 38a451555..28e04c912 100644
--- a/modules/pool/subgraph-mapper.ts
+++ b/modules/pool/subgraph-mapper.ts
@@ -3,7 +3,7 @@ import { BalancerPoolFragment } from '../subgraphs/balancer-subgraph/generated/b
 import { AddressZero } from '@ethersproject/constants';
 import * as dataMappers from './pool-data';
 
-export const subgraphToPrisma = (
+export const subgraphToPrismaCreate = (
     pool: BalancerPoolFragment,
     chain: Chain,
     blockNumber: number,
@@ -75,6 +75,61 @@ export const subgraphToPrisma = (
     return prismaPoolRecordWithAssociations;
 };
 
+export const subgraphToPrismaUpdate = (
+    pool: BalancerPoolFragment,
+    chain: Chain,
+    blockNumber: number,
+    nestedPools: { id: string; address: string }[],
+) => {
+    const dbData = subgraphMapper(pool, chain, blockNumber, nestedPools);
+    const { id, ...baseWithoutId } = dbData.base;
+
+    const prismaPoolRecordWithDataAssociations = {
+        ...baseWithoutId,
+        data: dbData.data, // DISCUSS: simplify DB schema by migrating from individual tables to a JSON column with types enforced on read. And same with dynamic data.
+        linearData:
+            dbData.base.type === 'LINEAR'
+                ? {
+                      update: {
+                          ...(dbData.data as ReturnType<typeof dataMapper['LINEAR']>),
+                      },
+                  }
+                : undefined,
+        elementData:
+            dbData.base.type === 'ELEMENT'
+                ? {
+                      update: {
+                          ...(dbData.data as ReturnType<typeof dataMapper['ELEMENT']>),
+                      },
+                  }
+                : undefined,
+        gyroData: ['GYRO', 'GYRO3', 'GYROE'].includes(dbData.base.type)
+            ? {
+                  update: {
+                      ...(dbData.data as ReturnType<typeof dataMapper['GYRO']>),
+                  },
+              }
+            : undefined,
+        linearDynamicData:
+            dbData.base.type === 'LINEAR'
+                ? {
+                      update: {
+                          ...(dbData.dynamicTypeData as ReturnType<typeof dynamicMapper['LINEAR']>),
+                      },
+                  }
+                : undefined,
+        stableDynamicData: ['STABLE', 'COMPOSABLE_STABLE', 'META_STABLE'].includes(dbData.base.type)
+            ? {
+                  update: {
+                      ...(dbData.dynamicTypeData as ReturnType<typeof dynamicMapper['STABLE']>),
+                  },
+              }
+            : undefined,
+    };
+
+    return prismaPoolRecordWithDataAssociations;
+};
+
 const subgraphMapper = (
     pool: BalancerPoolFragment,
     chain: Chain,

From 65d9451c1c9f3a762c2ed3fb82efd6e0471eab63 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Tue, 9 Jan 2024 17:59:23 +0100
Subject: [PATCH 11/23] obsolete poolSyncAllPoolTypesVersions

---
 modules/pool/lib/pool-creator.service.ts | 37 ------------------------
 modules/pool/pool.gql                    |  1 -
 modules/pool/pool.resolvers.ts           |  7 -----
 modules/pool/pool.service.ts             |  4 ---
 4 files changed, 49 deletions(-)

diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts
index 6b7f0fef2..9ecb0ced4 100644
--- a/modules/pool/lib/pool-creator.service.ts
+++ b/modules/pool/lib/pool-creator.service.ts
@@ -1,6 +1,5 @@
 import { BalancerPoolFragment } from '../../subgraphs/balancer-subgraph/generated/balancer-subgraph-types';
 import { prisma } from '../../../prisma/prisma-client';
-import { ZERO_ADDRESS } from '@gnosis.pm/safe-core-sdk/dist/src/utils/constants';
 import { PrismaPoolType } from '@prisma/client';
 import _ from 'lodash';
 import { prismaPoolWithExpandedNesting } from '../../../prisma/prisma-types';
@@ -294,42 +293,6 @@ export class PoolCreatorService {
         }
     }
 
-    public async updatePoolTypesAndVersionForAllPools() {
-        const subgraphPools = await this.balancerSubgraphService.getAllPools({}, false);
-
-        for (const subgraphPool of subgraphPools) {
-            // for the old phantom stable pool, we add it to the DB as type COMPOSABLE_STABLE with version 0
-            let poolTypeVersion = subgraphPool.poolTypeVersion ? subgraphPool.poolTypeVersion : 1;
-            if (subgraphPool.poolType === 'StablePhantom') {
-                poolTypeVersion = 0;
-            }
-
-            const poolType = this.mapSubgraphPoolTypeToPoolType(subgraphPool.poolType || '');
-
-            try {
-                await prisma.prismaPool.update({
-                    where: { id_chain: { chain: networkContext.chain, id: subgraphPool.id } },
-                    data: {
-                        version: poolTypeVersion,
-                        type: poolType,
-                    },
-                });
-            } catch (e: any) {
-                // Some pools are filtered from the DB, like test pools,
-                // so we just ignore them without breaking the loop
-                const error = e.meta ? e.meta.cause : e;
-                console.error(
-                    'Error in updating pool versions: ',
-                    error,
-                    'Network',
-                    networkContext.chain,
-                    'Pool ID: ',
-                    subgraphPool.id,
-                );
-            }
-        }
-    }
-
     private sortSubgraphPools(subgraphPools: BalancerPoolFragment[]) {
         return _.sortBy(subgraphPools, (pool) => {
             const poolType = this.mapSubgraphPoolTypeToPoolType(pool.poolType || '');
diff --git a/modules/pool/pool.gql b/modules/pool/pool.gql
index 91fac31fe..33172fd00 100644
--- a/modules/pool/pool.gql
+++ b/modules/pool/pool.gql
@@ -56,7 +56,6 @@ extend type Mutation {
     poolBlackListAddPool(poolId: String!): String!
     poolBlackListRemovePool(poolId: String!): String!
     poolDeletePool(poolId: String!): String!
-    poolSyncAllPoolTypesVersions: String!
     poolSyncPriceRateProviders: String!
     poolSyncProtocolYieldFeeExemptions: String!
     poolInitOnChainDataForAllPools: String!
diff --git a/modules/pool/pool.resolvers.ts b/modules/pool/pool.resolvers.ts
index 2e3bd994e..416f2b04b 100644
--- a/modules/pool/pool.resolvers.ts
+++ b/modules/pool/pool.resolvers.ts
@@ -314,13 +314,6 @@ const balancerResolvers: Resolvers = {
 
             return 'success';
         },
-        poolSyncAllPoolTypesVersions: async (parent, {}, context) => {
-            isAdminRoute(context);
-
-            await poolService.syncPoolTypeAndVersionForAllPools();
-
-            return 'success';
-        },
         poolSyncPriceRateProviders: async (parent, {}, context) => {
             isAdminRoute(context);
 
diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts
index ba8e9d4de..745a4e3c8 100644
--- a/modules/pool/pool.service.ts
+++ b/modules/pool/pool.service.ts
@@ -349,10 +349,6 @@ export class PoolService {
         await this.poolSyncService.setPoolsWithPreferredGaugesAsIncentivized();
     }
 
-    public async syncPoolTypeAndVersionForAllPools() {
-        await this.poolCreatorService.updatePoolTypesAndVersionForAllPools();
-    }
-
     public async syncProtocolYieldFeeExemptionsForAllPools() {
         const subgraphPools = await this.balancerSubgraphService.getAllPools({}, false);
         for (const subgraphPool of subgraphPools) {

From 6aa8aac325567db7bc4332170106d9a7ca39cf56 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Tue, 9 Jan 2024 18:45:14 +0100
Subject: [PATCH 12/23] include pool tokens in subgraph sync

---
 modules/pool/subgraph-mapper.ts | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts
index 28e04c912..776ca57d5 100644
--- a/modules/pool/subgraph-mapper.ts
+++ b/modules/pool/subgraph-mapper.ts
@@ -87,6 +87,19 @@ export const subgraphToPrismaUpdate = (
     const prismaPoolRecordWithDataAssociations = {
         ...baseWithoutId,
         data: dbData.data, // DISCUSS: simplify DB schema by migrating from individual tables to a JSON column with types enforced on read. And same with dynamic data.
+        tokens: {
+            update: dbData.tokens.map((token) => ({
+                where: {
+                    id_chain: {
+                        id: token.id,
+                        chain: chain,
+                    },
+                },
+                data: {
+                    ...token,
+                },
+            })),
+        },
         linearData:
             dbData.base.type === 'LINEAR'
                 ? {

From 9c533b29b31cc6a72f3681575265249eed38b5c9 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Tue, 9 Jan 2024 19:09:17 +0100
Subject: [PATCH 13/23] obsolete poolReloadPoolTokenIndexes

covered by syncAllPoolsFromSubgraph
---
 modules/pool/lib/pool-creator.service.ts | 21 ---------------------
 modules/pool/pool.gql                    |  1 -
 modules/pool/pool.resolvers.ts           |  7 -------
 modules/pool/pool.service.ts             |  4 ----
 4 files changed, 33 deletions(-)

diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts
index 9ecb0ced4..435e905d9 100644
--- a/modules/pool/lib/pool-creator.service.ts
+++ b/modules/pool/lib/pool-creator.service.ts
@@ -272,27 +272,6 @@ export class PoolCreatorService {
         });
     }
 
-    public async reloadPoolTokenIndexes(poolId: string): Promise<void> {
-        const { pool: subgraphPool } = await this.balancerSubgraphService.getPool({ id: poolId });
-
-        if (!subgraphPool) {
-            throw new Error('Pool with id does not exist');
-        }
-
-        const poolTokens = subgraphPool.tokens || [];
-
-        for (let i = 0; i < poolTokens.length; i++) {
-            const token = poolTokens[i];
-
-            await prisma.prismaPoolToken.update({
-                where: { id_chain: { id: token.id, chain: this.chain } },
-                data: {
-                    index: token.index || subgraphPool.tokensList.findIndex((address) => address === token.address),
-                },
-            });
-        }
-    }
-
     private sortSubgraphPools(subgraphPools: BalancerPoolFragment[]) {
         return _.sortBy(subgraphPools, (pool) => {
             const poolType = this.mapSubgraphPoolTypeToPoolType(pool.poolType || '');
diff --git a/modules/pool/pool.gql b/modules/pool/pool.gql
index 33172fd00..f249d880d 100644
--- a/modules/pool/pool.gql
+++ b/modules/pool/pool.gql
@@ -51,7 +51,6 @@ extend type Mutation {
     poolSyncPool(poolId: String!): String!
     poolReloadPoolNestedTokens(poolId: String!): String!
     poolReloadAllTokenNestedPoolIds: String!
-    poolReloadPoolTokenIndexes(poolId: String!): String!
     poolSetPoolsWithPreferredGaugesAsIncentivized: String!
     poolBlackListAddPool(poolId: String!): String!
     poolBlackListRemovePool(poolId: String!): String!
diff --git a/modules/pool/pool.resolvers.ts b/modules/pool/pool.resolvers.ts
index 416f2b04b..6d14f760d 100644
--- a/modules/pool/pool.resolvers.ts
+++ b/modules/pool/pool.resolvers.ts
@@ -279,13 +279,6 @@ const balancerResolvers: Resolvers = {
 
             return 'success';
         },
-        poolReloadPoolTokenIndexes: async (parent, { poolId }, context) => {
-            isAdminRoute(context);
-
-            await poolService.reloadPoolTokenIndexes(poolId);
-
-            return 'success';
-        },
         poolSetPoolsWithPreferredGaugesAsIncentivized: async (parent, {}, context) => {
             isAdminRoute(context);
 
diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts
index 745a4e3c8..6bb48305d 100644
--- a/modules/pool/pool.service.ts
+++ b/modules/pool/pool.service.ts
@@ -341,10 +341,6 @@ export class PoolService {
         await this.poolCreatorService.reloadAllTokenNestedPoolIds();
     }
 
-    public async reloadPoolTokenIndexes(poolId: string) {
-        await this.poolCreatorService.reloadPoolTokenIndexes(poolId);
-    }
-
     public async setPoolsWithPreferredGaugesAsIncentivized() {
         await this.poolSyncService.setPoolsWithPreferredGaugesAsIncentivized();
     }

From 5497a1d4586a5d03ee2aa1c6f0d71f84e2b7ae1b Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Tue, 9 Jan 2024 19:44:04 +0100
Subject: [PATCH 14/23] obsolete poolReloadPoolNestedTokens

covered by syncAllPoolsFromSubgraph
---
 modules/pool/lib/pool-creator.service.ts | 38 ++----------------------
 modules/pool/pool.gql                    |  1 -
 modules/pool/pool.resolvers.ts           |  7 -----
 modules/pool/pool.service.ts             |  4 ---
 4 files changed, 2 insertions(+), 48 deletions(-)

diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts
index 435e905d9..a8bc5ca2b 100644
--- a/modules/pool/lib/pool-creator.service.ts
+++ b/modules/pool/lib/pool-creator.service.ts
@@ -81,42 +81,6 @@ export class PoolCreatorService {
         return Array.from(poolIds);
     }
 
-    public async reloadPoolNestedTokens(poolId: string): Promise<void> {
-        const subgraphPools = await this.balancerSubgraphService.getAllPools({}, false);
-        const poolToLoad = subgraphPools.find((pool) => pool.id === poolId);
-
-        if (!poolToLoad) {
-            throw new Error('Pool with id does not exist');
-        }
-
-        const poolTokens = poolToLoad.tokens || [];
-
-        for (let i = 0; i < poolTokens.length; i++) {
-            const token = poolTokens[i];
-
-            if (token.address === poolToLoad.address) {
-                continue;
-            }
-
-            const nestedPool = subgraphPools.find((nestedPool) => {
-                const poolType = this.mapSubgraphPoolTypeToPoolType(nestedPool.poolType || '');
-
-                return (
-                    nestedPool.address === token.address && (poolType === 'LINEAR' || poolType === 'COMPOSABLE_STABLE')
-                );
-            });
-
-            if (nestedPool) {
-                await prisma.prismaPoolToken.update({
-                    where: { id_chain: { id: token.id, chain: this.chain } },
-                    data: { nestedPoolId: nestedPool.id },
-                });
-            }
-        }
-
-        await this.createAllTokensRelationshipForPool(poolId);
-    }
-
     public async reloadAllTokenNestedPoolIds(): Promise<void> {
         let operations: any[] = [];
         const pools = await prisma.prismaPool.findMany({
@@ -233,6 +197,8 @@ export class PoolCreatorService {
                 },
             },
         });
+
+        await this.createAllTokensRelationshipForPool(pool.id);
     }
 
     public async createAllTokensRelationshipForPool(poolId: string): Promise<void> {
diff --git a/modules/pool/pool.gql b/modules/pool/pool.gql
index f249d880d..74ef66f6f 100644
--- a/modules/pool/pool.gql
+++ b/modules/pool/pool.gql
@@ -49,7 +49,6 @@ extend type Mutation {
     poolUpdateLifetimeValuesForAllPools: String!
     poolInitializeSnapshotsForPool(poolId: String!): String!
     poolSyncPool(poolId: String!): String!
-    poolReloadPoolNestedTokens(poolId: String!): String!
     poolReloadAllTokenNestedPoolIds: String!
     poolSetPoolsWithPreferredGaugesAsIncentivized: String!
     poolBlackListAddPool(poolId: String!): String!
diff --git a/modules/pool/pool.resolvers.ts b/modules/pool/pool.resolvers.ts
index 6d14f760d..75262897c 100644
--- a/modules/pool/pool.resolvers.ts
+++ b/modules/pool/pool.resolvers.ts
@@ -265,13 +265,6 @@ const balancerResolvers: Resolvers = {
 
             return 'success';
         },
-        poolReloadPoolNestedTokens: async (parent, { poolId }, context) => {
-            isAdminRoute(context);
-
-            await poolService.reloadPoolNestedTokens(poolId);
-
-            return 'success';
-        },
         poolReloadAllTokenNestedPoolIds: async (parent, {}, context) => {
             isAdminRoute(context);
 
diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts
index 6bb48305d..9d5db753c 100644
--- a/modules/pool/pool.service.ts
+++ b/modules/pool/pool.service.ts
@@ -333,10 +333,6 @@ export class PoolService {
         await this.poolSnapshotService.createPoolSnapshotsForPoolsMissingSubgraphData(poolId);
     }
 
-    public async reloadPoolNestedTokens(poolId: string) {
-        await this.poolCreatorService.reloadPoolNestedTokens(poolId);
-    }
-
     public async reloadAllTokenNestedPoolIds() {
         await this.poolCreatorService.reloadAllTokenNestedPoolIds();
     }

From d5fb8e848a7df9d98ad8f837ae7661e659b846e3 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Tue, 9 Jan 2024 20:12:12 +0100
Subject: [PATCH 15/23] obsolete poolSync mutations

covered by syncAllPools
---
 modules/pool/pool.gql          |  2 --
 modules/pool/pool.resolvers.ts | 14 ---------
 modules/pool/pool.service.ts   | 52 ----------------------------------
 3 files changed, 68 deletions(-)

diff --git a/modules/pool/pool.gql b/modules/pool/pool.gql
index 74ef66f6f..db7656ce2 100644
--- a/modules/pool/pool.gql
+++ b/modules/pool/pool.gql
@@ -54,8 +54,6 @@ extend type Mutation {
     poolBlackListAddPool(poolId: String!): String!
     poolBlackListRemovePool(poolId: String!): String!
     poolDeletePool(poolId: String!): String!
-    poolSyncPriceRateProviders: String!
-    poolSyncProtocolYieldFeeExemptions: String!
     poolInitOnChainDataForAllPools: String!
 }
 
diff --git a/modules/pool/pool.resolvers.ts b/modules/pool/pool.resolvers.ts
index 75262897c..bb8275e65 100644
--- a/modules/pool/pool.resolvers.ts
+++ b/modules/pool/pool.resolvers.ts
@@ -298,20 +298,6 @@ const balancerResolvers: Resolvers = {
 
             await poolService.deletePool(poolId);
 
-            return 'success';
-        },
-        poolSyncPriceRateProviders: async (parent, {}, context) => {
-            isAdminRoute(context);
-
-            await poolService.syncPriceRateProvidersForAllPools();
-
-            return 'success';
-        },
-        poolSyncProtocolYieldFeeExemptions: async (parent, {}, context) => {
-            isAdminRoute(context);
-
-            await poolService.syncProtocolYieldFeeExemptionsForAllPools();
-
             return 'success';
         },
     },
diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts
index 9d5db753c..a697bcf10 100644
--- a/modules/pool/pool.service.ts
+++ b/modules/pool/pool.service.ts
@@ -341,58 +341,6 @@ export class PoolService {
         await this.poolSyncService.setPoolsWithPreferredGaugesAsIncentivized();
     }
 
-    public async syncProtocolYieldFeeExemptionsForAllPools() {
-        const subgraphPools = await this.balancerSubgraphService.getAllPools({}, false);
-        for (const subgraphPool of subgraphPools) {
-            const poolTokens = subgraphPool.tokens || [];
-            for (let i = 0; i < poolTokens.length; i++) {
-                const token = poolTokens[i];
-                try {
-                    await prisma.prismaPoolToken.update({
-                        where: { id_chain: { id: token.id, chain: networkContext.chain } },
-                        data: {
-                            exemptFromProtocolYieldFee: token.isExemptFromYieldProtocolFee
-                                ? token.isExemptFromYieldProtocolFee
-                                : false,
-                        },
-                    });
-                } catch (e) {
-                    console.error('Failed to update token ', token.id, ' error is: ', e);
-                }
-            }
-        }
-    }
-
-    public async syncPriceRateProvidersForAllPools() {
-        const subgraphPools = await this.balancerSubgraphService.getAllPools({}, false);
-        for (const subgraphPool of subgraphPools) {
-            if (!subgraphPool.priceRateProviders || !subgraphPool.priceRateProviders.length) continue;
-
-            const poolTokens = subgraphPool.tokens || [];
-            for (let i = 0; i < poolTokens.length; i++) {
-                const token = poolTokens[i];
-
-                let priceRateProvider;
-                const data = subgraphPool.priceRateProviders.find(
-                    (provider) => provider.token.address === token.address,
-                );
-                priceRateProvider = data?.address;
-                if (!priceRateProvider) continue;
-
-                try {
-                    await prisma.prismaPoolToken.update({
-                        where: { id_chain: { id: token.id, chain: networkContext.chain } },
-                        data: {
-                            priceRateProvider,
-                        },
-                    });
-                } catch (e) {
-                    console.error('Failed to update token ', token.id, ' error is: ', e);
-                }
-            }
-        }
-    }
-
     public async addToBlackList(poolId: string) {
         const category = await prisma.prismaPoolCategory.findFirst({
             where: { poolId, chain: this.chain, category: 'BLACK_LISTED' },

From d6e71f0ff350bb6cb33647c1911486fed6b0b4c8 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Thu, 11 Jan 2024 18:01:27 +0100
Subject: [PATCH 16/23] fix pool type mapping for StablePhantom

---
 modules/pool/subgraph-mapper.test.ts | 30 +++++++++++++++++++---------
 modules/pool/subgraph-mapper.ts      |  2 +-
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/modules/pool/subgraph-mapper.test.ts b/modules/pool/subgraph-mapper.test.ts
index 76a5fe62c..8f8ccb388 100644
--- a/modules/pool/subgraph-mapper.test.ts
+++ b/modules/pool/subgraph-mapper.test.ts
@@ -1,7 +1,7 @@
-import { subgraphToPrisma } from './subgraph-mapper';
+import { subgraphToPrismaCreate } from './subgraph-mapper';
 import { poolFactory, poolTokenFactory } from '../../test/factories';
 
-describe('subgraphToPrisma', () => {
+describe('subgraphToPrismaCreate', () => {
     const weightedPool = poolFactory.build({
         poolType: 'Weighted',
     });
@@ -11,6 +11,11 @@ describe('subgraphToPrisma', () => {
         amp: '0.1',
     });
 
+    const oldStablePool = poolFactory.build({
+        poolType: 'StablePhantom',
+        amp: '0.1',
+    });
+
     const linearPool = poolFactory.build({
         poolType: 'Linear',
         wrappedIndex: 1,
@@ -34,38 +39,45 @@ describe('subgraphToPrisma', () => {
     });
 
     it('should return correct object for weighted pool', () => {
-        const result = subgraphToPrisma(weightedPool, 'MAINNET', 1, []);
+        const result = subgraphToPrismaCreate(weightedPool, 'MAINNET', 1, []);
         expect(result.data.type).toBe('WEIGHTED');
     });
 
     it('should return correct object for stable pool', () => {
-        const result = subgraphToPrisma(stablePool, 'MAINNET', 1, []);
+        const result = subgraphToPrismaCreate(stablePool, 'MAINNET', 1, []);
         expect(result.data.type).toBe('COMPOSABLE_STABLE');
         expect(result.data.stableDynamicData?.create.amp).toBe(stablePool.amp);
     });
 
+    it('should return correct object for old stable pool', () => {
+        const result = subgraphToPrismaCreate(oldStablePool, 'MAINNET', 1, []);
+        expect(result.data.type).toBe('COMPOSABLE_STABLE');
+        expect(result.data.version).toBe(0);
+        expect(result.data.stableDynamicData?.create.amp).toBe(oldStablePool.amp);
+    });
+
     it('should return correct object for linear pool', () => {
-        const result = subgraphToPrisma(linearPool, 'MAINNET', 1, []);
+        const result = subgraphToPrismaCreate(linearPool, 'MAINNET', 1, []);
         expect(result.data.type).toBe('LINEAR');
         expect(result.data.linearDynamicData?.create.upperTarget).toBe(linearPool.upperTarget);
         expect(result.data.linearData?.create.wrappedIndex).toBe(linearPool.wrappedIndex);
     });
 
     it('should return correct object for element pool', () => {
-        const result = subgraphToPrisma(elementPool, 'MAINNET', 1, []);
+        const result = subgraphToPrismaCreate(elementPool, 'MAINNET', 1, []);
         expect(result.data.type).toBe('ELEMENT');
         expect(result.data.elementData?.create.principalToken).toBe(elementPool.principalToken);
     });
 
     it('should return correct object for gyro pool', () => {
-        const result = subgraphToPrisma(gyroPool, 'MAINNET', 1, []);
+        const result = subgraphToPrismaCreate(gyroPool, 'MAINNET', 1, []);
         expect(result.data.type).toBe('GYROE');
         expect(result.data.gyroData?.create.alpha).toBe(gyroPool.alpha);
         expect(result.data.gyroData?.create.tauAlphaX).toBe(gyroPool.tauAlphaX);
     });
 
     it('should return correct object for fx pool', () => {
-        const result = subgraphToPrisma(fxPool, 'MAINNET', 1, []);
+        const result = subgraphToPrismaCreate(fxPool, 'MAINNET', 1, []);
         expect(result.data.type).toBe('FX');
         expect(result.data.data['alpha']).toBe(gyroPool.alpha);
     });
@@ -83,7 +95,7 @@ describe('subgraphToPrisma', () => {
         });
 
         it('should recognise nested pools', () => {
-            const result = subgraphToPrisma(poolWithNestedPools, 'MAINNET', 1, nestedPools);
+            const result = subgraphToPrismaCreate(poolWithNestedPools, 'MAINNET', 1, nestedPools);
             expect(result.data.type).toBe('COMPOSABLE_STABLE');
             expect(result.data.tokens.createMany.data[0].nestedPoolId).toBe(linearPool.id);
         });
diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts
index 776ca57d5..69b14381f 100644
--- a/modules/pool/subgraph-mapper.ts
+++ b/modules/pool/subgraph-mapper.ts
@@ -150,7 +150,7 @@ const subgraphMapper = (
     nestedPools: { id: string; address: string }[],
 ) => {
     const type = mapSubgraphPoolTypeToPoolType(pool.poolType!);
-    const version = mapPoolTypeVersion(type, pool.poolTypeVersion!);
+    const version = mapPoolTypeVersion(pool.poolType!, pool.poolTypeVersion!);
 
     const base = {
         id: pool.id,

From 63fd0b28fda394dd75a8eaebe308addde763a67e Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Thu, 11 Jan 2024 18:20:01 +0100
Subject: [PATCH 17/23] add nestedPool list when creating new pools

---
 modules/pool/lib/pool-creator.service.ts | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts
index a8bc5ca2b..d7d2eea66 100644
--- a/modules/pool/lib/pool-creator.service.ts
+++ b/modules/pool/lib/pool-creator.service.ts
@@ -68,11 +68,22 @@ export class PoolCreatorService {
         const sortedSubgraphPools = this.sortSubgraphPools(subgraphPools);
         const poolIds = new Set<string>();
 
+        const allNestedTypePools = [
+            ...(await prisma.prismaPool.findMany({
+                where: {
+                    chain: this.chain,
+                    type: { in: [PrismaPoolType.LINEAR, PrismaPoolType.COMPOSABLE_STABLE] },
+                },
+                select: { id: true, address: true },
+            })),
+            ...sortedSubgraphPools.map((pool) => ({ id: pool.id, address: pool.address })),
+        ];
+
         for (const subgraphPool of sortedSubgraphPools) {
             const existsInDb = !!existingPools.find((pool) => pool.id === subgraphPool.id);
 
             if (!existsInDb) {
-                await this.createPoolRecord(subgraphPool, blockNumber);
+                await this.createPoolRecord(subgraphPool, blockNumber, allNestedTypePools);
 
                 poolIds.add(subgraphPool.id);
             }
@@ -135,7 +146,7 @@ export class PoolCreatorService {
     private async createPoolRecord(
         pool: BalancerPoolFragment,
         blockNumber: number,
-        nestedPools: { id: string; address: string }[] = [],
+        nestedPools: { id: string; address: string }[],
     ) {
         const poolTokens = pool.tokens || [];
 

From 2dee404eadffebf75785c7582501e67f99e52642 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Fri, 12 Jan 2024 18:13:16 +0100
Subject: [PATCH 18/23] renaming pool.data to pool.poolTypeSpecificData

---
 modules/pool/lib/pool-creator.service.ts      | 19 +++++++++++++++++--
 modules/pool/lib/pool-gql-loader.service.ts   |  2 +-
 modules/pool/pool.prisma                      |  2 +-
 modules/pool/subgraph-mapper.test.ts          |  2 +-
 modules/pool/subgraph-mapper.ts               |  4 ++--
 modules/sor/sorV2/sorV2.service.ts            |  2 +-
 .../migration.sql                             |  2 +-
 prisma/schema.prisma                          |  2 +-
 8 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/modules/pool/lib/pool-creator.service.ts b/modules/pool/lib/pool-creator.service.ts
index d7d2eea66..26ef74e99 100644
--- a/modules/pool/lib/pool-creator.service.ts
+++ b/modules/pool/lib/pool-creator.service.ts
@@ -197,10 +197,25 @@ export class PoolCreatorService {
         nestedPools: { id: string; address: string }[] = [],
     ) {
         const prismaPoolRecordWithAssociations = subgraphToPrismaUpdate(pool, this.chain, blockNumber, nestedPools);
+        const { tokens, ...poolWithoutTokens } = prismaPoolRecordWithAssociations;
+
+        // Make sure all tokens are there, for managed pools tokenlist can change
+        for (const token of tokens.update) {
+            await prisma.prismaPoolToken.upsert({
+                where: token.where,
+                create: {
+                    ...token.data,
+                    poolId: pool.id,
+                    chain: this.chain,
+                },
+                update: {
+                    ...token.data,
+                },
+            });
+        }
 
-        // Update pool record and type specific data
         await prisma.prismaPool.update({
-            data: prismaPoolRecordWithAssociations,
+            data: poolWithoutTokens,
             where: {
                 id_chain: {
                     id: pool.id,
diff --git a/modules/pool/lib/pool-gql-loader.service.ts b/modules/pool/lib/pool-gql-loader.service.ts
index e910344af..4a108a781 100644
--- a/modules/pool/lib/pool-gql-loader.service.ts
+++ b/modules/pool/lib/pool-gql-loader.service.ts
@@ -594,7 +594,7 @@ export class PoolGqlLoaderService {
                     dSq: pool.gyroData?.dSq || '',
                 };
             case 'FX':
-                const data = pool.data as FxData;
+                const data = pool.poolTypeSpecificData as FxData;
                 return {
                     __typename: 'GqlPoolFx',
                     ...mappedData,
diff --git a/modules/pool/pool.prisma b/modules/pool/pool.prisma
index 8bb8816ac..7fd90789f 100644
--- a/modules/pool/pool.prisma
+++ b/modules/pool/pool.prisma
@@ -18,7 +18,7 @@ model PrismaPool {
     linearData          PrismaPoolLinearData?
     elementData         PrismaPoolElementData?
     gyroData            PrismaPoolGyroData?
-    data                Json @default("{}")
+    poolTypeSpecificData Json @default("{}")
 
     tokens              PrismaPoolToken[]
 
diff --git a/modules/pool/subgraph-mapper.test.ts b/modules/pool/subgraph-mapper.test.ts
index 8f8ccb388..0aa8889b0 100644
--- a/modules/pool/subgraph-mapper.test.ts
+++ b/modules/pool/subgraph-mapper.test.ts
@@ -79,7 +79,7 @@ describe('subgraphToPrismaCreate', () => {
     it('should return correct object for fx pool', () => {
         const result = subgraphToPrismaCreate(fxPool, 'MAINNET', 1, []);
         expect(result.data.type).toBe('FX');
-        expect(result.data.data['alpha']).toBe(gyroPool.alpha);
+        expect(result.data.poolTypeSpecificData['alpha']).toBe(gyroPool.alpha);
     });
 
     describe('nested pools', () => {
diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts
index 69b14381f..bf5dc0b02 100644
--- a/modules/pool/subgraph-mapper.ts
+++ b/modules/pool/subgraph-mapper.ts
@@ -14,7 +14,7 @@ export const subgraphToPrismaCreate = (
     const prismaPoolRecordWithAssociations = {
         data: {
             ...dbData.base,
-            data: dbData.data, // DISCUSS: simplify DB schema by migrating from individual tables to a JSON column with types enforced on read. And same with dynamic data.
+            poolTypeSpecificData: dbData.data,
             tokens: {
                 createMany: {
                     data: dbData.tokens,
@@ -86,7 +86,7 @@ export const subgraphToPrismaUpdate = (
 
     const prismaPoolRecordWithDataAssociations = {
         ...baseWithoutId,
-        data: dbData.data, // DISCUSS: simplify DB schema by migrating from individual tables to a JSON column with types enforced on read. And same with dynamic data.
+        poolTypeSpecificData: dbData.data,
         tokens: {
             update: dbData.tokens.map((token) => ({
                 where: {
diff --git a/modules/sor/sorV2/sorV2.service.ts b/modules/sor/sorV2/sorV2.service.ts
index 8ec3a59fb..14f3e8509 100644
--- a/modules/sor/sorV2/sorV2.service.ts
+++ b/modules/sor/sorV2/sorV2.service.ts
@@ -430,7 +430,7 @@ export class SorV2Service implements SwapService {
                 name: 'n/a',
             };
             if (['FX'].includes(rawPool.poolType)) {
-                const data = prismaPool.data as FxData;
+                const data = prismaPool.poolTypeSpecificData as FxData;
                 rawPool = {
                     ...rawPool,
                     ...data,
diff --git a/prisma/migrations/20231221154118_pools_data_json_column/migration.sql b/prisma/migrations/20231221154118_pools_data_json_column/migration.sql
index c08b112b7..6032639db 100644
--- a/prisma/migrations/20231221154118_pools_data_json_column/migration.sql
+++ b/prisma/migrations/20231221154118_pools_data_json_column/migration.sql
@@ -1,2 +1,2 @@
 -- AlterTable
-ALTER TABLE "PrismaPool" ADD COLUMN     "data" JSONB NOT NULL DEFAULT '{}';
+ALTER TABLE "PrismaPool" ADD COLUMN     "poolTypeSpecificData" JSONB NOT NULL DEFAULT '{}';
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index ad5882758..fec2c4536 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -64,7 +64,7 @@ model PrismaPool {
     linearData          PrismaPoolLinearData?
     elementData         PrismaPoolElementData?
     gyroData            PrismaPoolGyroData?
-    data                Json @default("{}")
+    poolTypeSpecificData Json @default("{}")
 
     tokens              PrismaPoolToken[]
 

From 64ca22b49e9a87fd4bc71e14a88a322b066fdba9 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Fri, 12 Jan 2024 18:49:27 +0100
Subject: [PATCH 19/23] import all of the functions directly

to have references in the header
---
 modules/pool/subgraph-mapper.ts | 34 ++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts
index bf5dc0b02..22026a3df 100644
--- a/modules/pool/subgraph-mapper.ts
+++ b/modules/pool/subgraph-mapper.ts
@@ -1,7 +1,7 @@
 import { Chain, PrismaPoolType } from '@prisma/client';
 import { BalancerPoolFragment } from '../subgraphs/balancer-subgraph/generated/balancer-subgraph-types';
 import { AddressZero } from '@ethersproject/constants';
-import * as dataMappers from './pool-data';
+import { fx, gyro, linear, element, stableDynamic, linearDynamic } from './pool-data';
 
 export const subgraphToPrismaCreate = (
     pool: BalancerPoolFragment,
@@ -266,24 +266,24 @@ const mapPoolTypeVersion = (poolType: string, poolTypeVersion: number): number =
 };
 
 const dataMapper = {
-    ELEMENT: dataMappers.element,
-    FX: dataMappers.fx,
-    GYRO: dataMappers.gyro,
-    GYRO3: dataMappers.gyro,
-    GYROE: dataMappers.gyro,
-    LINEAR: dataMappers.linear,
+    ELEMENT: element,
+    FX: fx,
+    GYRO: gyro,
+    GYRO3: gyro,
+    GYROE: gyro,
+    LINEAR: linear,
 };
 
 const dynamicMapper = {
-    STABLE: dataMappers.stableDynamic,
-    COMPOSABLE_STABLE: dataMappers.stableDynamic,
-    META_STABLE: dataMappers.stableDynamic,
-    LINEAR: dataMappers.linearDynamic,
+    STABLE: stableDynamic,
+    COMPOSABLE_STABLE: stableDynamic,
+    META_STABLE: stableDynamic,
+    LINEAR: linearDynamic,
 };
 
-export type FxData = ReturnType<typeof dataMappers['fx']>;
-export type GyroData = ReturnType<typeof dataMappers['gyro']>;
-export type LinearData = ReturnType<typeof dataMappers['linear']>;
-export type ElementData = ReturnType<typeof dataMappers['element']>;
-export type StableDynamicData = ReturnType<typeof dataMappers['stableDynamic']>;
-export type LinearDynamicData = ReturnType<typeof dataMappers['linearDynamic']>;
+export type FxData = ReturnType<typeof fx>;
+export type GyroData = ReturnType<typeof gyro>;
+export type LinearData = ReturnType<typeof linear>;
+export type ElementData = ReturnType<typeof element>;
+export type StableDynamicData = ReturnType<typeof stableDynamic>;
+export type LinearDynamicData = ReturnType<typeof linearDynamic>;

From 48c1f9082bf27d287115ce8021dbccd785e7c590 Mon Sep 17 00:00:00 2001
From: gmbronco <83549293+gmbronco@users.noreply.github.com>
Date: Fri, 12 Jan 2024 19:01:28 +0100
Subject: [PATCH 20/23] delete cleanup based on constraints

---
 modules/pool/pool.service.ts | 45 ------------------------------------
 1 file changed, 45 deletions(-)

diff --git a/modules/pool/pool.service.ts b/modules/pool/pool.service.ts
index a697bcf10..7cd8eb9ac 100644
--- a/modules/pool/pool.service.ts
+++ b/modules/pool/pool.service.ts
@@ -379,13 +379,8 @@ export class PoolService {
             where: { chain: this.chain, poolId: poolId },
         });
 
-        const poolTokenIds = poolTokens.map((poolToken) => poolToken.id);
         const poolTokenAddresses = poolTokens.map((poolToken) => poolToken.address);
 
-        await prisma.prismaPoolSnapshot.deleteMany({
-            where: { chain: this.chain, poolId: poolId },
-        });
-
         await prisma.prismaTokenType.deleteMany({
             where: { chain: this.chain, tokenAddress: pool.address },
         });
@@ -394,50 +389,10 @@ export class PoolService {
             where: { chain: this.chain, poolId: poolId },
         });
 
-        await prisma.prismaPoolTokenDynamicData.deleteMany({
-            where: { chain: this.chain, poolTokenId: { in: poolTokenIds } },
-        });
-
         await prisma.prismaTokenDynamicData.deleteMany({
             where: { chain: this.chain, tokenAddress: { in: poolTokenAddresses } },
         });
 
-        await prisma.prismaPoolToken.deleteMany({
-            where: { chain: this.chain, poolId: poolId },
-        });
-
-        await prisma.prismaPoolDynamicData.deleteMany({
-            where: { chain: this.chain, poolId: poolId },
-        });
-
-        await prisma.prismaPoolToken.deleteMany({
-            where: { chain: this.chain, poolId: poolId },
-        });
-
-        await prisma.prismaPoolLinearData.deleteMany({
-            where: { chain: this.chain, poolId: poolId },
-        });
-
-        await prisma.prismaPoolGyroData.deleteMany({
-            where: { chain: this.chain, poolId: poolId },
-        });
-
-        await prisma.prismaPoolExpandedTokens.deleteMany({
-            where: { chain: this.chain, poolId: poolId },
-        });
-
-        await prisma.prismaPoolLinearDynamicData.deleteMany({
-            where: { chain: this.chain, poolId: poolId },
-        });
-
-        await prisma.prismaPoolAprItem.deleteMany({
-            where: { chain: this.chain, poolId: poolId },
-        });
-
-        await prisma.prismaPoolSwap.deleteMany({
-            where: { chain: this.chain, poolId: poolId },
-        });
-
         const poolStaking = await prisma.prismaPoolStaking.findMany({
             where: { chain: this.chain, poolId: poolId },
         });

From 00fd3e0de01f7d9ae284f3e09bd417769e69595c Mon Sep 17 00:00:00 2001
From: franz <franzns11@gmail.com>
Date: Thu, 18 Jan 2024 13:54:26 +0100
Subject: [PATCH 21/23] renaming

---
 modules/pool/subgraph-mapper.ts | 40 +++++++++++++++++----------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts
index 22026a3df..7737baf58 100644
--- a/modules/pool/subgraph-mapper.ts
+++ b/modules/pool/subgraph-mapper.ts
@@ -14,7 +14,7 @@ export const subgraphToPrismaCreate = (
     const prismaPoolRecordWithAssociations = {
         data: {
             ...dbData.base,
-            poolTypeSpecificData: dbData.data,
+            poolTypeSpecificData: dbData.staticTypeData,
             tokens: {
                 createMany: {
                     data: dbData.tokens,
@@ -31,7 +31,7 @@ export const subgraphToPrismaCreate = (
                     ? {
                           create: {
                               id: dbData.base.id,
-                              ...(dbData.data as ReturnType<typeof dataMapper['LINEAR']>),
+                              ...(dbData.staticTypeData as ReturnType<typeof staticTypeDataMapper['LINEAR']>),
                           },
                       }
                     : undefined,
@@ -40,7 +40,7 @@ export const subgraphToPrismaCreate = (
                     ? {
                           create: {
                               id: dbData.base.id,
-                              ...(dbData.data as ReturnType<typeof dataMapper['ELEMENT']>),
+                              ...(dbData.staticTypeData as ReturnType<typeof staticTypeDataMapper['ELEMENT']>),
                           },
                       }
                     : undefined,
@@ -48,7 +48,7 @@ export const subgraphToPrismaCreate = (
                 ? {
                       create: {
                           id: dbData.base.id,
-                          ...(dbData.data as ReturnType<typeof dataMapper['GYRO']>),
+                          ...(dbData.staticTypeData as ReturnType<typeof staticTypeDataMapper['GYRO']>),
                       },
                   }
                 : undefined,
@@ -57,7 +57,7 @@ export const subgraphToPrismaCreate = (
                     ? {
                           create: {
                               id: dbData.base.id,
-                              ...(dbData.dynamicTypeData as ReturnType<typeof dynamicMapper['LINEAR']>),
+                              ...(dbData.dynamicTypeData as ReturnType<typeof dynamicTypeDataMapper['LINEAR']>),
                           },
                       }
                     : undefined,
@@ -65,7 +65,7 @@ export const subgraphToPrismaCreate = (
                 ? {
                       create: {
                           id: dbData.base.id,
-                          ...(dbData.dynamicTypeData as ReturnType<typeof dynamicMapper['STABLE']>),
+                          ...(dbData.dynamicTypeData as ReturnType<typeof dynamicTypeDataMapper['STABLE']>),
                       },
                   }
                 : undefined,
@@ -86,7 +86,7 @@ export const subgraphToPrismaUpdate = (
 
     const prismaPoolRecordWithDataAssociations = {
         ...baseWithoutId,
-        poolTypeSpecificData: dbData.data,
+        poolTypeSpecificData: dbData.staticTypeData,
         tokens: {
             update: dbData.tokens.map((token) => ({
                 where: {
@@ -104,7 +104,7 @@ export const subgraphToPrismaUpdate = (
             dbData.base.type === 'LINEAR'
                 ? {
                       update: {
-                          ...(dbData.data as ReturnType<typeof dataMapper['LINEAR']>),
+                          ...(dbData.staticTypeData as ReturnType<typeof staticTypeDataMapper['LINEAR']>),
                       },
                   }
                 : undefined,
@@ -112,14 +112,14 @@ export const subgraphToPrismaUpdate = (
             dbData.base.type === 'ELEMENT'
                 ? {
                       update: {
-                          ...(dbData.data as ReturnType<typeof dataMapper['ELEMENT']>),
+                          ...(dbData.staticTypeData as ReturnType<typeof staticTypeDataMapper['ELEMENT']>),
                       },
                   }
                 : undefined,
         gyroData: ['GYRO', 'GYRO3', 'GYROE'].includes(dbData.base.type)
             ? {
                   update: {
-                      ...(dbData.data as ReturnType<typeof dataMapper['GYRO']>),
+                      ...(dbData.staticTypeData as ReturnType<typeof staticTypeDataMapper['GYRO']>),
                   },
               }
             : undefined,
@@ -127,14 +127,14 @@ export const subgraphToPrismaUpdate = (
             dbData.base.type === 'LINEAR'
                 ? {
                       update: {
-                          ...(dbData.dynamicTypeData as ReturnType<typeof dynamicMapper['LINEAR']>),
+                          ...(dbData.dynamicTypeData as ReturnType<typeof dynamicTypeDataMapper['LINEAR']>),
                       },
                   }
                 : undefined,
         stableDynamicData: ['STABLE', 'COMPOSABLE_STABLE', 'META_STABLE'].includes(dbData.base.type)
             ? {
                   update: {
-                      ...(dbData.dynamicTypeData as ReturnType<typeof dynamicMapper['STABLE']>),
+                      ...(dbData.dynamicTypeData as ReturnType<typeof dynamicTypeDataMapper['STABLE']>),
                   },
               }
             : undefined,
@@ -175,12 +175,14 @@ const subgraphMapper = (
         totalLiquidity: Math.max(parseFloat(pool.totalLiquidity), 0),
     };
 
-    const data: ReturnType<typeof dataMapper[keyof typeof dataMapper]> | {} = Object.keys(dataMapper).includes(type)
-        ? dataMapper[type as keyof typeof dataMapper](pool)
+    const staticTypeData: ReturnType<typeof staticTypeDataMapper[keyof typeof staticTypeDataMapper]> | {} = Object.keys(
+        staticTypeDataMapper,
+    ).includes(type)
+        ? staticTypeDataMapper[type as keyof typeof staticTypeDataMapper](pool)
         : {};
 
-    const dynamicTypeData = Object.keys(dynamicMapper).includes(type)
-        ? dynamicMapper[type as keyof typeof dynamicMapper](pool, blockNumber)
+    const dynamicTypeData = Object.keys(dynamicTypeDataMapper).includes(type)
+        ? dynamicTypeDataMapper[type as keyof typeof dynamicTypeDataMapper](pool, blockNumber)
         : {};
 
     const tokens =
@@ -211,7 +213,7 @@ const subgraphMapper = (
         base,
         dynamicData,
         tokens,
-        data,
+        staticTypeData,
         dynamicTypeData,
     };
 };
@@ -265,7 +267,7 @@ const mapPoolTypeVersion = (poolType: string, poolTypeVersion: number): number =
     return version;
 };
 
-const dataMapper = {
+const staticTypeDataMapper = {
     ELEMENT: element,
     FX: fx,
     GYRO: gyro,
@@ -274,7 +276,7 @@ const dataMapper = {
     LINEAR: linear,
 };
 
-const dynamicMapper = {
+const dynamicTypeDataMapper = {
     STABLE: stableDynamic,
     COMPOSABLE_STABLE: stableDynamic,
     META_STABLE: stableDynamic,

From 8fb588af2340ca52ef3e96cd6e12b8529849a0e5 Mon Sep 17 00:00:00 2001
From: franz <franzns11@gmail.com>
Date: Thu, 18 Jan 2024 14:51:32 +0100
Subject: [PATCH 22/23] rename column

---
 modules/pool/lib/pool-gql-loader.service.ts                   | 2 +-
 modules/pool/pool.prisma                                      | 2 +-
 modules/pool/subgraph-mapper.ts                               | 4 ++--
 modules/sor/sorV2/sorV2.service.ts                            | 2 +-
 .../20231221154118_pools_data_json_column/migration.sql       | 2 +-
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/modules/pool/lib/pool-gql-loader.service.ts b/modules/pool/lib/pool-gql-loader.service.ts
index 4a108a781..de731f980 100644
--- a/modules/pool/lib/pool-gql-loader.service.ts
+++ b/modules/pool/lib/pool-gql-loader.service.ts
@@ -594,7 +594,7 @@ export class PoolGqlLoaderService {
                     dSq: pool.gyroData?.dSq || '',
                 };
             case 'FX':
-                const data = pool.poolTypeSpecificData as FxData;
+                const data = pool.staticTypeData as FxData;
                 return {
                     __typename: 'GqlPoolFx',
                     ...mappedData,
diff --git a/modules/pool/pool.prisma b/modules/pool/pool.prisma
index 7fd90789f..e9189664e 100644
--- a/modules/pool/pool.prisma
+++ b/modules/pool/pool.prisma
@@ -18,7 +18,7 @@ model PrismaPool {
     linearData          PrismaPoolLinearData?
     elementData         PrismaPoolElementData?
     gyroData            PrismaPoolGyroData?
-    poolTypeSpecificData Json @default("{}")
+    staticTypeData      Json @default("{}")
 
     tokens              PrismaPoolToken[]
 
diff --git a/modules/pool/subgraph-mapper.ts b/modules/pool/subgraph-mapper.ts
index 7737baf58..9d09f0692 100644
--- a/modules/pool/subgraph-mapper.ts
+++ b/modules/pool/subgraph-mapper.ts
@@ -14,7 +14,7 @@ export const subgraphToPrismaCreate = (
     const prismaPoolRecordWithAssociations = {
         data: {
             ...dbData.base,
-            poolTypeSpecificData: dbData.staticTypeData,
+            staticTypeData: dbData.staticTypeData,
             tokens: {
                 createMany: {
                     data: dbData.tokens,
@@ -86,7 +86,7 @@ export const subgraphToPrismaUpdate = (
 
     const prismaPoolRecordWithDataAssociations = {
         ...baseWithoutId,
-        poolTypeSpecificData: dbData.staticTypeData,
+        staticTypeData: dbData.staticTypeData,
         tokens: {
             update: dbData.tokens.map((token) => ({
                 where: {
diff --git a/modules/sor/sorV2/sorV2.service.ts b/modules/sor/sorV2/sorV2.service.ts
index 14f3e8509..55672579b 100644
--- a/modules/sor/sorV2/sorV2.service.ts
+++ b/modules/sor/sorV2/sorV2.service.ts
@@ -430,7 +430,7 @@ export class SorV2Service implements SwapService {
                 name: 'n/a',
             };
             if (['FX'].includes(rawPool.poolType)) {
-                const data = prismaPool.poolTypeSpecificData as FxData;
+                const data = prismaPool.staticTypeData as FxData;
                 rawPool = {
                     ...rawPool,
                     ...data,
diff --git a/prisma/migrations/20231221154118_pools_data_json_column/migration.sql b/prisma/migrations/20231221154118_pools_data_json_column/migration.sql
index 6032639db..873e5ef60 100644
--- a/prisma/migrations/20231221154118_pools_data_json_column/migration.sql
+++ b/prisma/migrations/20231221154118_pools_data_json_column/migration.sql
@@ -1,2 +1,2 @@
 -- AlterTable
-ALTER TABLE "PrismaPool" ADD COLUMN     "poolTypeSpecificData" JSONB NOT NULL DEFAULT '{}';
+ALTER TABLE "PrismaPool" ADD COLUMN     "staticTypeData" JSONB NOT NULL DEFAULT '{}';

From 9eb0ea204d9624a4e501461e70563478250a62de Mon Sep 17 00:00:00 2001
From: franz <franzns11@gmail.com>
Date: Thu, 18 Jan 2024 15:02:29 +0100
Subject: [PATCH 23/23] prisma schema

---
 prisma/schema.prisma | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index fec2c4536..f3320019f 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -64,7 +64,7 @@ model PrismaPool {
     linearData          PrismaPoolLinearData?
     elementData         PrismaPoolElementData?
     gyroData            PrismaPoolGyroData?
-    poolTypeSpecificData Json @default("{}")
+    staticTypeData Json @default("{}")
 
     tokens              PrismaPoolToken[]