diff --git a/docs/new-pool-types.md b/docs/new-pool-types.md index 76d0a9a..092c785 100644 --- a/docs/new-pool-types.md +++ b/docs/new-pool-types.md @@ -4,81 +4,116 @@ To integrate new pool types into the Balancer subgraph, follow these steps below ## Setup -Navigate to the `subgraphs/pools` directory before starting the integration process. - -## Adding the Factory - -Run the following command to add your pool factory: - -``` -pnpm add-factory [factory-address] [network] -``` - -This command fetch the factory ABI, retrieves the deployment block, and adds it to the subgraph manifest. - -## Adding a Pool Instance - -Execute this command to fetch the pool ABI: - -``` -pnpm add-pool [pool-address] [network] -``` - -Ensure you have a pool deployed from your factory before running this command. - -## Generating Types - -Run the codegen command to ensure that types from your ABIs are generated: - -``` -pnpm codegen -``` +Navigate to the `subgraphs/v3-pools` directory before starting the integration process. ## Updating the GraphQL Schema -Edit the `schema.graphql` file to add any specific parameters based on your pool type to the `Pool` entity. - -```graphql -type Pool @entity { - # ... Existing fields - - " Your custom parameter " - customParam: BigInt -} -``` - -Add your custom fields to this schema as needed for your specific pool type. - -## Modifying the Pool Creation Handler - -Navigate to `src/mappings/factories.ts` and update the handler function for the new pool type: - - -```typescript -import { YourPool } from "../types/YourPoolFactory/YourPool"; - -export function handleYourPoolCreated(event: PoolCreated): void { - let poolAddress = event.params.pool; - let pool = new Pool(poolAddress); - pool.address = poolAddress; - - let factory = getFactory(event.address, PoolType.YourPoolType, 1); - pool.factory = factory.id; - - - // First, bind the pool address to its contract - let yourPool = YourPool.bind(poolAddress); - - // Then fetch the pool-specific parameters - let customParamResult = yourPool.try_getCustomParameter(); - if (!customParamResult.reverted) { - pool.customParam = customParamResult.value; - } - - // Add more parameter fetching logic as needed - - pool.save(); -} -``` - -In this function, replace the example parameter fetching logic with calls to your pool's specific methods to retrieve and store the relevant parameters. +1. Edit the `schema.graphql` file: + + a. Add your pool type to the `PoolType` enum: + + ```graphql + enum PoolType { + Weighted + Stable + Custom # Add your new pool type here + } + ``` + + b. Create an entity for your pool-type specific parameters: + + ```graphql + type CustomParams @entity { + id: Bytes! + customParam: BigInt! + # Add other custom parameters as needed + } + ``` + + c. Extend the `Pool` entity to expose your custom params: + + ```graphql + type Pool @entity { + id: Bytes! + address: Bytes! + factory: Factory! + stableParams: StableParams + weightedParams: WeightedParams + customParams: CustomParams # Add the new entity here + } + ``` + +2. Save the `schema.graphql` file. Run the codegen command to generate types from your ABIs: + + ```bash + pnpm codegen + ``` + +## Creating the Subgraph Manifest + +1. Update the `subgraph.sepolia.yaml` file to include your new pool factory: + + ```yaml + dataSources: + # Existing data sources... + - kind: ethereum/contract + name: CustomPoolFactory + network: sepolia + source: + address: "0x..." # Your custom pool factory address + abi: BasePoolFactory + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + file: ./src/mappings/custom.ts + entities: + - Pool + - CustomParams + abis: + - name: BasePoolFactory + file: ./abis/BasePoolFactory.json + eventHandlers: + - event: PoolCreated(indexed address,bytes32) + handler: handleCustomPoolCreated + ``` + +## Implementing Pool Factory Mapping + +1. Update `src/mappings/common.ts` to include your new pool type: + + ```typescript + export class PoolType { + static Weighted: string = "Weighted"; + static Stable: string = "Stable"; + static Custom: string = "Custom"; // Add your new pool type here + } + ``` + +2. Create a new file in the `src/mappings` directory for your custom pool factory (e.g., `custom.ts`). + +3. Implement the factory mapping. See Stable and Weighted implementations as reference. + + ```typescript + import { Address } from "@graphprotocol/graph-ts"; + + import { PoolCreated } from "../types/CustomPoolFactory/BasePoolFactory"; + import { handlePoolCreated } from "./factories"; + import { PoolType } from "./constants"; + + export function handleCustomPoolCreated(event: CustomPoolCreated): void { + handlePoolCreated( + event.params.pool, + event.address, // Factory + PoolType.Custom, + 1, // version of your pool type factory + handleCustomPoolParams, + "customParams" // should be the name of the field you added to the Pool entity + ); + } + + function handleCustomPoolParams(poolAddress: Address): Bytes { + // Implement custom logic to fetch and save custom parameters + // Return the ID of the saved CustomParams entity + } + ``` diff --git a/subgraphs/v3-pools/abis/BasePoolFactory.json b/subgraphs/v3-pools/abis/BasePoolFactory.json new file mode 100644 index 0000000..2713127 --- /dev/null +++ b/subgraphs/v3-pools/abis/BasePoolFactory.json @@ -0,0 +1,15 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolCreated", + "type": "event" + } +] diff --git a/subgraphs/v3-pools/abis/StablePoolFactory.json b/subgraphs/v3-pools/abis/StablePoolFactory.json deleted file mode 100644 index bd16df8..0000000 --- a/subgraphs/v3-pools/abis/StablePoolFactory.json +++ /dev/null @@ -1,371 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "contract IVault", - "name": "vault", - "type": "address" - }, - { - "internalType": "uint32", - "name": "pauseWindowDuration", - "type": "uint32" - }, - { - "internalType": "string", - "name": "factoryVersion", - "type": "string" - }, - { - "internalType": "string", - "name": "poolVersion", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "Disabled", - "type": "error" - }, - { - "inputs": [], - "name": "PoolPauseWindowDurationOverflow", - "type": "error" - }, - { - "inputs": [], - "name": "SenderNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "StandardPoolWithCreator", - "type": "error" - }, - { - "anonymous": false, - "inputs": [], - "name": "FactoryDisabled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolCreated", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "string", - "name": "symbol", - "type": "string" - }, - { - "components": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "internalType": "enum TokenType", - "name": "tokenType", - "type": "uint8" - }, - { - "internalType": "contract IRateProvider", - "name": "rateProvider", - "type": "address" - }, - { - "internalType": "bool", - "name": "paysYieldFees", - "type": "bool" - } - ], - "internalType": "struct TokenConfig[]", - "name": "tokens", - "type": "tuple[]" - }, - { - "internalType": "uint256[]", - "name": "normalizedWeights", - "type": "uint256[]" - }, - { - "components": [ - { - "internalType": "address", - "name": "pauseManager", - "type": "address" - }, - { - "internalType": "address", - "name": "swapFeeManager", - "type": "address" - }, - { - "internalType": "address", - "name": "poolCreator", - "type": "address" - } - ], - "internalType": "struct PoolRoleAccounts", - "name": "roleAccounts", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "swapFeePercentage", - "type": "uint256" - }, - { - "internalType": "address", - "name": "poolHooksContract", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "name": "create", - "outputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "disable", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "selector", - "type": "bytes4" - } - ], - "name": "getActionId", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getAuthorizer", - "outputs": [ - { - "internalType": "contract IAuthorizer", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getDefaultLiquidityManagement", - "outputs": [ - { - "components": [ - { - "internalType": "bool", - "name": "disableUnbalancedLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "enableAddLiquidityCustom", - "type": "bool" - }, - { - "internalType": "bool", - "name": "enableRemoveLiquidityCustom", - "type": "bool" - } - ], - "internalType": "struct LiquidityManagement", - "name": "liquidityManagement", - "type": "tuple" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "getDefaultPoolHooksContract", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "name": "getDeploymentAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNewPoolPauseWindowEndTime", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOriginalPauseWindowEndTime", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getPauseWindowDuration", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getPoolVersion", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getVault", - "outputs": [ - { - "internalType": "contract IVault", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isDisabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "isPoolFromFactory", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } -] diff --git a/subgraphs/v3-pools/abis/WeightedPoolFactory.json b/subgraphs/v3-pools/abis/WeightedPoolFactory.json deleted file mode 100644 index bd16df8..0000000 --- a/subgraphs/v3-pools/abis/WeightedPoolFactory.json +++ /dev/null @@ -1,371 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "contract IVault", - "name": "vault", - "type": "address" - }, - { - "internalType": "uint32", - "name": "pauseWindowDuration", - "type": "uint32" - }, - { - "internalType": "string", - "name": "factoryVersion", - "type": "string" - }, - { - "internalType": "string", - "name": "poolVersion", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "Disabled", - "type": "error" - }, - { - "inputs": [], - "name": "PoolPauseWindowDurationOverflow", - "type": "error" - }, - { - "inputs": [], - "name": "SenderNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "StandardPoolWithCreator", - "type": "error" - }, - { - "anonymous": false, - "inputs": [], - "name": "FactoryDisabled", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "PoolCreated", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "string", - "name": "symbol", - "type": "string" - }, - { - "components": [ - { - "internalType": "contract IERC20", - "name": "token", - "type": "address" - }, - { - "internalType": "enum TokenType", - "name": "tokenType", - "type": "uint8" - }, - { - "internalType": "contract IRateProvider", - "name": "rateProvider", - "type": "address" - }, - { - "internalType": "bool", - "name": "paysYieldFees", - "type": "bool" - } - ], - "internalType": "struct TokenConfig[]", - "name": "tokens", - "type": "tuple[]" - }, - { - "internalType": "uint256[]", - "name": "normalizedWeights", - "type": "uint256[]" - }, - { - "components": [ - { - "internalType": "address", - "name": "pauseManager", - "type": "address" - }, - { - "internalType": "address", - "name": "swapFeeManager", - "type": "address" - }, - { - "internalType": "address", - "name": "poolCreator", - "type": "address" - } - ], - "internalType": "struct PoolRoleAccounts", - "name": "roleAccounts", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "swapFeePercentage", - "type": "uint256" - }, - { - "internalType": "address", - "name": "poolHooksContract", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "name": "create", - "outputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "disable", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "selector", - "type": "bytes4" - } - ], - "name": "getActionId", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getAuthorizer", - "outputs": [ - { - "internalType": "contract IAuthorizer", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getDefaultLiquidityManagement", - "outputs": [ - { - "components": [ - { - "internalType": "bool", - "name": "disableUnbalancedLiquidity", - "type": "bool" - }, - { - "internalType": "bool", - "name": "enableAddLiquidityCustom", - "type": "bool" - }, - { - "internalType": "bool", - "name": "enableRemoveLiquidityCustom", - "type": "bool" - } - ], - "internalType": "struct LiquidityManagement", - "name": "liquidityManagement", - "type": "tuple" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [], - "name": "getDefaultPoolHooksContract", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "name": "getDeploymentAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getNewPoolPauseWindowEndTime", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getOriginalPauseWindowEndTime", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getPauseWindowDuration", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getPoolVersion", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getVault", - "outputs": [ - { - "internalType": "contract IVault", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "isDisabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "pool", - "type": "address" - } - ], - "name": "isPoolFromFactory", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "version", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } -] diff --git a/subgraphs/v3-pools/package.json b/subgraphs/v3-pools/package.json index b767925..2eaa5d0 100644 --- a/subgraphs/v3-pools/package.json +++ b/subgraphs/v3-pools/package.json @@ -4,7 +4,7 @@ "scripts": { "add-pool": "node scripts/cli.js", "add-factory": "node scripts/cli.js", - "codegen": "graph codegen --output-dir src/types/", + "codegen": "graph codegen subgraph.sepolia.yaml --output-dir src/types/", "deploy": "graph deploy", "build": "graph build", "test": "graph test" diff --git a/subgraphs/v3-pools/schema.graphql b/subgraphs/v3-pools/schema.graphql index 497808e..fd62639 100644 --- a/subgraphs/v3-pools/schema.graphql +++ b/subgraphs/v3-pools/schema.graphql @@ -37,8 +37,6 @@ type Pool @entity { address: Bytes! "Factory that created this Pool" factory: Factory! - "Type of the pool" - type: PoolType! "Parameters for Weighted pools (null for other pool types)" weightedParams: WeightedParams "Parameters for Stable pools (null for other pool types)" diff --git a/subgraphs/v3-pools/scripts/add-factory.js b/subgraphs/v3-pools/scripts/add-factory.js deleted file mode 100755 index 738a52c..0000000 --- a/subgraphs/v3-pools/scripts/add-factory.js +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env node - -const { execSync } = require('child_process'); - -const [,, address, networkName] = process.argv; - -if (!address || !networkName) { - console.error('Usage: pnpm cli
'); - process.exit(1); -} - -const subgraphManifest = `subgraph.${networkName}.yaml`; - -try { - execSync('git stash push --include-untracked', { stdio: 'inherit' }); - - execSync(`graph add ${address} ${subgraphManifest}`, { stdio: 'inherit' }); - - const changedFiles = execSync('git diff --name-only').toString().trim().split('\n'); - - // Keep only the downloaded ABIs and the subgraph manifest - const filesToKeep = [ - subgraphManifest, - 'abis', - ]; - - changedFiles.forEach(file => { - if (!filesToKeep.includes(file)) { - execSync(`git checkout -- "${file}"`, { stdio: 'inherit' }); - } - }); - - console.log(`Added pool factory ${address} to ${subgraphManifest}`); - console.log('Kept changes in:', filesToKeep.join(', ')); - - execSync('git stash pop', { stdio: 'inherit' }); - -} catch (error) { - console.error(`Failed: ${error.message}`); - try { - execSync('git stash pop', { stdio: 'inherit' }); - } catch (stashError) { - console.error('Failed to restore stashed changes:', stashError.message); - } - process.exit(1); -} \ No newline at end of file diff --git a/subgraphs/v3-pools/scripts/add-pool.js b/subgraphs/v3-pools/scripts/add-pool.js deleted file mode 100644 index c256655..0000000 --- a/subgraphs/v3-pools/scripts/add-pool.js +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env node - -const { execSync } = require('child_process'); - -const [,, address, networkName] = process.argv; - -if (!address || !networkName) { - console.error('Usage: pnpm cli
'); - process.exit(1); -} - -const subgraphManifest = `subgraph.${networkName}.yaml`; - -try { - execSync('git stash push --include-untracked', { stdio: 'inherit' }); - - execSync(`graph add ${address} ${subgraphManifest}`, { stdio: 'inherit' }); - - const changedFiles = execSync('git diff --name-only').toString().trim().split('\n'); - - // Keep only the downloaded ABI - const filesToKeep = [ - 'abis', - ]; - - changedFiles.forEach(file => { - if (!filesToKeep.includes(file)) { - execSync(`git checkout -- "${file}"`, { stdio: 'inherit' }); - } - }); - - console.log(`Added pool factory ${address} to ${subgraphManifest}`); - console.log('Kept changes in:', filesToKeep.join(', ')); - - execSync('git stash pop', { stdio: 'inherit' }); - -} catch (error) { - console.error(`Failed: ${error.message}`); - try { - execSync('git stash pop', { stdio: 'inherit' }); - } catch (stashError) { - console.error('Failed to restore stashed changes:', stashError.message); - } - process.exit(1); -} \ No newline at end of file diff --git a/subgraphs/v3-pools/src/helpers/constants.ts b/subgraphs/v3-pools/src/helpers/constants.ts deleted file mode 100644 index ac7cfb5..0000000 --- a/subgraphs/v3-pools/src/helpers/constants.ts +++ /dev/null @@ -1,6 +0,0 @@ -export namespace PoolType { - export const Weighted = "Weighted"; - export const Stable = "Stable"; -} - -export const ONE_HUNDRED_PERCENT = 1000000000000000000; diff --git a/subgraphs/v3-pools/src/helpers/misc.ts b/subgraphs/v3-pools/src/helpers/math.ts similarity index 100% rename from subgraphs/v3-pools/src/helpers/misc.ts rename to subgraphs/v3-pools/src/helpers/math.ts diff --git a/subgraphs/v3-pools/src/mappings/common.ts b/subgraphs/v3-pools/src/mappings/common.ts new file mode 100644 index 0000000..495e180 --- /dev/null +++ b/subgraphs/v3-pools/src/mappings/common.ts @@ -0,0 +1,36 @@ +import { Address, Bytes, Value } from "@graphprotocol/graph-ts"; + +import { getFactory } from "../helpers/entities"; +import { Pool } from "../types/schema"; + +export namespace PoolType { + export const Weighted = "Weighted"; + export const Stable = "Stable"; +} + +export function createBasePool( + poolAddress: Address, + factoryAddress: Address, + poolType: string, + version: i32 +): Pool { + let pool = new Pool(poolAddress); + pool.address = poolAddress; + let factory = getFactory(factoryAddress, poolType, version); + pool.factory = factory.id; + return pool; +} + +export function handlePoolCreated( + poolAddress: Address, + factoryAddress: Address, + poolType: string, + version: i32, + paramHandler: (address: Address) => Bytes, + paramField: string +): void { + let pool = createBasePool(poolAddress, factoryAddress, poolType, version); + let params = paramHandler(poolAddress); + pool.set(paramField, Value.fromBytes(params)); + pool.save(); +} diff --git a/subgraphs/v3-pools/src/mappings/factories.ts b/subgraphs/v3-pools/src/mappings/factories.ts deleted file mode 100644 index ab9f087..0000000 --- a/subgraphs/v3-pools/src/mappings/factories.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { BigDecimal } from "@graphprotocol/graph-ts"; -import { PoolCreated as WeightedPoolCreated } from "../types/WeightedPoolFactory/WeightedPoolFactory"; -import { WeightedPool } from "../types/WeightedPoolFactory/WeightedPool"; -import { StablePool } from "../types/StablePoolFactory/StablePool"; -import { scaleDown } from "../helpers/misc"; -import { getFactory } from "../helpers/entities"; -import { Pool } from "../types/schema"; - -namespace PoolType { - export const Weighted = "Weighted"; - export const Stable = "Stable"; -} - -/************************************ - ********* WEIGHTED POOLS *********** - ************************************/ - -export function handleWeightedPoolCreated(event: WeightedPoolCreated): void { - let poolAddress = event.params.pool; - let pool = new Pool(poolAddress); - pool.address = poolAddress; - - let factory = getFactory(event.address, PoolType.Weighted, 1); - pool.factory = factory.id; - - let weightedPool = WeightedPool.bind(poolAddress); - let weightsResult = weightedPool.try_getNormalizedWeights(); - if (weightsResult.reverted) return; - pool.weights = weightsResult.value.map((weight) => - scaleDown(weight, 18) - ); - - pool.save(); -} - -/************************************ - ********* STABLE POOLS ************* - ************************************/ - -export function handleStablePoolCreated(event: WeightedPoolCreated): void { - let poolAddress = event.params.pool; - let pool = new Pool(poolAddress); - pool.address = poolAddress; - - let factory = getFactory(event.address, PoolType.Stable, 1); - pool.factory = factory.id; - - let stablePool = StablePool.bind(poolAddress); - let ampResult = stablePool.try_getAmplificationParameter(); - if (ampResult.reverted) return; - - let ampValue = ampResult.value.value0; - let ampPrecision = ampResult.value.value2; - pool.amp = ampValue.div(ampPrecision); - - pool.save(); -} diff --git a/subgraphs/v3-pools/src/mappings/stable.ts b/subgraphs/v3-pools/src/mappings/stable.ts new file mode 100644 index 0000000..5c44200 --- /dev/null +++ b/subgraphs/v3-pools/src/mappings/stable.ts @@ -0,0 +1,30 @@ +import { Address, Bytes } from "@graphprotocol/graph-ts"; + +import { handlePoolCreated, PoolType } from "./common"; +import { PoolCreated } from "../types/StablePoolFactory/BasePoolFactory"; +import { StablePool } from "../types/StablePoolFactory/StablePool"; +import { StableParams } from "../types/schema"; + +function handleStablePoolParams(poolAddress: Address): Bytes { + let stablePool = StablePool.bind(poolAddress); + let ampResult = stablePool.try_getAmplificationParameter(); + let stableParams = new StableParams(poolAddress); + if (!ampResult.reverted) { + let ampValue = ampResult.value.value0; + let ampPrecision = ampResult.value.value2; + stableParams.amp = ampValue.div(ampPrecision); + } + stableParams.save(); + return stableParams.id; +} + +export function handleStablePoolCreated(event: PoolCreated): void { + handlePoolCreated( + event.params.pool, + event.address, // Factory + PoolType.Stable, + 1, + handleStablePoolParams, + "stableParams" + ); +} diff --git a/subgraphs/v3-pools/src/mappings/weighted.ts b/subgraphs/v3-pools/src/mappings/weighted.ts new file mode 100644 index 0000000..c84f22f --- /dev/null +++ b/subgraphs/v3-pools/src/mappings/weighted.ts @@ -0,0 +1,31 @@ +import { Address, BigDecimal, Bytes } from "@graphprotocol/graph-ts"; + +import { handlePoolCreated, PoolType } from "./common"; +import { PoolCreated } from "../types/WeightedPoolFactory/BasePoolFactory"; +import { WeightedPool } from "../types/WeightedPoolFactory/WeightedPool"; +import { WeightedParams } from "../types/schema"; +import { scaleDown } from "../helpers/math"; + +function handleWeightedPoolParams(poolAddress: Address): Bytes { + let weightedPool = WeightedPool.bind(poolAddress); + let weightsResult = weightedPool.try_getNormalizedWeights(); + let weightedParams = new WeightedParams(poolAddress); + if (!weightsResult.reverted) { + weightedParams.weights = weightsResult.value.map((weight) => + scaleDown(weight, 18) + ); + } + weightedParams.save(); + return weightedParams.id; +} + +export function handleWeightedPoolCreated(event: PoolCreated): void { + handlePoolCreated( + event.params.pool, + event.address, // Factory + PoolType.Weighted, + 1, + handleWeightedPoolParams, + "stableParams" + ); +} diff --git a/subgraphs/v3-pools/template.yaml b/subgraphs/v3-pools/template.yaml index 2fe2c6d..f05d402 100644 --- a/subgraphs/v3-pools/template.yaml +++ b/subgraphs/v3-pools/template.yaml @@ -4,11 +4,11 @@ schema: dataSources: - kind: ethereum name: WeightedPoolFactory - network: {{ network }} + network: { { network } } source: - abi: WeightedPoolFactory + abi: BasePoolFactory address: "{{ WeightedPoolFactory.address }}" - startBlock: {{ WeightedPoolFactory.startBlock }} + startBlock: { { WeightedPoolFactory.startBlock } } mapping: kind: ethereum/events apiVersion: 0.0.7 @@ -19,19 +19,19 @@ dataSources: abis: - name: WeightedPool file: ./abis/WeightedPool.json - - name: WeightedPoolFactory - file: ./abis/WeightedPoolFactory.json + - name: BasePoolFactory + file: ./abis/BasePoolFactory.json eventHandlers: - event: PoolCreated(indexed address) handler: handleWeightedPoolCreated - file: ./src/mappings/factories.ts + file: ./src/mappings/weighted.ts - kind: ethereum name: StablePoolFactory - network: {{ network }} + network: { { network } } source: - abi: StablePoolFactory + abi: BasePoolFactory address: "{{ StablePoolFactory.address }}" - startBlock: {{ StablePoolFactory.startBlock }} + startBlock: { { StablePoolFactory.startBlock } } mapping: kind: ethereum/events apiVersion: 0.0.7 @@ -42,9 +42,9 @@ dataSources: abis: - name: StablePool file: ./abis/StablePool.json - - name: StablePoolFactory - file: ./abis/StablePoolFactory.json + - name: BasePoolFactory + file: ./abis/BasePoolFactory.json eventHandlers: - event: PoolCreated(indexed address) handler: handleStablePoolCreated - file: ./src/mappings/factories.ts + file: ./src/mappings/stable.ts