From a3d7469742537ea9c26feccaabb8118757417e2a Mon Sep 17 00:00:00 2001 From: Jakub Swierczek Date: Wed, 22 May 2024 09:31:05 +0200 Subject: [PATCH 01/37] feat: [sc-15610] Cron Job to Save the Points (#252) Story details: https://app.shortcut.com/oazo-apps/story/15610 --------- Co-authored-by: Halaprix --- .env.template | 4 +- .../update-rays-cron-function/.eslintrc.cjs | 6 + .../update-rays-cron-function/jest.config.js | 15 + .../update-rays-cron-function/package.json | 27 + .../update-rays-cron-function/src/index.ts | 413 ++ .../src/point-accrual.ts | 478 ++ .../src/position-id-resolver.ts | 58 + .../update-rays-cron-function/sst-env.d.ts | 1 + .../update-rays-cron-function/tsconfig.json | 9 + packages/rays-db/package.json | 5 +- packages/rays-db/src/database-types.ts | 32 +- packages/rays-db/src/index.ts | 51 +- packages/rays-db/src/migrations/001_init.mts | 37 +- .../migrations/002_update_points_log.mts.ts | 56 + packages/rays-db/src/scripts/local-config.ts | 8 +- packages/rays-db/src/services/index.ts | 1 + .../src/services/update-lock-service.ts | 42 + .../serverless-shared/src/domain-types.ts | 14 +- packages/summer-events-subgraph/.eslintrc.cjs | 10 + .../summer-events-subgraph/graphql.config.yml | 32 + packages/summer-events-subgraph/package.json | 27 + .../queries/get-points.graphql | 76 + .../summer-events-subgraph/schema.graphql | 4693 +++++++++++++++++ packages/summer-events-subgraph/src/index.ts | 95 + packages/summer-events-subgraph/tsconfig.json | 9 + pnpm-lock.yaml | 199 +- pnpm-workspace.yaml | 1 + schema.graphql | 4693 +++++++++++++++++ stacks/rays-db.ts | 71 - stacks/rays.ts | 83 +- stacks/summer-stack.ts | 4 +- summerfi-api/get-rays-function/package.json | 2 - summerfi-api/get-rays-function/src/index.ts | 26 +- summerfi-api/get-rays-function/sst-env.d.ts | 12 +- turbo.json | 4 +- 35 files changed, 11056 insertions(+), 238 deletions(-) create mode 100644 background-jobs/update-rays-cron-function/.eslintrc.cjs create mode 100644 background-jobs/update-rays-cron-function/jest.config.js create mode 100644 background-jobs/update-rays-cron-function/package.json create mode 100644 background-jobs/update-rays-cron-function/src/index.ts create mode 100644 background-jobs/update-rays-cron-function/src/point-accrual.ts create mode 100644 background-jobs/update-rays-cron-function/src/position-id-resolver.ts create mode 100644 background-jobs/update-rays-cron-function/sst-env.d.ts create mode 100644 background-jobs/update-rays-cron-function/tsconfig.json create mode 100644 packages/rays-db/src/migrations/002_update_points_log.mts.ts create mode 100644 packages/rays-db/src/services/index.ts create mode 100644 packages/rays-db/src/services/update-lock-service.ts create mode 100644 packages/summer-events-subgraph/.eslintrc.cjs create mode 100644 packages/summer-events-subgraph/graphql.config.yml create mode 100644 packages/summer-events-subgraph/package.json create mode 100644 packages/summer-events-subgraph/queries/get-points.graphql create mode 100644 packages/summer-events-subgraph/schema.graphql create mode 100644 packages/summer-events-subgraph/src/index.ts create mode 100644 packages/summer-events-subgraph/tsconfig.json create mode 100644 schema.graphql delete mode 100644 stacks/rays-db.ts diff --git a/.env.template b/.env.template index bdfbaf59a0..d04f4f10f6 100644 --- a/.env.template +++ b/.env.template @@ -5,4 +5,6 @@ SUBGRAPH_BASE= POWERTOOLS_LOG_LEVEL= SST_USER= DEBANK_API_KEY= -DEBANK_API_URL= \ No newline at end of file +DEBANK_API_URL= +RAYS_DB_WRITE_CONNECTION_STRING=postgres://user:password@localhost:5500/rays +RAYS_DB_READ_CONNECTION_STRING=postgres://user:password@localhost:5500/rays \ No newline at end of file diff --git a/background-jobs/update-rays-cron-function/.eslintrc.cjs b/background-jobs/update-rays-cron-function/.eslintrc.cjs new file mode 100644 index 0000000000..2e7192ec34 --- /dev/null +++ b/background-jobs/update-rays-cron-function/.eslintrc.cjs @@ -0,0 +1,6 @@ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + extends: ['@summerfi/eslint-config/function.cjs'], + parser: '@typescript-eslint/parser', +} diff --git a/background-jobs/update-rays-cron-function/jest.config.js b/background-jobs/update-rays-cron-function/jest.config.js new file mode 100644 index 0000000000..2fac612765 --- /dev/null +++ b/background-jobs/update-rays-cron-function/jest.config.js @@ -0,0 +1,15 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + transform: { + // '^.+\\.[tj]sx?$' to process js/ts with `ts-jest` + // '^.+\\.m?[tj]sx?$' to process js/ts/mjs/mts with `ts-jest` + '^.+\\.tsx?$': [ + 'ts-jest', + { + tsconfig: {}, + }, + ], + }, +} diff --git a/background-jobs/update-rays-cron-function/package.json b/background-jobs/update-rays-cron-function/package.json new file mode 100644 index 0000000000..faf3fe59f9 --- /dev/null +++ b/background-jobs/update-rays-cron-function/package.json @@ -0,0 +1,27 @@ +{ + "name": "@summerfi/update-rays-cron-function", + "version": "0.0.1", + "scripts": { + "test": "jest --passWithNoTests", + "build": "tsc -b -v", + "lint": "eslint .", + "lint:fix": "eslint . --fix" + }, + "dependencies": { + "@aws-lambda-powertools/logger": "^2.0.2", + "@aws-lambda-powertools/metrics": "^2.0.2", + "@aws-lambda-powertools/tracer": "^2.0.2", + "kysely": "^0.27.3", + "zod": "^3.22.4", + "@summerfi/summer-events-subgraph": "workspace:*", + "@summerfi/rays-db": "workspace:*", + "@summerfi/serverless-shared": "workspace:*" + }, + "devDependencies": { + "@summerfi/eslint-config": "workspace:*", + "@summerfi/typescript-config": "workspace:*", + "@types/node": "^20.11.5", + "eslint": "^8.56.0", + "jest": "^29.7.0" + } +} diff --git a/background-jobs/update-rays-cron-function/src/index.ts b/background-jobs/update-rays-cron-function/src/index.ts new file mode 100644 index 0000000000..030d3b60b7 --- /dev/null +++ b/background-jobs/update-rays-cron-function/src/index.ts @@ -0,0 +1,413 @@ +import type { Context, EventBridgeEvent } from 'aws-lambda' +import { Logger } from '@aws-lambda-powertools/logger' +import { getRaysDB } from '@summerfi/rays-db' +import process from 'node:process' +import { getSummerPointsSubgraphClient } from '@summerfi/summer-events-subgraph' +import { ChainId } from '@summerfi/serverless-shared' +import { SummerPointsService } from './point-accrual' +import { positionIdResolver } from './position-id-resolver' + +const logger = new Logger({ serviceName: 'update-rays-cron-function' }) + +const LOCK_ID = 'update_points_lock' +const LAST_RUN_ID = 'update_points_last_run' + +const eligibilityConditionType = 'POSITION_OPEN_TIME' +const eligibilityConditionDescription = 'The position must be open for at least 30 days' +const eligibilityConditionMetadata = { + minDays: 30, +} + +export const handler = async ( + event: EventBridgeEvent<'Scheduled Event', never>, + context: Context, +): Promise => { + const { SUBGRAPH_BASE, RAYS_DB_CONNECTION_STRING } = process.env + + logger.addContext(context) + logger.info('Hello World!') + + if (!SUBGRAPH_BASE) { + logger.error('SUBGRAPH_BASE is not set') + return + } + + if (!RAYS_DB_CONNECTION_STRING) { + logger.error('RAYS_DB_CONNECTION_STRING is not set') + return + } + + const dbConfig = { + connectionString: RAYS_DB_CONNECTION_STRING, + logger, + } + const { db, services } = await getRaysDB(dbConfig) + + const mainnetSubgraphClient = getSummerPointsSubgraphClient({ + logger, + chainId: ChainId.MAINNET, + urlBase: SUBGRAPH_BASE, + }) + + const baseSubgraphClient = getSummerPointsSubgraphClient({ + logger, + chainId: ChainId.BASE, + urlBase: SUBGRAPH_BASE, + }) + + const optimismSubgraphClient = getSummerPointsSubgraphClient({ + logger, + chainId: ChainId.OPTIMISM, + urlBase: SUBGRAPH_BASE, + }) + + const arbitrumSubgraphClient = getSummerPointsSubgraphClient({ + logger, + chainId: ChainId.ARBITRUM, + urlBase: SUBGRAPH_BASE, + }) + + const clients = [ + mainnetSubgraphClient, + baseSubgraphClient, + optimismSubgraphClient, + arbitrumSubgraphClient, + ] + + const pointAccuralService = new SummerPointsService(clients, logger) + + const lastRunTimestamp = await db + .selectFrom('updatePointsLastRun') + .where('id', '=', LAST_RUN_ID) + .select('lastTimestamp') + .executeTakeFirst() + + const lock = await services.updateLockService.getLock() + + if (!lastRunTimestamp) { + logger.error('Failed to get last run timestamp') + return + } + + if (!lock) { + logger.error('Failed to get lock') + return + } + + if (lock.isLocked) { + logger.info('Update points is already running') + return + } + + const lastRun = Math.floor(lastRunTimestamp.lastTimestamp.getTime() / 1000) // Convert to seconds. + const startTimestamp = lastRun + 1 // Convert to seconds. + const endTimestamp = Math.floor(Date.now() / 1000) // Convert to seconds. + + logger.info('Trying to update points with parameters:', { + lastRun, + startTimestamp, + endTimestamp, + }) + + try { + const updatedLock = await db + .updateTable('updatePointsLock') + .set('isLocked', true) + .where('id', '=', LOCK_ID) + .executeTakeFirst() + + if (updatedLock.numUpdatedRows === 0n) { + logger.error('Failed to lock update points') + return + } + + const points = await pointAccuralService.accruePoints(startTimestamp, endTimestamp) + + logger.info(`Got: ${points.length} positions to update in the database`) + + const sortedPoints = points.sort((a, b) => a.positionId.localeCompare(b.positionId)) + + // split points by 30 item chunks + const chunkedPoints = [] + for (let i = 0; i < sortedPoints.length; i += 30) { + chunkedPoints.push(sortedPoints.slice(i, i + 30)) + } + for (let i = 0; i < chunkedPoints.length; i++) { + logger.info(`Processing: Chunk ${i} of ${chunkedPoints.length}`) + const chunk = chunkedPoints[i] + const addressesForChunk = chunk.map((c) => c.user) + const positionsForChunk = chunk.map((c) => c.positionId) + + const userAddresses = await db + .selectFrom('userAddress') + .where('address', 'in', addressesForChunk) + .selectAll() + .execute() + const positions = await db + .selectFrom('position') + .where('externalId', 'in', positionsForChunk) + .selectAll() + .execute() + + const usersMultipliers = await db + .selectFrom('multiplier') + .innerJoin('userAddress', 'multiplier.userAddressId', 'userAddress.id') + .where('userAddress.address', 'in', addressesForChunk) + .select([ + 'multiplier.value', + 'multiplier.type', + 'multiplier.id', + 'multiplier.userAddressId', + 'multiplier.positionId', + ]) + .execute() + + const positionsMultipliers = await db + .selectFrom('multiplier') + .innerJoin('position', 'multiplier.positionId', 'position.id') + .where('position.externalId', 'in', positionsForChunk) + .select([ + 'multiplier.value', + 'multiplier.type', + 'multiplier.id', + 'multiplier.userAddressId', + 'multiplier.positionId', + ]) + .execute() + + await Promise.all( + chunk.map(async (record) => { + let userAddress = userAddresses.find((ua) => ua.address === record.user) + + if (!userAddress) { + const result = await db + .insertInto('blockchainUser') + .values({ category: null }) + .returning(['id']) + .executeTakeFirstOrThrow() + userAddress = await db + .insertInto('userAddress') + .values({ address: record.user, userId: result.id }) + .returningAll() + .executeTakeFirstOrThrow() + } + + const positionId = positionIdResolver(record.positionId) + + let position = positions.find((p) => p.externalId === record.positionId) + if (!position) { + position = await db + .insertInto('position') + .values({ + externalId: record.positionId, + market: record.marketId, + protocol: positionId.protocol, + type: positionId.positionType, + userAddressId: userAddress.id, + vaultId: record.vaultId, + chainId: positionId.chainId, + address: positionId.address, + }) + .returningAll() + .executeTakeFirstOrThrow() + } + + if (record.points.openPositionsPoints > 0) { + await db + .insertInto('pointsDistribution') + .values({ + description: 'Points for opening a position', + points: record.points.openPositionsPoints, + positionId: position.id, + type: 'OPEN_POSITION', + }) + .executeTakeFirstOrThrow() + } + + const currentDate = new Date() + const dueDateTimestamp = currentDate.setDate(currentDate.getDate() + 30) + const dueDate = new Date(dueDateTimestamp) + + if (record.points.migrationPoints > 0) { + const eligibilityCondition = await db + .insertInto('eligibilityCondition') + .values({ + type: eligibilityConditionType, + description: eligibilityConditionDescription, + metadata: JSON.stringify(eligibilityConditionMetadata), + dueDate: dueDate, + }) + .returningAll() + .executeTakeFirstOrThrow() + + await db + .insertInto('pointsDistribution') + .values({ + description: 'Points for migrations', + points: record.points.migrationPoints, + positionId: position.id, + type: 'MIGRATION', + eligibilityConditionId: eligibilityCondition.id, + }) + .executeTakeFirstOrThrow() + } + + if (record.points.swapPoints > 0) { + await db + .insertInto('pointsDistribution') + .values({ + description: 'Points for swap', + points: record.points.swapPoints, + positionId: position.id, + type: 'SWAP', + }) + .executeTakeFirstOrThrow() + } + + // Multipliers + // protocolBoostMultiplier: -> user multiplier -> type = 'PROTOCOL_BOOST' + // swapMultiplier: number -> user multiplier -> type = 'SWAP' + // timeOpenMultiplier: number -> position multiplier -> type = 'TIME_OPEN' + // automationProtectionMultiplier: number -> position multiplier -> type = 'AUTOMATION' + // lazyVaultMultiplier: number -> position multiplier -> type = 'LAZY_VAULT' + + const userMultipliers = usersMultipliers.filter((m) => m.userAddressId === userAddress.id) + const positionMultipliers = positionsMultipliers.filter( + (m) => m.positionId === position.id, + ) + + let procotolBoostMultiplier = userMultipliers.find((m) => m.type === 'PROTOCOL_BOOST') + + if (!procotolBoostMultiplier) { + procotolBoostMultiplier = await db + .insertInto('multiplier') + .values({ + userAddressId: userAddress.id, + type: 'PROTOCOL_BOOST', + value: record.multipliers.protocolBoostMultiplier, + }) + .returningAll() + .executeTakeFirstOrThrow() + } else { + await db + .updateTable('multiplier') + .set('value', record.multipliers.protocolBoostMultiplier) + .where('id', '=', procotolBoostMultiplier.id) + .execute() + } + + let swapMultiplier = userMultipliers.find((m) => m.type === 'SWAP') + + if (!swapMultiplier) { + swapMultiplier = await db + .insertInto('multiplier') + .values({ + userAddressId: userAddress.id, + type: 'SWAP', + value: record.multipliers.swapMultiplier, + }) + .returningAll() + .executeTakeFirstOrThrow() + } else { + await db + .updateTable('multiplier') + .set('value', record.multipliers.swapMultiplier) + .where('id', '=', swapMultiplier.id) + .execute() + } + + let timeOpenMultiplier = positionMultipliers.find((m) => m.type === 'TIME_OPEN') + + if (!timeOpenMultiplier) { + timeOpenMultiplier = await db + .insertInto('multiplier') + .values({ + positionId: position.id, + type: 'TIME_OPEN', + value: record.multipliers.timeOpenMultiplier, + }) + .returningAll() + .executeTakeFirstOrThrow() + } else { + await db + .updateTable('multiplier') + .set('value', record.multipliers.timeOpenMultiplier) + .where('id', '=', timeOpenMultiplier.id) + .execute() + } + + let automationProtectionMultiplier = positionMultipliers.find( + (m) => m.type === 'AUTOMATION', + ) + + if (!automationProtectionMultiplier) { + automationProtectionMultiplier = await db + .insertInto('multiplier') + .values({ + positionId: position.id, + type: 'AUTOMATION', + value: record.multipliers.automationProtectionMultiplier, + }) + .returningAll() + .executeTakeFirstOrThrow() + } else { + await db + .updateTable('multiplier') + .set('value', record.multipliers.automationProtectionMultiplier) + .where('id', '=', automationProtectionMultiplier.id) + .execute() + } + + const lazyVaultMultiplier = positionMultipliers.find((m) => m.type === 'LAZY_VAULT') + if (!lazyVaultMultiplier) { + await db + .insertInto('multiplier') + .values({ + positionId: position.id, + type: 'LAZY_VAULT', + value: record.multipliers.lazyVaultMultiplier, + }) + .execute() + } else { + await db + .updateTable('multiplier') + .set('value', record.multipliers.lazyVaultMultiplier) + .where('id', '=', lazyVaultMultiplier.id) + .execute() + } + }), + ) + + logger.info(`Processed: Chunk ${i} of ${chunkedPoints.length}`) + } + + await db + .insertInto('updatePointsChangelog') + .values({ + endTimestamp: new Date(endTimestamp * 1000), + startTimestamp: new Date(startTimestamp * 1000), + metadata: { + positions: points.length, + }, + }) + .executeTakeFirstOrThrow() + + await db + .updateTable('updatePointsLastRun') + .set('lastTimestamp', new Date(endTimestamp * 1000)) + .where('id', '=', LAST_RUN_ID) + .execute() + } catch (e) { + logger.error('Failed to lock update points', { error: e }) + return + } finally { + logger.info('Releasing lock') + await db + .updateTable('updatePointsLock') + .set('isLocked', false) + .where('id', '=', LOCK_ID) + .executeTakeFirst() + } +} + +export default handler diff --git a/background-jobs/update-rays-cron-function/src/point-accrual.ts b/background-jobs/update-rays-cron-function/src/point-accrual.ts new file mode 100644 index 0000000000..567cadbbb7 --- /dev/null +++ b/background-jobs/update-rays-cron-function/src/point-accrual.ts @@ -0,0 +1,478 @@ +import { + MigrationEvent, + Position, + RecentSwap, + START_POINTS_TIMESTAMP, + SummerPointsSubgraphClient, + User, + UsersData, +} from '@summerfi/summer-events-subgraph' +import { Logger } from '@aws-lambda-powertools/logger' + +type PositionPoints = { + positionId: string + vaultId: number + user: string + protocol: string + marketId: string + points: { + openPositionsPoints: number + migrationPoints: number + swapPoints: number + } + netValue: number + multipliers: { + protocolBoostMultiplier: number + swapMultiplier: number + timeOpenMultiplier: number + automationProtectionMultiplier: number + lazyVaultMultiplier: number + } +}[] + +/** + * Service for fetching summer features. + */ +export class SummerPointsService { + private SECONDS_PER_YEAR = 365 * 24 * 60 * 60 + private SECONDS_PER_DAY = 86400 + private SECONDS_PER_HOUR = 3600 + private TWO_HOURS_IN_SECONDS = 2 * 60 * 60 + private MIGRATION_POINTS_FRACTION = 0.2 + private CORRELATED_SWAP_POINTS_FRACTION = 0.06 + private UNCORRELATED_SWAP_POINTS_FRACTION = 0.2 + private NET_VALUE_MULTIPLIER_THRESHOLD = 5000 + + private AUTOMATION_OPTIMISATION_MULTIPLIER = 1.5 + private AUTOMATION_PROTECTION_MULTIPLIER = 1.1 + + /** + * Creates an instance of SummerPointsService. + * @param clients - An array of clients for fetching data from the summer points subgraph. + * @param logger - The logger instance. + */ + constructor( + private clients: SummerPointsSubgraphClient[], + private logger: Logger, + ) {} + + async accruePoints(startTimestamp: number, endTimestamp: number): Promise { + const results = await Promise.all( + this.clients.map((client) => client.getUsersPoints({ startTimestamp, endTimestamp })), + ) + + const usersMap: Record = {} + + results.forEach((result) => { + result.users.forEach((user) => { + if (!usersMap[user.id]) { + // If the user doesn't exist in the map, add them + usersMap[user.id] = user + } else { + // If the user does exist, merge the data + usersMap[user.id].positions = [...usersMap[user.id].positions, ...user.positions] + usersMap[user.id].swaps = [...usersMap[user.id].swaps, ...user.swaps] + } + }) + }) + + return this.getBasisPointsForUsers(Object.values(usersMap), startTimestamp, endTimestamp) + } + + /** + * Calculates the points per USD per year based on the given USD amount. + * @param usdAmount - The USD amount for which to calculate the points. + * @returns The points per USD per year. + */ + getPointsPerUsdPerYear(usdAmount: number): number { + const a = 1.0005 + const b = 0.99999 + const c = 138.1456715 + const d = 1 + const x0 = 10000 + const frac = 2000 + return usdAmount <= x0 ? Math.pow(a * b, usdAmount) / frac : (c * Math.pow(d, usdAmount)) / frac + } + + /** + * Calculates the points per USD per second. + * + * @param usdAmount - The amount in USD. + * @returns The points per USD per second. + */ + private getPointsPerUsdPerSecond(usdAmount: number): number { + return this.getPointsPerUsdPerYear(usdAmount) / this.SECONDS_PER_YEAR + } + + /** + * Calculates the points per USD per day based on the given USD amount. + * @param usdAmount - The USD amount for which to calculate the points. + * @returns The points per USD per day. + */ + private getPointsPerUsdPerDay(usdAmount: number): number { + return this.getPointsPerUsdPerSecond(usdAmount) * this.SECONDS_PER_DAY + } + + /** + * Calculates the points per USD per hour based on the given USD amount. + * @param usdAmount - The USD amount for which to calculate the points. + * @returns The points per USD per hour. + */ + private getPointsPerUsdPerHour(usdAmount: number): number { + return this.getPointsPerUsdPerSecond(usdAmount) * this.SECONDS_PER_HOUR + } + + /** + * Calculates the swap multiplier based on the number of swaps. + * @param swaps - An array of swap objects containing a timestamp. + * @returns The swap multiplier. + */ + getSwapMultiplier(swaps: unknown[]): number { + const swapCount = swaps.length + if (swapCount > 25) { + return 5 + } else if (swapCount > 10) { + return 2 + } else if (swapCount > 5) { + return 1.5 + } else { + return 1 + } + } + + /** + * Calculates the multiplier for the lazy vault based on the given position. + * If the position has a lazy vault trigger, the multiplier is 1.2, otherwise it is 1. + * + * @param position - The position to calculate the multiplier for. + * @returns The multiplier for the lazy vault. + */ + getLazyVaultMultiplier(position: Position): number { + const hasLazyVault = position.protocol === 'erc4626' + return hasLazyVault ? 1.2 : 1 + } + + /** + * Calculates the basis points earned by users for a given time period. + * @param usersData - The data of the users. + * @param startTimestamp - The start timestamp of the time period. + * @param endTimestamp - The end timestamp of the time period. + * @returns The basis points earned by users. + */ + getBasisPointsForUsers( + users: UsersData, + startTimestamp: number, + endTimestamp: number, + ): PositionPoints { + const pointsEarned = users.map((user) => { + const swapMultiplier = this.getSwapMultiplier(user.swaps) + const protocolBoostMultiplier = this.getNetValueMutliplier(user) + + return user.positions.map((position) => { + const openPositionsPoints = this.getOpenPositionsPoints( + startTimestamp, + position, + endTimestamp, + ) + const migrationPoints = this.getMigrationPoints(position.migration) + const swapPoints = swapMultiplier * this.getSwapPoints(user.recentSwaps) + + const timeOpenMultiplier = this.getTimeOpenMultiplier(position, endTimestamp) + const automationProtectionMultiplier = this.getAutomationProtectionMultiplier(position) + const lazyVaultMultiplier = this.getLazyVaultMultiplier(position) + const totalMultiplier = + protocolBoostMultiplier * + timeOpenMultiplier * + automationProtectionMultiplier * + lazyVaultMultiplier + + return { + vaultId: position.account.vaultId, + positionId: position.id, + protocol: position.protocol, + marketId: position.marketId, + user: user.id, + points: { + openPositionsPoints: totalMultiplier * openPositionsPoints, + migrationPoints: migrationPoints, + swapPoints: swapPoints, + }, + netValue: position.netValue, + multipliers: { + protocolBoostMultiplier, + swapMultiplier, + timeOpenMultiplier, + automationProtectionMultiplier, + lazyVaultMultiplier, + }, + } + }) + }) + + return pointsEarned + .flat() + .sort((a, b) => b.points.openPositionsPoints - a.points.openPositionsPoints) + } + + /** + * Calculates the points for open positions within a given time range. + * + * @remarks The points are calculated based on the net value of the position and the time range. + * if there are no summer events, the points are calculated based on the net value of the position. + * if thre are summer events - for each time range between events, the points are calculated based on the net value of the position before the event + * + * @param startTimestamp - The start timestamp of the time range. + * @param position - The position object containing summer events and net value. + * @param endTimestamp - The end timestamp of the time range. + * @returns The total points for the open positions within the specified time range. + */ + private getOpenPositionsPoints(startTimestamp: number, position: Position, endTimestamp: number) { + let previousTimestamp = startTimestamp + let openPositionsPoints = 0 + + for (const event of position.summerEvents) { + const timeDifference = Math.min( + event.timestamp - previousTimestamp, + this.TWO_HOURS_IN_SECONDS, + ) + const pointsPerSecond = this.getPointsPerUsdPerSecond(event.netValueBefore) + openPositionsPoints += pointsPerSecond * timeDifference * event.netValueBefore + + previousTimestamp = event.timestamp + } + + // Calculate points for the time period after the last event + const timeDifference = Math.min(endTimestamp - previousTimestamp, this.TWO_HOURS_IN_SECONDS) + + const pointsPerSecond = this.getPointsPerUsdPerSecond(position.netValue) + + openPositionsPoints += pointsPerSecond * timeDifference * position.netValue + return openPositionsPoints + } + + /** + * Calculates the migration points based on the provided migration events. + * + * @remarks The migration points are calculated based on the net value after the migration event. + * + * @param events - An array of migration events. + * @returns The total migration points. + */ + getMigrationPoints(events: MigrationEvent[]): number { + let migrationPoints = 0 + for (const event of events) { + const pointsPerYear = this.getPointsPerUsdPerYear(event.netValueAfter) + migrationPoints += pointsPerYear * this.MIGRATION_POINTS_FRACTION + } + + return migrationPoints + } + + /** + * Calculates the total swap points for the given array of recent swaps. + * + * @remarks The swap points are calculated based on the amount in USD of the swap and whether the assets are correlated. + * @param swaps - An array of recent swaps. + * @returns The total swap points. + */ + getSwapPoints(swaps: RecentSwap[]): number { + let points = 0 + for (const swap of swaps) { + const pointsPerYear = this.getPointsPerUsdPerYear(swap.amountInUSD) + const isCorrelatedAsset = this.isCorrelatedAsset(swap.assetIn.symbol, swap.assetOut.symbol) + const fraction = isCorrelatedAsset + ? this.CORRELATED_SWAP_POINTS_FRACTION + : this.UNCORRELATED_SWAP_POINTS_FRACTION + points += pointsPerYear * fraction + } + return points + } + + /** + * Checks if two symbols are correlated. + * @param symbolA - The first symbol. + * @param symbolB - The second symbol. + * @returns True if the symbols are correlated. + */ + isCorrelatedAsset(symbolA: string, symbolB: string) { + const correlatedAssetMatrix = [ + [ + 'SUSDE', + 'USDE', + 'DAI', + 'USDT', + 'USDC', + 'PYUSD', + 'FRAX', + 'LUSD', + 'GUSD', + 'CRVUSD', + 'SDAI', + 'AETHSDAI', + 'AETHUSDC', + 'AETHUSDT', + 'AETHDAI', + 'AETHPYUSD', + 'AETHLUSD', + 'AUSDC', + 'ADAI', + 'AUSDT', + 'CUSDCV3', + 'CDAI', + 'CUSDC', + 'SUSD', + 'USDC.E', + 'GHO', + ], + [ + 'WSTETH', + 'RETH', + 'CBETH', + 'STETH', + 'AETHWSTETH', + 'AETHWETH', + 'AETHRETH', + 'AETHCBETH', + 'ASETH', + 'AWETH', + 'CETH', + 'CWETHV3', + 'WEETH', + 'WETH', + 'WETH.E', + 'WETHV3', + 'WETHV2', + 'WETHV1', + 'ETH', + 'apxETH', + ], + ['WBTC', 'TBTC', 'AWBTC', 'AETHWBTC'], + // Add more arrays here to expand the matrix in the future + ] + + // Iterate over each row in the matrix + for (let i = 0; i < correlatedAssetMatrix.length; i++) { + // Check if both symbols are in the same row + if ( + correlatedAssetMatrix[i].includes(symbolA.toUpperCase()) && + correlatedAssetMatrix[i].includes(symbolB.toUpperCase()) + ) { + return true + } + } + + // If we haven't found both symbols in the same row, they're not correlated + return false + } + + /** + * Calculates the time open multiplier based on the position's first event timestamp and the end timestamp. + * @param position - The position object. + * @param endTimestamp - The end timestamp. + * @returns The time open multiplier. + */ + getTimeOpenMultiplier(position: Position, endTimestamp: number): number { + if (!position.firstEvent.length) { + // there is one position with no first event, but it has net value + // it's due to the fact it was opened in a safe multicall transaction + // that included multiple summer.fi operations + return 1 + } + const firstEvent = position.firstEvent[0].timestamp + const lastEvent = endTimestamp + const startTime = Math.max(firstEvent, START_POINTS_TIMESTAMP) + const timeOpen = lastEvent - startTime + + if (timeOpen > 180 * this.SECONDS_PER_DAY) { + return 2 + } else if (timeOpen > 90 * this.SECONDS_PER_DAY) { + return 1.5 + } else if (timeOpen > 30 * this.SECONDS_PER_DAY) { + return 1.2 + } else { + return 1 + } + } + + protectionKinds = ['stoploss', 'basicsell'] + optimisationKinds = ['takeprofit', 'basicbuy'] + + /** + * Calculates the automation protection multiplier based on the given position. + * + * 1.1 for protection + * 1.5 for optimisation + * + * multipliers stack + * @param position - The position for which to calculate the automation protection multiplier. + * @returns The automation protection multiplier. + */ + getAutomationProtectionMultiplier(position: Position): number { + const hasProtectionTrigger = position.activeTriggers.some((trigger) => + this.protectionKinds.some((kind) => trigger.kind.toLowerCase().includes(kind.toLowerCase())), + ) + const hasOptimisationTrigger = position.activeTriggers.some((trigger) => + this.optimisationKinds.some((kind) => + trigger.kind.toLowerCase().includes(kind.toLowerCase()), + ), + ) + + let protectionMultiplier = 1 + if (hasProtectionTrigger) { + protectionMultiplier *= this.AUTOMATION_PROTECTION_MULTIPLIER + } + if (hasOptimisationTrigger) { + protectionMultiplier *= this.AUTOMATION_OPTIMISATION_MULTIPLIER + } + + return protectionMultiplier + } + + /** + * Calculates the net value multiplier based on the user's positions. + * + * @remarks The net value multiplier is based on the number of protocols with cumulative net value per protocol above 5000$. + * @param user - The user object containing positions. + * @returns The net value multiplier. + */ + getNetValueMutliplier(user: User): number { + const protocolSums: Record = {} + + user.positions.forEach((position) => { + if (!protocolSums[position.protocol]) { + protocolSums[position.protocol] = 0 + } + protocolSums[position.protocol] += position.netValue + }) + + let eligibleProtocolCount = 0 + for (const protocol in protocolSums) { + if (protocolSums[protocol] > this.NET_VALUE_MULTIPLIER_THRESHOLD) { + eligibleProtocolCount++ + } + } + + let protocolMultiplier + switch (eligibleProtocolCount) { + case 1: + protocolMultiplier = 1 + break + case 2: + protocolMultiplier = 1.2 + break + case 3: + protocolMultiplier = 1.5 + break + case 4: + protocolMultiplier = 2 + break + case 5: + protocolMultiplier = 3 + break + default: + protocolMultiplier = 1 + } + + return protocolMultiplier + } +} diff --git a/background-jobs/update-rays-cron-function/src/position-id-resolver.ts b/background-jobs/update-rays-cron-function/src/position-id-resolver.ts new file mode 100644 index 0000000000..af8895fba8 --- /dev/null +++ b/background-jobs/update-rays-cron-function/src/position-id-resolver.ts @@ -0,0 +1,58 @@ +// mainnet +// -0x000009818d53763c701ba86586152c667ac3acdb +// -0xdcc46571a9471dd973e4043513175712df873920 +// -aave_v2 +// -0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 +// -Lend + +import { ChainId, ChainIDByNetwork, Network } from '@summerfi/serverless-shared' +import { PositionType, Protocol } from '@summerfi/rays-db/dist/database-types' + +export interface PositionId { + chainId: ChainId + positionType: PositionType + protocol: Protocol + marketId: string + address: string +} + +const PROTOCOLS: Record = { + aave_v2: null, + aave_v3: null, + ajna: null, + erc4626: null, + maker: null, + morphoblue: null, + spark: null, +} + +const keys = Object.keys(PROTOCOLS) + +export const positionIdResolver = (positionId: string): PositionId => { + const elements = positionId.split('-') + const network = elements[0] + // const userAddress = elements[1] + const address = elements[2] + const protocol = elements[3] + const marketId = elements[4] + const positionType = elements[5] + // check if protocol is of type of Protocol + const isValidProtocol = keys.includes(protocol as Protocol) + + if (!isValidProtocol) { + throw new Error(`Invalid protocol: ${protocol}`) + } + + const chainId = ChainIDByNetwork[network.split(':')[0] as Network] + if (!chainId) { + throw new Error(`Invalid network: ${network}`) + } + + return { + chainId: chainId, + positionType: positionType as PositionType, + protocol: protocol as Protocol, + marketId, + address, + } +} diff --git a/background-jobs/update-rays-cron-function/sst-env.d.ts b/background-jobs/update-rays-cron-function/sst-env.d.ts new file mode 100644 index 0000000000..61de7a5d49 --- /dev/null +++ b/background-jobs/update-rays-cron-function/sst-env.d.ts @@ -0,0 +1 @@ +import '../../.sst/types' diff --git a/background-jobs/update-rays-cron-function/tsconfig.json b/background-jobs/update-rays-cron-function/tsconfig.json new file mode 100644 index 0000000000..caebdb3868 --- /dev/null +++ b/background-jobs/update-rays-cron-function/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@summerfi/typescript-config/tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "include": ["src/**/*.ts", "sst-env.d.ts"], + "exclude": ["node_modules", "**/*.spec.ts"] +} diff --git a/packages/rays-db/package.json b/packages/rays-db/package.json index 90f2ed6fad..112fa9d784 100644 --- a/packages/rays-db/package.json +++ b/packages/rays-db/package.json @@ -14,11 +14,10 @@ "migrate:down": "tsx src/scripts/local-migrate-down.ts" }, "dependencies": { - "@aws-sdk/client-rds-data": "^3.565.0", "kysely": "^0.27.3", - "kysely-data-api": "^0.2.1", "kysely-postgres-js": "^2.0.0", - "postgres": "^3.4.4" + "postgres": "^3.4.4", + "@summerfi/abstractions": "workspace:*" }, "devDependencies": { "@summerfi/eslint-config": "workspace:*", diff --git a/packages/rays-db/src/database-types.ts b/packages/rays-db/src/database-types.ts index ec2c7da72f..629510b00e 100644 --- a/packages/rays-db/src/database-types.ts +++ b/packages/rays-db/src/database-types.ts @@ -23,7 +23,7 @@ export type Numeric = ColumnType export type PositionType = 'Lend' | 'Supply' -export type Protocol = 'AAVE_v2' | 'AAVE_v3' | 'Ajna' | 'ERC_4626' | 'MorphoBlue' | 'Spark' +export type Protocol = 'aave_v2' | 'aave_v3' | 'ajna' | 'erc4626' | 'maker' | 'morphoblue' | 'spark' export type Timestamp = ColumnType @@ -52,7 +52,7 @@ export interface Multiplier { type: string updatedAt: Generated userAddressId: number | null - value: number + value: Numeric } export interface PointsDistribution { @@ -68,27 +68,35 @@ export interface PointsDistribution { } export interface Position { + address: string chainId: number createdAt: Generated externalId: string id: Generated market: string protocol: Protocol - proxyId: number type: Generated updatedAt: Generated userAddressId: number + vaultId: number } -export interface Proxy { - address: string - chainId: number +export interface UpdatePointsChangelog { createdAt: Generated + endTimestamp: Timestamp id: Generated - managedBy: string - type: string - updatedAt: Generated - userAddressId: number + metadata: Json + startTimestamp: Timestamp +} + +export interface UpdatePointsLastRun { + id: string + lastTimestamp: Generated +} + +export interface UpdatePointsLock { + id: string + isLocked: Generated } export interface UserAddress { @@ -106,6 +114,8 @@ export interface Database { multiplier: Multiplier pointsDistribution: PointsDistribution position: Position - proxy: Proxy + updatePointsChangelog: UpdatePointsChangelog + updatePointsLastRun: UpdatePointsLastRun + updatePointsLock: UpdatePointsLock userAddress: UserAddress } diff --git a/packages/rays-db/src/index.ts b/packages/rays-db/src/index.ts index 6de4322649..f3f791c54e 100644 --- a/packages/rays-db/src/index.ts +++ b/packages/rays-db/src/index.ts @@ -1,44 +1,39 @@ import { Database } from './database-types' import { CamelCasePlugin, Kysely } from 'kysely' -import { DataApiDialect } from 'kysely-data-api' -import { RDSData } from '@aws-sdk/client-rds-data' import { PostgresJSDialect } from 'kysely-postgres-js' import postgres from 'postgres' +import { Logger } from '@summerfi/abstractions' +import { getUpdateLockService, UpdateLockService } from './services' export interface PgRaysDbConfig { connectionString: string + logger: Logger } -export interface DataApiRaysDbConfig { - secretArn: string - resourceArn: string - database: string - client: RDSData +export interface RaysDB { + db: Kysely + services: { + updateLockService: UpdateLockService + } } -export const getRaysDB = async ( - config: PgRaysDbConfig | DataApiRaysDbConfig, -): Promise> => { - if ('connectionString' in config) { - const pg = postgres(config.connectionString) - return new Kysely({ - dialect: new PostgresJSDialect({ - postgres: pg, - }), - plugins: [new CamelCasePlugin()], - }) - } +export * from './database-types' +export * from './services' - return new Kysely({ - dialect: new DataApiDialect({ - mode: 'postgres', - driver: { - database: config.database, - secretArn: config.secretArn, - resourceArn: config.resourceArn, - client: config.client, - }, +export const getRaysDB = async (config: PgRaysDbConfig): Promise => { + const pg = postgres(config.connectionString) + const db = new Kysely({ + dialect: new PostgresJSDialect({ + postgres: pg, }), plugins: [new CamelCasePlugin()], }) + const updateLockService = getUpdateLockService({ db, logger: config.logger }) + + return { + db, + services: { + updateLockService, + }, + } } diff --git a/packages/rays-db/src/migrations/001_init.mts b/packages/rays-db/src/migrations/001_init.mts index 33f4177d9a..b43f93d671 100644 --- a/packages/rays-db/src/migrations/001_init.mts +++ b/packages/rays-db/src/migrations/001_init.mts @@ -55,31 +55,7 @@ export async function up(db: Kysely) { FOR EACH ROW EXECUTE FUNCTION update_modified_column();`.execute(db) - console.log('Creating table proxy') - await db.schema.createTable('proxy') - .addColumn('id', 'serial', (col) => col.primaryKey()) - .addColumn('address', 'varchar(50)', (col) => col.notNull()) - .addColumn('chain_id', 'integer', (col) => col.notNull()) - .addColumn('type', 'varchar(100)', (col) => col.notNull()) - .addColumn('managed_by', 'varchar(100)', (col) => col.notNull()) - .addColumn('user_address_id', 'integer', (col) => col.notNull().references('user_address.id').onDelete('restrict')) - .addColumn('created_at', 'timestamptz', (col) => col.notNull().defaultTo(sql`NOW - ()`)) - .addColumn('updated_at', 'timestamptz', (col) => col.notNull().defaultTo(sql`NOW - ()`)) - .addUniqueConstraint('proxy_address_chain_id_unique', ['address', 'chain_id']) - .execute() - - await db.schema.createIndex('proxy_address_chain_id_index').on('proxy').columns(['address', 'chain_id']).execute() - - await sql`CREATE TRIGGER update_proxy_updated_at - BEFORE UPDATE - ON proxy - FOR EACH ROW - EXECUTE FUNCTION update_modified_column();`.execute(db) - - - await db.schema.createType('protocol').asEnum(['AAVE_v3', 'MorphoBlue', 'Ajna', 'Spark', 'AAVE_v2', 'ERC_4626']).execute() + await db.schema.createType('protocol').asEnum(['aave_v2', 'morphoblue', 'ajna', 'spark', 'aave_v3', 'erc4626', 'maker']).execute() await db.schema.createType('position_type').asEnum(['Supply', 'Lend']).execute() @@ -92,15 +68,17 @@ export async function up(db: Kysely) { .addColumn('chain_id', 'integer', (col) => col.notNull()) .addColumn('market', 'varchar(255)', (col) => col.notNull()) .addColumn('type', sql`position_type`, (col) => col.notNull().defaultTo('Lend')) + .addColumn('address', 'varchar(50)', (col) => col.notNull()) + .addColumn('vault_id', 'integer', (col) => col.notNull()) .addColumn('created_at', 'timestamptz', (col) => col.notNull().defaultTo(sql`NOW ()`)) .addColumn('updated_at', 'timestamptz', (col) => col.notNull().defaultTo(sql`NOW ()`)) .addColumn('user_address_id', 'integer', (col) => col.notNull().references('user_address.id').onDelete('restrict')) - .addColumn('proxy_id', 'integer', (col) => col.notNull().references('proxy.id').onDelete('restrict')) .execute() await db.schema.createIndex('position_external_id_index').on('position').columns(['external_id']).execute() + await db.schema.createIndex('position_address_index').on('position').columns(['address']).execute() await sql`CREATE TRIGGER update_position_updated_at BEFORE UPDATE @@ -158,7 +136,7 @@ export async function up(db: Kysely) { await db.schema.createTable('multiplier') .addColumn('id', 'serial', (col) => col.primaryKey()) - .addColumn('value', 'integer', (col) => col.notNull()) + .addColumn('value', 'decimal(6, 4)', (col) => col.notNull()) .addColumn('type', 'varchar(100)', (col) => col.notNull()) .addColumn('description', 'varchar') .addColumn('created_at', 'timestamptz', (col) => col.notNull().defaultTo(sql`NOW @@ -212,11 +190,6 @@ export async function down(db: Kysely) { await db.schema.dropType('position_type').execute() await db.schema.dropType('protocol').execute() - console.log(`Dropping table proxy`) - await sql`DROP TRIGGER IF EXISTS update_proxy_updated_at ON proxy`.execute(db) - await db.deleteFrom('proxy').execute() - await db.schema.dropTable('proxy').execute() - console.log(`Dropping table user_address`) await sql`DROP TRIGGER IF EXISTS update_user_address_updated_at ON user_address`.execute(db) await db.deleteFrom('user_address').execute() diff --git a/packages/rays-db/src/migrations/002_update_points_log.mts.ts b/packages/rays-db/src/migrations/002_update_points_log.mts.ts new file mode 100644 index 0000000000..1621993d8d --- /dev/null +++ b/packages/rays-db/src/migrations/002_update_points_log.mts.ts @@ -0,0 +1,56 @@ +import { Kysely, sql } from 'kysely' + +/** + * @param db {Kysely} + */ +export async function up(db: Kysely) { + await db.schema + .createTable('update_points_changelog') + .addColumn('id', 'serial', (col) => col.primaryKey()) + .addColumn('metadata', 'jsonb', (col) => col.notNull()) + .addColumn('start_timestamp', 'timestamptz', (col) => col.notNull()) + .addColumn('end_timestamp', 'timestamptz', (col) => col.notNull()) + .addColumn('created_at', 'timestamptz', (col) => + col.notNull().defaultTo(sql`NOW + ()`), + ) + .execute() + + await db.schema + .createTable('update_points_lock') + .addColumn('id', 'varchar(50)', (col) => col.primaryKey()) + .addColumn('is_locked', 'boolean', (col) => col.notNull().defaultTo(false)) + .execute() + + await db + .insertInto('update_points_lock') + .values({ id: 'update_points_lock', is_locked: false }) + .execute() + + await db.schema + .createTable('update_points_last_run') + .addColumn('id', 'varchar(50)', (col) => col.primaryKey()) + .addColumn('last_timestamp', 'timestamptz', (col) => + col.notNull().defaultTo(sql`NOW + ()`), + ) + .execute() + + await db + .insertInto('update_points_last_run') + .values({ + id: 'update_points_last_run', + last_timestamp: sql`NOW + ()`, + }) // That needs to be changed to the proper date. + .execute() +} + +/** + * @param db {Kysely} + */ +export async function down(db: Kysely) { + await db.schema.dropTable('update_points_last_run').execute() + await db.schema.dropTable('update_points_changelog').execute() + await db.schema.dropTable('update_points_lock').execute() +} diff --git a/packages/rays-db/src/scripts/local-config.ts b/packages/rays-db/src/scripts/local-config.ts index d9de6caabc..73e75aa5a4 100644 --- a/packages/rays-db/src/scripts/local-config.ts +++ b/packages/rays-db/src/scripts/local-config.ts @@ -6,10 +6,12 @@ import { PostgresJSDialect } from 'kysely-postgres-js' import postgres from 'postgres' export function getMigrator() { + const { RAYS_DB_CONNECTION_STRING } = process.env + if (!RAYS_DB_CONNECTION_STRING) { + throw new Error('RAYS_DB_CONNECTION_STRING is not set') + } const dialect = new PostgresJSDialect({ - postgres: postgres( - process.env.RAYS_DB_CONNECTION_STRING || 'postgres://user:password@localhost:5500/rays', - ), + postgres: postgres(RAYS_DB_CONNECTION_STRING), }) const db = new Kysely({ diff --git a/packages/rays-db/src/services/index.ts b/packages/rays-db/src/services/index.ts new file mode 100644 index 0000000000..07886a9d1d --- /dev/null +++ b/packages/rays-db/src/services/index.ts @@ -0,0 +1 @@ +export * from './update-lock-service' diff --git a/packages/rays-db/src/services/update-lock-service.ts b/packages/rays-db/src/services/update-lock-service.ts new file mode 100644 index 0000000000..09e2da260e --- /dev/null +++ b/packages/rays-db/src/services/update-lock-service.ts @@ -0,0 +1,42 @@ +import { Kysely } from 'kysely' +import { Database } from '../database-types' +import { Logger } from '@summerfi/abstractions' + +export interface UpdateLockServiceParams { + db: Kysely + logger: Logger +} + +export interface UpdateLockService { + getLock: () => Promise<{ isLocked: boolean }> + setLock: () => Promise + unlock: () => Promise +} + +const UPDATE_POINTS_LOCK_ID = 'update_points_lock' + +export const getUpdateLockService = ({ db }: UpdateLockServiceParams): UpdateLockService => { + return { + getLock: async () => { + return await db + .selectFrom('updatePointsLock') + .where('id', '=', UPDATE_POINTS_LOCK_ID) + .select('isLocked') + .executeTakeFirstOrThrow() + }, + setLock: async () => { + await db + .updateTable('updatePointsLock') + .set('isLocked', true) + .where('id', '=', UPDATE_POINTS_LOCK_ID) + .executeTakeFirstOrThrow() + }, + unlock: async () => { + await db + .updateTable('updatePointsLock') + .set('isLocked', false) + .where('id', '=', UPDATE_POINTS_LOCK_ID) + .executeTakeFirstOrThrow() + }, + } +} diff --git a/packages/serverless-shared/src/domain-types.ts b/packages/serverless-shared/src/domain-types.ts index 738ff56bc9..aa32aecc80 100644 --- a/packages/serverless-shared/src/domain-types.ts +++ b/packages/serverless-shared/src/domain-types.ts @@ -3,7 +3,6 @@ export type PoolId = `0x${string}` export enum Network { MAINNET = 'mainnet', - GOERLI = 'goerli', ARBITRUM = 'arbitrum', OPTIMISM = 'optimism', BASE = 'base', @@ -12,15 +11,10 @@ export enum Network { export enum NetworkNames { ethereumMainnet = 'ethereum', - ethereumGoerli = 'ethereum_goerli', arbitrumMainnet = 'arbitrum', - arbitrumGoerli = 'arbitrum_goerli', polygonMainnet = 'polygon', - polygonMumbai = 'polygon_mumbai', optimismMainnet = 'optimism', - optimismGoerli = 'optimism_goerli', baseMainnet = 'base', - baseGoerli = 'base_goerli', } export enum ChainId { @@ -46,6 +40,14 @@ export const NetworkByChainID: Record = { [ChainId.SEPOLIA]: Network.SEPOLIA, } +export const ChainIDByNetwork: Record = { + [Network.MAINNET]: ChainId.MAINNET, + [Network.ARBITRUM]: ChainId.ARBITRUM, + [Network.OPTIMISM]: ChainId.OPTIMISM, + [Network.BASE]: ChainId.BASE, + [Network.SEPOLIA]: ChainId.SEPOLIA, +} + export enum ProtocolId { AAVE_V2 = 'aave-v2', AAVE_V3 = 'aave-v3', diff --git a/packages/summer-events-subgraph/.eslintrc.cjs b/packages/summer-events-subgraph/.eslintrc.cjs new file mode 100644 index 0000000000..b957f50888 --- /dev/null +++ b/packages/summer-events-subgraph/.eslintrc.cjs @@ -0,0 +1,10 @@ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + ignorePatterns: ['src/types/graphql/**'], + extends: ['@summerfi/eslint-config/library.cjs'], + parser: '@typescript-eslint/parser', + parserOptions: { + project: true, + }, +} diff --git a/packages/summer-events-subgraph/graphql.config.yml b/packages/summer-events-subgraph/graphql.config.yml new file mode 100644 index 0000000000..1da196d8f1 --- /dev/null +++ b/packages/summer-events-subgraph/graphql.config.yml @@ -0,0 +1,32 @@ +schema: schema.graphql +documents: './queries/**/*.graphql' +config: + namingConvention: + enumValues: keep +generates: + src/types/graphql/generated.ts: + plugins: + - add: + content: + - '// @ts-nocheck' + - '// This file was automatically generated and should not be edited.' + - typescript + - typescript-operations: + strictScalars: true + immutableTypes: false + scalars: + BigDecimal: number + BigInt: number + Int8: number + BooleanType: boolean + CustomData: Record + Date: string + DateTime: string + FloatType: number + IntType: number + ItemId: string + JsonField: unknown + Bytes: string + MetaTagAttributes: Record + UploadId: string + - typed-document-node diff --git a/packages/summer-events-subgraph/package.json b/packages/summer-events-subgraph/package.json new file mode 100644 index 0000000000..81dc5fde6a --- /dev/null +++ b/packages/summer-events-subgraph/package.json @@ -0,0 +1,27 @@ +{ + "name": "@summerfi/summer-events-subgraph", + "version": "1.0.0", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "test": "jest --passWithNoTests", + "build": "tsc -b -v", + "dev": "tsc -b -w", + "prebuild": "pnpm run generate-ts-types", + "generate-ts-types": "graphql-codegen --config graphql.config.yml", + "lint": "eslint .", + "lint:fix": "eslint . --fix" + }, + "dependencies": { + "graphql-request": "^6.1.0", + "@summerfi/abstractions": "workspace:*", + "@summerfi/serverless-shared": "workspace:*" + }, + "devDependencies": { + "@summerfi/eslint-config": "workspace:*", + "@summerfi/typescript-config": "workspace:*", + "@types/node": "^20.12.7", + "eslint": "^8.57.0" + } +} diff --git a/packages/summer-events-subgraph/queries/get-points.graphql b/packages/summer-events-subgraph/queries/get-points.graphql new file mode 100644 index 0000000000..f9715b1017 --- /dev/null +++ b/packages/summer-events-subgraph/queries/get-points.graphql @@ -0,0 +1,76 @@ +query SummerPoints( + $first: Int! + $lastId: Bytes! + $pointsStartTimestamp: BigInt! + $startTimestamp: BigInt! + $endTimestamp: BigInt! +) { + users( + orderBy: id + first: $first + where: { openPositions_gt: 0, id_gt: $lastId } + ) { + id + positions(where: { netValue_gt: 0 }) { + account { + vaultId + address + } + id + protocol + marketId + netValue + summerEvents( + where: { timestamp_gt: $startTimestamp, timestamp_lt: $endTimestamp } + ) { + netValueBefore + netValueAfter + timestamp + } + migration: summerEvents( + where: { + timestamp_gt: $startTimestamp + timestamp_lt: $endTimestamp + kind_contains_nocase: "migrate" + } + ) { + netValueBefore + netValueAfter + timestamp + } + activeTriggers: triggers( + where: { + or: [ + { removedBlock: null, executedBlock: null } + { continuous: true, removedBlock: null } + ] + } + ) { + id + kind + } + firstEvent: summerEvents( + first: 1 + orderBy: timestamp + orderDirection: asc + ) { + timestamp + } + } + swaps(where: { timestamp_gt: $pointsStartTimestamp }) { + id + } + recentSwaps: swaps( + where: { timestamp_gt: $startTimestamp, timestamp_lt: $endTimestamp } + ) { + id + amountInUSD + assetIn { + symbol + } + assetOut { + symbol + } + } + } +} diff --git a/packages/summer-events-subgraph/schema.graphql b/packages/summer-events-subgraph/schema.graphql new file mode 100644 index 0000000000..5e0780cb01 --- /dev/null +++ b/packages/summer-events-subgraph/schema.graphql @@ -0,0 +1,4693 @@ +""" +Marks the GraphQL type as indexable entity. Each type that should be an entity +is required to be annotated with this directive. +""" +directive @entity on OBJECT + +"""Defined a Subgraph ID for an object type""" +directive @subgraphId(id: String!) on OBJECT + +""" +creates a virtual field on the entity that may be queried but cannot be set manually through the mappings API. +""" +directive @derivedFrom(field: String!) on FIELD_DEFINITION + +type _Block_ { + """The hash of the block""" + hash: Bytes + + """The block number""" + number: Int! + + """Integer representation of the timestamp stored in blocks for the chain""" + timestamp: Int +} + +"""The type for the top-level _meta field""" +type _Meta_ { + """ + Information about a specific subgraph block. The hash of the block + will be null if the _meta field has a block constraint that asks for + a block number. It will be filled if the _meta field has no block constraint + and therefore asks for the latest block + + """ + block: _Block_! + + """The deployment ID""" + deployment: String! + + """If `true`, the subgraph encountered indexing errors at some past block""" + hasIndexingErrors: Boolean! +} + +enum _SubgraphErrorPolicy_ { + """Data will be returned even if the subgraph has indexing errors""" + allow + + """ + If the subgraph has indexing errors, data will be omitted. The default. + """ + deny +} + +type Account { + id: Bytes! + address: Bytes! + user: User! + type: String! + vaultId: BigInt! + createPositionEvents(skip: Int = 0, first: Int = 100, orderBy: CreatePositionEvent_orderBy, orderDirection: OrderDirection, where: CreatePositionEvent_filter): [CreatePositionEvent!]! + summerEvents(skip: Int = 0, first: Int = 100, orderBy: SummerEvent_orderBy, orderDirection: OrderDirection, where: SummerEvent_filter): [SummerEvent!]! + feePaids(skip: Int = 0, first: Int = 100, orderBy: FeePaid_orderBy, orderDirection: OrderDirection, where: FeePaid_filter): [FeePaid!]! + automationEvents(skip: Int = 0, first: Int = 100, orderBy: TriggerEvent_orderBy, orderDirection: OrderDirection, where: TriggerEvent_filter): [TriggerEvent!]! + swaps(skip: Int = 0, first: Int = 100, orderBy: AssetSwap_orderBy, orderDirection: OrderDirection, where: AssetSwap_filter): [AssetSwap!]! + positions(skip: Int = 0, first: Int = 100, orderBy: Position_orderBy, orderDirection: OrderDirection, where: Position_filter): [Position!]! + latestCreatePositionEvent: CreatePositionEvent +} + +input Account_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + address: Bytes + address_not: Bytes + address_gt: Bytes + address_lt: Bytes + address_gte: Bytes + address_lte: Bytes + address_in: [Bytes!] + address_not_in: [Bytes!] + address_contains: Bytes + address_not_contains: Bytes + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + type: String + type_not: String + type_gt: String + type_lt: String + type_gte: String + type_lte: String + type_in: [String!] + type_not_in: [String!] + type_contains: String + type_contains_nocase: String + type_not_contains: String + type_not_contains_nocase: String + type_starts_with: String + type_starts_with_nocase: String + type_not_starts_with: String + type_not_starts_with_nocase: String + type_ends_with: String + type_ends_with_nocase: String + type_not_ends_with: String + type_not_ends_with_nocase: String + vaultId: BigInt + vaultId_not: BigInt + vaultId_gt: BigInt + vaultId_lt: BigInt + vaultId_gte: BigInt + vaultId_lte: BigInt + vaultId_in: [BigInt!] + vaultId_not_in: [BigInt!] + createPositionEvents_: CreatePositionEvent_filter + summerEvents_: SummerEvent_filter + feePaids_: FeePaid_filter + automationEvents_: TriggerEvent_filter + swaps_: AssetSwap_filter + positions_: Position_filter + latestCreatePositionEvent: String + latestCreatePositionEvent_not: String + latestCreatePositionEvent_gt: String + latestCreatePositionEvent_lt: String + latestCreatePositionEvent_gte: String + latestCreatePositionEvent_lte: String + latestCreatePositionEvent_in: [String!] + latestCreatePositionEvent_not_in: [String!] + latestCreatePositionEvent_contains: String + latestCreatePositionEvent_contains_nocase: String + latestCreatePositionEvent_not_contains: String + latestCreatePositionEvent_not_contains_nocase: String + latestCreatePositionEvent_starts_with: String + latestCreatePositionEvent_starts_with_nocase: String + latestCreatePositionEvent_not_starts_with: String + latestCreatePositionEvent_not_starts_with_nocase: String + latestCreatePositionEvent_ends_with: String + latestCreatePositionEvent_ends_with_nocase: String + latestCreatePositionEvent_not_ends_with: String + latestCreatePositionEvent_not_ends_with_nocase: String + latestCreatePositionEvent_: CreatePositionEvent_filter + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Account_filter] + or: [Account_filter] +} + +enum Account_orderBy { + id + address + user + user__id + user__openPositions + type + vaultId + createPositionEvents + summerEvents + feePaids + automationEvents + swaps + positions + latestCreatePositionEvent + latestCreatePositionEvent__id + latestCreatePositionEvent__blockNumber + latestCreatePositionEvent__timestamp + latestCreatePositionEvent__txHash + latestCreatePositionEvent__logIndex + latestCreatePositionEvent__protocol + latestCreatePositionEvent__positionType + latestCreatePositionEvent__marketId +} + +type AssetSwap { + id: Bytes! + assetIn: Token! + assetOut: Token! + amountIn: BigInt! + amountOut: BigInt! + assetInPrice: BigDecimal! + oracle: String! + amountInUSD: BigDecimal! + mainEventHash: SummerEvent + user: User! + proxy: Account! + timestamp: BigInt! + block: BigInt! +} + +input AssetSwap_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + assetIn: String + assetIn_not: String + assetIn_gt: String + assetIn_lt: String + assetIn_gte: String + assetIn_lte: String + assetIn_in: [String!] + assetIn_not_in: [String!] + assetIn_contains: String + assetIn_contains_nocase: String + assetIn_not_contains: String + assetIn_not_contains_nocase: String + assetIn_starts_with: String + assetIn_starts_with_nocase: String + assetIn_not_starts_with: String + assetIn_not_starts_with_nocase: String + assetIn_ends_with: String + assetIn_ends_with_nocase: String + assetIn_not_ends_with: String + assetIn_not_ends_with_nocase: String + assetIn_: Token_filter + assetOut: String + assetOut_not: String + assetOut_gt: String + assetOut_lt: String + assetOut_gte: String + assetOut_lte: String + assetOut_in: [String!] + assetOut_not_in: [String!] + assetOut_contains: String + assetOut_contains_nocase: String + assetOut_not_contains: String + assetOut_not_contains_nocase: String + assetOut_starts_with: String + assetOut_starts_with_nocase: String + assetOut_not_starts_with: String + assetOut_not_starts_with_nocase: String + assetOut_ends_with: String + assetOut_ends_with_nocase: String + assetOut_not_ends_with: String + assetOut_not_ends_with_nocase: String + assetOut_: Token_filter + amountIn: BigInt + amountIn_not: BigInt + amountIn_gt: BigInt + amountIn_lt: BigInt + amountIn_gte: BigInt + amountIn_lte: BigInt + amountIn_in: [BigInt!] + amountIn_not_in: [BigInt!] + amountOut: BigInt + amountOut_not: BigInt + amountOut_gt: BigInt + amountOut_lt: BigInt + amountOut_gte: BigInt + amountOut_lte: BigInt + amountOut_in: [BigInt!] + amountOut_not_in: [BigInt!] + assetInPrice: BigDecimal + assetInPrice_not: BigDecimal + assetInPrice_gt: BigDecimal + assetInPrice_lt: BigDecimal + assetInPrice_gte: BigDecimal + assetInPrice_lte: BigDecimal + assetInPrice_in: [BigDecimal!] + assetInPrice_not_in: [BigDecimal!] + oracle: String + oracle_not: String + oracle_gt: String + oracle_lt: String + oracle_gte: String + oracle_lte: String + oracle_in: [String!] + oracle_not_in: [String!] + oracle_contains: String + oracle_contains_nocase: String + oracle_not_contains: String + oracle_not_contains_nocase: String + oracle_starts_with: String + oracle_starts_with_nocase: String + oracle_not_starts_with: String + oracle_not_starts_with_nocase: String + oracle_ends_with: String + oracle_ends_with_nocase: String + oracle_not_ends_with: String + oracle_not_ends_with_nocase: String + amountInUSD: BigDecimal + amountInUSD_not: BigDecimal + amountInUSD_gt: BigDecimal + amountInUSD_lt: BigDecimal + amountInUSD_gte: BigDecimal + amountInUSD_lte: BigDecimal + amountInUSD_in: [BigDecimal!] + amountInUSD_not_in: [BigDecimal!] + mainEventHash: String + mainEventHash_not: String + mainEventHash_gt: String + mainEventHash_lt: String + mainEventHash_gte: String + mainEventHash_lte: String + mainEventHash_in: [String!] + mainEventHash_not_in: [String!] + mainEventHash_contains: String + mainEventHash_contains_nocase: String + mainEventHash_not_contains: String + mainEventHash_not_contains_nocase: String + mainEventHash_starts_with: String + mainEventHash_starts_with_nocase: String + mainEventHash_not_starts_with: String + mainEventHash_not_starts_with_nocase: String + mainEventHash_ends_with: String + mainEventHash_ends_with_nocase: String + mainEventHash_not_ends_with: String + mainEventHash_not_ends_with_nocase: String + mainEventHash_: SummerEvent_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + proxy: String + proxy_not: String + proxy_gt: String + proxy_lt: String + proxy_gte: String + proxy_lte: String + proxy_in: [String!] + proxy_not_in: [String!] + proxy_contains: String + proxy_contains_nocase: String + proxy_not_contains: String + proxy_not_contains_nocase: String + proxy_starts_with: String + proxy_starts_with_nocase: String + proxy_not_starts_with: String + proxy_not_starts_with_nocase: String + proxy_ends_with: String + proxy_ends_with_nocase: String + proxy_not_ends_with: String + proxy_not_ends_with_nocase: String + proxy_: Account_filter + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + block: BigInt + block_not: BigInt + block_gt: BigInt + block_lt: BigInt + block_gte: BigInt + block_lte: BigInt + block_in: [BigInt!] + block_not_in: [BigInt!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [AssetSwap_filter] + or: [AssetSwap_filter] +} + +enum AssetSwap_orderBy { + id + assetIn + assetIn__id + assetIn__address + assetIn__symbol + assetIn__decimals + assetIn__precision + assetOut + assetOut__id + assetOut__address + assetOut__symbol + assetOut__decimals + assetOut__precision + amountIn + amountOut + assetInPrice + oracle + amountInUSD + mainEventHash + mainEventHash__id + mainEventHash__blockNumber + mainEventHash__timestamp + mainEventHash__txHash + mainEventHash__logIndex + mainEventHash__sender + mainEventHash__kind + mainEventHash__depositedUSD + mainEventHash__withdrawnUSD + mainEventHash__deltaUSD + mainEventHash__feePaidUSD + mainEventHash__protocol + mainEventHash__marketId + mainEventHash__debtBefore + mainEventHash__debtInUSDBefore + mainEventHash__debtAfter + mainEventHash__debtInUSDAfter + mainEventHash__collateralBefore + mainEventHash__collateralInUSDBefore + mainEventHash__collateralAfter + mainEventHash__collateralInUSDAfter + mainEventHash__supplyBefore + mainEventHash__supplyInUSDBefore + mainEventHash__supplyAfter + mainEventHash__supplyInUSDAfter + mainEventHash__netValueBefore + mainEventHash__netValueAfter + mainEventHash__collateralTokenPriceInUSD + mainEventHash__debtTokenPriceInUSD + mainEventHash__supplyTokenPriceInUSD + user + user__id + user__openPositions + proxy + proxy__id + proxy__address + proxy__type + proxy__vaultId + timestamp + block +} + +scalar BigDecimal + +scalar BigInt + +input Block_height { + hash: Bytes + number: Int + number_gte: Int +} + +input BlockChangedFilter { + number_gte: Int! +} + +scalar Bytes + +type CreatePositionEvent { + id: Bytes! + blockNumber: BigInt! + timestamp: BigInt! + txHash: Bytes! + logIndex: BigInt! + protocol: String! + positionType: String! + debtToken: Token! + collateralToken: Token! + marketId: String + user: User! + account: Account! +} + +input CreatePositionEvent_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + blockNumber: BigInt + blockNumber_not: BigInt + blockNumber_gt: BigInt + blockNumber_lt: BigInt + blockNumber_gte: BigInt + blockNumber_lte: BigInt + blockNumber_in: [BigInt!] + blockNumber_not_in: [BigInt!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + txHash: Bytes + txHash_not: Bytes + txHash_gt: Bytes + txHash_lt: Bytes + txHash_gte: Bytes + txHash_lte: Bytes + txHash_in: [Bytes!] + txHash_not_in: [Bytes!] + txHash_contains: Bytes + txHash_not_contains: Bytes + logIndex: BigInt + logIndex_not: BigInt + logIndex_gt: BigInt + logIndex_lt: BigInt + logIndex_gte: BigInt + logIndex_lte: BigInt + logIndex_in: [BigInt!] + logIndex_not_in: [BigInt!] + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + positionType: String + positionType_not: String + positionType_gt: String + positionType_lt: String + positionType_gte: String + positionType_lte: String + positionType_in: [String!] + positionType_not_in: [String!] + positionType_contains: String + positionType_contains_nocase: String + positionType_not_contains: String + positionType_not_contains_nocase: String + positionType_starts_with: String + positionType_starts_with_nocase: String + positionType_not_starts_with: String + positionType_not_starts_with_nocase: String + positionType_ends_with: String + positionType_ends_with_nocase: String + positionType_not_ends_with: String + positionType_not_ends_with_nocase: String + debtToken: String + debtToken_not: String + debtToken_gt: String + debtToken_lt: String + debtToken_gte: String + debtToken_lte: String + debtToken_in: [String!] + debtToken_not_in: [String!] + debtToken_contains: String + debtToken_contains_nocase: String + debtToken_not_contains: String + debtToken_not_contains_nocase: String + debtToken_starts_with: String + debtToken_starts_with_nocase: String + debtToken_not_starts_with: String + debtToken_not_starts_with_nocase: String + debtToken_ends_with: String + debtToken_ends_with_nocase: String + debtToken_not_ends_with: String + debtToken_not_ends_with_nocase: String + debtToken_: Token_filter + collateralToken: String + collateralToken_not: String + collateralToken_gt: String + collateralToken_lt: String + collateralToken_gte: String + collateralToken_lte: String + collateralToken_in: [String!] + collateralToken_not_in: [String!] + collateralToken_contains: String + collateralToken_contains_nocase: String + collateralToken_not_contains: String + collateralToken_not_contains_nocase: String + collateralToken_starts_with: String + collateralToken_starts_with_nocase: String + collateralToken_not_starts_with: String + collateralToken_not_starts_with_nocase: String + collateralToken_ends_with: String + collateralToken_ends_with_nocase: String + collateralToken_not_ends_with: String + collateralToken_not_ends_with_nocase: String + collateralToken_: Token_filter + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [CreatePositionEvent_filter] + or: [CreatePositionEvent_filter] +} + +enum CreatePositionEvent_orderBy { + id + blockNumber + timestamp + txHash + logIndex + protocol + positionType + debtToken + debtToken__id + debtToken__address + debtToken__symbol + debtToken__decimals + debtToken__precision + collateralToken + collateralToken__id + collateralToken__address + collateralToken__symbol + collateralToken__decimals + collateralToken__precision + marketId + user + user__id + user__openPositions + account + account__id + account__address + account__type + account__vaultId +} + +type FeePaid { + id: ID! + block: BigInt! + timestamp: BigInt! + transactionHash: Bytes! + logIndex: BigInt! + sender: Bytes! + beneficiary: Bytes! + amount: BigDecimal! + amountInFeeToken: BigInt + feeTokenPrice: BigDecimal + oracle: String! + feeToken: Token + mainEventHash: SummerEvent + user: User! + proxy: Account! +} + +input FeePaid_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + block: BigInt + block_not: BigInt + block_gt: BigInt + block_lt: BigInt + block_gte: BigInt + block_lte: BigInt + block_in: [BigInt!] + block_not_in: [BigInt!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + transactionHash: Bytes + transactionHash_not: Bytes + transactionHash_gt: Bytes + transactionHash_lt: Bytes + transactionHash_gte: Bytes + transactionHash_lte: Bytes + transactionHash_in: [Bytes!] + transactionHash_not_in: [Bytes!] + transactionHash_contains: Bytes + transactionHash_not_contains: Bytes + logIndex: BigInt + logIndex_not: BigInt + logIndex_gt: BigInt + logIndex_lt: BigInt + logIndex_gte: BigInt + logIndex_lte: BigInt + logIndex_in: [BigInt!] + logIndex_not_in: [BigInt!] + sender: Bytes + sender_not: Bytes + sender_gt: Bytes + sender_lt: Bytes + sender_gte: Bytes + sender_lte: Bytes + sender_in: [Bytes!] + sender_not_in: [Bytes!] + sender_contains: Bytes + sender_not_contains: Bytes + beneficiary: Bytes + beneficiary_not: Bytes + beneficiary_gt: Bytes + beneficiary_lt: Bytes + beneficiary_gte: Bytes + beneficiary_lte: Bytes + beneficiary_in: [Bytes!] + beneficiary_not_in: [Bytes!] + beneficiary_contains: Bytes + beneficiary_not_contains: Bytes + amount: BigDecimal + amount_not: BigDecimal + amount_gt: BigDecimal + amount_lt: BigDecimal + amount_gte: BigDecimal + amount_lte: BigDecimal + amount_in: [BigDecimal!] + amount_not_in: [BigDecimal!] + amountInFeeToken: BigInt + amountInFeeToken_not: BigInt + amountInFeeToken_gt: BigInt + amountInFeeToken_lt: BigInt + amountInFeeToken_gte: BigInt + amountInFeeToken_lte: BigInt + amountInFeeToken_in: [BigInt!] + amountInFeeToken_not_in: [BigInt!] + feeTokenPrice: BigDecimal + feeTokenPrice_not: BigDecimal + feeTokenPrice_gt: BigDecimal + feeTokenPrice_lt: BigDecimal + feeTokenPrice_gte: BigDecimal + feeTokenPrice_lte: BigDecimal + feeTokenPrice_in: [BigDecimal!] + feeTokenPrice_not_in: [BigDecimal!] + oracle: String + oracle_not: String + oracle_gt: String + oracle_lt: String + oracle_gte: String + oracle_lte: String + oracle_in: [String!] + oracle_not_in: [String!] + oracle_contains: String + oracle_contains_nocase: String + oracle_not_contains: String + oracle_not_contains_nocase: String + oracle_starts_with: String + oracle_starts_with_nocase: String + oracle_not_starts_with: String + oracle_not_starts_with_nocase: String + oracle_ends_with: String + oracle_ends_with_nocase: String + oracle_not_ends_with: String + oracle_not_ends_with_nocase: String + feeToken: String + feeToken_not: String + feeToken_gt: String + feeToken_lt: String + feeToken_gte: String + feeToken_lte: String + feeToken_in: [String!] + feeToken_not_in: [String!] + feeToken_contains: String + feeToken_contains_nocase: String + feeToken_not_contains: String + feeToken_not_contains_nocase: String + feeToken_starts_with: String + feeToken_starts_with_nocase: String + feeToken_not_starts_with: String + feeToken_not_starts_with_nocase: String + feeToken_ends_with: String + feeToken_ends_with_nocase: String + feeToken_not_ends_with: String + feeToken_not_ends_with_nocase: String + feeToken_: Token_filter + mainEventHash: String + mainEventHash_not: String + mainEventHash_gt: String + mainEventHash_lt: String + mainEventHash_gte: String + mainEventHash_lte: String + mainEventHash_in: [String!] + mainEventHash_not_in: [String!] + mainEventHash_contains: String + mainEventHash_contains_nocase: String + mainEventHash_not_contains: String + mainEventHash_not_contains_nocase: String + mainEventHash_starts_with: String + mainEventHash_starts_with_nocase: String + mainEventHash_not_starts_with: String + mainEventHash_not_starts_with_nocase: String + mainEventHash_ends_with: String + mainEventHash_ends_with_nocase: String + mainEventHash_not_ends_with: String + mainEventHash_not_ends_with_nocase: String + mainEventHash_: SummerEvent_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + proxy: String + proxy_not: String + proxy_gt: String + proxy_lt: String + proxy_gte: String + proxy_lte: String + proxy_in: [String!] + proxy_not_in: [String!] + proxy_contains: String + proxy_contains_nocase: String + proxy_not_contains: String + proxy_not_contains_nocase: String + proxy_starts_with: String + proxy_starts_with_nocase: String + proxy_not_starts_with: String + proxy_not_starts_with_nocase: String + proxy_ends_with: String + proxy_ends_with_nocase: String + proxy_not_ends_with: String + proxy_not_ends_with_nocase: String + proxy_: Account_filter + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [FeePaid_filter] + or: [FeePaid_filter] +} + +enum FeePaid_orderBy { + id + block + timestamp + transactionHash + logIndex + sender + beneficiary + amount + amountInFeeToken + feeTokenPrice + oracle + feeToken + feeToken__id + feeToken__address + feeToken__symbol + feeToken__decimals + feeToken__precision + mainEventHash + mainEventHash__id + mainEventHash__blockNumber + mainEventHash__timestamp + mainEventHash__txHash + mainEventHash__logIndex + mainEventHash__sender + mainEventHash__kind + mainEventHash__depositedUSD + mainEventHash__withdrawnUSD + mainEventHash__deltaUSD + mainEventHash__feePaidUSD + mainEventHash__protocol + mainEventHash__marketId + mainEventHash__debtBefore + mainEventHash__debtInUSDBefore + mainEventHash__debtAfter + mainEventHash__debtInUSDAfter + mainEventHash__collateralBefore + mainEventHash__collateralInUSDBefore + mainEventHash__collateralAfter + mainEventHash__collateralInUSDAfter + mainEventHash__supplyBefore + mainEventHash__supplyInUSDBefore + mainEventHash__supplyAfter + mainEventHash__supplyInUSDAfter + mainEventHash__netValueBefore + mainEventHash__netValueAfter + mainEventHash__collateralTokenPriceInUSD + mainEventHash__debtTokenPriceInUSD + mainEventHash__supplyTokenPriceInUSD + user + user__id + user__openPositions + proxy + proxy__id + proxy__address + proxy__type + proxy__vaultId +} + +type Ilk { + id: Bytes! + blockNumber: BigInt! + token: Token! + rate: BigDecimal! +} + +input Ilk_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + blockNumber: BigInt + blockNumber_not: BigInt + blockNumber_gt: BigInt + blockNumber_lt: BigInt + blockNumber_gte: BigInt + blockNumber_lte: BigInt + blockNumber_in: [BigInt!] + blockNumber_not_in: [BigInt!] + token: String + token_not: String + token_gt: String + token_lt: String + token_gte: String + token_lte: String + token_in: [String!] + token_not_in: [String!] + token_contains: String + token_contains_nocase: String + token_not_contains: String + token_not_contains_nocase: String + token_starts_with: String + token_starts_with_nocase: String + token_not_starts_with: String + token_not_starts_with_nocase: String + token_ends_with: String + token_ends_with_nocase: String + token_not_ends_with: String + token_not_ends_with_nocase: String + token_: Token_filter + rate: BigDecimal + rate_not: BigDecimal + rate_gt: BigDecimal + rate_lt: BigDecimal + rate_gte: BigDecimal + rate_lte: BigDecimal + rate_in: [BigDecimal!] + rate_not_in: [BigDecimal!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Ilk_filter] + or: [Ilk_filter] +} + +enum Ilk_orderBy { + id + blockNumber + token + token__id + token__address + token__symbol + token__decimals + token__precision + rate +} + +""" +8 bytes signed integer + +""" +scalar Int8 + +type MakerUrn { + id: Bytes! + cdp: BigInt! + ilk: Bytes! + urn: Bytes! +} + +input MakerUrn_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + cdp: BigInt + cdp_not: BigInt + cdp_gt: BigInt + cdp_lt: BigInt + cdp_gte: BigInt + cdp_lte: BigInt + cdp_in: [BigInt!] + cdp_not_in: [BigInt!] + ilk: Bytes + ilk_not: Bytes + ilk_gt: Bytes + ilk_lt: Bytes + ilk_gte: Bytes + ilk_lte: Bytes + ilk_in: [Bytes!] + ilk_not_in: [Bytes!] + ilk_contains: Bytes + ilk_not_contains: Bytes + urn: Bytes + urn_not: Bytes + urn_gt: Bytes + urn_lt: Bytes + urn_gte: Bytes + urn_lte: Bytes + urn_in: [Bytes!] + urn_not_in: [Bytes!] + urn_contains: Bytes + urn_not_contains: Bytes + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [MakerUrn_filter] + or: [MakerUrn_filter] +} + +enum MakerUrn_orderBy { + id + cdp + ilk + urn +} + +type Market { + id: ID! + protocol: String! + marketId: String! + supported: Boolean! +} + +input Market_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + supported: Boolean + supported_not: Boolean + supported_in: [Boolean!] + supported_not_in: [Boolean!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Market_filter] + or: [Market_filter] +} + +enum Market_orderBy { + id + protocol + marketId + supported +} + +"""Defines the order direction, either ascending or descending""" +enum OrderDirection { + asc + desc +} + +type Position { + id: ID! + account: Account! + user: User! + protocol: String! + marketId: String! + positionType: String + cumulativeDepositedUSD: BigDecimal! + cumulativeWithdrawnUSD: BigDecimal! + cumulativeDeltaUSD: BigDecimal! + cumulativeFeesUSD: BigDecimal! + debt: BigDecimal! + debtInUSD: BigDecimal! + collateral: BigDecimal! + collateralInUSD: BigDecimal! + supply: BigDecimal! + supplyInUSD: BigDecimal! + netValue: BigDecimal! + summerEvents(skip: Int = 0, first: Int = 100, orderBy: SummerEvent_orderBy, orderDirection: OrderDirection, where: SummerEvent_filter): [SummerEvent!]! + triggers(skip: Int = 0, first: Int = 100, orderBy: Trigger_orderBy, orderDirection: OrderDirection, where: Trigger_filter): [Trigger!]! + lastEvent: SummerEvent + _ajnaBucket: BigInt! +} + +input Position_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + positionType: String + positionType_not: String + positionType_gt: String + positionType_lt: String + positionType_gte: String + positionType_lte: String + positionType_in: [String!] + positionType_not_in: [String!] + positionType_contains: String + positionType_contains_nocase: String + positionType_not_contains: String + positionType_not_contains_nocase: String + positionType_starts_with: String + positionType_starts_with_nocase: String + positionType_not_starts_with: String + positionType_not_starts_with_nocase: String + positionType_ends_with: String + positionType_ends_with_nocase: String + positionType_not_ends_with: String + positionType_not_ends_with_nocase: String + cumulativeDepositedUSD: BigDecimal + cumulativeDepositedUSD_not: BigDecimal + cumulativeDepositedUSD_gt: BigDecimal + cumulativeDepositedUSD_lt: BigDecimal + cumulativeDepositedUSD_gte: BigDecimal + cumulativeDepositedUSD_lte: BigDecimal + cumulativeDepositedUSD_in: [BigDecimal!] + cumulativeDepositedUSD_not_in: [BigDecimal!] + cumulativeWithdrawnUSD: BigDecimal + cumulativeWithdrawnUSD_not: BigDecimal + cumulativeWithdrawnUSD_gt: BigDecimal + cumulativeWithdrawnUSD_lt: BigDecimal + cumulativeWithdrawnUSD_gte: BigDecimal + cumulativeWithdrawnUSD_lte: BigDecimal + cumulativeWithdrawnUSD_in: [BigDecimal!] + cumulativeWithdrawnUSD_not_in: [BigDecimal!] + cumulativeDeltaUSD: BigDecimal + cumulativeDeltaUSD_not: BigDecimal + cumulativeDeltaUSD_gt: BigDecimal + cumulativeDeltaUSD_lt: BigDecimal + cumulativeDeltaUSD_gte: BigDecimal + cumulativeDeltaUSD_lte: BigDecimal + cumulativeDeltaUSD_in: [BigDecimal!] + cumulativeDeltaUSD_not_in: [BigDecimal!] + cumulativeFeesUSD: BigDecimal + cumulativeFeesUSD_not: BigDecimal + cumulativeFeesUSD_gt: BigDecimal + cumulativeFeesUSD_lt: BigDecimal + cumulativeFeesUSD_gte: BigDecimal + cumulativeFeesUSD_lte: BigDecimal + cumulativeFeesUSD_in: [BigDecimal!] + cumulativeFeesUSD_not_in: [BigDecimal!] + debt: BigDecimal + debt_not: BigDecimal + debt_gt: BigDecimal + debt_lt: BigDecimal + debt_gte: BigDecimal + debt_lte: BigDecimal + debt_in: [BigDecimal!] + debt_not_in: [BigDecimal!] + debtInUSD: BigDecimal + debtInUSD_not: BigDecimal + debtInUSD_gt: BigDecimal + debtInUSD_lt: BigDecimal + debtInUSD_gte: BigDecimal + debtInUSD_lte: BigDecimal + debtInUSD_in: [BigDecimal!] + debtInUSD_not_in: [BigDecimal!] + collateral: BigDecimal + collateral_not: BigDecimal + collateral_gt: BigDecimal + collateral_lt: BigDecimal + collateral_gte: BigDecimal + collateral_lte: BigDecimal + collateral_in: [BigDecimal!] + collateral_not_in: [BigDecimal!] + collateralInUSD: BigDecimal + collateralInUSD_not: BigDecimal + collateralInUSD_gt: BigDecimal + collateralInUSD_lt: BigDecimal + collateralInUSD_gte: BigDecimal + collateralInUSD_lte: BigDecimal + collateralInUSD_in: [BigDecimal!] + collateralInUSD_not_in: [BigDecimal!] + supply: BigDecimal + supply_not: BigDecimal + supply_gt: BigDecimal + supply_lt: BigDecimal + supply_gte: BigDecimal + supply_lte: BigDecimal + supply_in: [BigDecimal!] + supply_not_in: [BigDecimal!] + supplyInUSD: BigDecimal + supplyInUSD_not: BigDecimal + supplyInUSD_gt: BigDecimal + supplyInUSD_lt: BigDecimal + supplyInUSD_gte: BigDecimal + supplyInUSD_lte: BigDecimal + supplyInUSD_in: [BigDecimal!] + supplyInUSD_not_in: [BigDecimal!] + netValue: BigDecimal + netValue_not: BigDecimal + netValue_gt: BigDecimal + netValue_lt: BigDecimal + netValue_gte: BigDecimal + netValue_lte: BigDecimal + netValue_in: [BigDecimal!] + netValue_not_in: [BigDecimal!] + summerEvents_: SummerEvent_filter + triggers_: Trigger_filter + lastEvent: String + lastEvent_not: String + lastEvent_gt: String + lastEvent_lt: String + lastEvent_gte: String + lastEvent_lte: String + lastEvent_in: [String!] + lastEvent_not_in: [String!] + lastEvent_contains: String + lastEvent_contains_nocase: String + lastEvent_not_contains: String + lastEvent_not_contains_nocase: String + lastEvent_starts_with: String + lastEvent_starts_with_nocase: String + lastEvent_not_starts_with: String + lastEvent_not_starts_with_nocase: String + lastEvent_ends_with: String + lastEvent_ends_with_nocase: String + lastEvent_not_ends_with: String + lastEvent_not_ends_with_nocase: String + lastEvent_: SummerEvent_filter + _ajnaBucket: BigInt + _ajnaBucket_not: BigInt + _ajnaBucket_gt: BigInt + _ajnaBucket_lt: BigInt + _ajnaBucket_gte: BigInt + _ajnaBucket_lte: BigInt + _ajnaBucket_in: [BigInt!] + _ajnaBucket_not_in: [BigInt!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Position_filter] + or: [Position_filter] +} + +enum Position_orderBy { + id + account + account__id + account__address + account__type + account__vaultId + user + user__id + user__openPositions + protocol + marketId + positionType + cumulativeDepositedUSD + cumulativeWithdrawnUSD + cumulativeDeltaUSD + cumulativeFeesUSD + debt + debtInUSD + collateral + collateralInUSD + supply + supplyInUSD + netValue + summerEvents + triggers + lastEvent + lastEvent__id + lastEvent__blockNumber + lastEvent__timestamp + lastEvent__txHash + lastEvent__logIndex + lastEvent__sender + lastEvent__kind + lastEvent__depositedUSD + lastEvent__withdrawnUSD + lastEvent__deltaUSD + lastEvent__feePaidUSD + lastEvent__protocol + lastEvent__marketId + lastEvent__debtBefore + lastEvent__debtInUSDBefore + lastEvent__debtAfter + lastEvent__debtInUSDAfter + lastEvent__collateralBefore + lastEvent__collateralInUSDBefore + lastEvent__collateralAfter + lastEvent__collateralInUSDAfter + lastEvent__supplyBefore + lastEvent__supplyInUSDBefore + lastEvent__supplyAfter + lastEvent__supplyInUSDAfter + lastEvent__netValueBefore + lastEvent__netValueAfter + lastEvent__collateralTokenPriceInUSD + lastEvent__debtTokenPriceInUSD + lastEvent__supplyTokenPriceInUSD + _ajnaBucket +} + +type Query { + storage( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Storage + storages( + skip: Int = 0 + first: Int = 100 + orderBy: Storage_orderBy + orderDirection: OrderDirection + where: Storage_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Storage!]! + snapshot( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Snapshot + snapshots( + skip: Int = 0 + first: Int = 100 + orderBy: Snapshot_orderBy + orderDirection: OrderDirection + where: Snapshot_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Snapshot!]! + user( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): User + users( + skip: Int = 0 + first: Int = 100 + orderBy: User_orderBy + orderDirection: OrderDirection + where: User_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [User!]! + summerEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): SummerEvent + summerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: SummerEvent_orderBy + orderDirection: OrderDirection + where: SummerEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [SummerEvent!]! + createPositionEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): CreatePositionEvent + createPositionEvents( + skip: Int = 0 + first: Int = 100 + orderBy: CreatePositionEvent_orderBy + orderDirection: OrderDirection + where: CreatePositionEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [CreatePositionEvent!]! + account( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Account + accounts( + skip: Int = 0 + first: Int = 100 + orderBy: Account_orderBy + orderDirection: OrderDirection + where: Account_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Account!]! + position( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Position + positions( + skip: Int = 0 + first: Int = 100 + orderBy: Position_orderBy + orderDirection: OrderDirection + where: Position_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Position!]! + feePaid( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): FeePaid + feePaids( + skip: Int = 0 + first: Int = 100 + orderBy: FeePaid_orderBy + orderDirection: OrderDirection + where: FeePaid_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [FeePaid!]! + assetSwap( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): AssetSwap + assetSwaps( + skip: Int = 0 + first: Int = 100 + orderBy: AssetSwap_orderBy + orderDirection: OrderDirection + where: AssetSwap_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [AssetSwap!]! + transfer( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Transfer + transfers( + skip: Int = 0 + first: Int = 100 + orderBy: Transfer_orderBy + orderDirection: OrderDirection + where: Transfer_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Transfer!]! + token( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Token + tokens( + skip: Int = 0 + first: Int = 100 + orderBy: Token_orderBy + orderDirection: OrderDirection + where: Token_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Token!]! + triggerEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): TriggerEvent + triggerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: TriggerEvent_orderBy + orderDirection: OrderDirection + where: TriggerEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [TriggerEvent!]! + trigger( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Trigger + triggers( + skip: Int = 0 + first: Int = 100 + orderBy: Trigger_orderBy + orderDirection: OrderDirection + where: Trigger_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Trigger!]! + makerUrn( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): MakerUrn + makerUrns( + skip: Int = 0 + first: Int = 100 + orderBy: MakerUrn_orderBy + orderDirection: OrderDirection + where: MakerUrn_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [MakerUrn!]! + ilk( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Ilk + ilks( + skip: Int = 0 + first: Int = 100 + orderBy: Ilk_orderBy + orderDirection: OrderDirection + where: Ilk_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Ilk!]! + tokenPrice( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): TokenPrice + tokenPrices( + skip: Int = 0 + first: Int = 100 + orderBy: TokenPrice_orderBy + orderDirection: OrderDirection + where: TokenPrice_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [TokenPrice!]! + market( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Market + markets( + skip: Int = 0 + first: Int = 100 + orderBy: Market_orderBy + orderDirection: OrderDirection + where: Market_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Market!]! + + """Access to subgraph metadata""" + _meta(block: Block_height): _Meta_ +} + +type Snapshot { + id: ID! + timestamp: BigInt! + netValue: BigDecimal! + positionCount: BigInt! + closedPositions: BigInt! + year: BigInt! + month: BigInt! + day: BigInt! + hour: BigInt! +} + +input Snapshot_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + netValue: BigDecimal + netValue_not: BigDecimal + netValue_gt: BigDecimal + netValue_lt: BigDecimal + netValue_gte: BigDecimal + netValue_lte: BigDecimal + netValue_in: [BigDecimal!] + netValue_not_in: [BigDecimal!] + positionCount: BigInt + positionCount_not: BigInt + positionCount_gt: BigInt + positionCount_lt: BigInt + positionCount_gte: BigInt + positionCount_lte: BigInt + positionCount_in: [BigInt!] + positionCount_not_in: [BigInt!] + closedPositions: BigInt + closedPositions_not: BigInt + closedPositions_gt: BigInt + closedPositions_lt: BigInt + closedPositions_gte: BigInt + closedPositions_lte: BigInt + closedPositions_in: [BigInt!] + closedPositions_not_in: [BigInt!] + year: BigInt + year_not: BigInt + year_gt: BigInt + year_lt: BigInt + year_gte: BigInt + year_lte: BigInt + year_in: [BigInt!] + year_not_in: [BigInt!] + month: BigInt + month_not: BigInt + month_gt: BigInt + month_lt: BigInt + month_gte: BigInt + month_lte: BigInt + month_in: [BigInt!] + month_not_in: [BigInt!] + day: BigInt + day_not: BigInt + day_gt: BigInt + day_lt: BigInt + day_gte: BigInt + day_lte: BigInt + day_in: [BigInt!] + day_not_in: [BigInt!] + hour: BigInt + hour_not: BigInt + hour_gt: BigInt + hour_lt: BigInt + hour_gte: BigInt + hour_lte: BigInt + hour_in: [BigInt!] + hour_not_in: [BigInt!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Snapshot_filter] + or: [Snapshot_filter] +} + +enum Snapshot_orderBy { + id + timestamp + netValue + positionCount + closedPositions + year + month + day + hour +} + +""" +Oasis App user + +""" +type Storage { + id: ID! + positions(skip: Int = 0, first: Int = 100, orderBy: Position_orderBy, orderDirection: OrderDirection, where: Position_filter): [Position!]! +} + +input Storage_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + positions: [String!] + positions_not: [String!] + positions_contains: [String!] + positions_contains_nocase: [String!] + positions_not_contains: [String!] + positions_not_contains_nocase: [String!] + positions_: Position_filter + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Storage_filter] + or: [Storage_filter] +} + +enum Storage_orderBy { + id + positions +} + +type Subscription { + storage( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Storage + storages( + skip: Int = 0 + first: Int = 100 + orderBy: Storage_orderBy + orderDirection: OrderDirection + where: Storage_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Storage!]! + snapshot( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Snapshot + snapshots( + skip: Int = 0 + first: Int = 100 + orderBy: Snapshot_orderBy + orderDirection: OrderDirection + where: Snapshot_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Snapshot!]! + user( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): User + users( + skip: Int = 0 + first: Int = 100 + orderBy: User_orderBy + orderDirection: OrderDirection + where: User_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [User!]! + summerEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): SummerEvent + summerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: SummerEvent_orderBy + orderDirection: OrderDirection + where: SummerEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [SummerEvent!]! + createPositionEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): CreatePositionEvent + createPositionEvents( + skip: Int = 0 + first: Int = 100 + orderBy: CreatePositionEvent_orderBy + orderDirection: OrderDirection + where: CreatePositionEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [CreatePositionEvent!]! + account( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Account + accounts( + skip: Int = 0 + first: Int = 100 + orderBy: Account_orderBy + orderDirection: OrderDirection + where: Account_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Account!]! + position( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Position + positions( + skip: Int = 0 + first: Int = 100 + orderBy: Position_orderBy + orderDirection: OrderDirection + where: Position_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Position!]! + feePaid( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): FeePaid + feePaids( + skip: Int = 0 + first: Int = 100 + orderBy: FeePaid_orderBy + orderDirection: OrderDirection + where: FeePaid_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [FeePaid!]! + assetSwap( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): AssetSwap + assetSwaps( + skip: Int = 0 + first: Int = 100 + orderBy: AssetSwap_orderBy + orderDirection: OrderDirection + where: AssetSwap_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [AssetSwap!]! + transfer( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Transfer + transfers( + skip: Int = 0 + first: Int = 100 + orderBy: Transfer_orderBy + orderDirection: OrderDirection + where: Transfer_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Transfer!]! + token( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Token + tokens( + skip: Int = 0 + first: Int = 100 + orderBy: Token_orderBy + orderDirection: OrderDirection + where: Token_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Token!]! + triggerEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): TriggerEvent + triggerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: TriggerEvent_orderBy + orderDirection: OrderDirection + where: TriggerEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [TriggerEvent!]! + trigger( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Trigger + triggers( + skip: Int = 0 + first: Int = 100 + orderBy: Trigger_orderBy + orderDirection: OrderDirection + where: Trigger_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Trigger!]! + makerUrn( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): MakerUrn + makerUrns( + skip: Int = 0 + first: Int = 100 + orderBy: MakerUrn_orderBy + orderDirection: OrderDirection + where: MakerUrn_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [MakerUrn!]! + ilk( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Ilk + ilks( + skip: Int = 0 + first: Int = 100 + orderBy: Ilk_orderBy + orderDirection: OrderDirection + where: Ilk_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Ilk!]! + tokenPrice( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): TokenPrice + tokenPrices( + skip: Int = 0 + first: Int = 100 + orderBy: TokenPrice_orderBy + orderDirection: OrderDirection + where: TokenPrice_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [TokenPrice!]! + market( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Market + markets( + skip: Int = 0 + first: Int = 100 + orderBy: Market_orderBy + orderDirection: OrderDirection + where: Market_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Market!]! + + """Access to subgraph metadata""" + _meta(block: Block_height): _Meta_ +} + +type SummerEvent { + id: Bytes! + blockNumber: BigInt! + timestamp: BigInt! + txHash: Bytes! + logIndex: BigInt! + sender: Bytes! + kind: String! + account: Account! + user: User! + position: Position! + depositedUSD: BigDecimal! + withdrawnUSD: BigDecimal! + deltaUSD: BigDecimal! + feePaidUSD: BigDecimal! + depositTransfers(skip: Int = 0, first: Int = 100, orderBy: Transfer_orderBy, orderDirection: OrderDirection, where: Transfer_filter): [Transfer!]! + withdrawTransfers(skip: Int = 0, first: Int = 100, orderBy: Transfer_orderBy, orderDirection: OrderDirection, where: Transfer_filter): [Transfer!]! + protocol: String! + marketId: String! + feePaids(skip: Int = 0, first: Int = 100, orderBy: FeePaid_orderBy, orderDirection: OrderDirection, where: FeePaid_filter): [FeePaid!]! + swaps(skip: Int = 0, first: Int = 100, orderBy: AssetSwap_orderBy, orderDirection: OrderDirection, where: AssetSwap_filter): [AssetSwap!]! + automationEvents(skip: Int = 0, first: Int = 100, orderBy: TriggerEvent_orderBy, orderDirection: OrderDirection, where: TriggerEvent_filter): [TriggerEvent!]! + debtBefore: BigDecimal! + debtInUSDBefore: BigDecimal! + debtAfter: BigDecimal! + debtInUSDAfter: BigDecimal! + collateralBefore: BigDecimal! + collateralInUSDBefore: BigDecimal! + collateralAfter: BigDecimal! + collateralInUSDAfter: BigDecimal! + supplyBefore: BigDecimal! + supplyInUSDBefore: BigDecimal! + supplyAfter: BigDecimal! + supplyInUSDAfter: BigDecimal! + netValueBefore: BigDecimal! + netValueAfter: BigDecimal! + collateralTokenPriceInUSD: BigDecimal! + debtTokenPriceInUSD: BigDecimal! + supplyTokenPriceInUSD: BigDecimal! +} + +input SummerEvent_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + blockNumber: BigInt + blockNumber_not: BigInt + blockNumber_gt: BigInt + blockNumber_lt: BigInt + blockNumber_gte: BigInt + blockNumber_lte: BigInt + blockNumber_in: [BigInt!] + blockNumber_not_in: [BigInt!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + txHash: Bytes + txHash_not: Bytes + txHash_gt: Bytes + txHash_lt: Bytes + txHash_gte: Bytes + txHash_lte: Bytes + txHash_in: [Bytes!] + txHash_not_in: [Bytes!] + txHash_contains: Bytes + txHash_not_contains: Bytes + logIndex: BigInt + logIndex_not: BigInt + logIndex_gt: BigInt + logIndex_lt: BigInt + logIndex_gte: BigInt + logIndex_lte: BigInt + logIndex_in: [BigInt!] + logIndex_not_in: [BigInt!] + sender: Bytes + sender_not: Bytes + sender_gt: Bytes + sender_lt: Bytes + sender_gte: Bytes + sender_lte: Bytes + sender_in: [Bytes!] + sender_not_in: [Bytes!] + sender_contains: Bytes + sender_not_contains: Bytes + kind: String + kind_not: String + kind_gt: String + kind_lt: String + kind_gte: String + kind_lte: String + kind_in: [String!] + kind_not_in: [String!] + kind_contains: String + kind_contains_nocase: String + kind_not_contains: String + kind_not_contains_nocase: String + kind_starts_with: String + kind_starts_with_nocase: String + kind_not_starts_with: String + kind_not_starts_with_nocase: String + kind_ends_with: String + kind_ends_with_nocase: String + kind_not_ends_with: String + kind_not_ends_with_nocase: String + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + position: String + position_not: String + position_gt: String + position_lt: String + position_gte: String + position_lte: String + position_in: [String!] + position_not_in: [String!] + position_contains: String + position_contains_nocase: String + position_not_contains: String + position_not_contains_nocase: String + position_starts_with: String + position_starts_with_nocase: String + position_not_starts_with: String + position_not_starts_with_nocase: String + position_ends_with: String + position_ends_with_nocase: String + position_not_ends_with: String + position_not_ends_with_nocase: String + position_: Position_filter + depositedUSD: BigDecimal + depositedUSD_not: BigDecimal + depositedUSD_gt: BigDecimal + depositedUSD_lt: BigDecimal + depositedUSD_gte: BigDecimal + depositedUSD_lte: BigDecimal + depositedUSD_in: [BigDecimal!] + depositedUSD_not_in: [BigDecimal!] + withdrawnUSD: BigDecimal + withdrawnUSD_not: BigDecimal + withdrawnUSD_gt: BigDecimal + withdrawnUSD_lt: BigDecimal + withdrawnUSD_gte: BigDecimal + withdrawnUSD_lte: BigDecimal + withdrawnUSD_in: [BigDecimal!] + withdrawnUSD_not_in: [BigDecimal!] + deltaUSD: BigDecimal + deltaUSD_not: BigDecimal + deltaUSD_gt: BigDecimal + deltaUSD_lt: BigDecimal + deltaUSD_gte: BigDecimal + deltaUSD_lte: BigDecimal + deltaUSD_in: [BigDecimal!] + deltaUSD_not_in: [BigDecimal!] + feePaidUSD: BigDecimal + feePaidUSD_not: BigDecimal + feePaidUSD_gt: BigDecimal + feePaidUSD_lt: BigDecimal + feePaidUSD_gte: BigDecimal + feePaidUSD_lte: BigDecimal + feePaidUSD_in: [BigDecimal!] + feePaidUSD_not_in: [BigDecimal!] + depositTransfers: [String!] + depositTransfers_not: [String!] + depositTransfers_contains: [String!] + depositTransfers_contains_nocase: [String!] + depositTransfers_not_contains: [String!] + depositTransfers_not_contains_nocase: [String!] + depositTransfers_: Transfer_filter + withdrawTransfers: [String!] + withdrawTransfers_not: [String!] + withdrawTransfers_contains: [String!] + withdrawTransfers_contains_nocase: [String!] + withdrawTransfers_not_contains: [String!] + withdrawTransfers_not_contains_nocase: [String!] + withdrawTransfers_: Transfer_filter + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + feePaids_: FeePaid_filter + swaps_: AssetSwap_filter + automationEvents_: TriggerEvent_filter + debtBefore: BigDecimal + debtBefore_not: BigDecimal + debtBefore_gt: BigDecimal + debtBefore_lt: BigDecimal + debtBefore_gte: BigDecimal + debtBefore_lte: BigDecimal + debtBefore_in: [BigDecimal!] + debtBefore_not_in: [BigDecimal!] + debtInUSDBefore: BigDecimal + debtInUSDBefore_not: BigDecimal + debtInUSDBefore_gt: BigDecimal + debtInUSDBefore_lt: BigDecimal + debtInUSDBefore_gte: BigDecimal + debtInUSDBefore_lte: BigDecimal + debtInUSDBefore_in: [BigDecimal!] + debtInUSDBefore_not_in: [BigDecimal!] + debtAfter: BigDecimal + debtAfter_not: BigDecimal + debtAfter_gt: BigDecimal + debtAfter_lt: BigDecimal + debtAfter_gte: BigDecimal + debtAfter_lte: BigDecimal + debtAfter_in: [BigDecimal!] + debtAfter_not_in: [BigDecimal!] + debtInUSDAfter: BigDecimal + debtInUSDAfter_not: BigDecimal + debtInUSDAfter_gt: BigDecimal + debtInUSDAfter_lt: BigDecimal + debtInUSDAfter_gte: BigDecimal + debtInUSDAfter_lte: BigDecimal + debtInUSDAfter_in: [BigDecimal!] + debtInUSDAfter_not_in: [BigDecimal!] + collateralBefore: BigDecimal + collateralBefore_not: BigDecimal + collateralBefore_gt: BigDecimal + collateralBefore_lt: BigDecimal + collateralBefore_gte: BigDecimal + collateralBefore_lte: BigDecimal + collateralBefore_in: [BigDecimal!] + collateralBefore_not_in: [BigDecimal!] + collateralInUSDBefore: BigDecimal + collateralInUSDBefore_not: BigDecimal + collateralInUSDBefore_gt: BigDecimal + collateralInUSDBefore_lt: BigDecimal + collateralInUSDBefore_gte: BigDecimal + collateralInUSDBefore_lte: BigDecimal + collateralInUSDBefore_in: [BigDecimal!] + collateralInUSDBefore_not_in: [BigDecimal!] + collateralAfter: BigDecimal + collateralAfter_not: BigDecimal + collateralAfter_gt: BigDecimal + collateralAfter_lt: BigDecimal + collateralAfter_gte: BigDecimal + collateralAfter_lte: BigDecimal + collateralAfter_in: [BigDecimal!] + collateralAfter_not_in: [BigDecimal!] + collateralInUSDAfter: BigDecimal + collateralInUSDAfter_not: BigDecimal + collateralInUSDAfter_gt: BigDecimal + collateralInUSDAfter_lt: BigDecimal + collateralInUSDAfter_gte: BigDecimal + collateralInUSDAfter_lte: BigDecimal + collateralInUSDAfter_in: [BigDecimal!] + collateralInUSDAfter_not_in: [BigDecimal!] + supplyBefore: BigDecimal + supplyBefore_not: BigDecimal + supplyBefore_gt: BigDecimal + supplyBefore_lt: BigDecimal + supplyBefore_gte: BigDecimal + supplyBefore_lte: BigDecimal + supplyBefore_in: [BigDecimal!] + supplyBefore_not_in: [BigDecimal!] + supplyInUSDBefore: BigDecimal + supplyInUSDBefore_not: BigDecimal + supplyInUSDBefore_gt: BigDecimal + supplyInUSDBefore_lt: BigDecimal + supplyInUSDBefore_gte: BigDecimal + supplyInUSDBefore_lte: BigDecimal + supplyInUSDBefore_in: [BigDecimal!] + supplyInUSDBefore_not_in: [BigDecimal!] + supplyAfter: BigDecimal + supplyAfter_not: BigDecimal + supplyAfter_gt: BigDecimal + supplyAfter_lt: BigDecimal + supplyAfter_gte: BigDecimal + supplyAfter_lte: BigDecimal + supplyAfter_in: [BigDecimal!] + supplyAfter_not_in: [BigDecimal!] + supplyInUSDAfter: BigDecimal + supplyInUSDAfter_not: BigDecimal + supplyInUSDAfter_gt: BigDecimal + supplyInUSDAfter_lt: BigDecimal + supplyInUSDAfter_gte: BigDecimal + supplyInUSDAfter_lte: BigDecimal + supplyInUSDAfter_in: [BigDecimal!] + supplyInUSDAfter_not_in: [BigDecimal!] + netValueBefore: BigDecimal + netValueBefore_not: BigDecimal + netValueBefore_gt: BigDecimal + netValueBefore_lt: BigDecimal + netValueBefore_gte: BigDecimal + netValueBefore_lte: BigDecimal + netValueBefore_in: [BigDecimal!] + netValueBefore_not_in: [BigDecimal!] + netValueAfter: BigDecimal + netValueAfter_not: BigDecimal + netValueAfter_gt: BigDecimal + netValueAfter_lt: BigDecimal + netValueAfter_gte: BigDecimal + netValueAfter_lte: BigDecimal + netValueAfter_in: [BigDecimal!] + netValueAfter_not_in: [BigDecimal!] + collateralTokenPriceInUSD: BigDecimal + collateralTokenPriceInUSD_not: BigDecimal + collateralTokenPriceInUSD_gt: BigDecimal + collateralTokenPriceInUSD_lt: BigDecimal + collateralTokenPriceInUSD_gte: BigDecimal + collateralTokenPriceInUSD_lte: BigDecimal + collateralTokenPriceInUSD_in: [BigDecimal!] + collateralTokenPriceInUSD_not_in: [BigDecimal!] + debtTokenPriceInUSD: BigDecimal + debtTokenPriceInUSD_not: BigDecimal + debtTokenPriceInUSD_gt: BigDecimal + debtTokenPriceInUSD_lt: BigDecimal + debtTokenPriceInUSD_gte: BigDecimal + debtTokenPriceInUSD_lte: BigDecimal + debtTokenPriceInUSD_in: [BigDecimal!] + debtTokenPriceInUSD_not_in: [BigDecimal!] + supplyTokenPriceInUSD: BigDecimal + supplyTokenPriceInUSD_not: BigDecimal + supplyTokenPriceInUSD_gt: BigDecimal + supplyTokenPriceInUSD_lt: BigDecimal + supplyTokenPriceInUSD_gte: BigDecimal + supplyTokenPriceInUSD_lte: BigDecimal + supplyTokenPriceInUSD_in: [BigDecimal!] + supplyTokenPriceInUSD_not_in: [BigDecimal!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [SummerEvent_filter] + or: [SummerEvent_filter] +} + +enum SummerEvent_orderBy { + id + blockNumber + timestamp + txHash + logIndex + sender + kind + account + account__id + account__address + account__type + account__vaultId + user + user__id + user__openPositions + position + position__id + position__protocol + position__marketId + position__positionType + position__cumulativeDepositedUSD + position__cumulativeWithdrawnUSD + position__cumulativeDeltaUSD + position__cumulativeFeesUSD + position__debt + position__debtInUSD + position__collateral + position__collateralInUSD + position__supply + position__supplyInUSD + position__netValue + position___ajnaBucket + depositedUSD + withdrawnUSD + deltaUSD + feePaidUSD + depositTransfers + withdrawTransfers + protocol + marketId + feePaids + swaps + automationEvents + debtBefore + debtInUSDBefore + debtAfter + debtInUSDAfter + collateralBefore + collateralInUSDBefore + collateralAfter + collateralInUSDAfter + supplyBefore + supplyInUSDBefore + supplyAfter + supplyInUSDAfter + netValueBefore + netValueAfter + collateralTokenPriceInUSD + debtTokenPriceInUSD + supplyTokenPriceInUSD +} + +type Token { + id: Bytes! + address: Bytes! + symbol: String! + decimals: BigInt! + precision: BigInt! +} + +input Token_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + address: Bytes + address_not: Bytes + address_gt: Bytes + address_lt: Bytes + address_gte: Bytes + address_lte: Bytes + address_in: [Bytes!] + address_not_in: [Bytes!] + address_contains: Bytes + address_not_contains: Bytes + symbol: String + symbol_not: String + symbol_gt: String + symbol_lt: String + symbol_gte: String + symbol_lte: String + symbol_in: [String!] + symbol_not_in: [String!] + symbol_contains: String + symbol_contains_nocase: String + symbol_not_contains: String + symbol_not_contains_nocase: String + symbol_starts_with: String + symbol_starts_with_nocase: String + symbol_not_starts_with: String + symbol_not_starts_with_nocase: String + symbol_ends_with: String + symbol_ends_with_nocase: String + symbol_not_ends_with: String + symbol_not_ends_with_nocase: String + decimals: BigInt + decimals_not: BigInt + decimals_gt: BigInt + decimals_lt: BigInt + decimals_gte: BigInt + decimals_lte: BigInt + decimals_in: [BigInt!] + decimals_not_in: [BigInt!] + precision: BigInt + precision_not: BigInt + precision_gt: BigInt + precision_lt: BigInt + precision_gte: BigInt + precision_lte: BigInt + precision_in: [BigInt!] + precision_not_in: [BigInt!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Token_filter] + or: [Token_filter] +} + +enum Token_orderBy { + id + address + symbol + decimals + precision +} + +type TokenPrice { + id: Bytes! + token: Token! + blockNumber: BigInt! + price: BigDecimal! + oracle: String! +} + +input TokenPrice_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + token: String + token_not: String + token_gt: String + token_lt: String + token_gte: String + token_lte: String + token_in: [String!] + token_not_in: [String!] + token_contains: String + token_contains_nocase: String + token_not_contains: String + token_not_contains_nocase: String + token_starts_with: String + token_starts_with_nocase: String + token_not_starts_with: String + token_not_starts_with_nocase: String + token_ends_with: String + token_ends_with_nocase: String + token_not_ends_with: String + token_not_ends_with_nocase: String + token_: Token_filter + blockNumber: BigInt + blockNumber_not: BigInt + blockNumber_gt: BigInt + blockNumber_lt: BigInt + blockNumber_gte: BigInt + blockNumber_lte: BigInt + blockNumber_in: [BigInt!] + blockNumber_not_in: [BigInt!] + price: BigDecimal + price_not: BigDecimal + price_gt: BigDecimal + price_lt: BigDecimal + price_gte: BigDecimal + price_lte: BigDecimal + price_in: [BigDecimal!] + price_not_in: [BigDecimal!] + oracle: String + oracle_not: String + oracle_gt: String + oracle_lt: String + oracle_gte: String + oracle_lte: String + oracle_in: [String!] + oracle_not_in: [String!] + oracle_contains: String + oracle_contains_nocase: String + oracle_not_contains: String + oracle_not_contains_nocase: String + oracle_starts_with: String + oracle_starts_with_nocase: String + oracle_not_starts_with: String + oracle_not_starts_with_nocase: String + oracle_ends_with: String + oracle_ends_with_nocase: String + oracle_not_ends_with: String + oracle_not_ends_with_nocase: String + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [TokenPrice_filter] + or: [TokenPrice_filter] +} + +enum TokenPrice_orderBy { + id + token + token__id + token__address + token__symbol + token__decimals + token__precision + blockNumber + price + oracle +} + +type Transfer { + id: Bytes! + event: SummerEvent! + from: Bytes! + to: Bytes! + token: Token! + amount: BigDecimal! + priceInUSD: BigDecimal! + oracle: String! + amountUSD: BigDecimal! + txHash: String! +} + +input Transfer_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + event: String + event_not: String + event_gt: String + event_lt: String + event_gte: String + event_lte: String + event_in: [String!] + event_not_in: [String!] + event_contains: String + event_contains_nocase: String + event_not_contains: String + event_not_contains_nocase: String + event_starts_with: String + event_starts_with_nocase: String + event_not_starts_with: String + event_not_starts_with_nocase: String + event_ends_with: String + event_ends_with_nocase: String + event_not_ends_with: String + event_not_ends_with_nocase: String + event_: SummerEvent_filter + from: Bytes + from_not: Bytes + from_gt: Bytes + from_lt: Bytes + from_gte: Bytes + from_lte: Bytes + from_in: [Bytes!] + from_not_in: [Bytes!] + from_contains: Bytes + from_not_contains: Bytes + to: Bytes + to_not: Bytes + to_gt: Bytes + to_lt: Bytes + to_gte: Bytes + to_lte: Bytes + to_in: [Bytes!] + to_not_in: [Bytes!] + to_contains: Bytes + to_not_contains: Bytes + token: String + token_not: String + token_gt: String + token_lt: String + token_gte: String + token_lte: String + token_in: [String!] + token_not_in: [String!] + token_contains: String + token_contains_nocase: String + token_not_contains: String + token_not_contains_nocase: String + token_starts_with: String + token_starts_with_nocase: String + token_not_starts_with: String + token_not_starts_with_nocase: String + token_ends_with: String + token_ends_with_nocase: String + token_not_ends_with: String + token_not_ends_with_nocase: String + token_: Token_filter + amount: BigDecimal + amount_not: BigDecimal + amount_gt: BigDecimal + amount_lt: BigDecimal + amount_gte: BigDecimal + amount_lte: BigDecimal + amount_in: [BigDecimal!] + amount_not_in: [BigDecimal!] + priceInUSD: BigDecimal + priceInUSD_not: BigDecimal + priceInUSD_gt: BigDecimal + priceInUSD_lt: BigDecimal + priceInUSD_gte: BigDecimal + priceInUSD_lte: BigDecimal + priceInUSD_in: [BigDecimal!] + priceInUSD_not_in: [BigDecimal!] + oracle: String + oracle_not: String + oracle_gt: String + oracle_lt: String + oracle_gte: String + oracle_lte: String + oracle_in: [String!] + oracle_not_in: [String!] + oracle_contains: String + oracle_contains_nocase: String + oracle_not_contains: String + oracle_not_contains_nocase: String + oracle_starts_with: String + oracle_starts_with_nocase: String + oracle_not_starts_with: String + oracle_not_starts_with_nocase: String + oracle_ends_with: String + oracle_ends_with_nocase: String + oracle_not_ends_with: String + oracle_not_ends_with_nocase: String + amountUSD: BigDecimal + amountUSD_not: BigDecimal + amountUSD_gt: BigDecimal + amountUSD_lt: BigDecimal + amountUSD_gte: BigDecimal + amountUSD_lte: BigDecimal + amountUSD_in: [BigDecimal!] + amountUSD_not_in: [BigDecimal!] + txHash: String + txHash_not: String + txHash_gt: String + txHash_lt: String + txHash_gte: String + txHash_lte: String + txHash_in: [String!] + txHash_not_in: [String!] + txHash_contains: String + txHash_contains_nocase: String + txHash_not_contains: String + txHash_not_contains_nocase: String + txHash_starts_with: String + txHash_starts_with_nocase: String + txHash_not_starts_with: String + txHash_not_starts_with_nocase: String + txHash_ends_with: String + txHash_ends_with_nocase: String + txHash_not_ends_with: String + txHash_not_ends_with_nocase: String + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Transfer_filter] + or: [Transfer_filter] +} + +enum Transfer_orderBy { + id + event + event__id + event__blockNumber + event__timestamp + event__txHash + event__logIndex + event__sender + event__kind + event__depositedUSD + event__withdrawnUSD + event__deltaUSD + event__feePaidUSD + event__protocol + event__marketId + event__debtBefore + event__debtInUSDBefore + event__debtAfter + event__debtInUSDAfter + event__collateralBefore + event__collateralInUSDBefore + event__collateralAfter + event__collateralInUSDAfter + event__supplyBefore + event__supplyInUSDBefore + event__supplyAfter + event__supplyInUSDAfter + event__netValueBefore + event__netValueAfter + event__collateralTokenPriceInUSD + event__debtTokenPriceInUSD + event__supplyTokenPriceInUSD + from + to + token + token__id + token__address + token__symbol + token__decimals + token__precision + amount + priceInUSD + oracle + amountUSD + txHash +} + +type Trigger { + id: ID! + account: Account! + user: User! + commandAddress: Bytes! + triggerType: BigInt! + kind: String! + triggerData: Bytes! + continuous: Boolean! + decodedData: [String!]! + decodedDataNames: [String!]! + addedBlock: BigInt! + addedTransaction: Bytes! + addedLogIndex: BigInt! + addedTimestamp: BigInt! + removedBlock: BigInt + removedTransaction: Bytes + removedLogIndex: BigInt + removedTimestamp: BigInt + executedBlock: BigInt + executedTransaction: Bytes + executedLogIndex: BigInt + executedTimestamp: BigInt + version: BigInt! + tokens(skip: Int = 0, first: Int = 100, orderBy: Token_orderBy, orderDirection: OrderDirection, where: Token_filter): [Token!] + protocol: String! + marketId: String! + position: Position! + operationName: String +} + +input Trigger_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + commandAddress: Bytes + commandAddress_not: Bytes + commandAddress_gt: Bytes + commandAddress_lt: Bytes + commandAddress_gte: Bytes + commandAddress_lte: Bytes + commandAddress_in: [Bytes!] + commandAddress_not_in: [Bytes!] + commandAddress_contains: Bytes + commandAddress_not_contains: Bytes + triggerType: BigInt + triggerType_not: BigInt + triggerType_gt: BigInt + triggerType_lt: BigInt + triggerType_gte: BigInt + triggerType_lte: BigInt + triggerType_in: [BigInt!] + triggerType_not_in: [BigInt!] + kind: String + kind_not: String + kind_gt: String + kind_lt: String + kind_gte: String + kind_lte: String + kind_in: [String!] + kind_not_in: [String!] + kind_contains: String + kind_contains_nocase: String + kind_not_contains: String + kind_not_contains_nocase: String + kind_starts_with: String + kind_starts_with_nocase: String + kind_not_starts_with: String + kind_not_starts_with_nocase: String + kind_ends_with: String + kind_ends_with_nocase: String + kind_not_ends_with: String + kind_not_ends_with_nocase: String + triggerData: Bytes + triggerData_not: Bytes + triggerData_gt: Bytes + triggerData_lt: Bytes + triggerData_gte: Bytes + triggerData_lte: Bytes + triggerData_in: [Bytes!] + triggerData_not_in: [Bytes!] + triggerData_contains: Bytes + triggerData_not_contains: Bytes + continuous: Boolean + continuous_not: Boolean + continuous_in: [Boolean!] + continuous_not_in: [Boolean!] + decodedData: [String!] + decodedData_not: [String!] + decodedData_contains: [String!] + decodedData_contains_nocase: [String!] + decodedData_not_contains: [String!] + decodedData_not_contains_nocase: [String!] + decodedDataNames: [String!] + decodedDataNames_not: [String!] + decodedDataNames_contains: [String!] + decodedDataNames_contains_nocase: [String!] + decodedDataNames_not_contains: [String!] + decodedDataNames_not_contains_nocase: [String!] + addedBlock: BigInt + addedBlock_not: BigInt + addedBlock_gt: BigInt + addedBlock_lt: BigInt + addedBlock_gte: BigInt + addedBlock_lte: BigInt + addedBlock_in: [BigInt!] + addedBlock_not_in: [BigInt!] + addedTransaction: Bytes + addedTransaction_not: Bytes + addedTransaction_gt: Bytes + addedTransaction_lt: Bytes + addedTransaction_gte: Bytes + addedTransaction_lte: Bytes + addedTransaction_in: [Bytes!] + addedTransaction_not_in: [Bytes!] + addedTransaction_contains: Bytes + addedTransaction_not_contains: Bytes + addedLogIndex: BigInt + addedLogIndex_not: BigInt + addedLogIndex_gt: BigInt + addedLogIndex_lt: BigInt + addedLogIndex_gte: BigInt + addedLogIndex_lte: BigInt + addedLogIndex_in: [BigInt!] + addedLogIndex_not_in: [BigInt!] + addedTimestamp: BigInt + addedTimestamp_not: BigInt + addedTimestamp_gt: BigInt + addedTimestamp_lt: BigInt + addedTimestamp_gte: BigInt + addedTimestamp_lte: BigInt + addedTimestamp_in: [BigInt!] + addedTimestamp_not_in: [BigInt!] + removedBlock: BigInt + removedBlock_not: BigInt + removedBlock_gt: BigInt + removedBlock_lt: BigInt + removedBlock_gte: BigInt + removedBlock_lte: BigInt + removedBlock_in: [BigInt!] + removedBlock_not_in: [BigInt!] + removedTransaction: Bytes + removedTransaction_not: Bytes + removedTransaction_gt: Bytes + removedTransaction_lt: Bytes + removedTransaction_gte: Bytes + removedTransaction_lte: Bytes + removedTransaction_in: [Bytes!] + removedTransaction_not_in: [Bytes!] + removedTransaction_contains: Bytes + removedTransaction_not_contains: Bytes + removedLogIndex: BigInt + removedLogIndex_not: BigInt + removedLogIndex_gt: BigInt + removedLogIndex_lt: BigInt + removedLogIndex_gte: BigInt + removedLogIndex_lte: BigInt + removedLogIndex_in: [BigInt!] + removedLogIndex_not_in: [BigInt!] + removedTimestamp: BigInt + removedTimestamp_not: BigInt + removedTimestamp_gt: BigInt + removedTimestamp_lt: BigInt + removedTimestamp_gte: BigInt + removedTimestamp_lte: BigInt + removedTimestamp_in: [BigInt!] + removedTimestamp_not_in: [BigInt!] + executedBlock: BigInt + executedBlock_not: BigInt + executedBlock_gt: BigInt + executedBlock_lt: BigInt + executedBlock_gte: BigInt + executedBlock_lte: BigInt + executedBlock_in: [BigInt!] + executedBlock_not_in: [BigInt!] + executedTransaction: Bytes + executedTransaction_not: Bytes + executedTransaction_gt: Bytes + executedTransaction_lt: Bytes + executedTransaction_gte: Bytes + executedTransaction_lte: Bytes + executedTransaction_in: [Bytes!] + executedTransaction_not_in: [Bytes!] + executedTransaction_contains: Bytes + executedTransaction_not_contains: Bytes + executedLogIndex: BigInt + executedLogIndex_not: BigInt + executedLogIndex_gt: BigInt + executedLogIndex_lt: BigInt + executedLogIndex_gte: BigInt + executedLogIndex_lte: BigInt + executedLogIndex_in: [BigInt!] + executedLogIndex_not_in: [BigInt!] + executedTimestamp: BigInt + executedTimestamp_not: BigInt + executedTimestamp_gt: BigInt + executedTimestamp_lt: BigInt + executedTimestamp_gte: BigInt + executedTimestamp_lte: BigInt + executedTimestamp_in: [BigInt!] + executedTimestamp_not_in: [BigInt!] + version: BigInt + version_not: BigInt + version_gt: BigInt + version_lt: BigInt + version_gte: BigInt + version_lte: BigInt + version_in: [BigInt!] + version_not_in: [BigInt!] + tokens: [String!] + tokens_not: [String!] + tokens_contains: [String!] + tokens_contains_nocase: [String!] + tokens_not_contains: [String!] + tokens_not_contains_nocase: [String!] + tokens_: Token_filter + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + position: String + position_not: String + position_gt: String + position_lt: String + position_gte: String + position_lte: String + position_in: [String!] + position_not_in: [String!] + position_contains: String + position_contains_nocase: String + position_not_contains: String + position_not_contains_nocase: String + position_starts_with: String + position_starts_with_nocase: String + position_not_starts_with: String + position_not_starts_with_nocase: String + position_ends_with: String + position_ends_with_nocase: String + position_not_ends_with: String + position_not_ends_with_nocase: String + position_: Position_filter + operationName: String + operationName_not: String + operationName_gt: String + operationName_lt: String + operationName_gte: String + operationName_lte: String + operationName_in: [String!] + operationName_not_in: [String!] + operationName_contains: String + operationName_contains_nocase: String + operationName_not_contains: String + operationName_not_contains_nocase: String + operationName_starts_with: String + operationName_starts_with_nocase: String + operationName_not_starts_with: String + operationName_not_starts_with_nocase: String + operationName_ends_with: String + operationName_ends_with_nocase: String + operationName_not_ends_with: String + operationName_not_ends_with_nocase: String + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Trigger_filter] + or: [Trigger_filter] +} + +enum Trigger_orderBy { + id + account + account__id + account__address + account__type + account__vaultId + user + user__id + user__openPositions + commandAddress + triggerType + kind + triggerData + continuous + decodedData + decodedDataNames + addedBlock + addedTransaction + addedLogIndex + addedTimestamp + removedBlock + removedTransaction + removedLogIndex + removedTimestamp + executedBlock + executedTransaction + executedLogIndex + executedTimestamp + version + tokens + protocol + marketId + position + position__id + position__protocol + position__marketId + position__positionType + position__cumulativeDepositedUSD + position__cumulativeWithdrawnUSD + position__cumulativeDeltaUSD + position__cumulativeFeesUSD + position__debt + position__debtInUSD + position__collateral + position__collateralInUSD + position__supply + position__supplyInUSD + position__netValue + position___ajnaBucket + operationName +} + +type TriggerEvent { + id: Bytes! + eventType: String! + trigger: Trigger! + account: Account! + user: User! + mainEventHash: SummerEvent + protocol: String! + marketId: String! + position: Position! + block: BigInt! + transactionHash: Bytes! + logIndex: BigInt! + timestamp: BigInt! +} + +input TriggerEvent_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + eventType: String + eventType_not: String + eventType_gt: String + eventType_lt: String + eventType_gte: String + eventType_lte: String + eventType_in: [String!] + eventType_not_in: [String!] + eventType_contains: String + eventType_contains_nocase: String + eventType_not_contains: String + eventType_not_contains_nocase: String + eventType_starts_with: String + eventType_starts_with_nocase: String + eventType_not_starts_with: String + eventType_not_starts_with_nocase: String + eventType_ends_with: String + eventType_ends_with_nocase: String + eventType_not_ends_with: String + eventType_not_ends_with_nocase: String + trigger: String + trigger_not: String + trigger_gt: String + trigger_lt: String + trigger_gte: String + trigger_lte: String + trigger_in: [String!] + trigger_not_in: [String!] + trigger_contains: String + trigger_contains_nocase: String + trigger_not_contains: String + trigger_not_contains_nocase: String + trigger_starts_with: String + trigger_starts_with_nocase: String + trigger_not_starts_with: String + trigger_not_starts_with_nocase: String + trigger_ends_with: String + trigger_ends_with_nocase: String + trigger_not_ends_with: String + trigger_not_ends_with_nocase: String + trigger_: Trigger_filter + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + mainEventHash: String + mainEventHash_not: String + mainEventHash_gt: String + mainEventHash_lt: String + mainEventHash_gte: String + mainEventHash_lte: String + mainEventHash_in: [String!] + mainEventHash_not_in: [String!] + mainEventHash_contains: String + mainEventHash_contains_nocase: String + mainEventHash_not_contains: String + mainEventHash_not_contains_nocase: String + mainEventHash_starts_with: String + mainEventHash_starts_with_nocase: String + mainEventHash_not_starts_with: String + mainEventHash_not_starts_with_nocase: String + mainEventHash_ends_with: String + mainEventHash_ends_with_nocase: String + mainEventHash_not_ends_with: String + mainEventHash_not_ends_with_nocase: String + mainEventHash_: SummerEvent_filter + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + position: String + position_not: String + position_gt: String + position_lt: String + position_gte: String + position_lte: String + position_in: [String!] + position_not_in: [String!] + position_contains: String + position_contains_nocase: String + position_not_contains: String + position_not_contains_nocase: String + position_starts_with: String + position_starts_with_nocase: String + position_not_starts_with: String + position_not_starts_with_nocase: String + position_ends_with: String + position_ends_with_nocase: String + position_not_ends_with: String + position_not_ends_with_nocase: String + position_: Position_filter + block: BigInt + block_not: BigInt + block_gt: BigInt + block_lt: BigInt + block_gte: BigInt + block_lte: BigInt + block_in: [BigInt!] + block_not_in: [BigInt!] + transactionHash: Bytes + transactionHash_not: Bytes + transactionHash_gt: Bytes + transactionHash_lt: Bytes + transactionHash_gte: Bytes + transactionHash_lte: Bytes + transactionHash_in: [Bytes!] + transactionHash_not_in: [Bytes!] + transactionHash_contains: Bytes + transactionHash_not_contains: Bytes + logIndex: BigInt + logIndex_not: BigInt + logIndex_gt: BigInt + logIndex_lt: BigInt + logIndex_gte: BigInt + logIndex_lte: BigInt + logIndex_in: [BigInt!] + logIndex_not_in: [BigInt!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [TriggerEvent_filter] + or: [TriggerEvent_filter] +} + +enum TriggerEvent_orderBy { + id + eventType + trigger + trigger__id + trigger__commandAddress + trigger__triggerType + trigger__kind + trigger__triggerData + trigger__continuous + trigger__addedBlock + trigger__addedTransaction + trigger__addedLogIndex + trigger__addedTimestamp + trigger__removedBlock + trigger__removedTransaction + trigger__removedLogIndex + trigger__removedTimestamp + trigger__executedBlock + trigger__executedTransaction + trigger__executedLogIndex + trigger__executedTimestamp + trigger__version + trigger__protocol + trigger__marketId + trigger__operationName + account + account__id + account__address + account__type + account__vaultId + user + user__id + user__openPositions + mainEventHash + mainEventHash__id + mainEventHash__blockNumber + mainEventHash__timestamp + mainEventHash__txHash + mainEventHash__logIndex + mainEventHash__sender + mainEventHash__kind + mainEventHash__depositedUSD + mainEventHash__withdrawnUSD + mainEventHash__deltaUSD + mainEventHash__feePaidUSD + mainEventHash__protocol + mainEventHash__marketId + mainEventHash__debtBefore + mainEventHash__debtInUSDBefore + mainEventHash__debtAfter + mainEventHash__debtInUSDAfter + mainEventHash__collateralBefore + mainEventHash__collateralInUSDBefore + mainEventHash__collateralAfter + mainEventHash__collateralInUSDAfter + mainEventHash__supplyBefore + mainEventHash__supplyInUSDBefore + mainEventHash__supplyAfter + mainEventHash__supplyInUSDAfter + mainEventHash__netValueBefore + mainEventHash__netValueAfter + mainEventHash__collateralTokenPriceInUSD + mainEventHash__debtTokenPriceInUSD + mainEventHash__supplyTokenPriceInUSD + protocol + marketId + position + position__id + position__protocol + position__marketId + position__positionType + position__cumulativeDepositedUSD + position__cumulativeWithdrawnUSD + position__cumulativeDeltaUSD + position__cumulativeFeesUSD + position__debt + position__debtInUSD + position__collateral + position__collateralInUSD + position__supply + position__supplyInUSD + position__netValue + position___ajnaBucket + block + transactionHash + logIndex + timestamp +} + +type User { + """ msg.sender address """ + id: Bytes! + accounts(skip: Int = 0, first: Int = 100, orderBy: Account_orderBy, orderDirection: OrderDirection, where: Account_filter): [Account!]! + feePaids(skip: Int = 0, first: Int = 100, orderBy: FeePaid_orderBy, orderDirection: OrderDirection, where: FeePaid_filter): [FeePaid!]! + summerEvents(skip: Int = 0, first: Int = 100, orderBy: SummerEvent_orderBy, orderDirection: OrderDirection, where: SummerEvent_filter): [SummerEvent!]! + createPositionEvents(skip: Int = 0, first: Int = 100, orderBy: CreatePositionEvent_orderBy, orderDirection: OrderDirection, where: CreatePositionEvent_filter): [CreatePositionEvent!]! + automationEvents(skip: Int = 0, first: Int = 100, orderBy: TriggerEvent_orderBy, orderDirection: OrderDirection, where: TriggerEvent_filter): [TriggerEvent!]! + positions(skip: Int = 0, first: Int = 100, orderBy: Position_orderBy, orderDirection: OrderDirection, where: Position_filter): [Position!]! + swaps(skip: Int = 0, first: Int = 100, orderBy: AssetSwap_orderBy, orderDirection: OrderDirection, where: AssetSwap_filter): [AssetSwap!]! + openPositions: BigInt! +} + +input User_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + accounts_: Account_filter + feePaids_: FeePaid_filter + summerEvents_: SummerEvent_filter + createPositionEvents_: CreatePositionEvent_filter + automationEvents_: TriggerEvent_filter + positions_: Position_filter + swaps_: AssetSwap_filter + openPositions: BigInt + openPositions_not: BigInt + openPositions_gt: BigInt + openPositions_lt: BigInt + openPositions_gte: BigInt + openPositions_lte: BigInt + openPositions_in: [BigInt!] + openPositions_not_in: [BigInt!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [User_filter] + or: [User_filter] +} + +enum User_orderBy { + id + accounts + feePaids + summerEvents + createPositionEvents + automationEvents + positions + swaps + openPositions +} + diff --git a/packages/summer-events-subgraph/src/index.ts b/packages/summer-events-subgraph/src/index.ts new file mode 100644 index 0000000000..da38279959 --- /dev/null +++ b/packages/summer-events-subgraph/src/index.ts @@ -0,0 +1,95 @@ +import { request } from 'graphql-request' + +import { ChainId } from '@summerfi/serverless-shared' +import { Logger } from '@summerfi/abstractions' +import { + SummerPointsDocument, + SummerPointsQuery, + SummerPointsQueryVariables, +} from './types/graphql/generated' + +const chainIdSubgraphMap: Partial> = { + [ChainId.MAINNET]: 'summer-events', + [ChainId.BASE]: 'summer-events-base', + [ChainId.OPTIMISM]: 'summer-events-optimism', + [ChainId.ARBITRUM]: 'summer-events-arbitrum', +} + +const getEndpoint = (chainId: ChainId, baseUrl: string) => { + const subgraph = chainIdSubgraphMap[chainId] + if (!subgraph) { + throw new Error(`No subgraph for chainId ${chainId}`) + } + return `${baseUrl}/${subgraph}` +} + +interface SubgraphClientConfig { + chainId: ChainId + urlBase: string + logger?: Logger +} + +export interface GetUsersPointsParams { + startTimestamp: number // In seconds. + endTimestamp: number // In seconds. +} + +export type ArrayElement = ArrayType[number] +export type User = ArrayElement +export type Position = ArrayElement +export type MigrationEvent = ArrayElement +export type RecentSwap = ArrayElement +export type UsersData = SummerPointsQuery['users'] + +export interface GetUsersPointsResult { + users: User[] +} + +export type GetUsersPoints = (params: GetUsersPointsParams) => Promise + +export const START_POINTS_TIMESTAMP = 1717372800 + +async function getUsersPoints( + params: GetUsersPointsParams, + config: SubgraphClientConfig, +): Promise { + const url = getEndpoint(config.chainId, config.urlBase) + const first = 1000 + let lastId = '' + const results: SummerPointsQuery = { users: [] } + + const { startTimestamp, endTimestamp } = params + + let data: SummerPointsQuery + do { + const variables: SummerPointsQueryVariables = { + first, + lastId, // Use lastID as the id_gt parameter + startTimestamp, + endTimestamp, + pointsStartTimestamp: START_POINTS_TIMESTAMP, + } + + data = await request(url, SummerPointsDocument, variables) + results.users.push(...data.users) + + // Set lastID to the ID of the last item in the fetched data + lastId = data.users[data.users.length - 1].id + } while (data.users.length >= first) + + return { + users: results.users, + } +} + +export interface SummerPointsSubgraphClient { + getUsersPoints: GetUsersPoints +} + +export function getSummerPointsSubgraphClient( + config: SubgraphClientConfig, +): SummerPointsSubgraphClient { + return { + getUsersPoints: (params: GetUsersPointsParams) => getUsersPoints(params, config), + } +} diff --git a/packages/summer-events-subgraph/tsconfig.json b/packages/summer-events-subgraph/tsconfig.json new file mode 100644 index 0000000000..51ebeeab47 --- /dev/null +++ b/packages/summer-events-subgraph/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@summerfi/typescript-config/tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "**/*.spec.ts"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ba769d0f41..3aa15a5834 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,6 +106,49 @@ importers: specifier: ^8.0.1 version: 8.0.1 + background-jobs/update-rays-cron-function: + dependencies: + '@aws-lambda-powertools/logger': + specifier: ^2.0.2 + version: 2.0.4 + '@aws-lambda-powertools/metrics': + specifier: ^2.0.2 + version: 2.0.4 + '@aws-lambda-powertools/tracer': + specifier: ^2.0.2 + version: 2.0.4 + '@summerfi/rays-db': + specifier: workspace:* + version: link:../../packages/rays-db + '@summerfi/serverless-shared': + specifier: workspace:* + version: link:../../packages/serverless-shared + '@summerfi/summer-events-subgraph': + specifier: workspace:* + version: link:../../packages/summer-events-subgraph + kysely: + specifier: ^0.27.3 + version: 0.27.3 + zod: + specifier: ^3.22.4 + version: 3.22.4 + devDependencies: + '@summerfi/eslint-config': + specifier: workspace:* + version: link:../../packages/eslint-config + '@summerfi/typescript-config': + specifier: workspace:* + version: link:../../packages/typescript-config + '@types/node': + specifier: ^20.11.5 + version: 20.12.7 + eslint: + specifier: ^8.56.0 + version: 8.57.0 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@20.12.7) + external-api/get-collateral-locked-function: dependencies: '@aws-lambda-powertools/logger': @@ -546,15 +589,12 @@ importers: packages/rays-db: dependencies: - '@aws-sdk/client-rds-data': - specifier: ^3.565.0 - version: 3.569.0 + '@summerfi/abstractions': + specifier: workspace:* + version: link:../abstractions kysely: specifier: ^0.27.3 version: 0.27.3 - kysely-data-api: - specifier: ^0.2.1 - version: 0.2.1(@aws-sdk/client-rds-data@3.569.0)(kysely@0.27.3) kysely-postgres-js: specifier: ^2.0.0 version: 2.0.0(kysely@0.27.3)(postgres@3.4.4) @@ -604,7 +644,7 @@ importers: dependencies: viem: specifier: ^2.9.19 - version: 2.9.19(typescript@5.4.5)(zod@3.22.4) + version: 2.10.8(typescript@5.4.5)(zod@3.22.4) zod: specifier: ^3.22.4 version: 3.22.4 @@ -622,6 +662,31 @@ importers: specifier: ^8.57.0 version: 8.57.0 + packages/summer-events-subgraph: + dependencies: + '@summerfi/abstractions': + specifier: workspace:* + version: link:../abstractions + '@summerfi/serverless-shared': + specifier: workspace:* + version: link:../serverless-shared + graphql-request: + specifier: ^6.1.0 + version: 6.1.0(graphql@16.8.1) + devDependencies: + '@summerfi/eslint-config': + specifier: workspace:* + version: link:../eslint-config + '@summerfi/typescript-config': + specifier: workspace:* + version: link:../typescript-config + '@types/node': + specifier: ^20.12.7 + version: 20.12.7 + eslint: + specifier: ^8.57.0 + version: 8.57.0 + packages/tenderly-utils: dependencies: '@inquirer/prompts': @@ -1750,9 +1815,6 @@ importers: '@aws-lambda-powertools/tracer': specifier: ^2.0.2 version: 2.0.4 - '@aws-sdk/client-rds-data': - specifier: ^3.565.0 - version: 3.569.0 '@summerfi/abstractions': specifier: workspace:* version: link:../../packages/abstractions @@ -1768,9 +1830,6 @@ importers: node-fetch: specifier: ^3.3.2 version: 3.3.2 - viem: - specifier: ^1.19.11 - version: 1.21.4(typescript@5.4.5)(zod@3.22.4) zod: specifier: ^3.22.4 version: 3.22.4 @@ -2172,6 +2231,7 @@ packages: resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} dependencies: tslib: 1.14.1 + dev: true /@aws-crypto/sha1-browser@3.0.0: resolution: {integrity: sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==} @@ -2196,6 +2256,7 @@ packages: '@aws-sdk/util-locate-window': 3.535.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 + dev: true /@aws-crypto/sha256-js@3.0.0: resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} @@ -2203,6 +2264,7 @@ packages: '@aws-crypto/util': 3.0.0 '@aws-sdk/types': 3.567.0 tslib: 1.14.1 + dev: true /@aws-crypto/sha256-js@5.2.0: resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} @@ -2217,6 +2279,7 @@ packages: resolution: {integrity: sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==} dependencies: tslib: 1.14.1 + dev: true /@aws-crypto/util@3.0.0: resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} @@ -2224,6 +2287,7 @@ packages: '@aws-sdk/types': 3.567.0 '@aws-sdk/util-utf8-browser': 3.259.0 tslib: 1.14.1 + dev: true /@aws-crypto/util@5.2.0: resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} @@ -2754,6 +2818,7 @@ packages: tslib: 2.6.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/client-s3@3.554.0: resolution: {integrity: sha512-d5TKKtGWhN0vl9QovUFrf3UsM7jgFQkowDPx1O+E/yeQUj1FBDOoRfDCcQOKW/9ghloI6k7f0bBpNxdd+x0oKA==} @@ -2967,6 +3032,7 @@ packages: transitivePeerDependencies: - '@aws-sdk/client-sts' - aws-crt + dev: true /@aws-sdk/client-sso@3.554.0: resolution: {integrity: sha512-yj6CgIxCT3UwMumEO481KH4QvwArkAPzD7Xvwe1QKgJATc9bKNEo/FxV8LfnWIJ7nOtMDxbNxYLMXH/Fs1qGaQ==} @@ -3058,6 +3124,7 @@ packages: tslib: 2.6.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/client-sts@3.554.0(@aws-sdk/credential-provider-node@3.554.0): resolution: {integrity: sha512-EhaA6T0M0DNg5M8TCF1a7XJI5D/ZxAF3dgVIchyF98iNzjYgl/7U8K6hJay2A11aFvVu70g46xYMpz3Meky4wQ==} @@ -3154,6 +3221,7 @@ packages: tslib: 2.6.2 transitivePeerDependencies: - aws-crt + dev: true /@aws-sdk/config-resolver@3.374.0: resolution: {integrity: sha512-eTSbmpcgZ97o7PuFls8pH1344OS03nfqq1NO9HxxvoYoZ6DFfUO7kqKeNUhP9LxOF7slyHXajDT7eoPclGnTuw==} @@ -3188,6 +3256,7 @@ packages: '@smithy/types': 2.12.0 fast-xml-parser: 4.2.5 tslib: 2.6.2 + dev: true /@aws-sdk/credential-provider-cognito-identity@3.554.0: resolution: {integrity: sha512-soF84soy9rTAfzsH1ODP0AnJt5JlsJI8k1aWtC08/Al0CZjLkxDRHzaB1wxubFyT2Ql6bpxbDfU6KDFXsQIpdA==} @@ -3220,6 +3289,7 @@ packages: '@smithy/property-provider': 2.2.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@aws-sdk/credential-provider-http@3.552.0: resolution: {integrity: sha512-vsmu7Cz1i45pFEqzVb4JcFmAmVnWFNLsGheZc8SCptlqCO5voETrZZILHYIl4cjKkSDk3pblBOf0PhyjqWW6WQ==} @@ -3249,6 +3319,7 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-stream': 2.2.0 tslib: 2.6.2 + dev: true /@aws-sdk/credential-provider-ini@3.554.0(@aws-sdk/credential-provider-node@3.554.0): resolution: {integrity: sha512-BQenhg43S6TMJHxrdjDVdVF+HH5tA1op9ZYLyJrvV5nn7CCO4kyAkkOuSAv1NkL+RZsIkW0/vHTXwQOQw3cUsg==} @@ -3290,6 +3361,7 @@ packages: transitivePeerDependencies: - '@aws-sdk/client-sso-oidc' - aws-crt + dev: true /@aws-sdk/credential-provider-node@3.554.0: resolution: {integrity: sha512-poX/+2OE3oxqp4f5MiaJh251p8l+bzcFwgcDBwz0e2rcpvMSYl9jw4AvGnCiG2bmf9yhNJdftBiS1A+KjxV0qA==} @@ -3331,6 +3403,7 @@ packages: - '@aws-sdk/client-sso-oidc' - '@aws-sdk/client-sts' - aws-crt + dev: true /@aws-sdk/credential-provider-process@3.535.0: resolution: {integrity: sha512-9O1OaprGCnlb/kYl8RwmH7Mlg8JREZctB8r9sa1KhSsWFq/SWO0AuJTyowxD7zL5PkeS4eTvzFFHWCa3OO5epA==} @@ -3352,6 +3425,7 @@ packages: '@smithy/shared-ini-file-loader': 2.4.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@aws-sdk/credential-provider-sso@3.554.0(@aws-sdk/credential-provider-node@3.554.0): resolution: {integrity: sha512-8QPpwBA31i/fZ7lDZJC4FA9EdxLg5SJ8sPB2qLSjp5UTGTYL2HRl0Eznkb7DXyp/wImsR/HFR1NxuFCCVotLCg==} @@ -3383,6 +3457,7 @@ packages: transitivePeerDependencies: - '@aws-sdk/client-sso-oidc' - aws-crt + dev: true /@aws-sdk/credential-provider-web-identity@3.554.0(@aws-sdk/credential-provider-node@3.554.0): resolution: {integrity: sha512-HN54DzLjepw5ZWSF9ycGevhFTyg6pjLuLKy5Y8t/f1jFDComzYdGEDe0cdV9YO653W3+PQwZZGz09YVygGYBLg==} @@ -3409,6 +3484,7 @@ packages: '@smithy/property-provider': 2.2.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@aws-sdk/credential-providers@3.554.0: resolution: {integrity: sha512-UMmJ4M7RknSz1p0981t57QUw6DibPEo/GG8+env6Q8dHrEc3pnRL206f1zxLcqzT5RI50XstH/bDtnyC7uRYiw==} @@ -3489,6 +3565,7 @@ packages: '@smithy/protocol-http': 3.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@aws-sdk/middleware-location-constraint@3.535.0: resolution: {integrity: sha512-SxfS9wfidUZZ+WnlKRTCRn3h+XTsymXRXPJj8VV6hNRNeOwzNweoG3YhQbTowuuNfXf89m9v6meYkBBtkdacKw==} @@ -3515,6 +3592,7 @@ packages: '@aws-sdk/types': 3.567.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@aws-sdk/middleware-recursion-detection@3.535.0: resolution: {integrity: sha512-am2qgGs+gwqmR4wHLWpzlZ8PWhm4ktj5bYSgDrsOfjhdBlWNxvPoID9/pDAz5RWL48+oH7I6SQzMqxXsFDikrw==} @@ -3534,6 +3612,7 @@ packages: '@smithy/protocol-http': 3.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@aws-sdk/middleware-retry@3.374.0: resolution: {integrity: sha512-ZnT84qnT+Zmelv7y6hAqgAEaZgpGlrvf/+rchNWT0oG4duxI5bLWcRi9U88Jz7G8JgNQcGKJqPfC6oogCd7p8w==} @@ -3602,6 +3681,7 @@ packages: '@smithy/protocol-http': 3.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@aws-sdk/region-config-resolver@3.535.0: resolution: {integrity: sha512-IXOznDiaItBjsQy4Fil0kzX/J3HxIOknEphqHbOfUf+LpA5ugcsxuQQONrbEQusCBnfJyymrldBvBhFmtlU9Wg==} @@ -3625,6 +3705,7 @@ packages: '@smithy/util-config-provider': 2.3.0 '@smithy/util-middleware': 2.2.0 tslib: 2.6.2 + dev: true /@aws-sdk/signature-v4-crt@3.552.0: resolution: {integrity: sha512-5Dy4E2RtHw3hFCx5L+OsRN2n1OW3yoX06xDPqJ5xe38Pd9H8ZPYxiCEOdyw/TIJUwRjDMgsa2uPKyM/Nwr9cMg==} @@ -3694,6 +3775,7 @@ packages: '@smithy/shared-ini-file-loader': 2.4.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@aws-sdk/types@3.535.0: resolution: {integrity: sha512-aY4MYfduNj+sRR37U7XxYR8wemfbKP6lx00ze2M2uubn7mZotuVrWYAafbMSXrdEMSToE5JDhr28vArSOoLcSg==} @@ -3708,6 +3790,7 @@ packages: dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@aws-sdk/util-arn-parser@3.535.0: resolution: {integrity: sha512-smVo29nUPAOprp8Z5Y3GHuhiOtw6c8/EtLCm5AVMtRsTPw4V414ZXL2H66tzmb5kEeSzQlbfBSBEdIFZoxO9kg==} @@ -3734,12 +3817,14 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-endpoints': 1.2.0 tslib: 2.6.2 + dev: true /@aws-sdk/util-locate-window@3.535.0: resolution: {integrity: sha512-PHJ3SL6d2jpcgbqdgiPxkXpu7Drc2PYViwxSIqvvMKhDwzSB1W3mMvtpzwKM4IE7zLFodZo0GKjJ9AsoXndXhA==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 + dev: true /@aws-sdk/util-user-agent-browser@3.535.0: resolution: {integrity: sha512-RWMcF/xV5n+nhaA/Ff5P3yNP3Kur/I+VNZngog4TEs92oB/nwOdAg/2JL8bVAhUbMrjTjpwm7PItziYFQoqyig==} @@ -3757,6 +3842,7 @@ packages: '@smithy/types': 2.12.0 bowser: 2.11.0 tslib: 2.6.2 + dev: true /@aws-sdk/util-user-agent-node@3.535.0(aws-crt@1.21.2): resolution: {integrity: sha512-dRek0zUuIT25wOWJlsRm97nTkUlh1NDcLsQZIN2Y8KxhwoXXWtJs5vaDPT+qAg+OpcNj80i1zLR/CirqlFg/TQ==} @@ -3787,11 +3873,13 @@ packages: '@smithy/node-config-provider': 2.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@aws-sdk/util-utf8-browser@3.259.0: resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} dependencies: tslib: 2.6.2 + dev: true /@aws-sdk/xml-builder@3.535.0: resolution: {integrity: sha512-VXAq/Jz8KIrU84+HqsOJhIKZqG0PNTdi6n6PFQ4xJf44ZQHD/5C7ouH4qCFX5XgZXcgbRIcMVVYGC6Jye0dRng==} @@ -7592,6 +7680,7 @@ packages: dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/chunked-blob-reader-native@2.2.0: resolution: {integrity: sha512-VNB5+1oCgX3Fzs072yuRsUoC2N4Zg/LJ11DTxX3+Qu+Paa6AmbIF0E9sc2wthz9Psrk/zcOlTCyuposlIhPjZQ==} @@ -7625,6 +7714,7 @@ packages: '@smithy/util-config-provider': 2.3.0 '@smithy/util-middleware': 2.2.0 tslib: 2.6.2 + dev: true /@smithy/core@1.4.2: resolution: {integrity: sha512-2fek3I0KZHWJlRLvRTqxTEri+qV0GRHrJIoLFuBMZB4EMg4WgeBGfF0X6abnrNYpq55KJ6R4D6x4f0vLnhzinA==} @@ -7638,6 +7728,7 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-middleware': 2.2.0 tslib: 2.6.2 + dev: true /@smithy/credential-provider-imds@2.3.0: resolution: {integrity: sha512-BWB9mIukO1wjEOo1Ojgl6LrG4avcaC7T/ZP6ptmAaW4xluhSIPZhY+/PI5YKzlk+jsm+4sQZB45Bt1OfMeQa3w==} @@ -7648,6 +7739,7 @@ packages: '@smithy/types': 2.12.0 '@smithy/url-parser': 2.2.0 tslib: 2.6.2 + dev: true /@smithy/eventstream-codec@2.2.0: resolution: {integrity: sha512-8janZoJw85nJmQZc4L8TuePp2pk1nxLgkxIR0TUjKJ5Dkj5oelB9WtiSSGXCQvNsJl0VSTvK/2ueMXxvpa9GVw==} @@ -7711,6 +7803,7 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-base64': 2.3.0 tslib: 2.6.2 + dev: true /@smithy/hash-blob-browser@2.2.0: resolution: {integrity: sha512-SGPoVH8mdXBqrkVCJ1Hd1X7vh1zDXojNN1yZyZTZsCno99hVue9+IYzWDjq/EQDDXxmITB0gBmuyPh8oAZSTcg==} @@ -7729,6 +7822,7 @@ packages: '@smithy/util-buffer-from': 2.2.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 + dev: true /@smithy/hash-stream-node@2.2.0: resolution: {integrity: sha512-aT+HCATOSRMGpPI7bi7NSsTNVZE/La9IaxLXWoVAYMxHT5hGO3ZOGEMZQg8A6nNL+pdFGtZQtND1eoY084HgHQ==} @@ -7744,6 +7838,7 @@ packages: dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/is-array-buffer@1.1.0: resolution: {integrity: sha512-twpQ/n+3OWZJ7Z+xu43MJErmhB/WO/mMTnqR6PwWQShvSJ/emx5d1N59LQZk6ZpTAeuRWrc+eHhkzTp9NFjNRQ==} @@ -7757,6 +7852,7 @@ packages: engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 + dev: true /@smithy/md5-js@2.2.0: resolution: {integrity: sha512-M26XTtt9IIusVMOWEAhIvFIr9jYj4ISPPGJROqw6vXngO3IYJCnVVSMFn4Tx1rUTG5BiKJNg9u2nxmBiZC5IlQ==} @@ -7773,6 +7869,7 @@ packages: '@smithy/protocol-http': 3.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/middleware-endpoint@2.5.1: resolution: {integrity: sha512-1/8kFp6Fl4OsSIVTWHnNjLnTL8IqpIb/D3sTSczrKFnrE9VMNWxnrRKNvpUHOJ6zpGD5f62TPm7+17ilTJpiCQ==} @@ -7785,6 +7882,7 @@ packages: '@smithy/url-parser': 2.2.0 '@smithy/util-middleware': 2.2.0 tslib: 2.6.2 + dev: true /@smithy/middleware-retry@1.1.0: resolution: {integrity: sha512-lINKYxIvT+W20YFOtHBKeGm7npuJg0/YCoShttU7fVpsmU+a2rdb9zrJn1MHqWfUL6DhTAWGa0tH2O7l4XrDcw==} @@ -7812,6 +7910,7 @@ packages: '@smithy/util-retry': 2.2.0 tslib: 2.6.2 uuid: 9.0.1 + dev: true /@smithy/middleware-serde@2.3.0: resolution: {integrity: sha512-sIADe7ojwqTyvEQBe1nc/GXB9wdHhi9UwyX0lTyttmUWDJLP655ZYE1WngnNyXREme8I27KCaUhyhZWRXL0q7Q==} @@ -7819,6 +7918,7 @@ packages: dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/middleware-stack@1.1.0: resolution: {integrity: sha512-XynYiIvXNea2BbLcppvpNK0zu8o2woJqgnmxqYTn4FWagH/Hr2QIk8LOsUz7BIJ4tooFhmx8urHKCdlPbbPDCA==} @@ -7833,6 +7933,7 @@ packages: dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/node-config-provider@2.3.0: resolution: {integrity: sha512-0elK5/03a1JPWMDPaS726Iw6LpQg80gFut1tNpPfxFuChEEklo2yL823V94SpTZTxmKlXFtFgsP55uh3dErnIg==} @@ -7842,6 +7943,7 @@ packages: '@smithy/shared-ini-file-loader': 2.4.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/node-http-handler@1.1.0: resolution: {integrity: sha512-d3kRriEgaIiGXLziAM8bjnaLn1fthCJeTLZIwEIpzQqe6yPX0a+yQoLCTyjb2fvdLwkMoG4p7THIIB5cj5lkbg==} @@ -7863,6 +7965,7 @@ packages: '@smithy/querystring-builder': 2.2.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/property-provider@2.2.0: resolution: {integrity: sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg==} @@ -7870,6 +7973,7 @@ packages: dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/protocol-http@1.2.0: resolution: {integrity: sha512-GfGfruksi3nXdFok5RhgtOnWe5f6BndzYfmEXISD+5gAGdayFGpjWu5pIqIweTudMtse20bGbc+7MFZXT1Tb8Q==} @@ -7885,6 +7989,7 @@ packages: dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/querystring-builder@1.1.0: resolution: {integrity: sha512-gDEi4LxIGLbdfjrjiY45QNbuDmpkwh9DX4xzrR2AzjjXpxwGyfSpbJaYhXARw9p17VH0h9UewnNQXNwaQyYMDA==} @@ -7902,6 +8007,7 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-uri-escape': 2.2.0 tslib: 2.6.2 + dev: true /@smithy/querystring-parser@2.2.0: resolution: {integrity: sha512-BvHCDrKfbG5Yhbpj4vsbuPV2GgcpHiAkLeIlcA1LtfpMz3jrqizP1+OguSNSj1MwBHEiN+jwNisXLGdajGDQJA==} @@ -7909,6 +8015,7 @@ packages: dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/service-error-classification@1.1.0: resolution: {integrity: sha512-OCTEeJ1igatd5kFrS2VDlYbainNNpf7Lj1siFOxnRWqYOP9oNvC5HOJBd3t+Z8MbrmehBtuDJ2QqeBsfeiNkww==} @@ -7927,6 +8034,7 @@ packages: dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/signature-v4@2.3.0: resolution: {integrity: sha512-ui/NlpILU+6HAQBfJX8BBsDXuKSNrjTSuOYArRblcrErwKFutjrCNb/OExfVRyj9+26F9J+ZmfWT+fKWuDrH3Q==} @@ -7939,6 +8047,7 @@ packages: '@smithy/util-uri-escape': 2.2.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 + dev: true /@smithy/smithy-client@1.1.0: resolution: {integrity: sha512-j32SGgVhv2G9nBTmel9u3OXux8KG20ssxuFakJrEeDug3kqbl1qrGzVLCe+Eib402UDtA0Sp1a4NZ2SEXDBxag==} @@ -7960,6 +8069,7 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-stream': 2.2.0 tslib: 2.6.2 + dev: true /@smithy/types@1.2.0: resolution: {integrity: sha512-z1r00TvBqF3dh4aHhya7nz1HhvCg4TRmw51fjMrh5do3h+ngSstt/yKlNbHeb9QxJmFbmN8KEVSWgb1bRvfEoA==} @@ -7980,6 +8090,7 @@ packages: '@smithy/querystring-parser': 2.2.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/util-base64@1.1.0: resolution: {integrity: sha512-FpYmDmVbOXAxqvoVCwqehUN0zXS+lN8V7VS9O7I8MKeVHdSTsZzlwiMEvGoyTNOXWn8luF4CTDYgNHnZViR30g==} @@ -7996,17 +8107,20 @@ packages: '@smithy/util-buffer-from': 2.2.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 + dev: true /@smithy/util-body-length-browser@2.2.0: resolution: {integrity: sha512-dtpw9uQP7W+n3vOtx0CfBD5EWd7EPdIdsQnWTDoFf77e3VUf05uA7R7TGipIo8e4WL2kuPdnsr3hMQn9ziYj5w==} dependencies: tslib: 2.6.2 + dev: true /@smithy/util-body-length-node@2.3.0: resolution: {integrity: sha512-ITWT1Wqjubf2CJthb0BuT9+bpzBfXeMokH/AAa5EJQgbv9aPMVfnM76iFIZVFf50hYXGbtiV71BHAthNWd6+dw==} engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 + dev: true /@smithy/util-buffer-from@1.1.0: resolution: {integrity: sha512-9m6NXE0ww+ra5HKHCHig20T+FAwxBAm7DIdwc/767uGWbRcY720ybgPacQNB96JMOI7xVr/CDa3oMzKmW4a+kw==} @@ -8022,6 +8136,7 @@ packages: dependencies: '@smithy/is-array-buffer': 2.2.0 tslib: 2.6.2 + dev: true /@smithy/util-config-provider@1.1.0: resolution: {integrity: sha512-rQ47YpNmF6Is4I9GiE3T3+0xQ+r7RKRKbmHYyGSbyep/0cSf9kteKcI0ssJTvveJ1K4QvwrxXj1tEFp/G2UqxQ==} @@ -8035,6 +8150,7 @@ packages: engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 + dev: true /@smithy/util-defaults-mode-browser@2.2.1: resolution: {integrity: sha512-RtKW+8j8skk17SYowucwRUjeh4mCtnm5odCL0Lm2NtHQBsYKrNW0od9Rhopu9wF1gHMfHeWF7i90NwBz/U22Kw==} @@ -8045,6 +8161,7 @@ packages: '@smithy/types': 2.12.0 bowser: 2.11.0 tslib: 2.6.2 + dev: true /@smithy/util-defaults-mode-node@2.3.1: resolution: {integrity: sha512-vkMXHQ0BcLFysBMWgSBLSk3+leMpFSyyFj8zQtv5ZyUBx8/owVh1/pPEkzmW/DR/Gy/5c8vjLDD9gZjXNKbrpA==} @@ -8057,6 +8174,7 @@ packages: '@smithy/smithy-client': 2.5.1 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/util-endpoints@1.2.0: resolution: {integrity: sha512-BuDHv8zRjsE5zXd3PxFXFknzBG3owCpjq8G3FcsXW3CykYXuEqM3nTSsmLzw5q+T12ZYuDlVUZKBdpNbhVtlrQ==} @@ -8065,6 +8183,7 @@ packages: '@smithy/node-config-provider': 2.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/util-hex-encoding@1.1.0: resolution: {integrity: sha512-7UtIE9eH0u41zpB60Jzr0oNCQ3hMJUabMcKRUVjmyHTXiWDE4vjSqN6qlih7rCNeKGbioS7f/y2Jgym4QZcKFg==} @@ -8078,6 +8197,7 @@ packages: engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 + dev: true /@smithy/util-middleware@1.1.0: resolution: {integrity: sha512-6hhckcBqVgjWAqLy2vqlPZ3rfxLDhFWEmM7oLh2POGvsi7j0tHkbN7w4DFhuBExVJAbJ/qqxqZdRY6Fu7/OezQ==} @@ -8092,6 +8212,7 @@ packages: dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/util-retry@1.1.0: resolution: {integrity: sha512-ygQW5HBqYXpR3ua09UciS0sL7UGJzGiktrKkOuEJwARoUuzz40yaEGU6xd9Gs7KBmAaFC8gMfnghHtwZ2nyBCQ==} @@ -8108,6 +8229,7 @@ packages: '@smithy/service-error-classification': 2.1.5 '@smithy/types': 2.12.0 tslib: 2.6.2 + dev: true /@smithy/util-stream@1.1.0: resolution: {integrity: sha512-w3lsdGsntaLQIrwDWJkIFKrFscgZXwU/oxsse09aSTNv5TckPhDeYea3LhsDrU5MGAG3vprhVZAKr33S45coVA==} @@ -8135,6 +8257,7 @@ packages: '@smithy/util-hex-encoding': 2.2.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 + dev: true /@smithy/util-uri-escape@1.1.0: resolution: {integrity: sha512-/jL/V1xdVRt5XppwiaEU8Etp5WHZj609n0xMTuehmCqdoOFbId1M+aEeDWZsQ+8JbEB/BJ6ynY2SlYmOaKtt8w==} @@ -8148,6 +8271,7 @@ packages: engines: {node: '>=14.0.0'} dependencies: tslib: 2.6.2 + dev: true /@smithy/util-utf8@1.1.0: resolution: {integrity: sha512-p/MYV+JmqmPyjdgyN2UxAeYDj9cBqCjp0C/NsTWnnjoZUVqoeZ6IrW915L9CAKWVECgv9lVQGc4u/yz26/bI1A==} @@ -8163,6 +8287,7 @@ packages: dependencies: '@smithy/util-buffer-from': 2.2.0 tslib: 2.6.2 + dev: true /@smithy/util-waiter@2.2.0: resolution: {integrity: sha512-IHk53BVw6MPMi2Gsn+hCng8rFA3ZmR3Rk7GllxDUW9qFJl/hiSvskn7XldkECapQVkIg/1dHpMAxI9xSTaLLSA==} @@ -9600,6 +9725,7 @@ packages: /bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + dev: true /boxen@5.1.2: resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} @@ -11957,6 +12083,7 @@ packages: hasBin: true dependencies: strnum: 1.0.5 + dev: true /fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} @@ -12424,7 +12551,7 @@ packages: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 5.0.1 + minimatch: 5.1.6 once: 1.4.0 dev: true @@ -13431,6 +13558,14 @@ packages: dependencies: ws: 8.13.0 + /isows@1.0.4(ws@8.13.0): + resolution: {integrity: sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ==} + peerDependencies: + ws: '*' + dependencies: + ws: 8.13.0 + dev: false + /istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -14209,16 +14344,6 @@ packages: kysely: 0.25.0 dev: true - /kysely-data-api@0.2.1(@aws-sdk/client-rds-data@3.569.0)(kysely@0.27.3): - resolution: {integrity: sha512-KmASvF1gmjVqyU9WOUXhCQlv29ofR+xc2DhjaIomz1+Bjd/VtR2/3g4ZuXwG1L4lWGKxMuo5iOvK3XyPbB4LdQ==} - peerDependencies: - '@aws-sdk/client-rds-data': 3.x - kysely: 0.x - dependencies: - '@aws-sdk/client-rds-data': 3.569.0 - kysely: 0.27.3 - dev: false - /kysely-postgres-js@2.0.0(kysely@0.27.3)(postgres@3.4.4): resolution: {integrity: sha512-R1tWx6/x3tSatWvsmbHJxpBZYhNNxcnMw52QzZaHKg7ZOWtHib4iZyEaw4gb2hNKVctWQ3jfMxZT/ZaEMK6kBQ==} peerDependencies: @@ -16950,6 +17075,7 @@ packages: /strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + dev: true /stylus-lookup@5.0.1: resolution: {integrity: sha512-tLtJEd5AGvnVy4f9UHQMw4bkJJtaAcmo54N+ovQBjDY3DuWyK9Eltxzr5+KG0q4ew6v2EHyuWWNnHeiw/Eo7rQ==} @@ -17248,6 +17374,7 @@ packages: /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true /tslib@2.4.0: resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} @@ -17622,6 +17749,7 @@ packages: /uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true + dev: true /v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} @@ -17699,6 +17827,29 @@ packages: - zod dev: false + /viem@2.10.8(typescript@5.4.5)(zod@3.22.4): + resolution: {integrity: sha512-ttCXlDmjjcZ8M/eJezXFzDtHj+RFOjEQ3elmXnCC7suXo/y8CuIM1LrIoyUFk7LKIE5E+bzmWUErS4u/MQBtpQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 1.0.0(typescript@5.4.5)(zod@3.22.4) + isows: 1.0.4(ws@8.13.0) + typescript: 5.4.5 + ws: 8.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + dev: false + /viem@2.9.19(typescript@5.4.5)(zod@3.22.4): resolution: {integrity: sha512-1txsVoTz9+XGQpuN62wcDXasNtalW52UR41KnzwWTwHtV2cDcGuVuS/j/hcuQdZ7pU8X8jtq2IrwwR4jjKpy9Q==} peerDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index af37e2971b..941ee7ad01 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -4,6 +4,7 @@ packages: - 'sdk/**' - 'stacks/**' - 'turbo/**' + - 'background-jobs/**' - 'summerfi-api/**' - 'external-api/**' - '!**/test/**' diff --git a/schema.graphql b/schema.graphql new file mode 100644 index 0000000000..5e0780cb01 --- /dev/null +++ b/schema.graphql @@ -0,0 +1,4693 @@ +""" +Marks the GraphQL type as indexable entity. Each type that should be an entity +is required to be annotated with this directive. +""" +directive @entity on OBJECT + +"""Defined a Subgraph ID for an object type""" +directive @subgraphId(id: String!) on OBJECT + +""" +creates a virtual field on the entity that may be queried but cannot be set manually through the mappings API. +""" +directive @derivedFrom(field: String!) on FIELD_DEFINITION + +type _Block_ { + """The hash of the block""" + hash: Bytes + + """The block number""" + number: Int! + + """Integer representation of the timestamp stored in blocks for the chain""" + timestamp: Int +} + +"""The type for the top-level _meta field""" +type _Meta_ { + """ + Information about a specific subgraph block. The hash of the block + will be null if the _meta field has a block constraint that asks for + a block number. It will be filled if the _meta field has no block constraint + and therefore asks for the latest block + + """ + block: _Block_! + + """The deployment ID""" + deployment: String! + + """If `true`, the subgraph encountered indexing errors at some past block""" + hasIndexingErrors: Boolean! +} + +enum _SubgraphErrorPolicy_ { + """Data will be returned even if the subgraph has indexing errors""" + allow + + """ + If the subgraph has indexing errors, data will be omitted. The default. + """ + deny +} + +type Account { + id: Bytes! + address: Bytes! + user: User! + type: String! + vaultId: BigInt! + createPositionEvents(skip: Int = 0, first: Int = 100, orderBy: CreatePositionEvent_orderBy, orderDirection: OrderDirection, where: CreatePositionEvent_filter): [CreatePositionEvent!]! + summerEvents(skip: Int = 0, first: Int = 100, orderBy: SummerEvent_orderBy, orderDirection: OrderDirection, where: SummerEvent_filter): [SummerEvent!]! + feePaids(skip: Int = 0, first: Int = 100, orderBy: FeePaid_orderBy, orderDirection: OrderDirection, where: FeePaid_filter): [FeePaid!]! + automationEvents(skip: Int = 0, first: Int = 100, orderBy: TriggerEvent_orderBy, orderDirection: OrderDirection, where: TriggerEvent_filter): [TriggerEvent!]! + swaps(skip: Int = 0, first: Int = 100, orderBy: AssetSwap_orderBy, orderDirection: OrderDirection, where: AssetSwap_filter): [AssetSwap!]! + positions(skip: Int = 0, first: Int = 100, orderBy: Position_orderBy, orderDirection: OrderDirection, where: Position_filter): [Position!]! + latestCreatePositionEvent: CreatePositionEvent +} + +input Account_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + address: Bytes + address_not: Bytes + address_gt: Bytes + address_lt: Bytes + address_gte: Bytes + address_lte: Bytes + address_in: [Bytes!] + address_not_in: [Bytes!] + address_contains: Bytes + address_not_contains: Bytes + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + type: String + type_not: String + type_gt: String + type_lt: String + type_gte: String + type_lte: String + type_in: [String!] + type_not_in: [String!] + type_contains: String + type_contains_nocase: String + type_not_contains: String + type_not_contains_nocase: String + type_starts_with: String + type_starts_with_nocase: String + type_not_starts_with: String + type_not_starts_with_nocase: String + type_ends_with: String + type_ends_with_nocase: String + type_not_ends_with: String + type_not_ends_with_nocase: String + vaultId: BigInt + vaultId_not: BigInt + vaultId_gt: BigInt + vaultId_lt: BigInt + vaultId_gte: BigInt + vaultId_lte: BigInt + vaultId_in: [BigInt!] + vaultId_not_in: [BigInt!] + createPositionEvents_: CreatePositionEvent_filter + summerEvents_: SummerEvent_filter + feePaids_: FeePaid_filter + automationEvents_: TriggerEvent_filter + swaps_: AssetSwap_filter + positions_: Position_filter + latestCreatePositionEvent: String + latestCreatePositionEvent_not: String + latestCreatePositionEvent_gt: String + latestCreatePositionEvent_lt: String + latestCreatePositionEvent_gte: String + latestCreatePositionEvent_lte: String + latestCreatePositionEvent_in: [String!] + latestCreatePositionEvent_not_in: [String!] + latestCreatePositionEvent_contains: String + latestCreatePositionEvent_contains_nocase: String + latestCreatePositionEvent_not_contains: String + latestCreatePositionEvent_not_contains_nocase: String + latestCreatePositionEvent_starts_with: String + latestCreatePositionEvent_starts_with_nocase: String + latestCreatePositionEvent_not_starts_with: String + latestCreatePositionEvent_not_starts_with_nocase: String + latestCreatePositionEvent_ends_with: String + latestCreatePositionEvent_ends_with_nocase: String + latestCreatePositionEvent_not_ends_with: String + latestCreatePositionEvent_not_ends_with_nocase: String + latestCreatePositionEvent_: CreatePositionEvent_filter + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Account_filter] + or: [Account_filter] +} + +enum Account_orderBy { + id + address + user + user__id + user__openPositions + type + vaultId + createPositionEvents + summerEvents + feePaids + automationEvents + swaps + positions + latestCreatePositionEvent + latestCreatePositionEvent__id + latestCreatePositionEvent__blockNumber + latestCreatePositionEvent__timestamp + latestCreatePositionEvent__txHash + latestCreatePositionEvent__logIndex + latestCreatePositionEvent__protocol + latestCreatePositionEvent__positionType + latestCreatePositionEvent__marketId +} + +type AssetSwap { + id: Bytes! + assetIn: Token! + assetOut: Token! + amountIn: BigInt! + amountOut: BigInt! + assetInPrice: BigDecimal! + oracle: String! + amountInUSD: BigDecimal! + mainEventHash: SummerEvent + user: User! + proxy: Account! + timestamp: BigInt! + block: BigInt! +} + +input AssetSwap_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + assetIn: String + assetIn_not: String + assetIn_gt: String + assetIn_lt: String + assetIn_gte: String + assetIn_lte: String + assetIn_in: [String!] + assetIn_not_in: [String!] + assetIn_contains: String + assetIn_contains_nocase: String + assetIn_not_contains: String + assetIn_not_contains_nocase: String + assetIn_starts_with: String + assetIn_starts_with_nocase: String + assetIn_not_starts_with: String + assetIn_not_starts_with_nocase: String + assetIn_ends_with: String + assetIn_ends_with_nocase: String + assetIn_not_ends_with: String + assetIn_not_ends_with_nocase: String + assetIn_: Token_filter + assetOut: String + assetOut_not: String + assetOut_gt: String + assetOut_lt: String + assetOut_gte: String + assetOut_lte: String + assetOut_in: [String!] + assetOut_not_in: [String!] + assetOut_contains: String + assetOut_contains_nocase: String + assetOut_not_contains: String + assetOut_not_contains_nocase: String + assetOut_starts_with: String + assetOut_starts_with_nocase: String + assetOut_not_starts_with: String + assetOut_not_starts_with_nocase: String + assetOut_ends_with: String + assetOut_ends_with_nocase: String + assetOut_not_ends_with: String + assetOut_not_ends_with_nocase: String + assetOut_: Token_filter + amountIn: BigInt + amountIn_not: BigInt + amountIn_gt: BigInt + amountIn_lt: BigInt + amountIn_gte: BigInt + amountIn_lte: BigInt + amountIn_in: [BigInt!] + amountIn_not_in: [BigInt!] + amountOut: BigInt + amountOut_not: BigInt + amountOut_gt: BigInt + amountOut_lt: BigInt + amountOut_gte: BigInt + amountOut_lte: BigInt + amountOut_in: [BigInt!] + amountOut_not_in: [BigInt!] + assetInPrice: BigDecimal + assetInPrice_not: BigDecimal + assetInPrice_gt: BigDecimal + assetInPrice_lt: BigDecimal + assetInPrice_gte: BigDecimal + assetInPrice_lte: BigDecimal + assetInPrice_in: [BigDecimal!] + assetInPrice_not_in: [BigDecimal!] + oracle: String + oracle_not: String + oracle_gt: String + oracle_lt: String + oracle_gte: String + oracle_lte: String + oracle_in: [String!] + oracle_not_in: [String!] + oracle_contains: String + oracle_contains_nocase: String + oracle_not_contains: String + oracle_not_contains_nocase: String + oracle_starts_with: String + oracle_starts_with_nocase: String + oracle_not_starts_with: String + oracle_not_starts_with_nocase: String + oracle_ends_with: String + oracle_ends_with_nocase: String + oracle_not_ends_with: String + oracle_not_ends_with_nocase: String + amountInUSD: BigDecimal + amountInUSD_not: BigDecimal + amountInUSD_gt: BigDecimal + amountInUSD_lt: BigDecimal + amountInUSD_gte: BigDecimal + amountInUSD_lte: BigDecimal + amountInUSD_in: [BigDecimal!] + amountInUSD_not_in: [BigDecimal!] + mainEventHash: String + mainEventHash_not: String + mainEventHash_gt: String + mainEventHash_lt: String + mainEventHash_gte: String + mainEventHash_lte: String + mainEventHash_in: [String!] + mainEventHash_not_in: [String!] + mainEventHash_contains: String + mainEventHash_contains_nocase: String + mainEventHash_not_contains: String + mainEventHash_not_contains_nocase: String + mainEventHash_starts_with: String + mainEventHash_starts_with_nocase: String + mainEventHash_not_starts_with: String + mainEventHash_not_starts_with_nocase: String + mainEventHash_ends_with: String + mainEventHash_ends_with_nocase: String + mainEventHash_not_ends_with: String + mainEventHash_not_ends_with_nocase: String + mainEventHash_: SummerEvent_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + proxy: String + proxy_not: String + proxy_gt: String + proxy_lt: String + proxy_gte: String + proxy_lte: String + proxy_in: [String!] + proxy_not_in: [String!] + proxy_contains: String + proxy_contains_nocase: String + proxy_not_contains: String + proxy_not_contains_nocase: String + proxy_starts_with: String + proxy_starts_with_nocase: String + proxy_not_starts_with: String + proxy_not_starts_with_nocase: String + proxy_ends_with: String + proxy_ends_with_nocase: String + proxy_not_ends_with: String + proxy_not_ends_with_nocase: String + proxy_: Account_filter + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + block: BigInt + block_not: BigInt + block_gt: BigInt + block_lt: BigInt + block_gte: BigInt + block_lte: BigInt + block_in: [BigInt!] + block_not_in: [BigInt!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [AssetSwap_filter] + or: [AssetSwap_filter] +} + +enum AssetSwap_orderBy { + id + assetIn + assetIn__id + assetIn__address + assetIn__symbol + assetIn__decimals + assetIn__precision + assetOut + assetOut__id + assetOut__address + assetOut__symbol + assetOut__decimals + assetOut__precision + amountIn + amountOut + assetInPrice + oracle + amountInUSD + mainEventHash + mainEventHash__id + mainEventHash__blockNumber + mainEventHash__timestamp + mainEventHash__txHash + mainEventHash__logIndex + mainEventHash__sender + mainEventHash__kind + mainEventHash__depositedUSD + mainEventHash__withdrawnUSD + mainEventHash__deltaUSD + mainEventHash__feePaidUSD + mainEventHash__protocol + mainEventHash__marketId + mainEventHash__debtBefore + mainEventHash__debtInUSDBefore + mainEventHash__debtAfter + mainEventHash__debtInUSDAfter + mainEventHash__collateralBefore + mainEventHash__collateralInUSDBefore + mainEventHash__collateralAfter + mainEventHash__collateralInUSDAfter + mainEventHash__supplyBefore + mainEventHash__supplyInUSDBefore + mainEventHash__supplyAfter + mainEventHash__supplyInUSDAfter + mainEventHash__netValueBefore + mainEventHash__netValueAfter + mainEventHash__collateralTokenPriceInUSD + mainEventHash__debtTokenPriceInUSD + mainEventHash__supplyTokenPriceInUSD + user + user__id + user__openPositions + proxy + proxy__id + proxy__address + proxy__type + proxy__vaultId + timestamp + block +} + +scalar BigDecimal + +scalar BigInt + +input Block_height { + hash: Bytes + number: Int + number_gte: Int +} + +input BlockChangedFilter { + number_gte: Int! +} + +scalar Bytes + +type CreatePositionEvent { + id: Bytes! + blockNumber: BigInt! + timestamp: BigInt! + txHash: Bytes! + logIndex: BigInt! + protocol: String! + positionType: String! + debtToken: Token! + collateralToken: Token! + marketId: String + user: User! + account: Account! +} + +input CreatePositionEvent_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + blockNumber: BigInt + blockNumber_not: BigInt + blockNumber_gt: BigInt + blockNumber_lt: BigInt + blockNumber_gte: BigInt + blockNumber_lte: BigInt + blockNumber_in: [BigInt!] + blockNumber_not_in: [BigInt!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + txHash: Bytes + txHash_not: Bytes + txHash_gt: Bytes + txHash_lt: Bytes + txHash_gte: Bytes + txHash_lte: Bytes + txHash_in: [Bytes!] + txHash_not_in: [Bytes!] + txHash_contains: Bytes + txHash_not_contains: Bytes + logIndex: BigInt + logIndex_not: BigInt + logIndex_gt: BigInt + logIndex_lt: BigInt + logIndex_gte: BigInt + logIndex_lte: BigInt + logIndex_in: [BigInt!] + logIndex_not_in: [BigInt!] + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + positionType: String + positionType_not: String + positionType_gt: String + positionType_lt: String + positionType_gte: String + positionType_lte: String + positionType_in: [String!] + positionType_not_in: [String!] + positionType_contains: String + positionType_contains_nocase: String + positionType_not_contains: String + positionType_not_contains_nocase: String + positionType_starts_with: String + positionType_starts_with_nocase: String + positionType_not_starts_with: String + positionType_not_starts_with_nocase: String + positionType_ends_with: String + positionType_ends_with_nocase: String + positionType_not_ends_with: String + positionType_not_ends_with_nocase: String + debtToken: String + debtToken_not: String + debtToken_gt: String + debtToken_lt: String + debtToken_gte: String + debtToken_lte: String + debtToken_in: [String!] + debtToken_not_in: [String!] + debtToken_contains: String + debtToken_contains_nocase: String + debtToken_not_contains: String + debtToken_not_contains_nocase: String + debtToken_starts_with: String + debtToken_starts_with_nocase: String + debtToken_not_starts_with: String + debtToken_not_starts_with_nocase: String + debtToken_ends_with: String + debtToken_ends_with_nocase: String + debtToken_not_ends_with: String + debtToken_not_ends_with_nocase: String + debtToken_: Token_filter + collateralToken: String + collateralToken_not: String + collateralToken_gt: String + collateralToken_lt: String + collateralToken_gte: String + collateralToken_lte: String + collateralToken_in: [String!] + collateralToken_not_in: [String!] + collateralToken_contains: String + collateralToken_contains_nocase: String + collateralToken_not_contains: String + collateralToken_not_contains_nocase: String + collateralToken_starts_with: String + collateralToken_starts_with_nocase: String + collateralToken_not_starts_with: String + collateralToken_not_starts_with_nocase: String + collateralToken_ends_with: String + collateralToken_ends_with_nocase: String + collateralToken_not_ends_with: String + collateralToken_not_ends_with_nocase: String + collateralToken_: Token_filter + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [CreatePositionEvent_filter] + or: [CreatePositionEvent_filter] +} + +enum CreatePositionEvent_orderBy { + id + blockNumber + timestamp + txHash + logIndex + protocol + positionType + debtToken + debtToken__id + debtToken__address + debtToken__symbol + debtToken__decimals + debtToken__precision + collateralToken + collateralToken__id + collateralToken__address + collateralToken__symbol + collateralToken__decimals + collateralToken__precision + marketId + user + user__id + user__openPositions + account + account__id + account__address + account__type + account__vaultId +} + +type FeePaid { + id: ID! + block: BigInt! + timestamp: BigInt! + transactionHash: Bytes! + logIndex: BigInt! + sender: Bytes! + beneficiary: Bytes! + amount: BigDecimal! + amountInFeeToken: BigInt + feeTokenPrice: BigDecimal + oracle: String! + feeToken: Token + mainEventHash: SummerEvent + user: User! + proxy: Account! +} + +input FeePaid_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + block: BigInt + block_not: BigInt + block_gt: BigInt + block_lt: BigInt + block_gte: BigInt + block_lte: BigInt + block_in: [BigInt!] + block_not_in: [BigInt!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + transactionHash: Bytes + transactionHash_not: Bytes + transactionHash_gt: Bytes + transactionHash_lt: Bytes + transactionHash_gte: Bytes + transactionHash_lte: Bytes + transactionHash_in: [Bytes!] + transactionHash_not_in: [Bytes!] + transactionHash_contains: Bytes + transactionHash_not_contains: Bytes + logIndex: BigInt + logIndex_not: BigInt + logIndex_gt: BigInt + logIndex_lt: BigInt + logIndex_gte: BigInt + logIndex_lte: BigInt + logIndex_in: [BigInt!] + logIndex_not_in: [BigInt!] + sender: Bytes + sender_not: Bytes + sender_gt: Bytes + sender_lt: Bytes + sender_gte: Bytes + sender_lte: Bytes + sender_in: [Bytes!] + sender_not_in: [Bytes!] + sender_contains: Bytes + sender_not_contains: Bytes + beneficiary: Bytes + beneficiary_not: Bytes + beneficiary_gt: Bytes + beneficiary_lt: Bytes + beneficiary_gte: Bytes + beneficiary_lte: Bytes + beneficiary_in: [Bytes!] + beneficiary_not_in: [Bytes!] + beneficiary_contains: Bytes + beneficiary_not_contains: Bytes + amount: BigDecimal + amount_not: BigDecimal + amount_gt: BigDecimal + amount_lt: BigDecimal + amount_gte: BigDecimal + amount_lte: BigDecimal + amount_in: [BigDecimal!] + amount_not_in: [BigDecimal!] + amountInFeeToken: BigInt + amountInFeeToken_not: BigInt + amountInFeeToken_gt: BigInt + amountInFeeToken_lt: BigInt + amountInFeeToken_gte: BigInt + amountInFeeToken_lte: BigInt + amountInFeeToken_in: [BigInt!] + amountInFeeToken_not_in: [BigInt!] + feeTokenPrice: BigDecimal + feeTokenPrice_not: BigDecimal + feeTokenPrice_gt: BigDecimal + feeTokenPrice_lt: BigDecimal + feeTokenPrice_gte: BigDecimal + feeTokenPrice_lte: BigDecimal + feeTokenPrice_in: [BigDecimal!] + feeTokenPrice_not_in: [BigDecimal!] + oracle: String + oracle_not: String + oracle_gt: String + oracle_lt: String + oracle_gte: String + oracle_lte: String + oracle_in: [String!] + oracle_not_in: [String!] + oracle_contains: String + oracle_contains_nocase: String + oracle_not_contains: String + oracle_not_contains_nocase: String + oracle_starts_with: String + oracle_starts_with_nocase: String + oracle_not_starts_with: String + oracle_not_starts_with_nocase: String + oracle_ends_with: String + oracle_ends_with_nocase: String + oracle_not_ends_with: String + oracle_not_ends_with_nocase: String + feeToken: String + feeToken_not: String + feeToken_gt: String + feeToken_lt: String + feeToken_gte: String + feeToken_lte: String + feeToken_in: [String!] + feeToken_not_in: [String!] + feeToken_contains: String + feeToken_contains_nocase: String + feeToken_not_contains: String + feeToken_not_contains_nocase: String + feeToken_starts_with: String + feeToken_starts_with_nocase: String + feeToken_not_starts_with: String + feeToken_not_starts_with_nocase: String + feeToken_ends_with: String + feeToken_ends_with_nocase: String + feeToken_not_ends_with: String + feeToken_not_ends_with_nocase: String + feeToken_: Token_filter + mainEventHash: String + mainEventHash_not: String + mainEventHash_gt: String + mainEventHash_lt: String + mainEventHash_gte: String + mainEventHash_lte: String + mainEventHash_in: [String!] + mainEventHash_not_in: [String!] + mainEventHash_contains: String + mainEventHash_contains_nocase: String + mainEventHash_not_contains: String + mainEventHash_not_contains_nocase: String + mainEventHash_starts_with: String + mainEventHash_starts_with_nocase: String + mainEventHash_not_starts_with: String + mainEventHash_not_starts_with_nocase: String + mainEventHash_ends_with: String + mainEventHash_ends_with_nocase: String + mainEventHash_not_ends_with: String + mainEventHash_not_ends_with_nocase: String + mainEventHash_: SummerEvent_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + proxy: String + proxy_not: String + proxy_gt: String + proxy_lt: String + proxy_gte: String + proxy_lte: String + proxy_in: [String!] + proxy_not_in: [String!] + proxy_contains: String + proxy_contains_nocase: String + proxy_not_contains: String + proxy_not_contains_nocase: String + proxy_starts_with: String + proxy_starts_with_nocase: String + proxy_not_starts_with: String + proxy_not_starts_with_nocase: String + proxy_ends_with: String + proxy_ends_with_nocase: String + proxy_not_ends_with: String + proxy_not_ends_with_nocase: String + proxy_: Account_filter + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [FeePaid_filter] + or: [FeePaid_filter] +} + +enum FeePaid_orderBy { + id + block + timestamp + transactionHash + logIndex + sender + beneficiary + amount + amountInFeeToken + feeTokenPrice + oracle + feeToken + feeToken__id + feeToken__address + feeToken__symbol + feeToken__decimals + feeToken__precision + mainEventHash + mainEventHash__id + mainEventHash__blockNumber + mainEventHash__timestamp + mainEventHash__txHash + mainEventHash__logIndex + mainEventHash__sender + mainEventHash__kind + mainEventHash__depositedUSD + mainEventHash__withdrawnUSD + mainEventHash__deltaUSD + mainEventHash__feePaidUSD + mainEventHash__protocol + mainEventHash__marketId + mainEventHash__debtBefore + mainEventHash__debtInUSDBefore + mainEventHash__debtAfter + mainEventHash__debtInUSDAfter + mainEventHash__collateralBefore + mainEventHash__collateralInUSDBefore + mainEventHash__collateralAfter + mainEventHash__collateralInUSDAfter + mainEventHash__supplyBefore + mainEventHash__supplyInUSDBefore + mainEventHash__supplyAfter + mainEventHash__supplyInUSDAfter + mainEventHash__netValueBefore + mainEventHash__netValueAfter + mainEventHash__collateralTokenPriceInUSD + mainEventHash__debtTokenPriceInUSD + mainEventHash__supplyTokenPriceInUSD + user + user__id + user__openPositions + proxy + proxy__id + proxy__address + proxy__type + proxy__vaultId +} + +type Ilk { + id: Bytes! + blockNumber: BigInt! + token: Token! + rate: BigDecimal! +} + +input Ilk_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + blockNumber: BigInt + blockNumber_not: BigInt + blockNumber_gt: BigInt + blockNumber_lt: BigInt + blockNumber_gte: BigInt + blockNumber_lte: BigInt + blockNumber_in: [BigInt!] + blockNumber_not_in: [BigInt!] + token: String + token_not: String + token_gt: String + token_lt: String + token_gte: String + token_lte: String + token_in: [String!] + token_not_in: [String!] + token_contains: String + token_contains_nocase: String + token_not_contains: String + token_not_contains_nocase: String + token_starts_with: String + token_starts_with_nocase: String + token_not_starts_with: String + token_not_starts_with_nocase: String + token_ends_with: String + token_ends_with_nocase: String + token_not_ends_with: String + token_not_ends_with_nocase: String + token_: Token_filter + rate: BigDecimal + rate_not: BigDecimal + rate_gt: BigDecimal + rate_lt: BigDecimal + rate_gte: BigDecimal + rate_lte: BigDecimal + rate_in: [BigDecimal!] + rate_not_in: [BigDecimal!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Ilk_filter] + or: [Ilk_filter] +} + +enum Ilk_orderBy { + id + blockNumber + token + token__id + token__address + token__symbol + token__decimals + token__precision + rate +} + +""" +8 bytes signed integer + +""" +scalar Int8 + +type MakerUrn { + id: Bytes! + cdp: BigInt! + ilk: Bytes! + urn: Bytes! +} + +input MakerUrn_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + cdp: BigInt + cdp_not: BigInt + cdp_gt: BigInt + cdp_lt: BigInt + cdp_gte: BigInt + cdp_lte: BigInt + cdp_in: [BigInt!] + cdp_not_in: [BigInt!] + ilk: Bytes + ilk_not: Bytes + ilk_gt: Bytes + ilk_lt: Bytes + ilk_gte: Bytes + ilk_lte: Bytes + ilk_in: [Bytes!] + ilk_not_in: [Bytes!] + ilk_contains: Bytes + ilk_not_contains: Bytes + urn: Bytes + urn_not: Bytes + urn_gt: Bytes + urn_lt: Bytes + urn_gte: Bytes + urn_lte: Bytes + urn_in: [Bytes!] + urn_not_in: [Bytes!] + urn_contains: Bytes + urn_not_contains: Bytes + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [MakerUrn_filter] + or: [MakerUrn_filter] +} + +enum MakerUrn_orderBy { + id + cdp + ilk + urn +} + +type Market { + id: ID! + protocol: String! + marketId: String! + supported: Boolean! +} + +input Market_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + supported: Boolean + supported_not: Boolean + supported_in: [Boolean!] + supported_not_in: [Boolean!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Market_filter] + or: [Market_filter] +} + +enum Market_orderBy { + id + protocol + marketId + supported +} + +"""Defines the order direction, either ascending or descending""" +enum OrderDirection { + asc + desc +} + +type Position { + id: ID! + account: Account! + user: User! + protocol: String! + marketId: String! + positionType: String + cumulativeDepositedUSD: BigDecimal! + cumulativeWithdrawnUSD: BigDecimal! + cumulativeDeltaUSD: BigDecimal! + cumulativeFeesUSD: BigDecimal! + debt: BigDecimal! + debtInUSD: BigDecimal! + collateral: BigDecimal! + collateralInUSD: BigDecimal! + supply: BigDecimal! + supplyInUSD: BigDecimal! + netValue: BigDecimal! + summerEvents(skip: Int = 0, first: Int = 100, orderBy: SummerEvent_orderBy, orderDirection: OrderDirection, where: SummerEvent_filter): [SummerEvent!]! + triggers(skip: Int = 0, first: Int = 100, orderBy: Trigger_orderBy, orderDirection: OrderDirection, where: Trigger_filter): [Trigger!]! + lastEvent: SummerEvent + _ajnaBucket: BigInt! +} + +input Position_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + positionType: String + positionType_not: String + positionType_gt: String + positionType_lt: String + positionType_gte: String + positionType_lte: String + positionType_in: [String!] + positionType_not_in: [String!] + positionType_contains: String + positionType_contains_nocase: String + positionType_not_contains: String + positionType_not_contains_nocase: String + positionType_starts_with: String + positionType_starts_with_nocase: String + positionType_not_starts_with: String + positionType_not_starts_with_nocase: String + positionType_ends_with: String + positionType_ends_with_nocase: String + positionType_not_ends_with: String + positionType_not_ends_with_nocase: String + cumulativeDepositedUSD: BigDecimal + cumulativeDepositedUSD_not: BigDecimal + cumulativeDepositedUSD_gt: BigDecimal + cumulativeDepositedUSD_lt: BigDecimal + cumulativeDepositedUSD_gte: BigDecimal + cumulativeDepositedUSD_lte: BigDecimal + cumulativeDepositedUSD_in: [BigDecimal!] + cumulativeDepositedUSD_not_in: [BigDecimal!] + cumulativeWithdrawnUSD: BigDecimal + cumulativeWithdrawnUSD_not: BigDecimal + cumulativeWithdrawnUSD_gt: BigDecimal + cumulativeWithdrawnUSD_lt: BigDecimal + cumulativeWithdrawnUSD_gte: BigDecimal + cumulativeWithdrawnUSD_lte: BigDecimal + cumulativeWithdrawnUSD_in: [BigDecimal!] + cumulativeWithdrawnUSD_not_in: [BigDecimal!] + cumulativeDeltaUSD: BigDecimal + cumulativeDeltaUSD_not: BigDecimal + cumulativeDeltaUSD_gt: BigDecimal + cumulativeDeltaUSD_lt: BigDecimal + cumulativeDeltaUSD_gte: BigDecimal + cumulativeDeltaUSD_lte: BigDecimal + cumulativeDeltaUSD_in: [BigDecimal!] + cumulativeDeltaUSD_not_in: [BigDecimal!] + cumulativeFeesUSD: BigDecimal + cumulativeFeesUSD_not: BigDecimal + cumulativeFeesUSD_gt: BigDecimal + cumulativeFeesUSD_lt: BigDecimal + cumulativeFeesUSD_gte: BigDecimal + cumulativeFeesUSD_lte: BigDecimal + cumulativeFeesUSD_in: [BigDecimal!] + cumulativeFeesUSD_not_in: [BigDecimal!] + debt: BigDecimal + debt_not: BigDecimal + debt_gt: BigDecimal + debt_lt: BigDecimal + debt_gte: BigDecimal + debt_lte: BigDecimal + debt_in: [BigDecimal!] + debt_not_in: [BigDecimal!] + debtInUSD: BigDecimal + debtInUSD_not: BigDecimal + debtInUSD_gt: BigDecimal + debtInUSD_lt: BigDecimal + debtInUSD_gte: BigDecimal + debtInUSD_lte: BigDecimal + debtInUSD_in: [BigDecimal!] + debtInUSD_not_in: [BigDecimal!] + collateral: BigDecimal + collateral_not: BigDecimal + collateral_gt: BigDecimal + collateral_lt: BigDecimal + collateral_gte: BigDecimal + collateral_lte: BigDecimal + collateral_in: [BigDecimal!] + collateral_not_in: [BigDecimal!] + collateralInUSD: BigDecimal + collateralInUSD_not: BigDecimal + collateralInUSD_gt: BigDecimal + collateralInUSD_lt: BigDecimal + collateralInUSD_gte: BigDecimal + collateralInUSD_lte: BigDecimal + collateralInUSD_in: [BigDecimal!] + collateralInUSD_not_in: [BigDecimal!] + supply: BigDecimal + supply_not: BigDecimal + supply_gt: BigDecimal + supply_lt: BigDecimal + supply_gte: BigDecimal + supply_lte: BigDecimal + supply_in: [BigDecimal!] + supply_not_in: [BigDecimal!] + supplyInUSD: BigDecimal + supplyInUSD_not: BigDecimal + supplyInUSD_gt: BigDecimal + supplyInUSD_lt: BigDecimal + supplyInUSD_gte: BigDecimal + supplyInUSD_lte: BigDecimal + supplyInUSD_in: [BigDecimal!] + supplyInUSD_not_in: [BigDecimal!] + netValue: BigDecimal + netValue_not: BigDecimal + netValue_gt: BigDecimal + netValue_lt: BigDecimal + netValue_gte: BigDecimal + netValue_lte: BigDecimal + netValue_in: [BigDecimal!] + netValue_not_in: [BigDecimal!] + summerEvents_: SummerEvent_filter + triggers_: Trigger_filter + lastEvent: String + lastEvent_not: String + lastEvent_gt: String + lastEvent_lt: String + lastEvent_gte: String + lastEvent_lte: String + lastEvent_in: [String!] + lastEvent_not_in: [String!] + lastEvent_contains: String + lastEvent_contains_nocase: String + lastEvent_not_contains: String + lastEvent_not_contains_nocase: String + lastEvent_starts_with: String + lastEvent_starts_with_nocase: String + lastEvent_not_starts_with: String + lastEvent_not_starts_with_nocase: String + lastEvent_ends_with: String + lastEvent_ends_with_nocase: String + lastEvent_not_ends_with: String + lastEvent_not_ends_with_nocase: String + lastEvent_: SummerEvent_filter + _ajnaBucket: BigInt + _ajnaBucket_not: BigInt + _ajnaBucket_gt: BigInt + _ajnaBucket_lt: BigInt + _ajnaBucket_gte: BigInt + _ajnaBucket_lte: BigInt + _ajnaBucket_in: [BigInt!] + _ajnaBucket_not_in: [BigInt!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Position_filter] + or: [Position_filter] +} + +enum Position_orderBy { + id + account + account__id + account__address + account__type + account__vaultId + user + user__id + user__openPositions + protocol + marketId + positionType + cumulativeDepositedUSD + cumulativeWithdrawnUSD + cumulativeDeltaUSD + cumulativeFeesUSD + debt + debtInUSD + collateral + collateralInUSD + supply + supplyInUSD + netValue + summerEvents + triggers + lastEvent + lastEvent__id + lastEvent__blockNumber + lastEvent__timestamp + lastEvent__txHash + lastEvent__logIndex + lastEvent__sender + lastEvent__kind + lastEvent__depositedUSD + lastEvent__withdrawnUSD + lastEvent__deltaUSD + lastEvent__feePaidUSD + lastEvent__protocol + lastEvent__marketId + lastEvent__debtBefore + lastEvent__debtInUSDBefore + lastEvent__debtAfter + lastEvent__debtInUSDAfter + lastEvent__collateralBefore + lastEvent__collateralInUSDBefore + lastEvent__collateralAfter + lastEvent__collateralInUSDAfter + lastEvent__supplyBefore + lastEvent__supplyInUSDBefore + lastEvent__supplyAfter + lastEvent__supplyInUSDAfter + lastEvent__netValueBefore + lastEvent__netValueAfter + lastEvent__collateralTokenPriceInUSD + lastEvent__debtTokenPriceInUSD + lastEvent__supplyTokenPriceInUSD + _ajnaBucket +} + +type Query { + storage( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Storage + storages( + skip: Int = 0 + first: Int = 100 + orderBy: Storage_orderBy + orderDirection: OrderDirection + where: Storage_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Storage!]! + snapshot( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Snapshot + snapshots( + skip: Int = 0 + first: Int = 100 + orderBy: Snapshot_orderBy + orderDirection: OrderDirection + where: Snapshot_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Snapshot!]! + user( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): User + users( + skip: Int = 0 + first: Int = 100 + orderBy: User_orderBy + orderDirection: OrderDirection + where: User_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [User!]! + summerEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): SummerEvent + summerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: SummerEvent_orderBy + orderDirection: OrderDirection + where: SummerEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [SummerEvent!]! + createPositionEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): CreatePositionEvent + createPositionEvents( + skip: Int = 0 + first: Int = 100 + orderBy: CreatePositionEvent_orderBy + orderDirection: OrderDirection + where: CreatePositionEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [CreatePositionEvent!]! + account( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Account + accounts( + skip: Int = 0 + first: Int = 100 + orderBy: Account_orderBy + orderDirection: OrderDirection + where: Account_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Account!]! + position( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Position + positions( + skip: Int = 0 + first: Int = 100 + orderBy: Position_orderBy + orderDirection: OrderDirection + where: Position_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Position!]! + feePaid( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): FeePaid + feePaids( + skip: Int = 0 + first: Int = 100 + orderBy: FeePaid_orderBy + orderDirection: OrderDirection + where: FeePaid_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [FeePaid!]! + assetSwap( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): AssetSwap + assetSwaps( + skip: Int = 0 + first: Int = 100 + orderBy: AssetSwap_orderBy + orderDirection: OrderDirection + where: AssetSwap_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [AssetSwap!]! + transfer( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Transfer + transfers( + skip: Int = 0 + first: Int = 100 + orderBy: Transfer_orderBy + orderDirection: OrderDirection + where: Transfer_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Transfer!]! + token( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Token + tokens( + skip: Int = 0 + first: Int = 100 + orderBy: Token_orderBy + orderDirection: OrderDirection + where: Token_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Token!]! + triggerEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): TriggerEvent + triggerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: TriggerEvent_orderBy + orderDirection: OrderDirection + where: TriggerEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [TriggerEvent!]! + trigger( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Trigger + triggers( + skip: Int = 0 + first: Int = 100 + orderBy: Trigger_orderBy + orderDirection: OrderDirection + where: Trigger_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Trigger!]! + makerUrn( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): MakerUrn + makerUrns( + skip: Int = 0 + first: Int = 100 + orderBy: MakerUrn_orderBy + orderDirection: OrderDirection + where: MakerUrn_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [MakerUrn!]! + ilk( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Ilk + ilks( + skip: Int = 0 + first: Int = 100 + orderBy: Ilk_orderBy + orderDirection: OrderDirection + where: Ilk_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Ilk!]! + tokenPrice( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): TokenPrice + tokenPrices( + skip: Int = 0 + first: Int = 100 + orderBy: TokenPrice_orderBy + orderDirection: OrderDirection + where: TokenPrice_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [TokenPrice!]! + market( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Market + markets( + skip: Int = 0 + first: Int = 100 + orderBy: Market_orderBy + orderDirection: OrderDirection + where: Market_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Market!]! + + """Access to subgraph metadata""" + _meta(block: Block_height): _Meta_ +} + +type Snapshot { + id: ID! + timestamp: BigInt! + netValue: BigDecimal! + positionCount: BigInt! + closedPositions: BigInt! + year: BigInt! + month: BigInt! + day: BigInt! + hour: BigInt! +} + +input Snapshot_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + netValue: BigDecimal + netValue_not: BigDecimal + netValue_gt: BigDecimal + netValue_lt: BigDecimal + netValue_gte: BigDecimal + netValue_lte: BigDecimal + netValue_in: [BigDecimal!] + netValue_not_in: [BigDecimal!] + positionCount: BigInt + positionCount_not: BigInt + positionCount_gt: BigInt + positionCount_lt: BigInt + positionCount_gte: BigInt + positionCount_lte: BigInt + positionCount_in: [BigInt!] + positionCount_not_in: [BigInt!] + closedPositions: BigInt + closedPositions_not: BigInt + closedPositions_gt: BigInt + closedPositions_lt: BigInt + closedPositions_gte: BigInt + closedPositions_lte: BigInt + closedPositions_in: [BigInt!] + closedPositions_not_in: [BigInt!] + year: BigInt + year_not: BigInt + year_gt: BigInt + year_lt: BigInt + year_gte: BigInt + year_lte: BigInt + year_in: [BigInt!] + year_not_in: [BigInt!] + month: BigInt + month_not: BigInt + month_gt: BigInt + month_lt: BigInt + month_gte: BigInt + month_lte: BigInt + month_in: [BigInt!] + month_not_in: [BigInt!] + day: BigInt + day_not: BigInt + day_gt: BigInt + day_lt: BigInt + day_gte: BigInt + day_lte: BigInt + day_in: [BigInt!] + day_not_in: [BigInt!] + hour: BigInt + hour_not: BigInt + hour_gt: BigInt + hour_lt: BigInt + hour_gte: BigInt + hour_lte: BigInt + hour_in: [BigInt!] + hour_not_in: [BigInt!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Snapshot_filter] + or: [Snapshot_filter] +} + +enum Snapshot_orderBy { + id + timestamp + netValue + positionCount + closedPositions + year + month + day + hour +} + +""" +Oasis App user + +""" +type Storage { + id: ID! + positions(skip: Int = 0, first: Int = 100, orderBy: Position_orderBy, orderDirection: OrderDirection, where: Position_filter): [Position!]! +} + +input Storage_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + positions: [String!] + positions_not: [String!] + positions_contains: [String!] + positions_contains_nocase: [String!] + positions_not_contains: [String!] + positions_not_contains_nocase: [String!] + positions_: Position_filter + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Storage_filter] + or: [Storage_filter] +} + +enum Storage_orderBy { + id + positions +} + +type Subscription { + storage( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Storage + storages( + skip: Int = 0 + first: Int = 100 + orderBy: Storage_orderBy + orderDirection: OrderDirection + where: Storage_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Storage!]! + snapshot( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Snapshot + snapshots( + skip: Int = 0 + first: Int = 100 + orderBy: Snapshot_orderBy + orderDirection: OrderDirection + where: Snapshot_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Snapshot!]! + user( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): User + users( + skip: Int = 0 + first: Int = 100 + orderBy: User_orderBy + orderDirection: OrderDirection + where: User_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [User!]! + summerEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): SummerEvent + summerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: SummerEvent_orderBy + orderDirection: OrderDirection + where: SummerEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [SummerEvent!]! + createPositionEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): CreatePositionEvent + createPositionEvents( + skip: Int = 0 + first: Int = 100 + orderBy: CreatePositionEvent_orderBy + orderDirection: OrderDirection + where: CreatePositionEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [CreatePositionEvent!]! + account( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Account + accounts( + skip: Int = 0 + first: Int = 100 + orderBy: Account_orderBy + orderDirection: OrderDirection + where: Account_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Account!]! + position( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Position + positions( + skip: Int = 0 + first: Int = 100 + orderBy: Position_orderBy + orderDirection: OrderDirection + where: Position_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Position!]! + feePaid( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): FeePaid + feePaids( + skip: Int = 0 + first: Int = 100 + orderBy: FeePaid_orderBy + orderDirection: OrderDirection + where: FeePaid_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [FeePaid!]! + assetSwap( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): AssetSwap + assetSwaps( + skip: Int = 0 + first: Int = 100 + orderBy: AssetSwap_orderBy + orderDirection: OrderDirection + where: AssetSwap_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [AssetSwap!]! + transfer( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Transfer + transfers( + skip: Int = 0 + first: Int = 100 + orderBy: Transfer_orderBy + orderDirection: OrderDirection + where: Transfer_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Transfer!]! + token( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Token + tokens( + skip: Int = 0 + first: Int = 100 + orderBy: Token_orderBy + orderDirection: OrderDirection + where: Token_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Token!]! + triggerEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): TriggerEvent + triggerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: TriggerEvent_orderBy + orderDirection: OrderDirection + where: TriggerEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [TriggerEvent!]! + trigger( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Trigger + triggers( + skip: Int = 0 + first: Int = 100 + orderBy: Trigger_orderBy + orderDirection: OrderDirection + where: Trigger_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Trigger!]! + makerUrn( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): MakerUrn + makerUrns( + skip: Int = 0 + first: Int = 100 + orderBy: MakerUrn_orderBy + orderDirection: OrderDirection + where: MakerUrn_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [MakerUrn!]! + ilk( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Ilk + ilks( + skip: Int = 0 + first: Int = 100 + orderBy: Ilk_orderBy + orderDirection: OrderDirection + where: Ilk_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Ilk!]! + tokenPrice( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): TokenPrice + tokenPrices( + skip: Int = 0 + first: Int = 100 + orderBy: TokenPrice_orderBy + orderDirection: OrderDirection + where: TokenPrice_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [TokenPrice!]! + market( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Market + markets( + skip: Int = 0 + first: Int = 100 + orderBy: Market_orderBy + orderDirection: OrderDirection + where: Market_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Market!]! + + """Access to subgraph metadata""" + _meta(block: Block_height): _Meta_ +} + +type SummerEvent { + id: Bytes! + blockNumber: BigInt! + timestamp: BigInt! + txHash: Bytes! + logIndex: BigInt! + sender: Bytes! + kind: String! + account: Account! + user: User! + position: Position! + depositedUSD: BigDecimal! + withdrawnUSD: BigDecimal! + deltaUSD: BigDecimal! + feePaidUSD: BigDecimal! + depositTransfers(skip: Int = 0, first: Int = 100, orderBy: Transfer_orderBy, orderDirection: OrderDirection, where: Transfer_filter): [Transfer!]! + withdrawTransfers(skip: Int = 0, first: Int = 100, orderBy: Transfer_orderBy, orderDirection: OrderDirection, where: Transfer_filter): [Transfer!]! + protocol: String! + marketId: String! + feePaids(skip: Int = 0, first: Int = 100, orderBy: FeePaid_orderBy, orderDirection: OrderDirection, where: FeePaid_filter): [FeePaid!]! + swaps(skip: Int = 0, first: Int = 100, orderBy: AssetSwap_orderBy, orderDirection: OrderDirection, where: AssetSwap_filter): [AssetSwap!]! + automationEvents(skip: Int = 0, first: Int = 100, orderBy: TriggerEvent_orderBy, orderDirection: OrderDirection, where: TriggerEvent_filter): [TriggerEvent!]! + debtBefore: BigDecimal! + debtInUSDBefore: BigDecimal! + debtAfter: BigDecimal! + debtInUSDAfter: BigDecimal! + collateralBefore: BigDecimal! + collateralInUSDBefore: BigDecimal! + collateralAfter: BigDecimal! + collateralInUSDAfter: BigDecimal! + supplyBefore: BigDecimal! + supplyInUSDBefore: BigDecimal! + supplyAfter: BigDecimal! + supplyInUSDAfter: BigDecimal! + netValueBefore: BigDecimal! + netValueAfter: BigDecimal! + collateralTokenPriceInUSD: BigDecimal! + debtTokenPriceInUSD: BigDecimal! + supplyTokenPriceInUSD: BigDecimal! +} + +input SummerEvent_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + blockNumber: BigInt + blockNumber_not: BigInt + blockNumber_gt: BigInt + blockNumber_lt: BigInt + blockNumber_gte: BigInt + blockNumber_lte: BigInt + blockNumber_in: [BigInt!] + blockNumber_not_in: [BigInt!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + txHash: Bytes + txHash_not: Bytes + txHash_gt: Bytes + txHash_lt: Bytes + txHash_gte: Bytes + txHash_lte: Bytes + txHash_in: [Bytes!] + txHash_not_in: [Bytes!] + txHash_contains: Bytes + txHash_not_contains: Bytes + logIndex: BigInt + logIndex_not: BigInt + logIndex_gt: BigInt + logIndex_lt: BigInt + logIndex_gte: BigInt + logIndex_lte: BigInt + logIndex_in: [BigInt!] + logIndex_not_in: [BigInt!] + sender: Bytes + sender_not: Bytes + sender_gt: Bytes + sender_lt: Bytes + sender_gte: Bytes + sender_lte: Bytes + sender_in: [Bytes!] + sender_not_in: [Bytes!] + sender_contains: Bytes + sender_not_contains: Bytes + kind: String + kind_not: String + kind_gt: String + kind_lt: String + kind_gte: String + kind_lte: String + kind_in: [String!] + kind_not_in: [String!] + kind_contains: String + kind_contains_nocase: String + kind_not_contains: String + kind_not_contains_nocase: String + kind_starts_with: String + kind_starts_with_nocase: String + kind_not_starts_with: String + kind_not_starts_with_nocase: String + kind_ends_with: String + kind_ends_with_nocase: String + kind_not_ends_with: String + kind_not_ends_with_nocase: String + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + position: String + position_not: String + position_gt: String + position_lt: String + position_gte: String + position_lte: String + position_in: [String!] + position_not_in: [String!] + position_contains: String + position_contains_nocase: String + position_not_contains: String + position_not_contains_nocase: String + position_starts_with: String + position_starts_with_nocase: String + position_not_starts_with: String + position_not_starts_with_nocase: String + position_ends_with: String + position_ends_with_nocase: String + position_not_ends_with: String + position_not_ends_with_nocase: String + position_: Position_filter + depositedUSD: BigDecimal + depositedUSD_not: BigDecimal + depositedUSD_gt: BigDecimal + depositedUSD_lt: BigDecimal + depositedUSD_gte: BigDecimal + depositedUSD_lte: BigDecimal + depositedUSD_in: [BigDecimal!] + depositedUSD_not_in: [BigDecimal!] + withdrawnUSD: BigDecimal + withdrawnUSD_not: BigDecimal + withdrawnUSD_gt: BigDecimal + withdrawnUSD_lt: BigDecimal + withdrawnUSD_gte: BigDecimal + withdrawnUSD_lte: BigDecimal + withdrawnUSD_in: [BigDecimal!] + withdrawnUSD_not_in: [BigDecimal!] + deltaUSD: BigDecimal + deltaUSD_not: BigDecimal + deltaUSD_gt: BigDecimal + deltaUSD_lt: BigDecimal + deltaUSD_gte: BigDecimal + deltaUSD_lte: BigDecimal + deltaUSD_in: [BigDecimal!] + deltaUSD_not_in: [BigDecimal!] + feePaidUSD: BigDecimal + feePaidUSD_not: BigDecimal + feePaidUSD_gt: BigDecimal + feePaidUSD_lt: BigDecimal + feePaidUSD_gte: BigDecimal + feePaidUSD_lte: BigDecimal + feePaidUSD_in: [BigDecimal!] + feePaidUSD_not_in: [BigDecimal!] + depositTransfers: [String!] + depositTransfers_not: [String!] + depositTransfers_contains: [String!] + depositTransfers_contains_nocase: [String!] + depositTransfers_not_contains: [String!] + depositTransfers_not_contains_nocase: [String!] + depositTransfers_: Transfer_filter + withdrawTransfers: [String!] + withdrawTransfers_not: [String!] + withdrawTransfers_contains: [String!] + withdrawTransfers_contains_nocase: [String!] + withdrawTransfers_not_contains: [String!] + withdrawTransfers_not_contains_nocase: [String!] + withdrawTransfers_: Transfer_filter + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + feePaids_: FeePaid_filter + swaps_: AssetSwap_filter + automationEvents_: TriggerEvent_filter + debtBefore: BigDecimal + debtBefore_not: BigDecimal + debtBefore_gt: BigDecimal + debtBefore_lt: BigDecimal + debtBefore_gte: BigDecimal + debtBefore_lte: BigDecimal + debtBefore_in: [BigDecimal!] + debtBefore_not_in: [BigDecimal!] + debtInUSDBefore: BigDecimal + debtInUSDBefore_not: BigDecimal + debtInUSDBefore_gt: BigDecimal + debtInUSDBefore_lt: BigDecimal + debtInUSDBefore_gte: BigDecimal + debtInUSDBefore_lte: BigDecimal + debtInUSDBefore_in: [BigDecimal!] + debtInUSDBefore_not_in: [BigDecimal!] + debtAfter: BigDecimal + debtAfter_not: BigDecimal + debtAfter_gt: BigDecimal + debtAfter_lt: BigDecimal + debtAfter_gte: BigDecimal + debtAfter_lte: BigDecimal + debtAfter_in: [BigDecimal!] + debtAfter_not_in: [BigDecimal!] + debtInUSDAfter: BigDecimal + debtInUSDAfter_not: BigDecimal + debtInUSDAfter_gt: BigDecimal + debtInUSDAfter_lt: BigDecimal + debtInUSDAfter_gte: BigDecimal + debtInUSDAfter_lte: BigDecimal + debtInUSDAfter_in: [BigDecimal!] + debtInUSDAfter_not_in: [BigDecimal!] + collateralBefore: BigDecimal + collateralBefore_not: BigDecimal + collateralBefore_gt: BigDecimal + collateralBefore_lt: BigDecimal + collateralBefore_gte: BigDecimal + collateralBefore_lte: BigDecimal + collateralBefore_in: [BigDecimal!] + collateralBefore_not_in: [BigDecimal!] + collateralInUSDBefore: BigDecimal + collateralInUSDBefore_not: BigDecimal + collateralInUSDBefore_gt: BigDecimal + collateralInUSDBefore_lt: BigDecimal + collateralInUSDBefore_gte: BigDecimal + collateralInUSDBefore_lte: BigDecimal + collateralInUSDBefore_in: [BigDecimal!] + collateralInUSDBefore_not_in: [BigDecimal!] + collateralAfter: BigDecimal + collateralAfter_not: BigDecimal + collateralAfter_gt: BigDecimal + collateralAfter_lt: BigDecimal + collateralAfter_gte: BigDecimal + collateralAfter_lte: BigDecimal + collateralAfter_in: [BigDecimal!] + collateralAfter_not_in: [BigDecimal!] + collateralInUSDAfter: BigDecimal + collateralInUSDAfter_not: BigDecimal + collateralInUSDAfter_gt: BigDecimal + collateralInUSDAfter_lt: BigDecimal + collateralInUSDAfter_gte: BigDecimal + collateralInUSDAfter_lte: BigDecimal + collateralInUSDAfter_in: [BigDecimal!] + collateralInUSDAfter_not_in: [BigDecimal!] + supplyBefore: BigDecimal + supplyBefore_not: BigDecimal + supplyBefore_gt: BigDecimal + supplyBefore_lt: BigDecimal + supplyBefore_gte: BigDecimal + supplyBefore_lte: BigDecimal + supplyBefore_in: [BigDecimal!] + supplyBefore_not_in: [BigDecimal!] + supplyInUSDBefore: BigDecimal + supplyInUSDBefore_not: BigDecimal + supplyInUSDBefore_gt: BigDecimal + supplyInUSDBefore_lt: BigDecimal + supplyInUSDBefore_gte: BigDecimal + supplyInUSDBefore_lte: BigDecimal + supplyInUSDBefore_in: [BigDecimal!] + supplyInUSDBefore_not_in: [BigDecimal!] + supplyAfter: BigDecimal + supplyAfter_not: BigDecimal + supplyAfter_gt: BigDecimal + supplyAfter_lt: BigDecimal + supplyAfter_gte: BigDecimal + supplyAfter_lte: BigDecimal + supplyAfter_in: [BigDecimal!] + supplyAfter_not_in: [BigDecimal!] + supplyInUSDAfter: BigDecimal + supplyInUSDAfter_not: BigDecimal + supplyInUSDAfter_gt: BigDecimal + supplyInUSDAfter_lt: BigDecimal + supplyInUSDAfter_gte: BigDecimal + supplyInUSDAfter_lte: BigDecimal + supplyInUSDAfter_in: [BigDecimal!] + supplyInUSDAfter_not_in: [BigDecimal!] + netValueBefore: BigDecimal + netValueBefore_not: BigDecimal + netValueBefore_gt: BigDecimal + netValueBefore_lt: BigDecimal + netValueBefore_gte: BigDecimal + netValueBefore_lte: BigDecimal + netValueBefore_in: [BigDecimal!] + netValueBefore_not_in: [BigDecimal!] + netValueAfter: BigDecimal + netValueAfter_not: BigDecimal + netValueAfter_gt: BigDecimal + netValueAfter_lt: BigDecimal + netValueAfter_gte: BigDecimal + netValueAfter_lte: BigDecimal + netValueAfter_in: [BigDecimal!] + netValueAfter_not_in: [BigDecimal!] + collateralTokenPriceInUSD: BigDecimal + collateralTokenPriceInUSD_not: BigDecimal + collateralTokenPriceInUSD_gt: BigDecimal + collateralTokenPriceInUSD_lt: BigDecimal + collateralTokenPriceInUSD_gte: BigDecimal + collateralTokenPriceInUSD_lte: BigDecimal + collateralTokenPriceInUSD_in: [BigDecimal!] + collateralTokenPriceInUSD_not_in: [BigDecimal!] + debtTokenPriceInUSD: BigDecimal + debtTokenPriceInUSD_not: BigDecimal + debtTokenPriceInUSD_gt: BigDecimal + debtTokenPriceInUSD_lt: BigDecimal + debtTokenPriceInUSD_gte: BigDecimal + debtTokenPriceInUSD_lte: BigDecimal + debtTokenPriceInUSD_in: [BigDecimal!] + debtTokenPriceInUSD_not_in: [BigDecimal!] + supplyTokenPriceInUSD: BigDecimal + supplyTokenPriceInUSD_not: BigDecimal + supplyTokenPriceInUSD_gt: BigDecimal + supplyTokenPriceInUSD_lt: BigDecimal + supplyTokenPriceInUSD_gte: BigDecimal + supplyTokenPriceInUSD_lte: BigDecimal + supplyTokenPriceInUSD_in: [BigDecimal!] + supplyTokenPriceInUSD_not_in: [BigDecimal!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [SummerEvent_filter] + or: [SummerEvent_filter] +} + +enum SummerEvent_orderBy { + id + blockNumber + timestamp + txHash + logIndex + sender + kind + account + account__id + account__address + account__type + account__vaultId + user + user__id + user__openPositions + position + position__id + position__protocol + position__marketId + position__positionType + position__cumulativeDepositedUSD + position__cumulativeWithdrawnUSD + position__cumulativeDeltaUSD + position__cumulativeFeesUSD + position__debt + position__debtInUSD + position__collateral + position__collateralInUSD + position__supply + position__supplyInUSD + position__netValue + position___ajnaBucket + depositedUSD + withdrawnUSD + deltaUSD + feePaidUSD + depositTransfers + withdrawTransfers + protocol + marketId + feePaids + swaps + automationEvents + debtBefore + debtInUSDBefore + debtAfter + debtInUSDAfter + collateralBefore + collateralInUSDBefore + collateralAfter + collateralInUSDAfter + supplyBefore + supplyInUSDBefore + supplyAfter + supplyInUSDAfter + netValueBefore + netValueAfter + collateralTokenPriceInUSD + debtTokenPriceInUSD + supplyTokenPriceInUSD +} + +type Token { + id: Bytes! + address: Bytes! + symbol: String! + decimals: BigInt! + precision: BigInt! +} + +input Token_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + address: Bytes + address_not: Bytes + address_gt: Bytes + address_lt: Bytes + address_gte: Bytes + address_lte: Bytes + address_in: [Bytes!] + address_not_in: [Bytes!] + address_contains: Bytes + address_not_contains: Bytes + symbol: String + symbol_not: String + symbol_gt: String + symbol_lt: String + symbol_gte: String + symbol_lte: String + symbol_in: [String!] + symbol_not_in: [String!] + symbol_contains: String + symbol_contains_nocase: String + symbol_not_contains: String + symbol_not_contains_nocase: String + symbol_starts_with: String + symbol_starts_with_nocase: String + symbol_not_starts_with: String + symbol_not_starts_with_nocase: String + symbol_ends_with: String + symbol_ends_with_nocase: String + symbol_not_ends_with: String + symbol_not_ends_with_nocase: String + decimals: BigInt + decimals_not: BigInt + decimals_gt: BigInt + decimals_lt: BigInt + decimals_gte: BigInt + decimals_lte: BigInt + decimals_in: [BigInt!] + decimals_not_in: [BigInt!] + precision: BigInt + precision_not: BigInt + precision_gt: BigInt + precision_lt: BigInt + precision_gte: BigInt + precision_lte: BigInt + precision_in: [BigInt!] + precision_not_in: [BigInt!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Token_filter] + or: [Token_filter] +} + +enum Token_orderBy { + id + address + symbol + decimals + precision +} + +type TokenPrice { + id: Bytes! + token: Token! + blockNumber: BigInt! + price: BigDecimal! + oracle: String! +} + +input TokenPrice_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + token: String + token_not: String + token_gt: String + token_lt: String + token_gte: String + token_lte: String + token_in: [String!] + token_not_in: [String!] + token_contains: String + token_contains_nocase: String + token_not_contains: String + token_not_contains_nocase: String + token_starts_with: String + token_starts_with_nocase: String + token_not_starts_with: String + token_not_starts_with_nocase: String + token_ends_with: String + token_ends_with_nocase: String + token_not_ends_with: String + token_not_ends_with_nocase: String + token_: Token_filter + blockNumber: BigInt + blockNumber_not: BigInt + blockNumber_gt: BigInt + blockNumber_lt: BigInt + blockNumber_gte: BigInt + blockNumber_lte: BigInt + blockNumber_in: [BigInt!] + blockNumber_not_in: [BigInt!] + price: BigDecimal + price_not: BigDecimal + price_gt: BigDecimal + price_lt: BigDecimal + price_gte: BigDecimal + price_lte: BigDecimal + price_in: [BigDecimal!] + price_not_in: [BigDecimal!] + oracle: String + oracle_not: String + oracle_gt: String + oracle_lt: String + oracle_gte: String + oracle_lte: String + oracle_in: [String!] + oracle_not_in: [String!] + oracle_contains: String + oracle_contains_nocase: String + oracle_not_contains: String + oracle_not_contains_nocase: String + oracle_starts_with: String + oracle_starts_with_nocase: String + oracle_not_starts_with: String + oracle_not_starts_with_nocase: String + oracle_ends_with: String + oracle_ends_with_nocase: String + oracle_not_ends_with: String + oracle_not_ends_with_nocase: String + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [TokenPrice_filter] + or: [TokenPrice_filter] +} + +enum TokenPrice_orderBy { + id + token + token__id + token__address + token__symbol + token__decimals + token__precision + blockNumber + price + oracle +} + +type Transfer { + id: Bytes! + event: SummerEvent! + from: Bytes! + to: Bytes! + token: Token! + amount: BigDecimal! + priceInUSD: BigDecimal! + oracle: String! + amountUSD: BigDecimal! + txHash: String! +} + +input Transfer_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + event: String + event_not: String + event_gt: String + event_lt: String + event_gte: String + event_lte: String + event_in: [String!] + event_not_in: [String!] + event_contains: String + event_contains_nocase: String + event_not_contains: String + event_not_contains_nocase: String + event_starts_with: String + event_starts_with_nocase: String + event_not_starts_with: String + event_not_starts_with_nocase: String + event_ends_with: String + event_ends_with_nocase: String + event_not_ends_with: String + event_not_ends_with_nocase: String + event_: SummerEvent_filter + from: Bytes + from_not: Bytes + from_gt: Bytes + from_lt: Bytes + from_gte: Bytes + from_lte: Bytes + from_in: [Bytes!] + from_not_in: [Bytes!] + from_contains: Bytes + from_not_contains: Bytes + to: Bytes + to_not: Bytes + to_gt: Bytes + to_lt: Bytes + to_gte: Bytes + to_lte: Bytes + to_in: [Bytes!] + to_not_in: [Bytes!] + to_contains: Bytes + to_not_contains: Bytes + token: String + token_not: String + token_gt: String + token_lt: String + token_gte: String + token_lte: String + token_in: [String!] + token_not_in: [String!] + token_contains: String + token_contains_nocase: String + token_not_contains: String + token_not_contains_nocase: String + token_starts_with: String + token_starts_with_nocase: String + token_not_starts_with: String + token_not_starts_with_nocase: String + token_ends_with: String + token_ends_with_nocase: String + token_not_ends_with: String + token_not_ends_with_nocase: String + token_: Token_filter + amount: BigDecimal + amount_not: BigDecimal + amount_gt: BigDecimal + amount_lt: BigDecimal + amount_gte: BigDecimal + amount_lte: BigDecimal + amount_in: [BigDecimal!] + amount_not_in: [BigDecimal!] + priceInUSD: BigDecimal + priceInUSD_not: BigDecimal + priceInUSD_gt: BigDecimal + priceInUSD_lt: BigDecimal + priceInUSD_gte: BigDecimal + priceInUSD_lte: BigDecimal + priceInUSD_in: [BigDecimal!] + priceInUSD_not_in: [BigDecimal!] + oracle: String + oracle_not: String + oracle_gt: String + oracle_lt: String + oracle_gte: String + oracle_lte: String + oracle_in: [String!] + oracle_not_in: [String!] + oracle_contains: String + oracle_contains_nocase: String + oracle_not_contains: String + oracle_not_contains_nocase: String + oracle_starts_with: String + oracle_starts_with_nocase: String + oracle_not_starts_with: String + oracle_not_starts_with_nocase: String + oracle_ends_with: String + oracle_ends_with_nocase: String + oracle_not_ends_with: String + oracle_not_ends_with_nocase: String + amountUSD: BigDecimal + amountUSD_not: BigDecimal + amountUSD_gt: BigDecimal + amountUSD_lt: BigDecimal + amountUSD_gte: BigDecimal + amountUSD_lte: BigDecimal + amountUSD_in: [BigDecimal!] + amountUSD_not_in: [BigDecimal!] + txHash: String + txHash_not: String + txHash_gt: String + txHash_lt: String + txHash_gte: String + txHash_lte: String + txHash_in: [String!] + txHash_not_in: [String!] + txHash_contains: String + txHash_contains_nocase: String + txHash_not_contains: String + txHash_not_contains_nocase: String + txHash_starts_with: String + txHash_starts_with_nocase: String + txHash_not_starts_with: String + txHash_not_starts_with_nocase: String + txHash_ends_with: String + txHash_ends_with_nocase: String + txHash_not_ends_with: String + txHash_not_ends_with_nocase: String + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Transfer_filter] + or: [Transfer_filter] +} + +enum Transfer_orderBy { + id + event + event__id + event__blockNumber + event__timestamp + event__txHash + event__logIndex + event__sender + event__kind + event__depositedUSD + event__withdrawnUSD + event__deltaUSD + event__feePaidUSD + event__protocol + event__marketId + event__debtBefore + event__debtInUSDBefore + event__debtAfter + event__debtInUSDAfter + event__collateralBefore + event__collateralInUSDBefore + event__collateralAfter + event__collateralInUSDAfter + event__supplyBefore + event__supplyInUSDBefore + event__supplyAfter + event__supplyInUSDAfter + event__netValueBefore + event__netValueAfter + event__collateralTokenPriceInUSD + event__debtTokenPriceInUSD + event__supplyTokenPriceInUSD + from + to + token + token__id + token__address + token__symbol + token__decimals + token__precision + amount + priceInUSD + oracle + amountUSD + txHash +} + +type Trigger { + id: ID! + account: Account! + user: User! + commandAddress: Bytes! + triggerType: BigInt! + kind: String! + triggerData: Bytes! + continuous: Boolean! + decodedData: [String!]! + decodedDataNames: [String!]! + addedBlock: BigInt! + addedTransaction: Bytes! + addedLogIndex: BigInt! + addedTimestamp: BigInt! + removedBlock: BigInt + removedTransaction: Bytes + removedLogIndex: BigInt + removedTimestamp: BigInt + executedBlock: BigInt + executedTransaction: Bytes + executedLogIndex: BigInt + executedTimestamp: BigInt + version: BigInt! + tokens(skip: Int = 0, first: Int = 100, orderBy: Token_orderBy, orderDirection: OrderDirection, where: Token_filter): [Token!] + protocol: String! + marketId: String! + position: Position! + operationName: String +} + +input Trigger_filter { + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + commandAddress: Bytes + commandAddress_not: Bytes + commandAddress_gt: Bytes + commandAddress_lt: Bytes + commandAddress_gte: Bytes + commandAddress_lte: Bytes + commandAddress_in: [Bytes!] + commandAddress_not_in: [Bytes!] + commandAddress_contains: Bytes + commandAddress_not_contains: Bytes + triggerType: BigInt + triggerType_not: BigInt + triggerType_gt: BigInt + triggerType_lt: BigInt + triggerType_gte: BigInt + triggerType_lte: BigInt + triggerType_in: [BigInt!] + triggerType_not_in: [BigInt!] + kind: String + kind_not: String + kind_gt: String + kind_lt: String + kind_gte: String + kind_lte: String + kind_in: [String!] + kind_not_in: [String!] + kind_contains: String + kind_contains_nocase: String + kind_not_contains: String + kind_not_contains_nocase: String + kind_starts_with: String + kind_starts_with_nocase: String + kind_not_starts_with: String + kind_not_starts_with_nocase: String + kind_ends_with: String + kind_ends_with_nocase: String + kind_not_ends_with: String + kind_not_ends_with_nocase: String + triggerData: Bytes + triggerData_not: Bytes + triggerData_gt: Bytes + triggerData_lt: Bytes + triggerData_gte: Bytes + triggerData_lte: Bytes + triggerData_in: [Bytes!] + triggerData_not_in: [Bytes!] + triggerData_contains: Bytes + triggerData_not_contains: Bytes + continuous: Boolean + continuous_not: Boolean + continuous_in: [Boolean!] + continuous_not_in: [Boolean!] + decodedData: [String!] + decodedData_not: [String!] + decodedData_contains: [String!] + decodedData_contains_nocase: [String!] + decodedData_not_contains: [String!] + decodedData_not_contains_nocase: [String!] + decodedDataNames: [String!] + decodedDataNames_not: [String!] + decodedDataNames_contains: [String!] + decodedDataNames_contains_nocase: [String!] + decodedDataNames_not_contains: [String!] + decodedDataNames_not_contains_nocase: [String!] + addedBlock: BigInt + addedBlock_not: BigInt + addedBlock_gt: BigInt + addedBlock_lt: BigInt + addedBlock_gte: BigInt + addedBlock_lte: BigInt + addedBlock_in: [BigInt!] + addedBlock_not_in: [BigInt!] + addedTransaction: Bytes + addedTransaction_not: Bytes + addedTransaction_gt: Bytes + addedTransaction_lt: Bytes + addedTransaction_gte: Bytes + addedTransaction_lte: Bytes + addedTransaction_in: [Bytes!] + addedTransaction_not_in: [Bytes!] + addedTransaction_contains: Bytes + addedTransaction_not_contains: Bytes + addedLogIndex: BigInt + addedLogIndex_not: BigInt + addedLogIndex_gt: BigInt + addedLogIndex_lt: BigInt + addedLogIndex_gte: BigInt + addedLogIndex_lte: BigInt + addedLogIndex_in: [BigInt!] + addedLogIndex_not_in: [BigInt!] + addedTimestamp: BigInt + addedTimestamp_not: BigInt + addedTimestamp_gt: BigInt + addedTimestamp_lt: BigInt + addedTimestamp_gte: BigInt + addedTimestamp_lte: BigInt + addedTimestamp_in: [BigInt!] + addedTimestamp_not_in: [BigInt!] + removedBlock: BigInt + removedBlock_not: BigInt + removedBlock_gt: BigInt + removedBlock_lt: BigInt + removedBlock_gte: BigInt + removedBlock_lte: BigInt + removedBlock_in: [BigInt!] + removedBlock_not_in: [BigInt!] + removedTransaction: Bytes + removedTransaction_not: Bytes + removedTransaction_gt: Bytes + removedTransaction_lt: Bytes + removedTransaction_gte: Bytes + removedTransaction_lte: Bytes + removedTransaction_in: [Bytes!] + removedTransaction_not_in: [Bytes!] + removedTransaction_contains: Bytes + removedTransaction_not_contains: Bytes + removedLogIndex: BigInt + removedLogIndex_not: BigInt + removedLogIndex_gt: BigInt + removedLogIndex_lt: BigInt + removedLogIndex_gte: BigInt + removedLogIndex_lte: BigInt + removedLogIndex_in: [BigInt!] + removedLogIndex_not_in: [BigInt!] + removedTimestamp: BigInt + removedTimestamp_not: BigInt + removedTimestamp_gt: BigInt + removedTimestamp_lt: BigInt + removedTimestamp_gte: BigInt + removedTimestamp_lte: BigInt + removedTimestamp_in: [BigInt!] + removedTimestamp_not_in: [BigInt!] + executedBlock: BigInt + executedBlock_not: BigInt + executedBlock_gt: BigInt + executedBlock_lt: BigInt + executedBlock_gte: BigInt + executedBlock_lte: BigInt + executedBlock_in: [BigInt!] + executedBlock_not_in: [BigInt!] + executedTransaction: Bytes + executedTransaction_not: Bytes + executedTransaction_gt: Bytes + executedTransaction_lt: Bytes + executedTransaction_gte: Bytes + executedTransaction_lte: Bytes + executedTransaction_in: [Bytes!] + executedTransaction_not_in: [Bytes!] + executedTransaction_contains: Bytes + executedTransaction_not_contains: Bytes + executedLogIndex: BigInt + executedLogIndex_not: BigInt + executedLogIndex_gt: BigInt + executedLogIndex_lt: BigInt + executedLogIndex_gte: BigInt + executedLogIndex_lte: BigInt + executedLogIndex_in: [BigInt!] + executedLogIndex_not_in: [BigInt!] + executedTimestamp: BigInt + executedTimestamp_not: BigInt + executedTimestamp_gt: BigInt + executedTimestamp_lt: BigInt + executedTimestamp_gte: BigInt + executedTimestamp_lte: BigInt + executedTimestamp_in: [BigInt!] + executedTimestamp_not_in: [BigInt!] + version: BigInt + version_not: BigInt + version_gt: BigInt + version_lt: BigInt + version_gte: BigInt + version_lte: BigInt + version_in: [BigInt!] + version_not_in: [BigInt!] + tokens: [String!] + tokens_not: [String!] + tokens_contains: [String!] + tokens_contains_nocase: [String!] + tokens_not_contains: [String!] + tokens_not_contains_nocase: [String!] + tokens_: Token_filter + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + position: String + position_not: String + position_gt: String + position_lt: String + position_gte: String + position_lte: String + position_in: [String!] + position_not_in: [String!] + position_contains: String + position_contains_nocase: String + position_not_contains: String + position_not_contains_nocase: String + position_starts_with: String + position_starts_with_nocase: String + position_not_starts_with: String + position_not_starts_with_nocase: String + position_ends_with: String + position_ends_with_nocase: String + position_not_ends_with: String + position_not_ends_with_nocase: String + position_: Position_filter + operationName: String + operationName_not: String + operationName_gt: String + operationName_lt: String + operationName_gte: String + operationName_lte: String + operationName_in: [String!] + operationName_not_in: [String!] + operationName_contains: String + operationName_contains_nocase: String + operationName_not_contains: String + operationName_not_contains_nocase: String + operationName_starts_with: String + operationName_starts_with_nocase: String + operationName_not_starts_with: String + operationName_not_starts_with_nocase: String + operationName_ends_with: String + operationName_ends_with_nocase: String + operationName_not_ends_with: String + operationName_not_ends_with_nocase: String + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [Trigger_filter] + or: [Trigger_filter] +} + +enum Trigger_orderBy { + id + account + account__id + account__address + account__type + account__vaultId + user + user__id + user__openPositions + commandAddress + triggerType + kind + triggerData + continuous + decodedData + decodedDataNames + addedBlock + addedTransaction + addedLogIndex + addedTimestamp + removedBlock + removedTransaction + removedLogIndex + removedTimestamp + executedBlock + executedTransaction + executedLogIndex + executedTimestamp + version + tokens + protocol + marketId + position + position__id + position__protocol + position__marketId + position__positionType + position__cumulativeDepositedUSD + position__cumulativeWithdrawnUSD + position__cumulativeDeltaUSD + position__cumulativeFeesUSD + position__debt + position__debtInUSD + position__collateral + position__collateralInUSD + position__supply + position__supplyInUSD + position__netValue + position___ajnaBucket + operationName +} + +type TriggerEvent { + id: Bytes! + eventType: String! + trigger: Trigger! + account: Account! + user: User! + mainEventHash: SummerEvent + protocol: String! + marketId: String! + position: Position! + block: BigInt! + transactionHash: Bytes! + logIndex: BigInt! + timestamp: BigInt! +} + +input TriggerEvent_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + eventType: String + eventType_not: String + eventType_gt: String + eventType_lt: String + eventType_gte: String + eventType_lte: String + eventType_in: [String!] + eventType_not_in: [String!] + eventType_contains: String + eventType_contains_nocase: String + eventType_not_contains: String + eventType_not_contains_nocase: String + eventType_starts_with: String + eventType_starts_with_nocase: String + eventType_not_starts_with: String + eventType_not_starts_with_nocase: String + eventType_ends_with: String + eventType_ends_with_nocase: String + eventType_not_ends_with: String + eventType_not_ends_with_nocase: String + trigger: String + trigger_not: String + trigger_gt: String + trigger_lt: String + trigger_gte: String + trigger_lte: String + trigger_in: [String!] + trigger_not_in: [String!] + trigger_contains: String + trigger_contains_nocase: String + trigger_not_contains: String + trigger_not_contains_nocase: String + trigger_starts_with: String + trigger_starts_with_nocase: String + trigger_not_starts_with: String + trigger_not_starts_with_nocase: String + trigger_ends_with: String + trigger_ends_with_nocase: String + trigger_not_ends_with: String + trigger_not_ends_with_nocase: String + trigger_: Trigger_filter + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + mainEventHash: String + mainEventHash_not: String + mainEventHash_gt: String + mainEventHash_lt: String + mainEventHash_gte: String + mainEventHash_lte: String + mainEventHash_in: [String!] + mainEventHash_not_in: [String!] + mainEventHash_contains: String + mainEventHash_contains_nocase: String + mainEventHash_not_contains: String + mainEventHash_not_contains_nocase: String + mainEventHash_starts_with: String + mainEventHash_starts_with_nocase: String + mainEventHash_not_starts_with: String + mainEventHash_not_starts_with_nocase: String + mainEventHash_ends_with: String + mainEventHash_ends_with_nocase: String + mainEventHash_not_ends_with: String + mainEventHash_not_ends_with_nocase: String + mainEventHash_: SummerEvent_filter + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + position: String + position_not: String + position_gt: String + position_lt: String + position_gte: String + position_lte: String + position_in: [String!] + position_not_in: [String!] + position_contains: String + position_contains_nocase: String + position_not_contains: String + position_not_contains_nocase: String + position_starts_with: String + position_starts_with_nocase: String + position_not_starts_with: String + position_not_starts_with_nocase: String + position_ends_with: String + position_ends_with_nocase: String + position_not_ends_with: String + position_not_ends_with_nocase: String + position_: Position_filter + block: BigInt + block_not: BigInt + block_gt: BigInt + block_lt: BigInt + block_gte: BigInt + block_lte: BigInt + block_in: [BigInt!] + block_not_in: [BigInt!] + transactionHash: Bytes + transactionHash_not: Bytes + transactionHash_gt: Bytes + transactionHash_lt: Bytes + transactionHash_gte: Bytes + transactionHash_lte: Bytes + transactionHash_in: [Bytes!] + transactionHash_not_in: [Bytes!] + transactionHash_contains: Bytes + transactionHash_not_contains: Bytes + logIndex: BigInt + logIndex_not: BigInt + logIndex_gt: BigInt + logIndex_lt: BigInt + logIndex_gte: BigInt + logIndex_lte: BigInt + logIndex_in: [BigInt!] + logIndex_not_in: [BigInt!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [TriggerEvent_filter] + or: [TriggerEvent_filter] +} + +enum TriggerEvent_orderBy { + id + eventType + trigger + trigger__id + trigger__commandAddress + trigger__triggerType + trigger__kind + trigger__triggerData + trigger__continuous + trigger__addedBlock + trigger__addedTransaction + trigger__addedLogIndex + trigger__addedTimestamp + trigger__removedBlock + trigger__removedTransaction + trigger__removedLogIndex + trigger__removedTimestamp + trigger__executedBlock + trigger__executedTransaction + trigger__executedLogIndex + trigger__executedTimestamp + trigger__version + trigger__protocol + trigger__marketId + trigger__operationName + account + account__id + account__address + account__type + account__vaultId + user + user__id + user__openPositions + mainEventHash + mainEventHash__id + mainEventHash__blockNumber + mainEventHash__timestamp + mainEventHash__txHash + mainEventHash__logIndex + mainEventHash__sender + mainEventHash__kind + mainEventHash__depositedUSD + mainEventHash__withdrawnUSD + mainEventHash__deltaUSD + mainEventHash__feePaidUSD + mainEventHash__protocol + mainEventHash__marketId + mainEventHash__debtBefore + mainEventHash__debtInUSDBefore + mainEventHash__debtAfter + mainEventHash__debtInUSDAfter + mainEventHash__collateralBefore + mainEventHash__collateralInUSDBefore + mainEventHash__collateralAfter + mainEventHash__collateralInUSDAfter + mainEventHash__supplyBefore + mainEventHash__supplyInUSDBefore + mainEventHash__supplyAfter + mainEventHash__supplyInUSDAfter + mainEventHash__netValueBefore + mainEventHash__netValueAfter + mainEventHash__collateralTokenPriceInUSD + mainEventHash__debtTokenPriceInUSD + mainEventHash__supplyTokenPriceInUSD + protocol + marketId + position + position__id + position__protocol + position__marketId + position__positionType + position__cumulativeDepositedUSD + position__cumulativeWithdrawnUSD + position__cumulativeDeltaUSD + position__cumulativeFeesUSD + position__debt + position__debtInUSD + position__collateral + position__collateralInUSD + position__supply + position__supplyInUSD + position__netValue + position___ajnaBucket + block + transactionHash + logIndex + timestamp +} + +type User { + """ msg.sender address """ + id: Bytes! + accounts(skip: Int = 0, first: Int = 100, orderBy: Account_orderBy, orderDirection: OrderDirection, where: Account_filter): [Account!]! + feePaids(skip: Int = 0, first: Int = 100, orderBy: FeePaid_orderBy, orderDirection: OrderDirection, where: FeePaid_filter): [FeePaid!]! + summerEvents(skip: Int = 0, first: Int = 100, orderBy: SummerEvent_orderBy, orderDirection: OrderDirection, where: SummerEvent_filter): [SummerEvent!]! + createPositionEvents(skip: Int = 0, first: Int = 100, orderBy: CreatePositionEvent_orderBy, orderDirection: OrderDirection, where: CreatePositionEvent_filter): [CreatePositionEvent!]! + automationEvents(skip: Int = 0, first: Int = 100, orderBy: TriggerEvent_orderBy, orderDirection: OrderDirection, where: TriggerEvent_filter): [TriggerEvent!]! + positions(skip: Int = 0, first: Int = 100, orderBy: Position_orderBy, orderDirection: OrderDirection, where: Position_filter): [Position!]! + swaps(skip: Int = 0, first: Int = 100, orderBy: AssetSwap_orderBy, orderDirection: OrderDirection, where: AssetSwap_filter): [AssetSwap!]! + openPositions: BigInt! +} + +input User_filter { + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + accounts_: Account_filter + feePaids_: FeePaid_filter + summerEvents_: SummerEvent_filter + createPositionEvents_: CreatePositionEvent_filter + automationEvents_: TriggerEvent_filter + positions_: Position_filter + swaps_: AssetSwap_filter + openPositions: BigInt + openPositions_not: BigInt + openPositions_gt: BigInt + openPositions_lt: BigInt + openPositions_gte: BigInt + openPositions_lte: BigInt + openPositions_in: [BigInt!] + openPositions_not_in: [BigInt!] + + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [User_filter] + or: [User_filter] +} + +enum User_orderBy { + id + accounts + feePaids + summerEvents + createPositionEvents + automationEvents + positions + swaps + openPositions +} + diff --git a/stacks/rays-db.ts b/stacks/rays-db.ts deleted file mode 100644 index ecbfa2e1aa..0000000000 --- a/stacks/rays-db.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { RDS } from 'sst/constructs' -import * as cdk from 'aws-cdk-lib' -import { SummerStackContext } from './summer-stack-context' - -export function addRaysDb({ - stack, - vpc, - isDev, - isProd, - isStaging, -}: SummerStackContext): RDS | null { - if (isDev) { - console.info('RDS is only created in staging and prod stages') - return null - } - - if (!vpc) { - console.error('VPC and VPC subnets are required for RDS. Please add them to the stack context') - throw new Error('VPC and VPC subnets are required for RDS') - } - - const scalingStaging = { - autoPause: 30, // auto pause after 30 minutes - minCapacity: 'ACU_2' as const, - maxCapacity: 'ACU_16' as const, - } - - const scalingProd = { - autoPause: false, - minCapacity: 'ACU_4' as const, - maxCapacity: 'ACU_32' as const, - } - - const scalingDev = { - autoPause: true, - minCapacity: 'ACU_2' as const, - maxCapacity: 'ACU_2' as const, - } - - const scaling = isProd ? scalingProd : isStaging ? scalingStaging : scalingDev - - const rds = new RDS(stack, 'rays-database', { - engine: 'postgresql13.9', - defaultDatabaseName: 'rays', - migrations: 'stacks/node_modules/@summerfi/rays-db/dist/migrations', - types: { - camelCase: true, - path: 'packages/rays-db/src/database-types.ts', - }, - scaling: { - autoPause: scaling.autoPause, - minCapacity: scaling.minCapacity, - }, - cdk: { - cluster: { - vpc: vpc.vpc, - vpcSubnets: { - subnets: [...vpc.vpc.privateSubnets, ...vpc.vpc.publicSubnets], - }, - securityGroups: [vpc.securityGroup], - }, - }, - }) - - rds.cdk.cluster.connections.allowDefaultPortFromAnyIpv4() - - const resource = rds.node.defaultChild as cdk.CfnResource - resource?.applyRemovalPolicy(cdk.RemovalPolicy.RETAIN) - - return rds -} diff --git a/stacks/rays.ts b/stacks/rays.ts index b8b518e789..607ad7218b 100644 --- a/stacks/rays.ts +++ b/stacks/rays.ts @@ -1,35 +1,64 @@ import { SummerStackContext } from './summer-stack-context' -import { Function, RDS } from 'sst/constructs' +import { Cron, Function, FunctionProps } from 'sst/constructs' +import * as process from 'node:process' -export function addRaysConfig({ stack, api, db, vpc }: SummerStackContext & { db: RDS | null }) { - const raysFunction = vpc - ? new Function(stack, 'get-rays-function', { - handler: 'summerfi-api/get-rays-function/src/index.handler', - runtime: 'nodejs20.x', - logFormat: 'JSON', - environment: { - POWERTOOLS_LOG_LEVEL: process.env.POWERTOOLS_LOG_LEVEL || 'INFO', - }, - vpc: vpc.vpc, - vpcSubnets: { - subnets: [...vpc.vpc.privateSubnets], - }, - }) - : new Function(stack, 'get-rays-function', { - handler: 'summerfi-api/get-rays-function/src/index.handler', - runtime: 'nodejs20.x', - logFormat: 'JSON', - environment: { - POWERTOOLS_LOG_LEVEL: process.env.POWERTOOLS_LOG_LEVEL || 'INFO', - RAYS_DB_CONNECTION_STRING: - process.env.RAYS_DB_CONNECTION_STRING || 'postgres://user:password@localhost:5500/rays', - }, - }) +export function addRaysConfig({ stack, api, vpc, app }: SummerStackContext) { + const { RAYS_DB_WRITE_CONNECTION_STRING, RAYS_DB_READ_CONNECTION_STRING, SUBGRAPH_BASE } = + process.env + if (!RAYS_DB_WRITE_CONNECTION_STRING) { + throw new Error('RAYS_DB_WRITE_CONNECTION_STRING is not set') + } + if (!RAYS_DB_READ_CONNECTION_STRING) { + throw new Error('RAYS_DB_READ_CONNECTION_STRING is not set') + } + if (!SUBGRAPH_BASE) { + throw new Error('SUBGRAPH_BASE is not set') + } - if (db) { - raysFunction.bind([db]) + const raysFunctionProps: FunctionProps = { + handler: 'summerfi-api/get-rays-function/src/index.handler', + runtime: 'nodejs20.x', + logFormat: 'JSON', + environment: { + POWERTOOLS_LOG_LEVEL: process.env.POWERTOOLS_LOG_LEVEL || 'INFO', + RAYS_DB_CONNECTION_STRING: RAYS_DB_READ_CONNECTION_STRING, + }, + ...(vpc && { + vpc: vpc.vpc, + vpcSubnets: { + subnets: [...vpc.vpc.privateSubnets], + }, + }), } + const updateRaysCronFunctionProps: FunctionProps = { + handler: 'background-jobs/update-rays-cron-function/src/index.handler', + runtime: 'nodejs20.x', + environment: { + POWERTOOLS_LOG_LEVEL: process.env.POWERTOOLS_LOG_LEVEL || 'INFO', + RAYS_DB_CONNECTION_STRING: RAYS_DB_WRITE_CONNECTION_STRING, + SUBGRAPH_BASE, + }, + ...(vpc && { + vpc: vpc.vpc, + vpcSubnets: { + subnets: [...vpc.vpc.privateSubnets], + }, + }), + } + const raysFunction = new Function(stack, 'get-rays-function', raysFunctionProps) + const updateRaysCronFunction = new Function( + stack, + 'update-rays-cron-function', + updateRaysCronFunctionProps, + ) + + new Cron(stack, 'update-rays-cron', { + schedule: 'rate(2 hours)', + enabled: app.stage === 'staging', // only run in staging right now. + job: updateRaysCronFunction, + }) + api.addRoutes(stack, { 'GET /api/rays': raysFunction, }) diff --git a/stacks/summer-stack.ts b/stacks/summer-stack.ts index 93c13f3d95..c4da629821 100644 --- a/stacks/summer-stack.ts +++ b/stacks/summer-stack.ts @@ -7,7 +7,6 @@ import { addMorpho } from './morpho' import { addApyConfig } from './apy' import { attachVPC } from './vpc' import { SummerStackContext } from './summer-stack-context' -import { addRaysDb } from './rays-db' import { addRaysConfig } from './rays' import { addRedis } from './redis' @@ -41,14 +40,13 @@ export function API(stackContext: StackContext) { isStaging, } - const db = addRaysDb(summerContext) addTriggersConfig(summerContext) addSdkConfig(summerContext) addMigrationsConfig(summerContext) addPortfolioConfig(summerContext) addMorpho(summerContext) addApyConfig(summerContext) - addRaysConfig({ ...summerContext, db }) + addRaysConfig(summerContext) stack.addOutputs({ ApiEndpoint: api.url, diff --git a/summerfi-api/get-rays-function/package.json b/summerfi-api/get-rays-function/package.json index 3273784fdc..fc6fab4b0d 100644 --- a/summerfi-api/get-rays-function/package.json +++ b/summerfi-api/get-rays-function/package.json @@ -11,13 +11,11 @@ "@aws-lambda-powertools/logger": "^2.0.2", "@aws-lambda-powertools/metrics": "^2.0.2", "@aws-lambda-powertools/tracer": "^2.0.2", - "@aws-sdk/client-rds-data": "^3.565.0", "@summerfi/abstractions": "workspace:*", "@summerfi/serverless-shared": "workspace:*", "@summerfi/rays-db": "workspace:*", "kysely": "^0.27.3", "node-fetch": "^3.3.2", - "viem": "^1.19.11", "zod": "^3.22.4" }, "devDependencies": { diff --git a/summerfi-api/get-rays-function/src/index.ts b/summerfi-api/get-rays-function/src/index.ts index d2553b99a6..ab33729ef9 100644 --- a/summerfi-api/get-rays-function/src/index.ts +++ b/summerfi-api/get-rays-function/src/index.ts @@ -2,8 +2,6 @@ import type { APIGatewayProxyEventV2, APIGatewayProxyResultV2, Context } from 'a import { ResponseBadRequest, ResponseOk } from '@summerfi/serverless-shared/responses' import { Logger } from '@aws-lambda-powertools/logger' import { getRaysDB } from '@summerfi/rays-db' -import { RDS } from 'sst/node/rds' -import { RDSData } from '@aws-sdk/client-rds-data' import { addressSchema } from '@summerfi/serverless-shared' import { z } from 'zod' @@ -35,6 +33,11 @@ export const handler = async ( event: APIGatewayProxyEventV2, context: Context, ): Promise => { + const { RAYS_DB_CONNECTION_STRING } = process.env + if (!RAYS_DB_CONNECTION_STRING) { + throw new Error('RAYS_DB_CONNECTION_STRING is not set') + } + logger.addContext(context) const parsedResult = queryParamsSchema.safeParse(event.queryStringParameters) @@ -44,19 +47,12 @@ export const handler = async ( const { address } = parsedResult.data - const dbConfig = - process.env.IS_LOCAL === 'true' - ? { - connectionString: process.env.RAYS_DB_CONNECTION_STRING ?? '', - } - : { - database: RDS['rays-database'].defaultDatabaseName, - secretArn: RDS['rays-database'].secretArn, - resourceArn: RDS['rays-database'].clusterArn, - client: new RDSData({}), - } - - const db = await getRaysDB(dbConfig) + const dbConfig = { + connectionString: RAYS_DB_CONNECTION_STRING, + logger, + } + + const { db } = await getRaysDB(dbConfig) const userPoints = await db .selectFrom('pointsDistribution') diff --git a/summerfi-api/get-rays-function/sst-env.d.ts b/summerfi-api/get-rays-function/sst-env.d.ts index a4e7ac7466..61de7a5d49 100644 --- a/summerfi-api/get-rays-function/sst-env.d.ts +++ b/summerfi-api/get-rays-function/sst-env.d.ts @@ -1,11 +1 @@ -import 'sst/node/rds' - -declare module 'sst/node/rds' { - export interface RDSResources { - 'rays-database': { - defaultDatabaseName: string - secretArn: string - clusterArn: string - } - } -} +import '../../.sst/types' diff --git a/turbo.json b/turbo.json index 680ed09608..06711d0611 100644 --- a/turbo.json +++ b/turbo.json @@ -42,7 +42,9 @@ "VPC_ID", "SECURITY_GROUP_ID", "RAYS_DB_CONNECTION_STRING", - "IS_LOCAL" + "IS_LOCAL", + "RAYS_DB_WRITE_CONNECTION_STRING", + "RAYS_DB_READ_CONNECTION_STRING" ], "pipeline": { "dev": { From fc977c17cd9accdca72658399aa760b70f8e3fa8 Mon Sep 17 00:00:00 2001 From: Jakub Swierczek Date: Wed, 22 May 2024 09:50:04 +0200 Subject: [PATCH 02/37] Add database connection strings to GitHub workflows (#278) Added read and write connection strings for the RAYS database to GitHub deployment workflows. This includes both production and staging environments, enhancing the configuration details needed for deploying the application. --- .github/workflows/deploy-production.yaml | 2 ++ .github/workflows/deploy-staging.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/deploy-production.yaml b/.github/workflows/deploy-production.yaml index 2ca7726b7e..138cf4e764 100644 --- a/.github/workflows/deploy-production.yaml +++ b/.github/workflows/deploy-production.yaml @@ -32,6 +32,8 @@ jobs: REDIS_CACHE_PASSWORD: ${{ secrets.REDIS_CACHE_PASSWORD }} VPC_ID: ${{ secrets.VPC_ID }} SECURITY_GROUP_ID: ${{ secrets.SECURITY_GROUP_ID }} + RAYS_DB_WRITE_CONNECTION_STRING: ${{ secrets.RAYS_DB_WRITE_CONNECTION_STRING }} + RAYS_DB_READ_CONNECTION_STRING: ${{ secrets.RAYS_DB_READ_CONNECTION_STRING }} steps: - name: Git clone the repository uses: actions/checkout@v3 diff --git a/.github/workflows/deploy-staging.yaml b/.github/workflows/deploy-staging.yaml index 6acd3a291d..fd17adcc79 100644 --- a/.github/workflows/deploy-staging.yaml +++ b/.github/workflows/deploy-staging.yaml @@ -32,6 +32,8 @@ jobs: REDIS_CACHE_PASSWORD: ${{ secrets.REDIS_CACHE_PASSWORD }} VPC_ID: ${{ secrets.VPC_ID }} SECURITY_GROUP_ID: ${{ secrets.SECURITY_GROUP_ID }} + RAYS_DB_WRITE_CONNECTION_STRING: ${{ secrets.RAYS_DB_WRITE_CONNECTION_STRING }} + RAYS_DB_READ_CONNECTION_STRING: ${{ secrets.RAYS_DB_READ_CONNECTION_STRING }} steps: - name: Git clone the repository uses: actions/checkout@v3 From b6ff997a0b2d0c276cfeefc5eab10844e161dbb2 Mon Sep 17 00:00:00 2001 From: Cristian Dascalu Date: Wed, 22 May 2024 10:13:00 +0200 Subject: [PATCH 03/37] Separate GH secret for `DEBANK_API_URL` in staging (#279) --- .github/workflows/deploy-staging.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-staging.yaml b/.github/workflows/deploy-staging.yaml index fd17adcc79..0d0f1af094 100644 --- a/.github/workflows/deploy-staging.yaml +++ b/.github/workflows/deploy-staging.yaml @@ -25,7 +25,7 @@ jobs: SUBGRAPH_BASE: ${{ secrets.SUBGRAPH_BASE }} RPC_GATEWAY: ${{ secrets.RPC_GATEWAY }} DEBANK_API_KEY: ${{ secrets.DEBANK_API_KEY }} - DEBANK_API_URL: ${{ secrets.DEBANK_API_URL }} + DEBANK_API_URL: ${{ secrets.STAGING_DEBANK_API_URL }} POWERTOOLS_LOG_LEVEL: ${{ vars.POWERTOOLS_LOG_LEVEL }} REDIS_CACHE_URL: ${{ secrets.REDIS_CACHE_URL }} REDIS_CACHE_USER: ${{ secrets.REDIS_CACHE_USER }} From e8bb13abae659f249615a936d267bca4b5c4f39f Mon Sep 17 00:00:00 2001 From: Cristian Dascalu Date: Wed, 22 May 2024 11:27:40 +0200 Subject: [PATCH 04/37] Separate GH secret for `DEBANK_API_URL` in prod (#280) --- .github/workflows/deploy-production.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-production.yaml b/.github/workflows/deploy-production.yaml index 138cf4e764..7de9bda2e3 100644 --- a/.github/workflows/deploy-production.yaml +++ b/.github/workflows/deploy-production.yaml @@ -25,7 +25,7 @@ jobs: SUBGRAPH_BASE: ${{ secrets.SUBGRAPH_BASE }} RPC_GATEWAY: ${{ secrets.RPC_GATEWAY }} DEBANK_API_KEY: ${{ secrets.DEBANK_API_KEY }} - DEBANK_API_URL: ${{ secrets.DEBANK_API_URL }} + DEBANK_API_URL: ${{ secrets.PROD_DEBANK_API_URL }} POWERTOOLS_LOG_LEVEL: ${{ vars.POWERTOOLS_LOG_LEVEL }} REDIS_CACHE_URL: ${{ secrets.REDIS_CACHE_URL }} REDIS_CACHE_USER: ${{ secrets.REDIS_CACHE_USER }} From b70c98a6de93e2d9952ddf1d1212e851290368e9 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Wed, 22 May 2024 13:33:32 +0200 Subject: [PATCH 05/37] feat: Aave + Spark Protocol Plugins for refinance (#258) --- package.json | 1 + .../contracts/actions/aave/v3/Payback.sol | 6 +- .../contracts/core/types/Aave.sol | 1 + .../src/config/Config.ts | 2 + sdk/order-planner-service/tsconfig.json | 7 +- .../aave-v3/actions/AaveV3BorrowAction.ts | 32 +++ .../aave-v3/actions/AaveV3DepositAction.ts | 37 +++ .../aave-v3/actions/AaveV3PaybackAction.ts | 38 ++++ .../aave-v3/actions/AaveV3SetEmodeAction.ts | 33 +++ .../aave-v3/actions/AaveV3WithdrawAction.ts | 35 +++ .../src/plugins/aave-v3/actions/index.ts | 5 + .../AaveV3DepositBorrowActionBuilder.ts | 93 ++++++++ .../AaveV3OpenPositionActionBuilder.ts | 30 +++ .../AaveV3PaybackWithdrawActionBuilder.ts | 99 ++++++++ .../aave-v3/builders/AaveV3StepBuilders.ts | 10 +- .../src/plugins/aave-v3/builders/index.ts | 3 + .../implementation/AAVEv3ProtocolPlugin.ts | 2 +- .../implementation/EmodeCategoryMap.ts | 10 +- .../src/plugins/aave-v3/index.ts | 2 + .../builders/OpenPositionActionBuilder.ts | 14 ++ .../src/plugins/common/builders/index.ts | 1 + .../AAVEv3LikeBaseProtocolPlugin.ts | 6 +- .../AAVEv3LikeProtocolDataBuilder.ts | 6 +- .../MakerImportPositionActionBuilder.ts | 4 +- .../MakerOpenPositionActionBuilder.ts | 15 ++ .../MakerPaybackWithdrawActionBuilder.ts | 4 +- .../src/plugins/maker/builders/index.ts | 7 +- .../MorphoOpenPositionActionBuilder.ts | 15 ++ .../src/plugins/morphoblue/builders/index.ts | 2 + .../spark/actions/SparkPaybackAction.ts | 35 +++ .../spark/actions/SparkSetEmodeAction.ts | 33 +++ .../spark/actions/SparkWithdrawAction.ts | 35 +++ .../src/plugins/spark/actions/index.ts | 7 +- .../SparkDepositBorrowActionBuilder.ts | 5 + .../SparkOpenPositionActionBuilder.ts | 30 +++ .../SparkPaybackWithdrawActionBuilder.ts | 97 ++++++++ .../spark/builders/SparkStepBuilders.ts | 4 + .../src/plugins/spark/builders/index.ts | 2 + .../spark/implementation/EmodeCategoryMap.ts | 10 +- .../actions/aaveV3/AaveV3BorrowAction.spec.ts | 54 +++++ .../aaveV3/AaveV3DepositAction.spec.ts | 52 +++++ .../aaveV3/AaveV3PaybackAction.spec.ts | 57 +++++ .../aaveV3/AaveV3SetEModeAction.spec.ts | 35 +++ .../aaveV3/AaveV3WithdrawAction.spec.ts | 54 +++++ .../actions/morpho/MorphoBorrowAction.spec.ts | 1 - .../morpho/MorphoDepositAction.spec.ts | 1 - .../morpho/MorphoPaybackAction.spec.ts | 1 - .../morpho/MorphoWithdrawAction.spec.ts | 3 +- .../actions/spark/SparkBorrowAction.spec.ts | 54 +++++ .../actions/spark/SparkDepositAction.spec.ts | 52 +++++ .../actions/spark/SparkPaybackAction.spec.ts | 54 +++++ .../actions/spark/SparkSetEModeAction.spec.ts | 35 +++ .../actions/spark/SparkWithdrawAction.spec.ts | 54 +++++ .../DepositBorrowActionBuilder.spec.ts | 64 ++---- .../builders/FlashloanActionBuilder.spec.ts | 20 +- .../ImportPositionActionBuilder.spec.ts | 144 ++++++++++++ .../OpenPositionActionBuilder.spec.ts | 135 +++++++++++ .../PaybackWithdrawActionBuilder.spec.ts | 3 +- .../builders/PullTokenActionBuilder.spec.ts | 20 +- .../builders/ReturnFundsActionBuilder.spec.ts | 20 +- .../unit/builders/SwapActionBuilder.spec.ts | 40 ++-- .../AaveV3DepositBorrowActionBuilder.spec.ts | 214 ++++++++++++++++++ .../AaveV3OpenPositionActionBuilder.spec.ts | 151 ++++++++++++ ...AaveV3PaybackWithdrawActionBuilder.spec.ts | 189 ++++++++++++++++ .../MakerImportPositionActionBuilder.spec.ts | 178 +++++++++++++++ .../MakerOpenPositionActionBuilder.spec.ts | 155 +++++++++++++ .../MakerPaybackWithdrawActionBuilder.spec.ts | 194 ++++++++++++++++ .../MorphoDepositBorrowActionBuilder.spec.ts | 3 +- .../MorphoOpenPositionActionBuilder.spec.ts | 155 +++++++++++++ ...MorphoPaybackWithdrawActionBuilder.spec.ts | 3 +- .../SparkDepositBorrowActionBuilder.spec.ts | 214 ++++++++++++++++++ .../SparkOpenPositionActionBuilder.spec.ts | 151 ++++++++++++ .../SparkPaybackWithdrawActionBuilder.spec.ts | 189 ++++++++++++++++ .../tests/utils/ProtocolPluginMock.ts | 26 ++- .../utils/ProtocolsPluginRegistryMock.ts | 2 + .../src/common/utils/PositionUtils.ts | 1 + sdk/sdk-common/src/common/utils/index.ts | 2 + sdk/sdk-common/src/simulation/Enums.ts | 1 + .../src/simulation/SimulationStrategy.ts | 1 + sdk/sdk-common/src/simulation/Steps.ts | 10 +- sdk/sdk-e2e/tests/refinance.test.ts | 213 +++++++++++++++++ .../tests/refinanceAaveV3SparkAnyPair.test.ts | 201 ++++++++++++++++ .../reducer/depositBorrowReducer.ts | 20 +- .../reducer/flashloanReducer.ts | 5 +- .../simulator-engine/reducer/importReducer.ts | 5 +- .../reducer/newPositionEventReducer.ts | 5 +- .../reducer/openPositionReducer.ts | 16 ++ .../reducer/paybackWithdrawReducer.ts | 17 +- .../reducer/pullTokenReducer.ts | 9 +- .../reducer/repayFlashloanReducer.ts | 5 +- .../reducer/returnFundsReducer.ts | 5 +- .../simulator-engine/reducer/stateReducers.ts | 2 + .../simulator-engine/reducer/swapReducer.ts | 11 +- .../simulator-engine/simulator.ts | 116 +++++----- .../depositBorrowOutputProcessor.ts | 10 +- .../stepProcessor/openPositionProcessor.ts | 12 + .../paybackWithdrawOutputProcessor.ts | 10 +- .../stepProcessor/stepOutputProcessors.ts | 2 + .../utils/EstimateSwapFromAmount.ts | 52 +++++ .../utils/GetRefinanceSimulationType.ts | 20 ++ .../implementation/utils/SimulatorUtils.ts | 4 +- .../src/implementation/utils/index.ts | 2 +- .../src/interfaces/helperTypes.ts | 9 +- .../src/interfaces/simulation.ts | 6 +- sdk/simulator-service/src/interfaces/steps.ts | 51 ++++- .../src/strategies/import/Strategy.ts | 1 + .../RefinanceLendingToLendingAnyPair.ts | 128 +++-------- .../strategies/refinanceAnyPair/Strategy.ts | 15 +- .../RefinanceLendingToLendingNoDebt.ts | 32 ++- .../strategies/refinanceNoDebt/Strategy.ts | 11 +- .../RefinanceLendingToLendingSamePair.ts | 26 ++- .../strategies/refinanceSamePair/Strategy.ts | 12 +- sdk/simulator-service/src/types/Types.ts | 4 +- .../src/mocks/managers/TokensManagerMock.ts | 2 +- .../tests/StaticTokensProvider.spec.ts | 2 +- 115 files changed, 4212 insertions(+), 399 deletions(-) create mode 100644 sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3BorrowAction.ts create mode 100644 sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3DepositAction.ts create mode 100644 sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3PaybackAction.ts create mode 100644 sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3SetEmodeAction.ts create mode 100644 sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3WithdrawAction.ts create mode 100644 sdk/protocol-plugins/src/plugins/aave-v3/actions/index.ts create mode 100644 sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts create mode 100644 sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3OpenPositionActionBuilder.ts create mode 100644 sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3PaybackWithdrawActionBuilder.ts create mode 100644 sdk/protocol-plugins/src/plugins/common/builders/OpenPositionActionBuilder.ts create mode 100644 sdk/protocol-plugins/src/plugins/maker/builders/MakerOpenPositionActionBuilder.ts create mode 100644 sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoOpenPositionActionBuilder.ts create mode 100644 sdk/protocol-plugins/src/plugins/spark/actions/SparkPaybackAction.ts create mode 100644 sdk/protocol-plugins/src/plugins/spark/actions/SparkSetEmodeAction.ts create mode 100644 sdk/protocol-plugins/src/plugins/spark/actions/SparkWithdrawAction.ts create mode 100644 sdk/protocol-plugins/src/plugins/spark/builders/SparkOpenPositionActionBuilder.ts create mode 100644 sdk/protocol-plugins/src/plugins/spark/builders/SparkPaybackWithdrawActionBuilder.ts create mode 100644 sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3BorrowAction.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3DepositAction.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3PaybackAction.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3SetEModeAction.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3WithdrawAction.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/actions/spark/SparkBorrowAction.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/actions/spark/SparkDepositAction.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/actions/spark/SparkPaybackAction.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/actions/spark/SparkSetEModeAction.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/actions/spark/SparkWithdrawAction.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/builders/ImportPositionActionBuilder.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/builders/OpenPositionActionBuilder.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3OpenPositionActionBuilder.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/builders/maker/MakerImportPositionActionBuilder.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/builders/maker/MakerOpenPositionActionBuilder.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/builders/morpho/MorphoOpenPositionActionBuilder.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/builders/spark/SparkDepositBorrowActionBuilder.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/builders/spark/SparkOpenPositionActionBuilder.spec.ts create mode 100644 sdk/protocol-plugins/tests/unit/builders/spark/SparkPaybackWithdrawActionBuilder.spec.ts create mode 100644 sdk/sdk-e2e/tests/refinance.test.ts create mode 100644 sdk/sdk-e2e/tests/refinanceAaveV3SparkAnyPair.test.ts create mode 100644 sdk/simulator-service/src/implementation/simulator-engine/reducer/openPositionReducer.ts create mode 100644 sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/openPositionProcessor.ts create mode 100644 sdk/simulator-service/src/implementation/utils/EstimateSwapFromAmount.ts create mode 100644 sdk/simulator-service/src/implementation/utils/GetRefinanceSimulationType.ts diff --git a/package.json b/package.json index a730577562..2af3bad0a4 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "test:integration": "turbo run test:integration --cache-dir=.turbo", "check-circular": "turbo run check-circular --cache-dir=.turbo", "cicheck": "turbo run cicheck --cache-dir=.turbo && pnpm run coverage:total", + "cicheck:dev": "turbo run cicheck --cache-dir=.turbo --output-logs=new-only --concurrency=100% --continue", "sst:dev": "sst dev", "sst:build": "sst build", "sst:deploy:dev": "sst deploy", diff --git a/packages/core-contracts/contracts/actions/aave/v3/Payback.sol b/packages/core-contracts/contracts/actions/aave/v3/Payback.sol index 1ee27e1b04..57b3010e90 100644 --- a/packages/core-contracts/contracts/actions/aave/v3/Payback.sol +++ b/packages/core-contracts/contracts/actions/aave/v3/Payback.sol @@ -33,11 +33,15 @@ contract AaveV3Payback is Executable, UseStore { payback.amount = store().readUint(bytes32(payback.amount), paramsMap[1], address(this)); + if (payback.onBehalf == address(0)) { + payback.onBehalf = address(this); + } + IPoolV3(registry.getRegisteredService(AAVE_POOL)).repay( payback.asset, payback.paybackAll ? type(uint256).max : payback.amount, 2, - address(this) + payback.onBehalf ); store().write(bytes32(payback.amount)); diff --git a/packages/core-contracts/contracts/core/types/Aave.sol b/packages/core-contracts/contracts/core/types/Aave.sol index 135208c2f0..779a11a680 100644 --- a/packages/core-contracts/contracts/core/types/Aave.sol +++ b/packages/core-contracts/contracts/core/types/Aave.sol @@ -24,6 +24,7 @@ struct PaybackData { address asset; uint256 amount; bool paybackAll; + address onBehalf; } /** diff --git a/sdk/order-planner-service/src/config/Config.ts b/sdk/order-planner-service/src/config/Config.ts index de09eb7909..29b8af3e55 100644 --- a/sdk/order-planner-service/src/config/Config.ts +++ b/sdk/order-planner-service/src/config/Config.ts @@ -10,6 +10,7 @@ import { RepayFlashloanActionBuilder, ReturnFundsActionBuilder, SwapActionBuilder, + OpenPositionActionBuilder, } from '@summerfi/protocol-plugins/plugins/common' export const ActionBuildersConfig: ActionBuildersMap = { @@ -22,4 +23,5 @@ export const ActionBuildersConfig: ActionBuildersMap = { [SimulationSteps.ReturnFunds]: ReturnFundsActionBuilder, [SimulationSteps.NewPositionEvent]: PositionCreatedActionBuilder, [SimulationSteps.Import]: ImportPositionActionBuilder, + [SimulationSteps.OpenPosition]: OpenPositionActionBuilder, } diff --git a/sdk/order-planner-service/tsconfig.json b/sdk/order-planner-service/tsconfig.json index f778098c74..124049ec71 100644 --- a/sdk/order-planner-service/tsconfig.json +++ b/sdk/order-planner-service/tsconfig.json @@ -3,8 +3,13 @@ "compilerOptions": { "rootDir": ".", "outDir": "dist", - "baseUrl": "." + "baseUrl": ".", + "paths": { + "@summerfi/tokens-common": ["../tokens-common/src/index.ts"], + "@summerfi/oracle-common": ["../oracle-common/src/index.ts"] + } }, + "references": [{ "path": "../tokens-common" }, { "path": "../oracle-common" }], "include": ["src/**/*.ts", "tests/**/*.ts", "scripts/**/*.ts"], "exclude": ["node_modules"] } diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3BorrowAction.ts b/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3BorrowAction.ts new file mode 100644 index 0000000000..039d45354e --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3BorrowAction.ts @@ -0,0 +1,32 @@ +import { ActionCall, BaseAction, InputSlotsMapping } from '@summerfi/protocol-plugins-common' +import { IAddress, ITokenAmount } from '@summerfi/sdk-common/common' + +export class AaveV3BorrowAction extends BaseAction { + public static readonly Config = { + name: 'AaveV3Borrow', + version: 4, + parametersAbi: ['(address asset, uint256 amount, address to)'], + storageInputs: [], + storageOutputs: ['borrowedAmount'], + } as const + + public encodeCall( + params: { borrowAmount: ITokenAmount; borrowTo: IAddress }, + paramsMapping?: InputSlotsMapping, + ): ActionCall { + return this._encodeCall({ + arguments: [ + { + asset: params.borrowAmount.token.address.value, + amount: BigInt(params.borrowAmount.toBaseUnit()), + to: params.borrowTo.value, + }, + ], + mapping: paramsMapping, + }) + } + + public get config() { + return AaveV3BorrowAction.Config + } +} diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3DepositAction.ts b/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3DepositAction.ts new file mode 100644 index 0000000000..0de89601cb --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3DepositAction.ts @@ -0,0 +1,37 @@ +import { ActionCall, BaseAction, InputSlotsMapping } from '@summerfi/protocol-plugins-common' +import { ITokenAmount } from '@summerfi/sdk-common/common' + +export class AaveV3DepositAction extends BaseAction { + public static readonly Config = { + name: 'AaveV3Deposit', + version: 0, + parametersAbi: ['(address asset, uint256 amount, bool sumAmounts, bool setAsCollateral)'], + storageInputs: ['asset', 'amountToDeposit'], + storageOutputs: ['depositedAmount'], + } as const + + public encodeCall( + params: { + depositAmount: ITokenAmount + sumAmounts: boolean + setAsCollateral: boolean + }, + paramsMapping?: InputSlotsMapping, + ): ActionCall { + return this._encodeCall({ + arguments: [ + { + asset: params.depositAmount.token.address.value, + amount: BigInt(params.depositAmount.toBaseUnit()), + sumAmounts: params.sumAmounts, + setAsCollateral: params.setAsCollateral, + }, + ], + mapping: paramsMapping, + }) + } + + public get config() { + return AaveV3DepositAction.Config + } +} diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3PaybackAction.ts b/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3PaybackAction.ts new file mode 100644 index 0000000000..910ac9f948 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3PaybackAction.ts @@ -0,0 +1,38 @@ +import { ActionCall, BaseAction, InputSlotsMapping } from '@summerfi/protocol-plugins-common' +import { IAddress } from '@summerfi/sdk-common' +import { ITokenAmount } from '@summerfi/sdk-common/common' + +export class AaveV3PaybackAction extends BaseAction { + public static readonly Config = { + name: 'AaveV3Payback', + version: 4, + parametersAbi: ['(address asset, uint256 amount, bool paybackAll, address onBehalf)'], + storageInputs: ['asset', 'amountToPayback'], + storageOutputs: ['paybackedAmount'], + } as const + + public encodeCall( + params: { + paybackAmount: ITokenAmount + paybackAll: boolean + onBehalf: IAddress + }, + paramsMapping?: InputSlotsMapping, + ): ActionCall { + return this._encodeCall({ + arguments: [ + { + asset: params.paybackAmount.token.address.value, + amount: BigInt(params.paybackAmount.toBaseUnit()), + paybackAll: params.paybackAll, + onBehalf: params.onBehalf.value, + }, + ], + mapping: paramsMapping, + }) + } + + public get config() { + return AaveV3PaybackAction.Config + } +} diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3SetEmodeAction.ts b/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3SetEmodeAction.ts new file mode 100644 index 0000000000..267729f706 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3SetEmodeAction.ts @@ -0,0 +1,33 @@ +import { ActionCall, BaseAction, InputSlotsMapping } from '@summerfi/protocol-plugins-common' +import { EmodeType } from '../../common/enums/EmodeType' +import { aaveV3EmodeCategoryMap } from '../implementation/EmodeCategoryMap' + +export class AaveV3SetEmodeAction extends BaseAction { + public static readonly Config = { + name: 'AaveV3SetEMode', + version: 0, + parametersAbi: ['(uint8 categoryId)'], + storageInputs: [], + storageOutputs: ['emodeCategory'], + } as const + + public encodeCall( + params: { + emode: EmodeType + }, + paramsMapping?: InputSlotsMapping, + ): ActionCall { + return this._encodeCall({ + arguments: [ + { + categoryId: aaveV3EmodeCategoryMap[params.emode], + }, + ], + mapping: paramsMapping, + }) + } + + public get config() { + return AaveV3SetEmodeAction.Config + } +} diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3WithdrawAction.ts b/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3WithdrawAction.ts new file mode 100644 index 0000000000..c976c06835 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/aave-v3/actions/AaveV3WithdrawAction.ts @@ -0,0 +1,35 @@ +import { ActionCall, BaseAction, InputSlotsMapping } from '@summerfi/protocol-plugins-common' +import { IAddress, ITokenAmount } from '@summerfi/sdk-common/common' + +export class AaveV3WithdrawAction extends BaseAction { + public static readonly Config = { + name: 'AaveV3Withdraw', + version: 0, + parametersAbi: ['(address asset, uint256 amount, address to)'], + storageInputs: [], + storageOutputs: ['withdrawnAmount'], + } as const + + public encodeCall( + params: { + withdrawAmount: ITokenAmount + withdrawTo: IAddress + }, + paramsMapping?: InputSlotsMapping, + ): ActionCall { + return this._encodeCall({ + arguments: [ + { + asset: params.withdrawAmount.token.address.value, + amount: BigInt(params.withdrawAmount.toBaseUnit()), + to: params.withdrawTo.value, + }, + ], + mapping: paramsMapping, + }) + } + + public get config() { + return AaveV3WithdrawAction.Config + } +} diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/actions/index.ts b/sdk/protocol-plugins/src/plugins/aave-v3/actions/index.ts new file mode 100644 index 0000000000..954431beb6 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/aave-v3/actions/index.ts @@ -0,0 +1,5 @@ +export * from './AaveV3BorrowAction' +export * from './AaveV3DepositAction' +export * from './AaveV3PaybackAction' +export * from './AaveV3WithdrawAction' +export * from './AaveV3SetEmodeAction' diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts new file mode 100644 index 0000000000..a3e19b8dcb --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts @@ -0,0 +1,93 @@ +import { + steps, + getValueFromReference, + TokenTransferTargetType, +} from '@summerfi/sdk-common/simulation' +import { ActionNames } from '@summerfi/deployment-types' +import { IAddress } from '@summerfi/sdk-common/common' +import { ActionBuilder, ActionBuilderParams } from '@summerfi/protocol-plugins-common' +import { SetApprovalAction } from '../../common' +import { AaveV3DepositAction } from '../actions/AaveV3DepositAction' +import { AaveV3BorrowAction } from '../actions/AaveV3BorrowAction' +import { getContractAddress } from '../../utils/GetContractAddress' +import { isAaveV3LendingPool } from '../interfaces/IAaveV3LendingPool' + +export const AaveV3DepositBorrowActionList: ActionNames[] = ['AaveV3Deposit', 'AaveV3Borrow'] + +async function getBorrowTargetAddress( + params: ActionBuilderParams, +): Promise { + const { user, step, positionsManager, addressBookManager } = params + if (step.inputs.borrowTargetType === TokenTransferTargetType.PositionsManager) { + return positionsManager.address + } + + return getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'OperationExecutor', + }) +} + +export const AaveV3DepositBorrowActionBuilder: ActionBuilder = async ( + params, +): Promise => { + const { context, step, addressBookManager, user } = params + + if (!isAaveV3LendingPool(step.inputs.position.pool)) { + throw new Error('Invalid AaveV3 lending pool') + } + + const aaveV3LendingPoolAddress = await getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'AaveV3LendingPool', + }) + + context.addActionCall({ + step: step, + action: new SetApprovalAction(), + arguments: { + approvalAmount: getValueFromReference(step.inputs.depositAmount), + delegate: aaveV3LendingPoolAddress, + sumAmounts: false, + }, + connectedInputs: { + depositAmount: 'approvalAmount', + }, + connectedOutputs: {}, + }) + + context.addActionCall({ + step: params.step, + action: new AaveV3DepositAction(), + arguments: { + depositAmount: getValueFromReference(step.inputs.depositAmount), + sumAmounts: false, + setAsCollateral: true, + }, + connectedInputs: { + depositAmount: 'amountToDeposit', + }, + connectedOutputs: { + depositAmount: 'depositedAmount', + }, + }) + + const borrowAmount = getValueFromReference(step.inputs.borrowAmount) + + if (!borrowAmount.toBN().isZero()) { + context.addActionCall({ + step: step, + action: new AaveV3BorrowAction(), + arguments: { + borrowAmount: borrowAmount, + borrowTo: await getBorrowTargetAddress(params), + }, + connectedInputs: {}, + connectedOutputs: { + borrowAmount: 'borrowedAmount', + }, + }) + } +} diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3OpenPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3OpenPositionActionBuilder.ts new file mode 100644 index 0000000000..66d3659129 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3OpenPositionActionBuilder.ts @@ -0,0 +1,30 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import { ActionNames } from '@summerfi/deployment-types' + +import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { isAaveV3LendingPool } from '../interfaces' +import { AaveV3SetEmodeAction } from '../actions/AaveV3SetEmodeAction' + +export const AaveV3OpenPositionList: ActionNames[] = ['AaveV3SetEMode'] + +export const AaveV3OpenPositionActionBuilder: ActionBuilder = async ( + params, +): Promise => { + const { context, step } = params + + if (!isAaveV3LendingPool(step.inputs.pool)) { + throw new Error('Invalid AaveV3 lending pool') + } + + const pool = step.inputs.pool + + context.addActionCall({ + step: step, + action: new AaveV3SetEmodeAction(), + arguments: { + emode: pool.id.emodeType, + }, + connectedInputs: {}, + connectedOutputs: {}, + }) +} diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3PaybackWithdrawActionBuilder.ts b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3PaybackWithdrawActionBuilder.ts new file mode 100644 index 0000000000..90e3721881 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3PaybackWithdrawActionBuilder.ts @@ -0,0 +1,99 @@ +import { + steps, + getValueFromReference, + TokenTransferTargetType, +} from '@summerfi/sdk-common/simulation' +import { ActionNames } from '@summerfi/deployment-types' + +import { IAddress } from '@summerfi/sdk-common/common' +import { ActionBuilder, ActionBuilderParams } from '@summerfi/protocol-plugins-common' +import { SetApprovalAction } from '../../common' +import { AaveV3WithdrawAction } from '../actions/AaveV3WithdrawAction' +import { AaveV3PaybackAction } from '../actions/AaveV3PaybackAction' +import { getContractAddress } from '../../utils/GetContractAddress' +import { isAaveV3LendingPool } from '../interfaces/IAaveV3LendingPool' +import { Address } from '@summerfi/sdk-common' + +export const AaveV3PaybackWithdrawActionList: ActionNames[] = ['AaveV3Payback', 'AaveV3Withdraw'] + +async function getWithdrawTargetAddress( + params: ActionBuilderParams, +): Promise { + const { user, step, positionsManager, addressBookManager } = params + if (step.inputs.withdrawTargetType === TokenTransferTargetType.PositionsManager) { + return positionsManager.address + } + + return getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'OperationExecutor', + }) +} + +export const AaveV3PaybackWithdrawActionBuilder: ActionBuilder = async ( + params, +): Promise => { + const { context, step, addressBookManager, user } = params + + if (!isAaveV3LendingPool(step.inputs.position.pool)) { + throw new Error('Invalid AaveV3 lending pool') + } + + const sparkLendingPoolAddress = await getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'AavePool', + }) + + const paybackAmount = getValueFromReference(step.inputs.paybackAmount) + + if (!paybackAmount.toBN().isZero()) { + context.addActionCall({ + step: step, + action: new SetApprovalAction(), + arguments: { + approvalAmount: getValueFromReference(step.inputs.paybackAmount), + delegate: sparkLendingPoolAddress, + sumAmounts: false, + }, + connectedInputs: { + paybackAmount: 'approvalAmount', + }, + connectedOutputs: {}, + }) + + context.addActionCall({ + step: params.step, + action: new AaveV3PaybackAction(), + arguments: { + paybackAmount: getValueFromReference(step.inputs.paybackAmount), + paybackAll: getValueFromReference(step.inputs.paybackAmount) + .toBN() + .gt(step.inputs.position.debtAmount.toBN()), + onBehalf: Address.ZeroAddressEthereum, + }, + connectedInputs: {}, + connectedOutputs: { + paybackAmount: 'paybackedAmount', + }, + }) + } + + const withdrawAmount = getValueFromReference(step.inputs.withdrawAmount) + + if (!withdrawAmount.toBN().isZero()) { + context.addActionCall({ + step: step, + action: new AaveV3WithdrawAction(), + arguments: { + withdrawAmount: withdrawAmount, + withdrawTo: await getWithdrawTargetAddress(params), + }, + connectedInputs: {}, + connectedOutputs: { + withdrawAmount: 'withdrawnAmount', + }, + }) + } +} diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3StepBuilders.ts b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3StepBuilders.ts index 8bc202b71e..c6d170f493 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3StepBuilders.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3StepBuilders.ts @@ -1,3 +1,11 @@ import { ActionBuildersMap } from '@summerfi/protocol-plugins-common' +import { AaveV3DepositBorrowActionBuilder } from './AaveV3DepositBorrowActionBuilder' +import { SimulationSteps } from '@summerfi/sdk-common' +import { AaveV3PaybackWithdrawActionBuilder } from './AaveV3PaybackWithdrawActionBuilder' +import { AaveV3OpenPositionActionBuilder } from './AaveV3OpenPositionActionBuilder' -export const AaveV3StepBuilders: Partial = {} +export const AaveV3StepBuilders: Partial = { + [SimulationSteps.DepositBorrow]: AaveV3DepositBorrowActionBuilder, + [SimulationSteps.PaybackWithdraw]: AaveV3PaybackWithdrawActionBuilder, + [SimulationSteps.OpenPosition]: AaveV3OpenPositionActionBuilder, +} diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/builders/index.ts b/sdk/protocol-plugins/src/plugins/aave-v3/builders/index.ts index cf848f3266..eac6fa26f0 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/builders/index.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/builders/index.ts @@ -1 +1,4 @@ export * from './AaveV3StepBuilders' +export * from './AaveV3DepositBorrowActionBuilder' +export * from './AaveV3PaybackWithdrawActionBuilder' +export * from './AaveV3OpenPositionActionBuilder' diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts index ea4482110b..bcffec4598 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts @@ -19,7 +19,6 @@ import { } from '../interfaces/IAaveV3LendingPoolId' import { IUser } from '@summerfi/sdk-common/user' import { IExternalPosition, IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' -import { AaveV3StepBuilders } from '../builders' import { IAaveV3PositionIdData, isAaveV3PositionId } from '../interfaces/IAaveV3PositionId' import { AaveV3LendingPoolInfo } from './AaveV3LendingPoolInfo' import { aaveV3EmodeCategoryMap } from './EmodeCategoryMap' @@ -27,6 +26,7 @@ import { AAVEv3LikeBaseProtocolPlugin } from '../../common/helpers/aaveV3Like/AA import { FiatCurrency } from '@summerfi/sdk-common' import { ContractInfo } from '../../common/types/ContractInfo' import { ChainContractsProvider } from '../../utils/ChainContractProvider' +import { AaveV3StepBuilders } from '../builders/AaveV3StepBuilders' /** * @class AaveV3ProtocolPlugin diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/EmodeCategoryMap.ts b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/EmodeCategoryMap.ts index a76cb6db16..eac52da26d 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/EmodeCategoryMap.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/EmodeCategoryMap.ts @@ -1,11 +1,13 @@ import { EmodeType } from '../../common/enums/EmodeType' -export const aaveV3EmodeCategoryMap: Record = Object.keys(EmodeType).reduce< - Record +// TODO: this is only correct for Mainnet, each network has its own category map + +export const aaveV3EmodeCategoryMap: Record = Object.keys(EmodeType).reduce< + Record >( (accumulator, key, index) => { - accumulator[EmodeType[key as keyof typeof EmodeType]] = BigInt(index) + accumulator[EmodeType[key as keyof typeof EmodeType]] = index return accumulator }, - {} as Record, + {} as Record, ) diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/index.ts b/sdk/protocol-plugins/src/plugins/aave-v3/index.ts index 6d23aa57ac..8fb7ae608c 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/index.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/index.ts @@ -1,2 +1,4 @@ export * from './interfaces' export * from './implementation' +export * from './actions' +export * from './builders' diff --git a/sdk/protocol-plugins/src/plugins/common/builders/OpenPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/OpenPositionActionBuilder.ts new file mode 100644 index 0000000000..2ce24cd86e --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/common/builders/OpenPositionActionBuilder.ts @@ -0,0 +1,14 @@ +import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { steps } from '@summerfi/sdk-common/simulation' +import { delegateToProtocolActionBuilder } from '../../utils/DelegateToProtocolActionBuilder' + +export const OpenPositionActionBuilder: ActionBuilder = async ( + params, +): Promise => { + const pool = params.step.inputs.pool + + await delegateToProtocolActionBuilder({ + protocolName: pool.id.protocol.name, + actionBuilderParams: params, + }) +} diff --git a/sdk/protocol-plugins/src/plugins/common/builders/index.ts b/sdk/protocol-plugins/src/plugins/common/builders/index.ts index 0f1b4ae370..99456eab44 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/index.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/index.ts @@ -11,3 +11,4 @@ export { ReturnFundsActionBuilder } from './ReturnFundsActionBuilder' export { SwapActionBuilder } from './SwapActionBuilder' export { PositionCreatedActionBuilder } from './PositionCreatedActionBuilder' export { ImportPositionActionBuilder } from './ImportPositionActionBuilder' +export { OpenPositionActionBuilder } from './OpenPositionActionBuilder' diff --git a/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts index e6afa8ab5b..8fae171d03 100644 --- a/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts @@ -106,7 +106,7 @@ export abstract class AAVEv3LikeBaseProtocolPlugin< */ protected async _getAssetFromToken( token: IToken, - emode: bigint, + emode: number, ): Promise> { if (!this._assetsList) { throw new Error('Assets list not initialized') @@ -133,7 +133,7 @@ export abstract class AAVEv3LikeBaseProtocolPlugin< */ protected async _getCollateralInfo(params: { token: IToken - emode: bigint + emode: number poolBaseCurrencyToken: Denomination }): Promise> { const { token, emode, poolBaseCurrencyToken } = params @@ -198,7 +198,7 @@ export abstract class AAVEv3LikeBaseProtocolPlugin< */ protected async _getDebtInfo( token: IToken, - emode: bigint, + emode: number, poolBaseCurrencyToken: Denomination, ): Promise> { const asset = await this._getAssetFromToken(token, emode) diff --git a/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeProtocolDataBuilder.ts b/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeProtocolDataBuilder.ts index 20e0c8e09f..6f33c0a9e7 100644 --- a/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeProtocolDataBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeProtocolDataBuilder.ts @@ -403,12 +403,12 @@ export class AaveV3LikeProtocolDataBuilder< // FILTERS export function filterAssetsListByEMode( assetsList: T[], - emode: bigint, + emode: number, ): T[] { // All reserves allowed for category 0n - if (emode === 0n) { + if (emode === 0) { return assetsList } - return assetsList.filter((asset) => asset.emode === emode) + return assetsList.filter((asset) => Number(asset.emode) === emode) } diff --git a/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts index 814686f2d1..eafbb11486 100644 --- a/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts @@ -1,9 +1,7 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { ActionNames } from '@summerfi/deployment-types' import { ActionBuilder } from '@summerfi/protocol-plugins-common' import { ProtocolName } from '@summerfi/sdk-common/protocols' import { isMakerLendingPoolId } from '../interfaces/IMakerLendingPoolId' -export const MakerPaybackWithdrawActionList: ActionNames[] = ['MakerPayback', 'MakerWithdraw'] export const MakerImportPositionActionBuilder: ActionBuilder = async ( params, @@ -11,7 +9,7 @@ export const MakerImportPositionActionBuilder: ActionBuilder = const { protocolsRegistry, step, user, context, positionsManager } = params if (!isMakerLendingPoolId(step.inputs.externalPosition.position.pool.id)) { - throw new Error('Maker: Invalid pool id') + throw new Error('Invalid Maker lending pool id') } const makerPlugin = protocolsRegistry.getPlugin({ protocolName: ProtocolName.Maker }) diff --git a/sdk/protocol-plugins/src/plugins/maker/builders/MakerOpenPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/maker/builders/MakerOpenPositionActionBuilder.ts new file mode 100644 index 0000000000..c0de352ce9 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/maker/builders/MakerOpenPositionActionBuilder.ts @@ -0,0 +1,15 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { isMakerLendingPool } from '../interfaces/IMakerLendingPool' + +export const MakerOpenPositionActionBuilder: ActionBuilder = async ( + params, +): Promise => { + const { step } = params + + if (!isMakerLendingPool(step.inputs.pool)) { + throw new Error('Invalid Maker lending pool id') + } + + // No-op for Maker +} diff --git a/sdk/protocol-plugins/src/plugins/maker/builders/MakerPaybackWithdrawActionBuilder.ts b/sdk/protocol-plugins/src/plugins/maker/builders/MakerPaybackWithdrawActionBuilder.ts index 3a30a94906..dc45d0b96e 100644 --- a/sdk/protocol-plugins/src/plugins/maker/builders/MakerPaybackWithdrawActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/maker/builders/MakerPaybackWithdrawActionBuilder.ts @@ -1,12 +1,10 @@ import { getValueFromReference, steps } from '@summerfi/sdk-common/simulation' -import { ActionNames } from '@summerfi/deployment-types' import { MakerPaybackAction } from '../actions/MakerPaybackAction' import { MakerWithdrawAction } from '../actions/MakerWithdrawAction' import { ActionBuilder } from '@summerfi/protocol-plugins-common' import { MakerIlkToJoinMap } from '../types/MakerIlkToJoinMap' import { isMakerLendingPoolId } from '../interfaces/IMakerLendingPoolId' import { getContractAddress } from '../../utils/GetContractAddress' -export const MakerPaybackWithdrawActionList: ActionNames[] = ['MakerPayback', 'MakerWithdraw'] export const MakerPaybackWithdrawActionBuilder: ActionBuilder = async ( params, @@ -14,7 +12,7 @@ export const MakerPaybackWithdrawActionBuilder: ActionBuilder = async ( + params, +): Promise => { + const { step } = params + + if (!isMorphoLendingPool(step.inputs.pool)) { + throw new Error('Invalid Morpho lending pool id') + } + + // No-op for Morpho +} diff --git a/sdk/protocol-plugins/src/plugins/morphoblue/builders/index.ts b/sdk/protocol-plugins/src/plugins/morphoblue/builders/index.ts index 50121dd717..c272629560 100644 --- a/sdk/protocol-plugins/src/plugins/morphoblue/builders/index.ts +++ b/sdk/protocol-plugins/src/plugins/morphoblue/builders/index.ts @@ -1,2 +1,4 @@ export * from './MorphoDepositBorrowActionBuilder' +export * from './MorphoPaybackWithdrawActionBuilder' +export * from './MorphoOpenPositionActionBuilder' export * from './MorphoStepBuilders' diff --git a/sdk/protocol-plugins/src/plugins/spark/actions/SparkPaybackAction.ts b/sdk/protocol-plugins/src/plugins/spark/actions/SparkPaybackAction.ts new file mode 100644 index 0000000000..910cd68569 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/spark/actions/SparkPaybackAction.ts @@ -0,0 +1,35 @@ +import { ActionCall, BaseAction, InputSlotsMapping } from '@summerfi/protocol-plugins-common' +import { ITokenAmount } from '@summerfi/sdk-common/common' + +export class SparkPaybackAction extends BaseAction { + public static readonly Config = { + name: 'SparkPayback', + version: 2, + parametersAbi: ['(address asset, uint256 amount, bool paybackAll)'], + storageInputs: ['asset', 'amountToPayback'], + storageOutputs: ['paybackedAmount'], + } as const + + public encodeCall( + params: { + paybackAmount: ITokenAmount + paybackAll: boolean + }, + paramsMapping?: InputSlotsMapping, + ): ActionCall { + return this._encodeCall({ + arguments: [ + { + asset: params.paybackAmount.token.address.value, + amount: BigInt(params.paybackAmount.toBaseUnit()), + paybackAll: params.paybackAll, + }, + ], + mapping: paramsMapping, + }) + } + + public get config() { + return SparkPaybackAction.Config + } +} diff --git a/sdk/protocol-plugins/src/plugins/spark/actions/SparkSetEmodeAction.ts b/sdk/protocol-plugins/src/plugins/spark/actions/SparkSetEmodeAction.ts new file mode 100644 index 0000000000..d4edab63ac --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/spark/actions/SparkSetEmodeAction.ts @@ -0,0 +1,33 @@ +import { ActionCall, BaseAction, InputSlotsMapping } from '@summerfi/protocol-plugins-common' +import { EmodeType } from '../../common/enums/EmodeType' +import { sparkEmodeCategoryMap } from '../implementation/EmodeCategoryMap' + +export class SparkSetEmodeAction extends BaseAction { + public static readonly Config = { + name: 'SparkSetEMode', + version: 0, + parametersAbi: ['(uint8 categoryId)'], + storageInputs: [], + storageOutputs: ['emodeCategory'], + } as const + + public encodeCall( + params: { + emode: EmodeType + }, + paramsMapping?: InputSlotsMapping, + ): ActionCall { + return this._encodeCall({ + arguments: [ + { + categoryId: sparkEmodeCategoryMap[params.emode], + }, + ], + mapping: paramsMapping, + }) + } + + public get config() { + return SparkSetEmodeAction.Config + } +} diff --git a/sdk/protocol-plugins/src/plugins/spark/actions/SparkWithdrawAction.ts b/sdk/protocol-plugins/src/plugins/spark/actions/SparkWithdrawAction.ts new file mode 100644 index 0000000000..c3d4ee653e --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/spark/actions/SparkWithdrawAction.ts @@ -0,0 +1,35 @@ +import { ActionCall, BaseAction, InputSlotsMapping } from '@summerfi/protocol-plugins-common' +import { IAddress, ITokenAmount } from '@summerfi/sdk-common/common' + +export class SparkWithdrawAction extends BaseAction { + public static readonly Config = { + name: 'SparkWithdraw', + version: 0, + parametersAbi: ['(address asset, uint256 amount, address to)'], + storageInputs: [], + storageOutputs: ['withdrawnAmount'], + } as const + + public encodeCall( + params: { + withdrawAmount: ITokenAmount + withdrawTo: IAddress + }, + paramsMapping?: InputSlotsMapping, + ): ActionCall { + return this._encodeCall({ + arguments: [ + { + asset: params.withdrawAmount.token.address.value, + amount: BigInt(params.withdrawAmount.toBaseUnit()), + to: params.withdrawTo.value, + }, + ], + mapping: paramsMapping, + }) + } + + public get config() { + return SparkWithdrawAction.Config + } +} diff --git a/sdk/protocol-plugins/src/plugins/spark/actions/index.ts b/sdk/protocol-plugins/src/plugins/spark/actions/index.ts index 9f3cc43bd4..76cf502cdd 100644 --- a/sdk/protocol-plugins/src/plugins/spark/actions/index.ts +++ b/sdk/protocol-plugins/src/plugins/spark/actions/index.ts @@ -1,2 +1,5 @@ -export { SparkBorrowAction } from './SparkBorrowAction' -export { SparkDepositAction } from './SparkDepositAction' +export * from './SparkBorrowAction' +export * from './SparkDepositAction' +export * from './SparkPaybackAction' +export * from './SparkWithdrawAction' +export * from './SparkSetEmodeAction' diff --git a/sdk/protocol-plugins/src/plugins/spark/builders/SparkDepositBorrowActionBuilder.ts b/sdk/protocol-plugins/src/plugins/spark/builders/SparkDepositBorrowActionBuilder.ts index 5d1fbd8ca9..c7cc6a491f 100644 --- a/sdk/protocol-plugins/src/plugins/spark/builders/SparkDepositBorrowActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/spark/builders/SparkDepositBorrowActionBuilder.ts @@ -11,6 +11,7 @@ import { IAddress } from '@summerfi/sdk-common/common' import { ActionBuilder, ActionBuilderParams } from '@summerfi/protocol-plugins-common' import { SetApprovalAction } from '../../common' import { getContractAddress } from '../../utils/GetContractAddress' +import { isSparkLendingPool } from '../interfaces/ISparkLendingPool' export const SparkDepositBorrowActionList: ActionNames[] = ['SparkDeposit', 'SparkBorrow'] @@ -34,6 +35,10 @@ export const SparkDepositBorrowActionBuilder: ActionBuilder => { const { context, user, step, addressBookManager } = params + if (!isSparkLendingPool(step.inputs.position.pool)) { + throw new Error('Invalid Spark lending pool') + } + const sparkLendingPoolAddress = await getContractAddress({ addressBookManager, chainInfo: user.chainInfo, diff --git a/sdk/protocol-plugins/src/plugins/spark/builders/SparkOpenPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/spark/builders/SparkOpenPositionActionBuilder.ts new file mode 100644 index 0000000000..1186305240 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/spark/builders/SparkOpenPositionActionBuilder.ts @@ -0,0 +1,30 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import { ActionNames } from '@summerfi/deployment-types' + +import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { isSparkLendingPool } from '../interfaces' +import { SparkSetEmodeAction } from '../actions' + +export const SparkOpenPositionList: ActionNames[] = ['SparkSetEMode'] + +export const SparkOpenPositionActionBuilder: ActionBuilder = async ( + params, +): Promise => { + const { context, step } = params + + if (!isSparkLendingPool(step.inputs.pool)) { + throw new Error('Invalid Spark lending pool') + } + + const pool = step.inputs.pool + + context.addActionCall({ + step: step, + action: new SparkSetEmodeAction(), + arguments: { + emode: pool.id.emodeType, + }, + connectedInputs: {}, + connectedOutputs: {}, + }) +} diff --git a/sdk/protocol-plugins/src/plugins/spark/builders/SparkPaybackWithdrawActionBuilder.ts b/sdk/protocol-plugins/src/plugins/spark/builders/SparkPaybackWithdrawActionBuilder.ts new file mode 100644 index 0000000000..18bc8081d3 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/spark/builders/SparkPaybackWithdrawActionBuilder.ts @@ -0,0 +1,97 @@ +import { + steps, + getValueFromReference, + TokenTransferTargetType, +} from '@summerfi/sdk-common/simulation' +import { ActionNames } from '@summerfi/deployment-types' + +import { IAddress } from '@summerfi/sdk-common/common' +import { ActionBuilder, ActionBuilderParams } from '@summerfi/protocol-plugins-common' +import { SetApprovalAction } from '../../common' +import { SparkWithdrawAction } from '../actions/SparkWithdrawAction' +import { SparkPaybackAction } from '../actions/SparkPaybackAction' +import { getContractAddress } from '../../utils/GetContractAddress' +import { isSparkLendingPool } from '../interfaces/ISparkLendingPool' + +export const SparkPaybackWithdrawActionList: ActionNames[] = ['SparkPayback', 'SparkWithdraw'] + +async function getWithdrawTargetAddress( + params: ActionBuilderParams, +): Promise { + const { user, step, positionsManager, addressBookManager } = params + if (step.inputs.withdrawTargetType === TokenTransferTargetType.PositionsManager) { + return positionsManager.address + } + + return getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'OperationExecutor', + }) +} + +export const SparkPaybackWithdrawActionBuilder: ActionBuilder = async ( + params, +): Promise => { + const { context, step, addressBookManager, user } = params + + if (!isSparkLendingPool(step.inputs.position.pool)) { + throw new Error('Invalid Spark lending pool') + } + + const sparkLendingPoolAddress = await getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'SparkLendingPool', + }) + + const paybackAmount = getValueFromReference(step.inputs.paybackAmount) + + if (!paybackAmount.toBN().isZero()) { + context.addActionCall({ + step: step, + action: new SetApprovalAction(), + arguments: { + approvalAmount: getValueFromReference(step.inputs.paybackAmount), + delegate: sparkLendingPoolAddress, + sumAmounts: false, + }, + connectedInputs: { + paybackAmount: 'approvalAmount', + }, + connectedOutputs: {}, + }) + + context.addActionCall({ + step: params.step, + action: new SparkPaybackAction(), + arguments: { + paybackAmount: getValueFromReference(step.inputs.paybackAmount), + paybackAll: getValueFromReference(step.inputs.paybackAmount) + .toBN() + .gt(step.inputs.position.debtAmount.toBN()), + }, + connectedInputs: {}, + connectedOutputs: { + paybackAmount: 'paybackedAmount', + }, + }) + } + + const withdrawAmount = getValueFromReference(step.inputs.withdrawAmount) + + if (!withdrawAmount.toBN().isZero()) { + context.addActionCall({ + step: step, + action: new SparkWithdrawAction(), + arguments: { + withdrawAmount: withdrawAmount, + withdrawTo: await getWithdrawTargetAddress(params), + }, + connectedInputs: {}, + connectedOutputs: { + withdrawAmount: 'withdrawnAmount', + }, + }) + } +} diff --git a/sdk/protocol-plugins/src/plugins/spark/builders/SparkStepBuilders.ts b/sdk/protocol-plugins/src/plugins/spark/builders/SparkStepBuilders.ts index fa13b4bead..4b149e998f 100644 --- a/sdk/protocol-plugins/src/plugins/spark/builders/SparkStepBuilders.ts +++ b/sdk/protocol-plugins/src/plugins/spark/builders/SparkStepBuilders.ts @@ -1,7 +1,11 @@ import { ActionBuildersMap } from '@summerfi/protocol-plugins-common' import { SparkDepositBorrowActionBuilder } from './SparkDepositBorrowActionBuilder' import { SimulationSteps } from '@summerfi/sdk-common/simulation' +import { SparkPaybackWithdrawActionBuilder } from './SparkPaybackWithdrawActionBuilder' +import { SparkOpenPositionActionBuilder } from './SparkOpenPositionActionBuilder' export const SparkStepBuilders: Partial = { [SimulationSteps.DepositBorrow]: SparkDepositBorrowActionBuilder, + [SimulationSteps.PaybackWithdraw]: SparkPaybackWithdrawActionBuilder, + [SimulationSteps.OpenPosition]: SparkOpenPositionActionBuilder, } diff --git a/sdk/protocol-plugins/src/plugins/spark/builders/index.ts b/sdk/protocol-plugins/src/plugins/spark/builders/index.ts index a9c7ff8ef0..40ab2e5bdd 100644 --- a/sdk/protocol-plugins/src/plugins/spark/builders/index.ts +++ b/sdk/protocol-plugins/src/plugins/spark/builders/index.ts @@ -1,2 +1,4 @@ export * from './SparkDepositBorrowActionBuilder' +export * from './SparkPaybackWithdrawActionBuilder' +export * from './SparkOpenPositionActionBuilder' export * from './SparkStepBuilders' diff --git a/sdk/protocol-plugins/src/plugins/spark/implementation/EmodeCategoryMap.ts b/sdk/protocol-plugins/src/plugins/spark/implementation/EmodeCategoryMap.ts index 4b33bac4fc..33ac639d42 100644 --- a/sdk/protocol-plugins/src/plugins/spark/implementation/EmodeCategoryMap.ts +++ b/sdk/protocol-plugins/src/plugins/spark/implementation/EmodeCategoryMap.ts @@ -1,11 +1,13 @@ import { EmodeType } from '../../common/enums/EmodeType' -export const sparkEmodeCategoryMap: Record = Object.keys(EmodeType).reduce< - Record +// TODO: this is only correct for Mainnet, each network has its own category map + +export const sparkEmodeCategoryMap: Record = Object.keys(EmodeType).reduce< + Record >( (accumulator, key, index) => { - accumulator[EmodeType[key as keyof typeof EmodeType]] = BigInt(index) + accumulator[EmodeType[key as keyof typeof EmodeType]] = index return accumulator }, - {} as Record, + {} as Record, ) diff --git a/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3BorrowAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3BorrowAction.spec.ts new file mode 100644 index 0000000000..e6d156da5d --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3BorrowAction.spec.ts @@ -0,0 +1,54 @@ +import { Address, Token, TokenAmount } from '@summerfi/sdk-common/common' +import { decodeActionCalldata, getTargetHash } from '@summerfi/testing-utils' +import { ChainFamilyMap } from '@summerfi/sdk-common' +import { AaveV3BorrowAction } from '../../../../src' + +describe('AaveV3BorrowAction Action', () => { + const action = new AaveV3BorrowAction() + const contractNameWithVersion = `${action.config.name}_${action.config.version}` + + const DAI = Token.createFrom({ + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + decimals: 18, + name: 'Dai Stablecoin', + symbol: 'DAI', + }) + + const recipient = Address.createFromEthereum({ + value: '0x6ADb2E268de2aA1aBF6578E4a8119b960E02928F', + }) + + const tokenAmount = TokenAmount.createFrom({ token: DAI, amount: '578' }) + + it('should return the versioned name', () => { + expect(action.getVersionedName()).toBe(contractNameWithVersion) + }) + + it('should encode calls', async () => { + const call = action.encodeCall( + { + borrowAmount: tokenAmount, + borrowTo: recipient, + }, + [1, 8, 5, 3], + ) + + expect(call.targetHash).toBe(getTargetHash(action)) + + const actionDecodedArgs = decodeActionCalldata({ + action, + calldata: call.callData, + }) + + expect(actionDecodedArgs).toBeDefined() + expect(actionDecodedArgs?.args).toEqual([ + { + asset: tokenAmount.token.address.value, + amount: BigInt(tokenAmount.toBaseUnit()), + to: recipient.value, + }, + ]) + expect(actionDecodedArgs?.mapping).toEqual([1, 8, 5, 3]) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3DepositAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3DepositAction.spec.ts new file mode 100644 index 0000000000..a982e418e0 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3DepositAction.spec.ts @@ -0,0 +1,52 @@ +import { Address, Token, TokenAmount } from '@summerfi/sdk-common/common' +import { decodeActionCalldata, getTargetHash } from '@summerfi/testing-utils' +import { AaveV3DepositAction } from '../../../../src' +import { ChainFamilyMap } from '@summerfi/sdk-common' + +describe('AaveV3DepositAction Action', () => { + const action = new AaveV3DepositAction() + const contractNameWithVersion = `${action.config.name}` + + const DAI = Token.createFrom({ + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + decimals: 18, + name: 'Dai Stablecoin', + symbol: 'DAI', + }) + + const tokenAmount = TokenAmount.createFrom({ token: DAI, amount: '578' }) + + it('should return the versioned name', () => { + expect(action.getVersionedName()).toBe(contractNameWithVersion) + }) + + it('should encode calls', async () => { + const call = action.encodeCall( + { + depositAmount: tokenAmount, + sumAmounts: false, + setAsCollateral: true, + }, + [1, 8, 5, 3], + ) + + expect(call.targetHash).toBe(getTargetHash(action)) + + const actionDecodedArgs = decodeActionCalldata({ + action, + calldata: call.callData, + }) + + expect(actionDecodedArgs).toBeDefined() + expect(actionDecodedArgs?.args).toEqual([ + { + asset: tokenAmount.token.address.value, + amount: BigInt(tokenAmount.toBaseUnit()), + sumAmounts: false, + setAsCollateral: true, + }, + ]) + expect(actionDecodedArgs?.mapping).toEqual([1, 8, 5, 3]) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3PaybackAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3PaybackAction.spec.ts new file mode 100644 index 0000000000..c06b2954e0 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3PaybackAction.spec.ts @@ -0,0 +1,57 @@ +import { Address, Token, TokenAmount } from '@summerfi/sdk-common/common' +import { decodeActionCalldata, getTargetHash } from '@summerfi/testing-utils' +import { AaveV3PaybackAction } from '../../../../src' +import { ChainFamilyMap } from '@summerfi/sdk-common' +import { on } from 'events' + +describe('AaveV3PaybackAction Action', () => { + const action = new AaveV3PaybackAction() + const contractNameWithVersion = `${action.config.name}_${action.config.version}` + + const DAI = Token.createFrom({ + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + decimals: 18, + name: 'Dai Stablecoin', + symbol: 'DAI', + }) + + const onBehalf = Address.createFromEthereum({ + value: '0x6ADb2E268de2aA1aBF6578E4a8119b960E02928F', + }) + + const tokenAmount = TokenAmount.createFrom({ token: DAI, amount: '578' }) + + it('should return the versioned name', () => { + expect(action.getVersionedName()).toBe(contractNameWithVersion) + }) + + it('should encode calls', async () => { + const call = action.encodeCall( + { + paybackAmount: tokenAmount, + paybackAll: true, + onBehalf: onBehalf, + }, + [2, 6, 7, 9], + ) + + expect(call.targetHash).toBe(getTargetHash(action)) + + const actionDecodedArgs = decodeActionCalldata({ + action, + calldata: call.callData, + }) + + expect(actionDecodedArgs).toBeDefined() + expect(actionDecodedArgs?.args).toEqual([ + { + asset: tokenAmount.token.address.value, + amount: BigInt(tokenAmount.toBaseUnit()), + paybackAll: true, + onBehalf: onBehalf.value, + }, + ]) + expect(actionDecodedArgs?.mapping).toEqual([2, 6, 7, 9]) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3SetEModeAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3SetEModeAction.spec.ts new file mode 100644 index 0000000000..933c4f7014 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3SetEModeAction.spec.ts @@ -0,0 +1,35 @@ +import { decodeActionCalldata, getTargetHash } from '@summerfi/testing-utils' +import { EmodeType, AaveV3SetEmodeAction, aaveV3EmodeCategoryMap } from '../../../../src' + +describe('MorphoPaybackAction Action', () => { + const action = new AaveV3SetEmodeAction() + const contractNameWithVersion = `${action.config.name}` + + it('should return the versioned name', () => { + expect(action.getVersionedName()).toBe(contractNameWithVersion) + }) + + it('should encode calls', async () => { + const call = action.encodeCall( + { + emode: EmodeType.Stablecoins, + }, + [2, 6, 7, 9], + ) + + expect(call.targetHash).toBe(getTargetHash(action)) + + const actionDecodedArgs = decodeActionCalldata({ + action, + calldata: call.callData, + }) + + expect(actionDecodedArgs).toBeDefined() + expect(actionDecodedArgs?.args).toEqual([ + { + categoryId: aaveV3EmodeCategoryMap[EmodeType.Stablecoins], + }, + ]) + expect(actionDecodedArgs?.mapping).toEqual([2, 6, 7, 9]) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3WithdrawAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3WithdrawAction.spec.ts new file mode 100644 index 0000000000..18a6237919 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/actions/aaveV3/AaveV3WithdrawAction.spec.ts @@ -0,0 +1,54 @@ +import { Address, Token, TokenAmount } from '@summerfi/sdk-common/common' +import { decodeActionCalldata, getTargetHash } from '@summerfi/testing-utils' +import { AaveV3WithdrawAction } from '../../../../src' +import { ChainFamilyMap } from '@summerfi/sdk-common' + +describe('AaveV3WithdrawAction Action', () => { + const action = new AaveV3WithdrawAction() + const contractNameWithVersion = `${action.config.name}` + + const DAI = Token.createFrom({ + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + decimals: 18, + name: 'Dai Stablecoin', + symbol: 'DAI', + }) + + const recipient = Address.createFromEthereum({ + value: '0x6ADb2E268de2aA1aBF6578E4a8119b960E02928F', + }) + + const tokenAmount = TokenAmount.createFrom({ token: DAI, amount: '578' }) + + it('should return the versioned name', () => { + expect(action.getVersionedName()).toBe(contractNameWithVersion) + }) + + it('should encode calls', async () => { + const call = action.encodeCall( + { + withdrawAmount: tokenAmount, + withdrawTo: recipient, + }, + [2, 6, 7, 9], + ) + + expect(call.targetHash).toBe(getTargetHash(action)) + + const actionDecodedArgs = decodeActionCalldata({ + action, + calldata: call.callData, + }) + + expect(actionDecodedArgs).toBeDefined() + expect(actionDecodedArgs?.args).toEqual([ + { + amount: BigInt(tokenAmount.toBaseUnit()), + asset: tokenAmount.token.address.value, + to: recipient.value, + }, + ]) + expect(actionDecodedArgs?.mapping).toEqual([2, 6, 7, 9]) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoBorrowAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoBorrowAction.spec.ts index 207e96ec8f..eeaebf1e3f 100644 --- a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoBorrowAction.spec.ts +++ b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoBorrowAction.spec.ts @@ -9,7 +9,6 @@ import { import { ChainFamilyMap, Percentage, - Protocol, ProtocolName, RiskRatio, RiskRatioType, diff --git a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoDepositAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoDepositAction.spec.ts index 6efc3d5bf9..0743a0a74e 100644 --- a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoDepositAction.spec.ts +++ b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoDepositAction.spec.ts @@ -9,7 +9,6 @@ import { import { ChainFamilyMap, Percentage, - Protocol, ProtocolName, RiskRatio, RiskRatioType, diff --git a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoPaybackAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoPaybackAction.spec.ts index 23c469f995..c4b0cbe58c 100644 --- a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoPaybackAction.spec.ts +++ b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoPaybackAction.spec.ts @@ -9,7 +9,6 @@ import { import { ChainFamilyMap, Percentage, - Protocol, ProtocolName, RiskRatio, RiskRatioType, diff --git a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoWithdrawAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoWithdrawAction.spec.ts index 86f1d74cf7..45545d2b4d 100644 --- a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoWithdrawAction.spec.ts +++ b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoWithdrawAction.spec.ts @@ -9,7 +9,6 @@ import { import { ChainFamilyMap, Percentage, - Protocol, ProtocolName, RiskRatio, RiskRatioType, @@ -17,7 +16,7 @@ import { import { PoolType } from '@summerfi/sdk-common/protocols' import { MorphoLLTVPrecision } from '../../../../src/plugins/morphoblue/constants/MorphoConstants' -describe('MorphoPaybackAction Action', () => { +describe('MorphoWithdrawAction Action', () => { const action = new MorphoWithdrawAction() const contractNameWithVersion = `${action.config.name}` diff --git a/sdk/protocol-plugins/tests/unit/actions/spark/SparkBorrowAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/spark/SparkBorrowAction.spec.ts new file mode 100644 index 0000000000..8acad32b2e --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/actions/spark/SparkBorrowAction.spec.ts @@ -0,0 +1,54 @@ +import { Address, Token, TokenAmount } from '@summerfi/sdk-common/common' +import { decodeActionCalldata, getTargetHash } from '@summerfi/testing-utils' +import { SparkBorrowAction } from '../../../../src' +import { ChainFamilyMap } from '@summerfi/sdk-common' + +describe('SparkBorrowAction Action', () => { + const action = new SparkBorrowAction() + const contractNameWithVersion = `${action.config.name}_${action.config.version}` + + const DAI = Token.createFrom({ + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + decimals: 18, + name: 'Dai Stablecoin', + symbol: 'DAI', + }) + + const recipient = Address.createFromEthereum({ + value: '0x6ADb2E268de2aA1aBF6578E4a8119b960E02928F', + }) + + const tokenAmount = TokenAmount.createFrom({ token: DAI, amount: '578' }) + + it('should return the versioned name', () => { + expect(action.getVersionedName()).toBe(contractNameWithVersion) + }) + + it('should encode calls', async () => { + const call = action.encodeCall( + { + borrowAmount: tokenAmount, + borrowTo: recipient, + }, + [1, 8, 5, 3], + ) + + expect(call.targetHash).toBe(getTargetHash(action)) + + const actionDecodedArgs = decodeActionCalldata({ + action, + calldata: call.callData, + }) + + expect(actionDecodedArgs).toBeDefined() + expect(actionDecodedArgs?.args).toEqual([ + { + asset: tokenAmount.token.address.value, + amount: BigInt(tokenAmount.toBaseUnit()), + to: recipient.value, + }, + ]) + expect(actionDecodedArgs?.mapping).toEqual([1, 8, 5, 3]) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/actions/spark/SparkDepositAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/spark/SparkDepositAction.spec.ts new file mode 100644 index 0000000000..e650e5b786 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/actions/spark/SparkDepositAction.spec.ts @@ -0,0 +1,52 @@ +import { Address, Token, TokenAmount } from '@summerfi/sdk-common/common' +import { decodeActionCalldata, getTargetHash } from '@summerfi/testing-utils' +import { SparkDepositAction } from '../../../../src' +import { ChainFamilyMap } from '@summerfi/sdk-common' + +describe('SparkDepositAction Action', () => { + const action = new SparkDepositAction() + const contractNameWithVersion = `${action.config.name}` + + const DAI = Token.createFrom({ + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + decimals: 18, + name: 'Dai Stablecoin', + symbol: 'DAI', + }) + + const tokenAmount = TokenAmount.createFrom({ token: DAI, amount: '578' }) + + it('should return the versioned name', () => { + expect(action.getVersionedName()).toBe(contractNameWithVersion) + }) + + it('should encode calls', async () => { + const call = action.encodeCall( + { + depositAmount: tokenAmount, + sumAmounts: false, + setAsCollateral: true, + }, + [1, 8, 5, 3], + ) + + expect(call.targetHash).toBe(getTargetHash(action)) + + const actionDecodedArgs = decodeActionCalldata({ + action, + calldata: call.callData, + }) + + expect(actionDecodedArgs).toBeDefined() + expect(actionDecodedArgs?.args).toEqual([ + { + asset: tokenAmount.token.address.value, + amount: BigInt(tokenAmount.toBaseUnit()), + sumAmounts: false, + setAsCollateral: true, + }, + ]) + expect(actionDecodedArgs?.mapping).toEqual([1, 8, 5, 3]) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/actions/spark/SparkPaybackAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/spark/SparkPaybackAction.spec.ts new file mode 100644 index 0000000000..9b0d2c10c9 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/actions/spark/SparkPaybackAction.spec.ts @@ -0,0 +1,54 @@ +import { Address, Token, TokenAmount } from '@summerfi/sdk-common/common' +import { decodeActionCalldata, getTargetHash } from '@summerfi/testing-utils' +import { SparkPaybackAction } from '../../../../src' +import { ChainFamilyMap } from '@summerfi/sdk-common' + +describe('SparkPaybackAction Action', () => { + const action = new SparkPaybackAction() + const contractNameWithVersion = `${action.config.name}_${action.config.version}` + + const DAI = Token.createFrom({ + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + decimals: 18, + name: 'Dai Stablecoin', + symbol: 'DAI', + }) + + const onBehalf = Address.createFromEthereum({ + value: '0x6ADb2E268de2aA1aBF6578E4a8119b960E02928F', + }) + + const tokenAmount = TokenAmount.createFrom({ token: DAI, amount: '578' }) + + it('should return the versioned name', () => { + expect(action.getVersionedName()).toBe(contractNameWithVersion) + }) + + it('should encode calls', async () => { + const call = action.encodeCall( + { + paybackAmount: tokenAmount, + paybackAll: true, + }, + [2, 6, 7, 9], + ) + + expect(call.targetHash).toBe(getTargetHash(action)) + + const actionDecodedArgs = decodeActionCalldata({ + action, + calldata: call.callData, + }) + + expect(actionDecodedArgs).toBeDefined() + expect(actionDecodedArgs?.args).toEqual([ + { + asset: tokenAmount.token.address.value, + amount: BigInt(tokenAmount.toBaseUnit()), + paybackAll: true, + }, + ]) + expect(actionDecodedArgs?.mapping).toEqual([2, 6, 7, 9]) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/actions/spark/SparkSetEModeAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/spark/SparkSetEModeAction.spec.ts new file mode 100644 index 0000000000..b044373d10 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/actions/spark/SparkSetEModeAction.spec.ts @@ -0,0 +1,35 @@ +import { decodeActionCalldata, getTargetHash } from '@summerfi/testing-utils' +import { EmodeType, SparkSetEmodeAction, aaveV3EmodeCategoryMap } from '../../../../src' + +describe('MorphoPaybackAction Action', () => { + const action = new SparkSetEmodeAction() + const contractNameWithVersion = `${action.config.name}` + + it('should return the versioned name', () => { + expect(action.getVersionedName()).toBe(contractNameWithVersion) + }) + + it('should encode calls', async () => { + const call = action.encodeCall( + { + emode: EmodeType.Stablecoins, + }, + [2, 6, 7, 9], + ) + + expect(call.targetHash).toBe(getTargetHash(action)) + + const actionDecodedArgs = decodeActionCalldata({ + action, + calldata: call.callData, + }) + + expect(actionDecodedArgs).toBeDefined() + expect(actionDecodedArgs?.args).toEqual([ + { + categoryId: aaveV3EmodeCategoryMap[EmodeType.Stablecoins], + }, + ]) + expect(actionDecodedArgs?.mapping).toEqual([2, 6, 7, 9]) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/actions/spark/SparkWithdrawAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/spark/SparkWithdrawAction.spec.ts new file mode 100644 index 0000000000..3df761c3c5 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/actions/spark/SparkWithdrawAction.spec.ts @@ -0,0 +1,54 @@ +import { Address, Token, TokenAmount } from '@summerfi/sdk-common/common' +import { decodeActionCalldata, getTargetHash } from '@summerfi/testing-utils' +import { SparkWithdrawAction } from '../../../../src' +import { ChainFamilyMap } from '@summerfi/sdk-common' + +describe('SparkWithdrawAction Action', () => { + const action = new SparkWithdrawAction() + const contractNameWithVersion = `${action.config.name}` + + const DAI = Token.createFrom({ + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + decimals: 18, + name: 'Dai Stablecoin', + symbol: 'DAI', + }) + + const recipient = Address.createFromEthereum({ + value: '0x6ADb2E268de2aA1aBF6578E4a8119b960E02928F', + }) + + const tokenAmount = TokenAmount.createFrom({ token: DAI, amount: '578' }) + + it('should return the versioned name', () => { + expect(action.getVersionedName()).toBe(contractNameWithVersion) + }) + + it('should encode calls', async () => { + const call = action.encodeCall( + { + withdrawAmount: tokenAmount, + withdrawTo: recipient, + }, + [2, 6, 7, 9], + ) + + expect(call.targetHash).toBe(getTargetHash(action)) + + const actionDecodedArgs = decodeActionCalldata({ + action, + calldata: call.callData, + }) + + expect(actionDecodedArgs).toBeDefined() + expect(actionDecodedArgs?.args).toEqual([ + { + amount: BigInt(tokenAmount.toBaseUnit()), + asset: tokenAmount.token.address.value, + to: recipient.value, + }, + ]) + expect(actionDecodedArgs?.mapping).toEqual([2, 6, 7, 9]) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/builders/DepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/DepositBorrowActionBuilder.spec.ts index 9a25c962fc..3c15776ec4 100644 --- a/sdk/protocol-plugins/tests/unit/builders/DepositBorrowActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/DepositBorrowActionBuilder.spec.ts @@ -82,26 +82,26 @@ describe('Deposit Borrow Action Builder', () => { pool: pool, }) + const derivedStep: steps.DepositBorrowStep = { + type: SimulationSteps.DepositBorrow, + name: 'DepositBorrowStep', + inputs: { + depositAmount: depositAmount, + borrowAmount: borrowAmount, + position: position, + borrowTargetType: TokenTransferTargetType.PositionsManager, + }, + outputs: { + depositAmount: depositAmount, + borrowAmount: borrowAmount, + }, + } + beforeEach(() => { builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) }) it('should fail if no protocol plugin exists', async () => { - const derivedStep: steps.DepositBorrowStep = { - type: SimulationSteps.DepositBorrow, - name: 'DepositBorrowStep', - inputs: { - depositAmount: depositAmount, - borrowAmount: borrowAmount, - position: position, - borrowTargetType: TokenTransferTargetType.PositionsManager, - }, - outputs: { - depositAmount: depositAmount, - borrowAmount: borrowAmount, - }, - } - try { await DepositBorrowActionBuilder({ ...builderParams, @@ -115,23 +115,6 @@ describe('Deposit Borrow Action Builder', () => { }) it('should fail if no protocol builder for the step exists', async () => { - const builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) - - const derivedStep: steps.DepositBorrowStep = { - type: SimulationSteps.DepositBorrow, - name: 'DepositBorrowStep', - inputs: { - depositAmount: depositAmount, - borrowAmount: borrowAmount, - position: position, - borrowTargetType: TokenTransferTargetType.PositionsManager, - }, - outputs: { - depositAmount: depositAmount, - borrowAmount: borrowAmount, - }, - } - try { await DepositBorrowActionBuilder({ ...builderParams, @@ -145,23 +128,6 @@ describe('Deposit Borrow Action Builder', () => { }) it('should call the proper builder', async () => { - const builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) - - const derivedStep: steps.DepositBorrowStep = { - type: SimulationSteps.DepositBorrow, - name: 'DepositBorrowStep', - inputs: { - depositAmount: depositAmount, - borrowAmount: borrowAmount, - position: position, - borrowTargetType: TokenTransferTargetType.PositionsManager, - }, - outputs: { - depositAmount: depositAmount, - borrowAmount: borrowAmount, - }, - } - await DepositBorrowActionBuilder({ ...builderParams, step: derivedStep, diff --git a/sdk/protocol-plugins/tests/unit/builders/FlashloanActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/FlashloanActionBuilder.spec.ts index dcccc8f00b..5f55485eee 100644 --- a/sdk/protocol-plugins/tests/unit/builders/FlashloanActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/FlashloanActionBuilder.spec.ts @@ -22,21 +22,21 @@ describe('Flashloan Action Builder', () => { amount: '134.5', }) + const derivedStep: steps.FlashloanStep = { + type: SimulationSteps.Flashloan, + name: 'FlashloanStep', + inputs: { + amount: flashloanAmount, + provider: FlashloanProvider.Balancer, + }, + outputs: undefined, + } + beforeEach(() => { builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) }) it('should start a new subcontext', async () => { - const derivedStep: steps.FlashloanStep = { - type: SimulationSteps.Flashloan, - name: 'FlashloanStep', - inputs: { - amount: flashloanAmount, - provider: FlashloanProvider.Balancer, - }, - outputs: undefined, - } - await FlashloanActionBuilder({ ...builderParams, step: derivedStep, diff --git a/sdk/protocol-plugins/tests/unit/builders/ImportPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/ImportPositionActionBuilder.spec.ts new file mode 100644 index 0000000000..febac39244 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/builders/ImportPositionActionBuilder.spec.ts @@ -0,0 +1,144 @@ +import { + Address, + ChainFamilyMap, + ChainInfo, + Position, + PositionId, + PositionType, + Token, + TokenAmount, +} from '@summerfi/sdk-common/common' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SetupBuilderReturnType, setupBuilderParams } from '../../utils/SetupBuilderParams' +import { DepositBorrowActionBuilder } from '../../../src/plugins/common/builders/DepositBorrowActionBuilder' +import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { getErrorMessage } from '@summerfi/testing-utils' +import assert from 'assert' +import { ILKType } from '../../../src/plugins/maker/enums/ILKType' +import { + ImportPositionActionBuilder, + MakerLendingPool, + MakerLendingPoolId, + MakerPosition, + MakerPositionId, + MakerProtocol, +} from '../../../src' +import { ExternalPositionType } from '@summerfi/sdk-common' + +describe('Deposit Borrow Action Builder', () => { + let builderParams: SetupBuilderReturnType + + const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet + + // Tokens + const WETH = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + }) + + const DAI = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + }) + + const depositAmount = TokenAmount.createFrom({ + token: WETH, + amount: '134.5', + }) + + const borrowAmount = TokenAmount.createFrom({ + token: DAI, + amount: '1000', + }) + + const protocol = MakerProtocol.createFrom({ + name: ProtocolName.Maker, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + const poolId = MakerLendingPoolId.createFrom({ + protocol: protocol, + ilkType: ILKType.ETH_A, + collateralToken: WETH, + debtToken: DAI, + }) + + const pool = MakerLendingPool.createFrom({ + type: PoolType.Lending, + id: poolId, + collateralToken: WETH, + debtToken: DAI, + }) + + const position = MakerPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: borrowAmount, + collateralAmount: depositAmount, + pool: pool, + }) + + const externalPositionOwner = Address.createFromEthereum({ + value: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', + }) + + const derivedStep: steps.ImportStep = { + type: SimulationSteps.Import, + name: 'ImportPosition', + inputs: { + externalPosition: { + position: position, + externalId: { + address: externalPositionOwner, + type: ExternalPositionType.WALLET, + }, + }, + }, + outputs: undefined, + } + + beforeEach(() => { + builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) + }) + + it('should fail if no protocol plugin exists', async () => { + try { + await ImportPositionActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('No protocol plugin found for protocol Maker') + } + }) + + it('should fail if no protocol builder for the step exists', async () => { + try { + await ImportPositionActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyBuildersProtocolRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('No action builder found for protocol Maker') + } + }) + + it('should call the proper builder', async () => { + await ImportPositionActionBuilder({ + ...builderParams, + step: derivedStep, + }) + + expect(builderParams.context.checkpoints[0]).toEqual('ImportPositionActionBuilderMock') + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/builders/OpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/OpenPositionActionBuilder.spec.ts new file mode 100644 index 0000000000..d54e59b9b9 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/builders/OpenPositionActionBuilder.spec.ts @@ -0,0 +1,135 @@ +import { + Address, + ChainFamilyMap, + ChainInfo, + Position, + PositionId, + PositionType, + Token, + TokenAmount, +} from '@summerfi/sdk-common/common' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SetupBuilderReturnType, setupBuilderParams } from '../../utils/SetupBuilderParams' +import { DepositBorrowActionBuilder } from '../../../src/plugins/common/builders/DepositBorrowActionBuilder' +import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { getErrorMessage } from '@summerfi/testing-utils' +import assert from 'assert' +import { ILKType } from '../../../src/plugins/maker/enums/ILKType' +import { + MakerLendingPool, + MakerLendingPoolId, + MakerPosition, + MakerPositionId, + MakerProtocol, + OpenPositionActionBuilder, +} from '../../../src' + +describe('Deposit Borrow Action Builder', () => { + let builderParams: SetupBuilderReturnType + + const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet + + // Tokens + const WETH = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + }) + + const DAI = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + }) + + const depositAmount = TokenAmount.createFrom({ + token: WETH, + amount: '134.5', + }) + + const borrowAmount = TokenAmount.createFrom({ + token: DAI, + amount: '1000', + }) + + const protocol = MakerProtocol.createFrom({ + name: ProtocolName.Maker, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + const poolId = MakerLendingPoolId.createFrom({ + protocol: protocol, + ilkType: ILKType.ETH_A, + collateralToken: WETH, + debtToken: DAI, + }) + + const pool = MakerLendingPool.createFrom({ + type: PoolType.Lending, + id: poolId, + collateralToken: WETH, + debtToken: DAI, + }) + + const position = MakerPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: borrowAmount, + collateralAmount: depositAmount, + pool: pool, + }) + + const derivedStep: steps.OpenPosition = { + type: SimulationSteps.OpenPosition, + name: 'OpenPosition', + inputs: { + pool: pool, + }, + outputs: { + position: position, + }, + } + + beforeEach(() => { + builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) + }) + + it('should fail if no protocol plugin exists', async () => { + try { + await OpenPositionActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('No protocol plugin found for protocol Maker') + } + }) + + it('should fail if no protocol builder for the step exists', async () => { + try { + await OpenPositionActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyBuildersProtocolRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('No action builder found for protocol Maker') + } + }) + + it('should call the proper builder', async () => { + await OpenPositionActionBuilder({ + ...builderParams, + step: derivedStep, + }) + + expect(builderParams.context.checkpoints[0]).toEqual('OpenPositionActionBuilderMock') + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/builders/PaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/PaybackWithdrawActionBuilder.spec.ts index 995c43bb71..517ecf8b11 100644 --- a/sdk/protocol-plugins/tests/unit/builders/PaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/PaybackWithdrawActionBuilder.spec.ts @@ -8,7 +8,7 @@ import { Token, TokenAmount, } from '@summerfi/sdk-common/common' -import { SimulationSteps, steps } from '@summerfi/sdk-common/simulation' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' import { SetupBuilderReturnType, setupBuilderParams } from '../../utils/SetupBuilderParams' import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' import { getErrorMessage } from '@summerfi/testing-utils' @@ -84,6 +84,7 @@ describe('Payback Withdraw Action Builder', () => { paybackAmount: paybackAmount, withdrawAmount: withdrawAmount, position: position, + withdrawTargetType: TokenTransferTargetType.PositionsManager, }, outputs: { paybackAmount: paybackAmount, diff --git a/sdk/protocol-plugins/tests/unit/builders/PullTokenActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/PullTokenActionBuilder.spec.ts index 53ee99f8cc..872cb88138 100644 --- a/sdk/protocol-plugins/tests/unit/builders/PullTokenActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/PullTokenActionBuilder.spec.ts @@ -24,22 +24,20 @@ describe('Pull TokenAction Builder', () => { amount: '134.5', }) + const derivedStep: steps.PullTokenStep = { + type: SimulationSteps.PullToken, + name: 'PullTokenStep', + inputs: { + amount: pullAmount, + }, + outputs: undefined, + } + beforeEach(() => { builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) }) it('should encode the action calldata correctly', async () => { - const builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) - - const derivedStep: steps.PullTokenStep = { - type: SimulationSteps.PullToken, - name: 'PullTokenStep', - inputs: { - amount: pullAmount, - }, - outputs: undefined, - } - builderParams.context.startSubContext() await PullTokenActionBuilder({ diff --git a/sdk/protocol-plugins/tests/unit/builders/ReturnFundsActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/ReturnFundsActionBuilder.spec.ts index 1fce12a109..1d340a7a44 100644 --- a/sdk/protocol-plugins/tests/unit/builders/ReturnFundsActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/ReturnFundsActionBuilder.spec.ts @@ -19,22 +19,20 @@ describe('Return Funds Action Builder', () => { decimals: 18, }) + const derivedStep: steps.ReturnFundsStep = { + type: SimulationSteps.ReturnFunds, + name: 'ReturnFundsStep', + inputs: { + token: WETH, + }, + outputs: undefined, + } + beforeEach(() => { builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) }) it('should encode the action calldata correctly', async () => { - const builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) - - const derivedStep: steps.ReturnFundsStep = { - type: SimulationSteps.ReturnFunds, - name: 'ReturnFundsStep', - inputs: { - token: WETH, - }, - outputs: undefined, - } - builderParams.context.startSubContext() await ReturnFundsActionBuilder({ diff --git a/sdk/protocol-plugins/tests/unit/builders/SwapActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/SwapActionBuilder.spec.ts index a818da59f9..f24f1b0e97 100644 --- a/sdk/protocol-plugins/tests/unit/builders/SwapActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/SwapActionBuilder.spec.ts @@ -69,6 +69,26 @@ describe('Swap Action Builder', () => { const inputAmountAfterFee = inputAmount.multiply(percent100.subtract(fee)) + const derivedStep: steps.SwapStep = { + type: SimulationSteps.Swap, + name: 'SwapStep', + inputs: { + provider: SwapProviderType.OneInch, + routes: [], + spotPrice: spotPrice, + offerPrice: offerPrice, + inputAmount: inputAmount, + inputAmountAfterFee: inputAmountAfterFee, + estimatedReceivedAmount: toAmount, + minimumReceivedAmount: toAmount, + summerFee: fee, + slippage, + }, + outputs: { + received: toAmount, + }, + } + beforeEach(() => { builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) ;(builderParams.addressBookManager as AddressBookManagerMock).setAddressByName({ @@ -79,26 +99,6 @@ describe('Swap Action Builder', () => { }) it('should encode the action calldata correctly', async () => { - const derivedStep: steps.SwapStep = { - type: SimulationSteps.Swap, - name: 'SwapStep', - inputs: { - provider: SwapProviderType.OneInch, - routes: [], - spotPrice: spotPrice, - offerPrice: offerPrice, - inputAmount: inputAmount, - inputAmountAfterFee: inputAmountAfterFee, - estimatedReceivedAmount: toAmount, - minimumReceivedAmount: toAmount, - summerFee: fee, - slippage, - }, - outputs: { - received: toAmount, - }, - } - // Setup swap manager returned data builderParams.swapManager.setSwapData({ provider: SwapProviderType.OneInch, diff --git a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts new file mode 100644 index 0000000000..8531258dea --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts @@ -0,0 +1,214 @@ +import { + Address, + ChainFamilyMap, + ChainInfo, + PositionType, + Token, + TokenAmount, +} from '@summerfi/sdk-common/common' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SetupBuilderReturnType, setupBuilderParams } from '../../../utils/SetupBuilderParams' +import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { getErrorMessage } from '@summerfi/testing-utils' +import assert from 'assert' +import { + EmodeType, + ILKType, + MakerLendingPool, + MakerLendingPoolId, + MakerPosition, + MakerPositionId, + MakerProtocol, + AaveV3DepositBorrowActionBuilder, + AaveV3LendingPool, + AaveV3LendingPoolId, + AaveV3Position, + AaveV3Protocol, +} from '../../../../src' + +describe('AaveV3 Deposit Borrow Action Builder', () => { + let builderParams: SetupBuilderReturnType + + const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet + + // Tokens + const WETH = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + }) + + const DAI = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + }) + + const depositAmount = TokenAmount.createFrom({ + token: WETH, + amount: '134.5', + }) + + const borrowAmount = TokenAmount.createFrom({ + token: DAI, + amount: '1000', + }) + + const protocol = AaveV3Protocol.createFrom({ + name: ProtocolName.AAVEv3, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + const poolId = AaveV3LendingPoolId.createFrom({ + protocol: protocol, + collateralToken: WETH, + debtToken: DAI, + emodeType: EmodeType.None, + }) + + const pool = AaveV3LendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: poolId, + type: PoolType.Lending, + }) + + const position = AaveV3Position.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: borrowAmount, + collateralAmount: depositAmount, + pool: pool, + }) + + const wrongPosition = MakerPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: borrowAmount, + collateralAmount: depositAmount, + pool: MakerLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: MakerLendingPoolId.createFrom({ + collateralToken: WETH, + debtToken: DAI, + protocol: MakerProtocol.createFrom({ + name: ProtocolName.Maker, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }), + ilkType: ILKType.ETH_A, + }), + type: PoolType.Lending, + }), + }) + + const derivedStep: steps.DepositBorrowStep = { + type: SimulationSteps.DepositBorrow, + name: 'DepositBorrowStep', + inputs: { + depositAmount: depositAmount, + borrowAmount: borrowAmount, + position: position, + borrowTargetType: TokenTransferTargetType.StrategyExecutor, + }, + outputs: { + depositAmount: depositAmount, + borrowAmount: borrowAmount, + }, + } + + beforeEach(() => { + builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) + }) + + it('should fail the position is not a AaveV3 one', async () => { + try { + await AaveV3DepositBorrowActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + position: wrongPosition, + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('Invalid AaveV3 lending pool') + } + }) + + it('should add all the action calls', async () => { + builderParams.context.startSubContext() + + await AaveV3DepositBorrowActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(3) + + expect(callsBatch[0].name).toBe('SetApproval') + expect(callsBatch[1].name).toBe('AaveV3Deposit') + expect(callsBatch[2].name).toBe('AaveV3Borrow') + }) + + it('should not add borrow nor send token when borrow amount is 0', async () => { + builderParams.context.startSubContext() + + await AaveV3DepositBorrowActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + borrowAmount: TokenAmount.createFrom({ + token: DAI, + amount: '0', + }), + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(2) + + expect(callsBatch[0].name).toBe('SetApproval') + expect(callsBatch[1].name).toBe('AaveV3Deposit') + }) + + it('should add borrow but not send token when borrow target is positions manager', async () => { + builderParams.context.startSubContext() + + await AaveV3DepositBorrowActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + borrowTargetType: TokenTransferTargetType.PositionsManager, + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(3) + + expect(callsBatch[0].name).toBe('SetApproval') + expect(callsBatch[1].name).toBe('AaveV3Deposit') + expect(callsBatch[2].name).toBe('AaveV3Borrow') + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3OpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3OpenPositionActionBuilder.spec.ts new file mode 100644 index 0000000000..874ce0977b --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3OpenPositionActionBuilder.spec.ts @@ -0,0 +1,151 @@ +import { + Address, + ChainFamilyMap, + ChainInfo, + PositionType, + Token, + TokenAmount, +} from '@summerfi/sdk-common/common' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SetupBuilderReturnType, setupBuilderParams } from '../../../utils/SetupBuilderParams' +import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { getErrorMessage } from '@summerfi/testing-utils' +import assert from 'assert' +import { + EmodeType, + ILKType, + MakerLendingPool, + MakerLendingPoolId, + MakerPositionId, + MakerProtocol, + AaveV3LendingPool, + AaveV3LendingPoolId, + AaveV3OpenPositionActionBuilder, + AaveV3Position, + AaveV3Protocol, +} from '../../../../src' + +describe('AaveV3 Open Position Action Builder', () => { + let builderParams: SetupBuilderReturnType + + const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet + + // Tokens + const WETH = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + }) + + const DAI = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + }) + + const depositAmount = TokenAmount.createFrom({ + token: WETH, + amount: '134.5', + }) + + const borrowAmount = TokenAmount.createFrom({ + token: DAI, + amount: '1000', + }) + + const protocol = AaveV3Protocol.createFrom({ + name: ProtocolName.AAVEv3, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + const poolId = AaveV3LendingPoolId.createFrom({ + protocol: protocol, + collateralToken: WETH, + debtToken: DAI, + emodeType: EmodeType.None, + }) + + const pool = AaveV3LendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: poolId, + type: PoolType.Lending, + }) + + const position = AaveV3Position.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: borrowAmount, + collateralAmount: depositAmount, + pool: pool, + }) + + const wrongPool = MakerLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: MakerLendingPoolId.createFrom({ + collateralToken: WETH, + debtToken: DAI, + protocol: MakerProtocol.createFrom({ + name: ProtocolName.Maker, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }), + ilkType: ILKType.ETH_A, + }), + type: PoolType.Lending, + }) + + const derivedStep: steps.OpenPosition = { + type: SimulationSteps.OpenPosition, + name: 'OpenPosition', + inputs: { + pool: pool, + }, + outputs: { + position: position, + }, + } + + beforeEach(() => { + builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) + }) + + it('should fail the position is not a AaveV3 one', async () => { + try { + await AaveV3OpenPositionActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + pool: wrongPool, + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('Invalid AaveV3 lending pool') + } + }) + + it('should add a transaction to the context', async () => { + builderParams.context.startSubContext() + + await AaveV3OpenPositionActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(1) + + expect(callsBatch[0].name).toBe('AaveV3SetEMode') + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts new file mode 100644 index 0000000000..3d17c20353 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts @@ -0,0 +1,189 @@ +import { + Address, + ChainFamilyMap, + ChainInfo, + PositionType, + Token, + TokenAmount, +} from '@summerfi/sdk-common/common' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SetupBuilderReturnType, setupBuilderParams } from '../../../utils/SetupBuilderParams' +import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { getErrorMessage } from '@summerfi/testing-utils' +import assert from 'assert' +import { + EmodeType, + ILKType, + MakerLendingPool, + MakerLendingPoolId, + MakerPosition, + MakerPositionId, + MakerProtocol, + AaveV3LendingPool, + AaveV3LendingPoolId, + AaveV3Position, + AaveV3Protocol, +} from '../../../../src' +import { AaveV3PaybackWithdrawActionBuilder } from '../../../../src' + +describe('AaveV3 Payback Withdraw Action Builder', () => { + let builderParams: SetupBuilderReturnType + + const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet + + // Tokens + const WETH = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + }) + + const DAI = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + }) + + const paybackAmount = TokenAmount.createFrom({ + token: WETH, + amount: '134.5', + }) + + const withdrawAmount = TokenAmount.createFrom({ + token: DAI, + amount: '1000', + }) + + const protocol = AaveV3Protocol.createFrom({ + name: ProtocolName.AAVEv3, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + const poolId = AaveV3LendingPoolId.createFrom({ + protocol: protocol, + collateralToken: WETH, + debtToken: DAI, + emodeType: EmodeType.None, + }) + + const pool = AaveV3LendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: poolId, + type: PoolType.Lending, + }) + + const position = AaveV3Position.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: withdrawAmount, + collateralAmount: paybackAmount, + pool: pool, + }) + + const wrongPosition = MakerPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: withdrawAmount, + collateralAmount: paybackAmount, + pool: MakerLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: MakerLendingPoolId.createFrom({ + collateralToken: WETH, + debtToken: DAI, + protocol: MakerProtocol.createFrom({ + name: ProtocolName.Maker, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }), + ilkType: ILKType.ETH_A, + }), + type: PoolType.Lending, + }), + }) + + const derivedStep: steps.PaybackWithdrawStep = { + type: SimulationSteps.PaybackWithdraw, + name: 'PaybackWithdrawStep', + inputs: { + paybackAmount: paybackAmount, + withdrawAmount: withdrawAmount, + position: position, + withdrawTargetType: TokenTransferTargetType.PositionsManager, + }, + outputs: { + paybackAmount: paybackAmount, + withdrawAmount: withdrawAmount, + }, + } + + beforeEach(() => { + builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) + }) + + it('should fail the position is not a AaveV3 one', async () => { + try { + await AaveV3PaybackWithdrawActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + position: wrongPosition, + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('Invalid AaveV3 lending pool') + } + }) + + it('should add all the action calls', async () => { + builderParams.context.startSubContext() + + await AaveV3PaybackWithdrawActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(3) + + expect(callsBatch[0].name).toBe('SetApproval') + expect(callsBatch[1].name).toBe('AaveV3Payback') + expect(callsBatch[2].name).toBe('AaveV3Withdraw') + }) + + it('should not add payback when payback amount is 0', async () => { + builderParams.context.startSubContext() + + await AaveV3PaybackWithdrawActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + paybackAmount: TokenAmount.createFrom({ + token: DAI, + amount: '0', + }), + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(1) + + expect(callsBatch[0].name).toBe('AaveV3Withdraw') + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/builders/maker/MakerImportPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/maker/MakerImportPositionActionBuilder.spec.ts new file mode 100644 index 0000000000..be318185e5 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/builders/maker/MakerImportPositionActionBuilder.spec.ts @@ -0,0 +1,178 @@ +import { + Address, + ChainFamilyMap, + ChainInfo, + Percentage, + PositionType, + RiskRatio, + RiskRatioType, + Token, + TokenAmount, +} from '@summerfi/sdk-common/common' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SetupBuilderReturnType, setupBuilderParams } from '../../../utils/SetupBuilderParams' +import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { getErrorMessage } from '@summerfi/testing-utils' +import assert from 'assert' +import { + ILKType, + MakerPositionId, + MakerLendingPool, + MakerLendingPoolId, + MakerPosition, + MakerProtocol, + MakerImportPositionActionBuilder, + MorphoPosition, + MorphoLendingPool, + MorphoLendingPoolId, + MorphoProtocol, +} from '../../../../src' +import { ExternalPositionType } from '@summerfi/sdk-common' + +describe('Maker Import Position Action Builder', () => { + let builderParams: SetupBuilderReturnType + + const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet + + // Tokens + const WETH = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + }) + + const DAI = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + }) + + const externalPositionOwner = Address.createFromEthereum({ + value: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', + }) + + const depositAmount = TokenAmount.createFrom({ + token: WETH, + amount: '134.5', + }) + + const borrowAmount = TokenAmount.createFrom({ + token: DAI, + amount: '1000', + }) + + const protocol = MakerProtocol.createFrom({ + name: ProtocolName.Maker, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + const poolId = MakerLendingPoolId.createFrom({ + collateralToken: WETH, + debtToken: DAI, + ilkType: ILKType.ETH_A, + protocol: protocol, + }) + + const pool = MakerLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: poolId, + type: PoolType.Lending, + }) + + const position = MakerPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: borrowAmount, + collateralAmount: depositAmount, + pool: pool, + }) + + const wrongPosition = MorphoPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: borrowAmount, + collateralAmount: depositAmount, + pool: MorphoLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: MorphoLendingPoolId.createFrom({ + marketId: '0x1234', + protocol: MorphoProtocol.createFrom({ + name: ProtocolName.Morpho, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }), + }), + irm: Address.createFromEthereum({ value: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599' }), + oracle: Address.createFromEthereum({ value: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' }), + lltv: RiskRatio.createFrom({ + value: Percentage.createFrom({ value: 0.5 }), + type: RiskRatioType.LTV, + }), + type: PoolType.Lending, + }), + }) + + const derivedStep: steps.ImportStep = { + type: SimulationSteps.Import, + name: 'ImportPosition', + inputs: { + externalPosition: { + position: position, + externalId: { + address: externalPositionOwner, + type: ExternalPositionType.WALLET, + }, + }, + }, + outputs: undefined, + } + + beforeEach(() => { + builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) + }) + + it('should fail the position is not a Maker one', async () => { + try { + await MakerImportPositionActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + externalPosition: { + position: wrongPosition, + externalId: { + address: externalPositionOwner, + type: ExternalPositionType.WALLET, + }, + }, + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('Invalid Maker lending pool id') + } + }) + + it('should add a new transaction to the context', async () => { + builderParams.context.startSubContext() + + await MakerImportPositionActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.protocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(0) + expect(builderParams.context.transactions.length).toEqual(1) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/builders/maker/MakerOpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/maker/MakerOpenPositionActionBuilder.spec.ts new file mode 100644 index 0000000000..bcd2154c07 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/builders/maker/MakerOpenPositionActionBuilder.spec.ts @@ -0,0 +1,155 @@ +import { + Address, + ChainFamilyMap, + ChainInfo, + Percentage, + PositionType, + RiskRatio, + RiskRatioType, + Token, + TokenAmount, +} from '@summerfi/sdk-common/common' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SetupBuilderReturnType, setupBuilderParams } from '../../../utils/SetupBuilderParams' +import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { getErrorMessage } from '@summerfi/testing-utils' +import assert from 'assert' +import { + ILKType, + MakerPositionId, + MakerLendingPool, + MakerLendingPoolId, + MakerOpenPositionActionBuilder, + MakerPosition, + MakerProtocol, + MorphoLendingPool, + MorphoLendingPoolId, + MorphoProtocol, +} from '../../../../src' + +describe('Maker Open Position Action Builder', () => { + let builderParams: SetupBuilderReturnType + + const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet + + // Tokens + const WETH = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + }) + + const DAI = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + }) + + const depositAmount = TokenAmount.createFrom({ + token: WETH, + amount: '134.5', + }) + + const borrowAmount = TokenAmount.createFrom({ + token: DAI, + amount: '1000', + }) + + const protocol = MakerProtocol.createFrom({ + name: ProtocolName.Maker, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + const poolId = MakerLendingPoolId.createFrom({ + protocol: protocol, + collateralToken: WETH, + debtToken: DAI, + ilkType: ILKType.ETH_A, + }) + + const pool = MakerLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: poolId, + type: PoolType.Lending, + }) + + const position = MakerPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: borrowAmount, + collateralAmount: depositAmount, + pool: pool, + }) + + const wrongPool = MorphoLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: MorphoLendingPoolId.createFrom({ + marketId: '0x1234', + protocol: MorphoProtocol.createFrom({ + name: ProtocolName.Morpho, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }), + }), + irm: Address.createFromEthereum({ value: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599' }), + oracle: Address.createFromEthereum({ value: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' }), + lltv: RiskRatio.createFrom({ + value: Percentage.createFrom({ value: 0.5 }), + type: RiskRatioType.LTV, + }), + type: PoolType.Lending, + }) + + const derivedStep: steps.OpenPosition = { + type: SimulationSteps.OpenPosition, + name: 'OpenPosition', + inputs: { + pool: pool, + }, + outputs: { + position: position, + }, + } + + beforeEach(() => { + builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) + }) + + it('should fail the position is not a Maker one', async () => { + try { + await MakerOpenPositionActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + pool: wrongPool, + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('Invalid Maker lending pool id') + } + }) + + it('should not add a transaction to the context', async () => { + builderParams.context.startSubContext() + + await MakerOpenPositionActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(0) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts new file mode 100644 index 0000000000..13d0e1bd8e --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts @@ -0,0 +1,194 @@ +import { + Address, + ChainFamilyMap, + ChainInfo, + Percentage, + PositionType, + Token, + TokenAmount, +} from '@summerfi/sdk-common/common' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SetupBuilderReturnType, setupBuilderParams } from '../../../utils/SetupBuilderParams' +import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { getErrorMessage } from '@summerfi/testing-utils' +import assert from 'assert' +import { + ILKType, + MakerPositionId, + MakerLendingPool, + MakerLendingPoolId, + MakerPosition, + MakerProtocol, + MorphoPosition, + MorphoLendingPool, + MorphoLendingPoolId, + MorphoProtocol, + MakerPaybackWithdrawActionBuilder, +} from '../../../../src' + +import { RiskRatio, RiskRatioType } from '@summerfi/sdk-common' + +describe('Maker Payback Withdraw Action Builder', () => { + let builderParams: SetupBuilderReturnType + + const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet + + // Tokens + const WETH = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + }) + + const DAI = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + }) + + const debtAmount = TokenAmount.createFrom({ + token: WETH, + amount: '134.5', + }) + + const collateralAmount = TokenAmount.createFrom({ + token: DAI, + amount: '1000', + }) + + const protocol = MakerProtocol.createFrom({ + name: ProtocolName.Maker, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + const poolId = MakerLendingPoolId.createFrom({ + collateralToken: collateralAmount.token, + debtToken: debtAmount.token, + ilkType: ILKType.ETH_A, + protocol: protocol, + }) + + const pool = MakerLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: poolId, + type: PoolType.Lending, + }) + + const position = MakerPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: debtAmount, + collateralAmount: collateralAmount, + pool: pool, + }) + + const wrongPosition = MorphoPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: debtAmount, + collateralAmount: collateralAmount, + pool: MorphoLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: MorphoLendingPoolId.createFrom({ + marketId: '0x1234', + protocol: MorphoProtocol.createFrom({ + name: ProtocolName.Morpho, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }), + }), + irm: Address.createFromEthereum({ value: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599' }), + oracle: Address.createFromEthereum({ value: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' }), + lltv: RiskRatio.createFrom({ + value: Percentage.createFrom({ value: 0.5 }), + type: RiskRatioType.LTV, + }), + type: PoolType.Lending, + }), + }) + + const derivedStep: steps.PaybackWithdrawStep = { + type: SimulationSteps.PaybackWithdraw, + name: 'PaybackWithdrawStep', + inputs: { + paybackAmount: debtAmount, + withdrawAmount: collateralAmount, + position: position, + withdrawTargetType: TokenTransferTargetType.PositionsManager, + }, + outputs: { + paybackAmount: debtAmount, + withdrawAmount: collateralAmount, + }, + } + + beforeEach(() => { + builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) + }) + + it('should fail the position is not a Maker one', async () => { + try { + await MakerPaybackWithdrawActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + position: wrongPosition, + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('Invalid Maker lending pool id') + } + }) + + it('should add all the action calls', async () => { + builderParams.context.startSubContext() + + await MakerPaybackWithdrawActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(2) + + expect(callsBatch[0].name).toBe('MakerPayback') + expect(callsBatch[1].name).toBe('MakerWithdraw') + }) + + it('should not add payback when payback amount is 0', async () => { + builderParams.context.startSubContext() + + await MakerPaybackWithdrawActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + paybackAmount: TokenAmount.createFrom({ + token: DAI, + amount: '0', + }), + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(1) + + expect(callsBatch[0].name).toBe('MakerWithdraw') + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts index ecdf1d35db..c9ceb71345 100644 --- a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts @@ -25,6 +25,7 @@ import { MorphoLendingPool, MorphoLendingPoolId, MorphoPosition, + MorphoPositionId, MorphoProtocol, } from '../../../../src' @@ -85,7 +86,7 @@ describe('Morpho Deposit Borrow Action Builder', () => { const position = MorphoPosition.createFrom({ type: PositionType.Multiply, - id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + id: MorphoPositionId.createFrom({ id: 'someposition' }), debtAmount: borrowAmount, collateralAmount: depositAmount, pool: pool, diff --git a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoOpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoOpenPositionActionBuilder.spec.ts new file mode 100644 index 0000000000..e37a8402bc --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoOpenPositionActionBuilder.spec.ts @@ -0,0 +1,155 @@ +import { + Address, + ChainFamilyMap, + ChainInfo, + Percentage, + PositionType, + RiskRatio, + RiskRatioType, + Token, + TokenAmount, +} from '@summerfi/sdk-common/common' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SetupBuilderReturnType, setupBuilderParams } from '../../../utils/SetupBuilderParams' +import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { getErrorMessage } from '@summerfi/testing-utils' +import assert from 'assert' +import { + ILKType, + MorphoPositionId, + MorphoPosition, + MorphoLendingPool, + MorphoLendingPoolId, + MorphoProtocol, + MakerLendingPool, + MakerLendingPoolId, + MakerProtocol, + MorphoOpenPositionActionBuilder, +} from '../../../../src' + +describe('Morpho Open Position Action Builder', () => { + let builderParams: SetupBuilderReturnType + + const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet + + // Tokens + const WETH = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + }) + + const DAI = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + }) + + const depositAmount = TokenAmount.createFrom({ + token: WETH, + amount: '134.5', + }) + + const borrowAmount = TokenAmount.createFrom({ + token: DAI, + amount: '1000', + }) + + const protocol = MorphoProtocol.createFrom({ + name: ProtocolName.Morpho, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + const poolId = MorphoLendingPoolId.createFrom({ + marketId: '0x1234', + protocol: protocol, + }) + + const pool = MorphoLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: poolId, + irm: Address.createFromEthereum({ value: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599' }), + oracle: Address.createFromEthereum({ value: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' }), + lltv: RiskRatio.createFrom({ + value: Percentage.createFrom({ value: 0.5 }), + type: RiskRatioType.LTV, + }), + type: PoolType.Lending, + }) + + const position = MorphoPosition.createFrom({ + type: PositionType.Multiply, + id: MorphoPositionId.createFrom({ id: 'someposition' }), + debtAmount: borrowAmount, + collateralAmount: depositAmount, + pool: pool, + }) + + const wrongPool = MakerLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: MakerLendingPoolId.createFrom({ + collateralToken: WETH, + debtToken: DAI, + protocol: MakerProtocol.createFrom({ + name: ProtocolName.Maker, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }), + ilkType: ILKType.ETH_A, + }), + type: PoolType.Lending, + }) + + const derivedStep: steps.OpenPosition = { + type: SimulationSteps.OpenPosition, + name: 'OpenPosition', + inputs: { + pool: pool, + }, + outputs: { + position: position, + }, + } + + beforeEach(() => { + builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) + }) + + it('should fail the position is not a Morpho one', async () => { + try { + await MorphoOpenPositionActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + pool: wrongPool, + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('Invalid Morpho lending pool id') + } + }) + + it('should not add a transaction to the context', async () => { + builderParams.context.startSubContext() + + await MorphoOpenPositionActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(0) + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts index 1361ddfd11..6baf51bbfe 100644 --- a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts @@ -113,11 +113,12 @@ describe('Morpho Payback Withdraw Action Builder', () => { const derivedStep: steps.PaybackWithdrawStep = { type: SimulationSteps.PaybackWithdraw, - name: 'DepositBorrowStep', + name: 'PaybackWithdrawStep', inputs: { paybackAmount: paybackAmount, withdrawAmount: withdrawAmount, position: position, + withdrawTargetType: TokenTransferTargetType.PositionsManager, }, outputs: { paybackAmount: paybackAmount, diff --git a/sdk/protocol-plugins/tests/unit/builders/spark/SparkDepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/spark/SparkDepositBorrowActionBuilder.spec.ts new file mode 100644 index 0000000000..2c095989c1 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/builders/spark/SparkDepositBorrowActionBuilder.spec.ts @@ -0,0 +1,214 @@ +import { + Address, + ChainFamilyMap, + ChainInfo, + PositionType, + Token, + TokenAmount, +} from '@summerfi/sdk-common/common' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SetupBuilderReturnType, setupBuilderParams } from '../../../utils/SetupBuilderParams' +import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { getErrorMessage } from '@summerfi/testing-utils' +import assert from 'assert' +import { + EmodeType, + ILKType, + MakerLendingPool, + MakerLendingPoolId, + MakerPosition, + MakerPositionId, + MakerProtocol, + SparkDepositBorrowActionBuilder, + SparkLendingPool, + SparkLendingPoolId, + SparkPosition, + SparkProtocol, +} from '../../../../src' + +describe('Spark Deposit Borrow Action Builder', () => { + let builderParams: SetupBuilderReturnType + + const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet + + // Tokens + const WETH = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + }) + + const DAI = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + }) + + const depositAmount = TokenAmount.createFrom({ + token: WETH, + amount: '134.5', + }) + + const borrowAmount = TokenAmount.createFrom({ + token: DAI, + amount: '1000', + }) + + const protocol = SparkProtocol.createFrom({ + name: ProtocolName.Spark, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + const poolId = SparkLendingPoolId.createFrom({ + protocol: protocol, + collateralToken: WETH, + debtToken: DAI, + emodeType: EmodeType.None, + }) + + const pool = SparkLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: poolId, + type: PoolType.Lending, + }) + + const position = SparkPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: borrowAmount, + collateralAmount: depositAmount, + pool: pool, + }) + + const wrongPosition = MakerPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: borrowAmount, + collateralAmount: depositAmount, + pool: MakerLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: MakerLendingPoolId.createFrom({ + collateralToken: WETH, + debtToken: DAI, + protocol: MakerProtocol.createFrom({ + name: ProtocolName.Maker, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }), + ilkType: ILKType.ETH_A, + }), + type: PoolType.Lending, + }), + }) + + const derivedStep: steps.DepositBorrowStep = { + type: SimulationSteps.DepositBorrow, + name: 'DepositBorrowStep', + inputs: { + depositAmount: depositAmount, + borrowAmount: borrowAmount, + position: position, + borrowTargetType: TokenTransferTargetType.StrategyExecutor, + }, + outputs: { + depositAmount: depositAmount, + borrowAmount: borrowAmount, + }, + } + + beforeEach(() => { + builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) + }) + + it('should fail the position is not a Spark one', async () => { + try { + await SparkDepositBorrowActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + position: wrongPosition, + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('Invalid Spark lending pool') + } + }) + + it('should add all the action calls', async () => { + builderParams.context.startSubContext() + + await SparkDepositBorrowActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(3) + + expect(callsBatch[0].name).toBe('SetApproval') + expect(callsBatch[1].name).toBe('SparkDeposit') + expect(callsBatch[2].name).toBe('SparkBorrow') + }) + + it('should not add borrow nor send token when borrow amount is 0', async () => { + builderParams.context.startSubContext() + + await SparkDepositBorrowActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + borrowAmount: TokenAmount.createFrom({ + token: DAI, + amount: '0', + }), + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(2) + + expect(callsBatch[0].name).toBe('SetApproval') + expect(callsBatch[1].name).toBe('SparkDeposit') + }) + + it('should add borrow but not send token when borrow target is positions manager', async () => { + builderParams.context.startSubContext() + + await SparkDepositBorrowActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + borrowTargetType: TokenTransferTargetType.PositionsManager, + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(3) + + expect(callsBatch[0].name).toBe('SetApproval') + expect(callsBatch[1].name).toBe('SparkDeposit') + expect(callsBatch[2].name).toBe('SparkBorrow') + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/builders/spark/SparkOpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/spark/SparkOpenPositionActionBuilder.spec.ts new file mode 100644 index 0000000000..23744076fb --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/builders/spark/SparkOpenPositionActionBuilder.spec.ts @@ -0,0 +1,151 @@ +import { + Address, + ChainFamilyMap, + ChainInfo, + PositionType, + Token, + TokenAmount, +} from '@summerfi/sdk-common/common' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SetupBuilderReturnType, setupBuilderParams } from '../../../utils/SetupBuilderParams' +import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { getErrorMessage } from '@summerfi/testing-utils' +import assert from 'assert' +import { + EmodeType, + ILKType, + MakerLendingPool, + MakerLendingPoolId, + MakerPositionId, + MakerProtocol, + SparkLendingPool, + SparkLendingPoolId, + SparkOpenPositionActionBuilder, + SparkPosition, + SparkProtocol, +} from '../../../../src' + +describe('Spark Deposit Borrow Action Builder', () => { + let builderParams: SetupBuilderReturnType + + const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet + + // Tokens + const WETH = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + }) + + const DAI = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + }) + + const depositAmount = TokenAmount.createFrom({ + token: WETH, + amount: '134.5', + }) + + const borrowAmount = TokenAmount.createFrom({ + token: DAI, + amount: '1000', + }) + + const protocol = SparkProtocol.createFrom({ + name: ProtocolName.Spark, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + const poolId = SparkLendingPoolId.createFrom({ + protocol: protocol, + collateralToken: WETH, + debtToken: DAI, + emodeType: EmodeType.None, + }) + + const pool = SparkLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: poolId, + type: PoolType.Lending, + }) + + const position = SparkPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: borrowAmount, + collateralAmount: depositAmount, + pool: pool, + }) + + const wrongPool = MakerLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: MakerLendingPoolId.createFrom({ + collateralToken: WETH, + debtToken: DAI, + protocol: MakerProtocol.createFrom({ + name: ProtocolName.Maker, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }), + ilkType: ILKType.ETH_A, + }), + type: PoolType.Lending, + }) + + const derivedStep: steps.OpenPosition = { + type: SimulationSteps.OpenPosition, + name: 'OpenPosition', + inputs: { + pool: pool, + }, + outputs: { + position: position, + }, + } + + beforeEach(() => { + builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) + }) + + it('should fail the position is not a Spark one', async () => { + try { + await SparkOpenPositionActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + pool: wrongPool, + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('Invalid Spark lending pool') + } + }) + + it('should add all the action calls', async () => { + builderParams.context.startSubContext() + + await SparkOpenPositionActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(1) + + expect(callsBatch[0].name).toBe('SparkSetEMode') + }) +}) diff --git a/sdk/protocol-plugins/tests/unit/builders/spark/SparkPaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/spark/SparkPaybackWithdrawActionBuilder.spec.ts new file mode 100644 index 0000000000..e39cd39f08 --- /dev/null +++ b/sdk/protocol-plugins/tests/unit/builders/spark/SparkPaybackWithdrawActionBuilder.spec.ts @@ -0,0 +1,189 @@ +import { + Address, + ChainFamilyMap, + ChainInfo, + PositionType, + Token, + TokenAmount, +} from '@summerfi/sdk-common/common' +import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SetupBuilderReturnType, setupBuilderParams } from '../../../utils/SetupBuilderParams' +import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' +import { getErrorMessage } from '@summerfi/testing-utils' +import assert from 'assert' +import { + EmodeType, + ILKType, + MakerLendingPool, + MakerLendingPoolId, + MakerPosition, + MakerPositionId, + MakerProtocol, + SparkLendingPool, + SparkLendingPoolId, + SparkPosition, + SparkProtocol, +} from '../../../../src' +import { SparkPaybackWithdrawActionBuilder } from '../../../../src/' + +describe('Spark Payback Withdraw Action Builder', () => { + let builderParams: SetupBuilderReturnType + + const chainInfo: ChainInfo = ChainFamilyMap.Ethereum.Mainnet + + // Tokens + const WETH = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }), + symbol: 'WETH', + name: 'Wrapped Ether', + decimals: 18, + }) + + const DAI = Token.createFrom({ + chainInfo, + address: Address.createFromEthereum({ value: '0x6B175474E89094C44Da98b954EedeAC495271d0F' }), + symbol: 'DAI', + name: 'Dai Stablecoin', + decimals: 18, + }) + + const paybackAmount = TokenAmount.createFrom({ + token: WETH, + amount: '134.5', + }) + + const withdrawAmount = TokenAmount.createFrom({ + token: DAI, + amount: '1000', + }) + + const protocol = SparkProtocol.createFrom({ + name: ProtocolName.Spark, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + const poolId = SparkLendingPoolId.createFrom({ + protocol: protocol, + collateralToken: WETH, + debtToken: DAI, + emodeType: EmodeType.None, + }) + + const pool = SparkLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: poolId, + type: PoolType.Lending, + }) + + const position = SparkPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: withdrawAmount, + collateralAmount: paybackAmount, + pool: pool, + }) + + const wrongPosition = MakerPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: 'someposition', vaultId: '123' }), + debtAmount: withdrawAmount, + collateralAmount: paybackAmount, + pool: MakerLendingPool.createFrom({ + collateralToken: WETH, + debtToken: DAI, + id: MakerLendingPoolId.createFrom({ + collateralToken: WETH, + debtToken: DAI, + protocol: MakerProtocol.createFrom({ + name: ProtocolName.Maker, + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }), + ilkType: ILKType.ETH_A, + }), + type: PoolType.Lending, + }), + }) + + const derivedStep: steps.PaybackWithdrawStep = { + type: SimulationSteps.PaybackWithdraw, + name: 'PaybackWithdrawStep', + inputs: { + paybackAmount: paybackAmount, + withdrawAmount: withdrawAmount, + position: position, + withdrawTargetType: TokenTransferTargetType.PositionsManager, + }, + outputs: { + paybackAmount: paybackAmount, + withdrawAmount: withdrawAmount, + }, + } + + beforeEach(() => { + builderParams = setupBuilderParams({ chainInfo: ChainFamilyMap.Ethereum.Mainnet }) + }) + + it('should fail the position is not a Spark one', async () => { + try { + await SparkPaybackWithdrawActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + position: wrongPosition, + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + assert.fail('Should have thrown an error') + } catch (error: unknown) { + expect(getErrorMessage(error)).toEqual('Invalid Spark lending pool') + } + }) + + it('should add all the action calls', async () => { + builderParams.context.startSubContext() + + await SparkPaybackWithdrawActionBuilder({ + ...builderParams, + step: derivedStep, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(3) + + expect(callsBatch[0].name).toBe('SetApproval') + expect(callsBatch[1].name).toBe('SparkPayback') + expect(callsBatch[2].name).toBe('SparkWithdraw') + }) + + it('should not add payback when payback amount is 0', async () => { + builderParams.context.startSubContext() + + await SparkPaybackWithdrawActionBuilder({ + ...builderParams, + step: { + ...derivedStep, + inputs: { + ...derivedStep.inputs, + paybackAmount: TokenAmount.createFrom({ + token: DAI, + amount: '0', + }), + }, + }, + protocolsRegistry: builderParams.emptyProtocolsRegistry, + }) + + const { callsBatch } = builderParams.context.endSubContext() + + expect(callsBatch.length).toEqual(1) + + expect(callsBatch[0].name).toBe('SparkWithdraw') + }) +}) diff --git a/sdk/protocol-plugins/tests/utils/ProtocolPluginMock.ts b/sdk/protocol-plugins/tests/utils/ProtocolPluginMock.ts index d62495b08b..7866c2bc6f 100644 --- a/sdk/protocol-plugins/tests/utils/ProtocolPluginMock.ts +++ b/sdk/protocol-plugins/tests/utils/ProtocolPluginMock.ts @@ -34,6 +34,18 @@ export const DepositBorrowActionBuilderMock: ActionBuilder = async ( + params, +): Promise => { + ;(params.context as StepBuilderContextMock).setCheckpoint('ImportPositionActionBuilderMock') +} + +export const OpenPositionActionBuilderMock: ActionBuilder = async ( + params, +): Promise => { + ;(params.context as StepBuilderContextMock).setCheckpoint('OpenPositionActionBuilderMock') +} + export const PaybackWithdrawActionBuilderNoCheckpointMock: ActionBuilder< steps.PaybackWithdrawStep > = async (params): Promise => {} @@ -42,12 +54,22 @@ export const DepositBorrowActionBuilderNoCheckpointMock: ActionBuilder< steps.DepositBorrowStep > = async (params): Promise => {} +export const ImportPositionActionBuilderNoCheckpointMock: ActionBuilder = async ( + params, +): Promise => {} + +export const OpenPositionActionBuilderNoCheckpointMock: ActionBuilder = async ( + params, +): Promise => {} + export class ProtocolPluginMock implements IProtocolPlugin { protocolName = ProtocolName.Spark supportedChains = [ChainFamilyMap.Ethereum.Mainnet] stepBuilders: Partial = { [SimulationSteps.PaybackWithdraw]: PaybackWithdrawActionBuilderMock, [SimulationSteps.DepositBorrow]: DepositBorrowActionBuilderMock, + [SimulationSteps.Import]: ImportPositionActionBuilderMock, + [SimulationSteps.OpenPosition]: OpenPositionActionBuilderMock, } context = undefined as unknown as IProtocolPluginContext @@ -78,7 +100,7 @@ export class ProtocolPluginMock implements IProtocolPlugin { externalPosition: IExternalPosition positionsManager: IPositionsManager }): Promise> { - return undefined as unknown as TransactionInfo + return {} as unknown as TransactionInfo } } @@ -125,6 +147,8 @@ export class NoCheckpointProtocolPluginMock implements IProtocolPlugin { stepBuilders: Partial = { [SimulationSteps.PaybackWithdraw]: PaybackWithdrawActionBuilderNoCheckpointMock, [SimulationSteps.DepositBorrow]: DepositBorrowActionBuilderNoCheckpointMock, + [SimulationSteps.Import]: ImportPositionActionBuilderNoCheckpointMock, + [SimulationSteps.OpenPosition]: OpenPositionActionBuilderNoCheckpointMock, } context = undefined as unknown as IProtocolPluginContext diff --git a/sdk/protocol-plugins/tests/utils/ProtocolsPluginRegistryMock.ts b/sdk/protocol-plugins/tests/utils/ProtocolsPluginRegistryMock.ts index 602753295c..bb76e24605 100644 --- a/sdk/protocol-plugins/tests/utils/ProtocolsPluginRegistryMock.ts +++ b/sdk/protocol-plugins/tests/utils/ProtocolsPluginRegistryMock.ts @@ -30,7 +30,9 @@ export function createProtocolPluginsRegistry(): IProtocolPluginsRegistry { return new ProtocolPluginsRegistry({ plugins: { [ProtocolName.Maker]: ProtocolPluginMock, + [ProtocolName.AAVEv3]: ProtocolPluginMock, [ProtocolName.Spark]: ProtocolPluginMock, + [ProtocolName.Morpho]: ProtocolPluginMock, }, context: protocolPluginContext, }) diff --git a/sdk/sdk-common/src/common/utils/PositionUtils.ts b/sdk/sdk-common/src/common/utils/PositionUtils.ts index eafc93d1b6..591e3d515c 100644 --- a/sdk/sdk-common/src/common/utils/PositionUtils.ts +++ b/sdk/sdk-common/src/common/utils/PositionUtils.ts @@ -6,6 +6,7 @@ import { IPosition } from '../interfaces/IPosition' import { ITokenAmount } from '../interfaces/ITokenAmount' // TODO: add a proper internal position type only used by the simulator that can be instantiated +// TODO implement Simulated position export function newEmptyPositionFromPool(pool: ILendingPoolData): IPosition { return { diff --git a/sdk/sdk-common/src/common/utils/index.ts b/sdk/sdk-common/src/common/utils/index.ts index 2cf60dfb23..197f3a6693 100644 --- a/sdk/sdk-common/src/common/utils/index.ts +++ b/sdk/sdk-common/src/common/utils/index.ts @@ -1 +1,3 @@ export * from './PositionUtils' +export * from './PercentageUtils' +export * from './PriceUtils' diff --git a/sdk/sdk-common/src/simulation/Enums.ts b/sdk/sdk-common/src/simulation/Enums.ts index e0dba82680..72e9232d8f 100644 --- a/sdk/sdk-common/src/simulation/Enums.ts +++ b/sdk/sdk-common/src/simulation/Enums.ts @@ -24,6 +24,7 @@ export enum SimulationSteps { RepayFlashloan = 'RepayFlashloan', Import = 'Import', NewPositionEvent = 'NewPositionEvent', + OpenPosition = 'OpenPosition', } export enum FlashloanProvider { diff --git a/sdk/sdk-common/src/simulation/SimulationStrategy.ts b/sdk/sdk-common/src/simulation/SimulationStrategy.ts index 3ae319d905..5f0164580d 100644 --- a/sdk/sdk-common/src/simulation/SimulationStrategy.ts +++ b/sdk/sdk-common/src/simulation/SimulationStrategy.ts @@ -1,6 +1,7 @@ import type { SimulationSteps } from './Enums' export interface StrategyStep { + name: string step: SimulationSteps optional: boolean } diff --git a/sdk/sdk-common/src/simulation/Steps.ts b/sdk/sdk-common/src/simulation/Steps.ts index b4a08f1394..a0092b1e62 100644 --- a/sdk/sdk-common/src/simulation/Steps.ts +++ b/sdk/sdk-common/src/simulation/Steps.ts @@ -7,10 +7,11 @@ import { ITokenAmount } from '../common/interfaces/ITokenAmount' import { IPrice } from '../common/interfaces/IPrice' import { IPosition } from '../common/interfaces/IPosition' import { IToken } from '../common/interfaces/IToken' +import { ILendingPool } from '../protocols/interfaces/ILendingPool' -export interface Step { +export interface Step { type: T - name: N + name: string inputs: I outputs: O skip?: boolean @@ -51,6 +52,7 @@ export interface PaybackWithdrawStep paybackAmount: ReferenceableField withdrawAmount: ITokenAmount position: IPosition + withdrawTargetType: TokenTransferTargetType }, { paybackAmount: ITokenAmount @@ -108,6 +110,9 @@ export interface NewPositionEventStep export interface ImportStep extends Step {} +export interface OpenPosition + extends Step {} + export type Steps = | FlashloanStep | PullTokenStep @@ -118,3 +123,4 @@ export type Steps = | RepayFlashloanStep | NewPositionEventStep | ImportStep + | OpenPosition diff --git a/sdk/sdk-e2e/tests/refinance.test.ts b/sdk/sdk-e2e/tests/refinance.test.ts new file mode 100644 index 0000000000..41aa6a2611 --- /dev/null +++ b/sdk/sdk-e2e/tests/refinance.test.ts @@ -0,0 +1,213 @@ +import { + Percentage, + Token, + TokenAmount, + Address, + type Maybe, + ChainFamilyMap, + PositionType, +} from '@summerfi/sdk-common/common' + +import { ProtocolName, isLendingPool } from '@summerfi/sdk-common/protocols' +import { ProtocolClient, makeSDK, type Chain, type User } from '@summerfi/sdk-client' +import { PositionsManager, IRefinanceParameters, Order } from '@summerfi/sdk-common/orders' +import { ISimulation } from '@summerfi/sdk-common/simulation' +import { TransactionUtils } from './utils/TransactionUtils' + +import { Hex } from 'viem' +import assert from 'assert' +import { EmodeType } from '@summerfi/protocol-plugins/plugins/common' +import { AddressValue, CommonTokenSymbols, RefinanceSimulationTypes } from '@summerfi/sdk-common' +import { + SparkLendingPoolId, + isSparkLendingPoolId, + isSparkProtocol, +} from '@summerfi/protocol-plugins/plugins/spark' +import { + ILKType, + MakerLendingPoolId, + MakerPosition, + MakerPositionId, + isMakerLendingPool, + isMakerProtocol, +} from '@summerfi/protocol-plugins/plugins/maker' + +jest.setTimeout(300000) + +/** TEST CONFIG */ +const config = { + SDKAPiUrl: 'https://nkllstfoy8.execute-api.us-east-1.amazonaws.com/api/sdk', + TenderlyForkUrl: 'https://virtual.mainnet.rpc.tenderly.co/5a4e0cc3-48d2-4819-8426-068f029b23be', + makerVaultId: '31709', + DPMAddress: '0xc1475b2735fb9130a4701ee9e2215b6305dd501b', + walletAddress: '0x34314adbfBb5d239bb67f0265c9c45EB8b834412', + collateralAmount: '5000.0', + debtAmount: '5000000.0', +} + +describe.skip('Refinance All | SDK', () => { + it('should allow refinance Maker -> Spark with same pair', async () => { + // SDK + const sdk = makeSDK({ apiURL: config.SDKAPiUrl }) + + // Chain + const chain: Maybe = await sdk.chains.getChain({ + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + assert(chain, 'Chain not found') + + // User + const walletAddress = Address.createFromEthereum({ + value: config.walletAddress as AddressValue, + }) + const user: User = await sdk.users.getUser({ + chainInfo: chain.chainInfo, + walletAddress: walletAddress, + }) + expect(user).toBeDefined() + expect(user.wallet.address).toEqual(walletAddress) + expect(user.chainInfo).toEqual(chain.chainInfo) + + // Positions Manager + const positionsManager = PositionsManager.createFrom({ + address: Address.createFromEthereum({ + value: config.DPMAddress as AddressValue, + }), + }) + + // Tokens + const WETH: Maybe = await chain.tokens.getTokenBySymbol({ + symbol: CommonTokenSymbols.WETH, + }) + assert(WETH, 'WETH not found') + + const DAI: Maybe = await chain.tokens.getTokenBySymbol({ + symbol: CommonTokenSymbols.DAI, + }) + assert(DAI, 'DAI not found') + + const USDC: Maybe = await chain.tokens.getTokenBySymbol({ + symbol: CommonTokenSymbols.USDC, + }) + assert(USDC, 'USDC not found') + + const WBTC: Maybe = await chain.tokens.getTokenBySymbol({ + symbol: CommonTokenSymbols.WBTC, + }) + assert(WBTC, 'WBTC not found') + + const WSTETH: Maybe = await chain.tokens.getTokenBySymbol({ + symbol: CommonTokenSymbols.wstETH, + }) + assert(WSTETH, 'WSTETH not found') + + const SDAI: Maybe = await chain.tokens.getTokenBySymbol({ + symbol: CommonTokenSymbols.sDAI, + }) + assert(SDAI, 'WSTETH not found') + + const maker = await chain.protocols.getProtocol({ name: ProtocolName.Maker }) + assert(maker, 'Maker protocol not found') + + if (!isMakerProtocol(maker)) { + assert(false, 'Maker protocol type is not lending') + } + + const makerPoolId = MakerLendingPoolId.createFrom({ + protocol: maker, + debtToken: DAI, + collateralToken: WETH, + ilkType: ILKType.ETH_C, + }) + + const makerPool = await maker.getLendingPool({ + poolId: makerPoolId, + }) + assert(makerPool, 'Maker pool not found') + + if (!isMakerLendingPool(makerPool)) { + assert(false, 'Maker pool type is not lending') + } + + // Source position + const makerPosition: MakerPosition = MakerPosition.createFrom({ + type: PositionType.Multiply, + id: MakerPositionId.createFrom({ id: '31697', vaultId: '31697' }), + debtAmount: TokenAmount.createFrom({ + token: DAI, + amount: config.debtAmount, + }), + collateralAmount: TokenAmount.createFrom({ + token: WETH, + amount: config.collateralAmount, + }), + pool: makerPool, + }) + + // Target protocol + const spark: Maybe = await chain.protocols.getProtocol({ + name: ProtocolName.Spark, + }) + assert(spark, 'Spark not found') + + if (!isSparkProtocol(spark)) { + assert(false, 'Protocol type is not Spark') + } + + const poolId = SparkLendingPoolId.createFrom({ + protocol: spark, + collateralToken: WETH, + debtToken: DAI, + emodeType: EmodeType.None, + }) + + const sparkPool = await spark.getLendingPool({ + poolId, + }) + + assert(sparkPool, 'Pool not found') + + if (!isSparkLendingPoolId(sparkPool.id)) { + assert(false, 'Pool ID is not a Spark one') + } + + if (!isLendingPool(sparkPool)) { + assert(false, 'Spark pool type is not lending') + } + + const refinanceSimulation: ISimulation = + await sdk.simulator.refinance.simulateRefinancePosition({ + sourcePosition: makerPosition, + targetPool: sparkPool, + slippage: Percentage.createFrom({ value: 0.2 }), + } as IRefinanceParameters) + + expect(refinanceSimulation).toBeDefined() + + expect(refinanceSimulation.sourcePosition?.id).toEqual(makerPosition.id) + expect(refinanceSimulation.targetPosition.pool.id).toEqual(sparkPool.id) + + const refinanceOrder: Maybe = await user.newOrder({ + positionsManager, + simulation: refinanceSimulation, + }) + + assert(refinanceOrder, 'Order not found') + + // Send transaction + console.log('Sending transaction...') + + const privateKey = process.env.DEPLOYER_PRIVATE_KEY as Hex + const transactionUtils = new TransactionUtils({ + rpcUrl: config.TenderlyForkUrl, + walletPrivateKey: privateKey, + }) + + const receipt = await transactionUtils.sendTransaction({ + transaction: refinanceOrder.transactions[0].transaction, + }) + + console.log('Transaction sent:', receipt) + }) +}) diff --git a/sdk/sdk-e2e/tests/refinanceAaveV3SparkAnyPair.test.ts b/sdk/sdk-e2e/tests/refinanceAaveV3SparkAnyPair.test.ts new file mode 100644 index 0000000000..53b6aa0112 --- /dev/null +++ b/sdk/sdk-e2e/tests/refinanceAaveV3SparkAnyPair.test.ts @@ -0,0 +1,201 @@ +import { ProtocolClient, makeSDK, type Chain, type User } from '@summerfi/sdk-client' +import { ProtocolName, isLendingPool } from '@summerfi/sdk-common/protocols' +import { EmodeType } from '@summerfi/protocol-plugins/plugins/common' +import { + AddressValue, + CommonTokenSymbols, + RefinanceSimulationTypes, + ISimulation, + Percentage, + TokenAmount, + Address, + type Maybe, + ChainFamilyMap, + PositionType, + IToken, +} from '@summerfi/sdk-common' +import { PositionsManager, Order, RefinanceParameters } from '@summerfi/sdk-common/orders' +import { + SparkLendingPoolId, + isSparkLendingPoolId, + isSparkProtocol, +} from '@summerfi/protocol-plugins/plugins/spark' + +import assert from 'assert' +import { TransactionUtils } from './utils/TransactionUtils' +import { Hex } from 'viem' +import { + AaveV3LendingPoolId, + AaveV3Position, + AaveV3PositionId, + isAaveV3LendingPool, + isAaveV3Protocol, +} from '@summerfi/protocol-plugins' + +jest.setTimeout(300000) + +/** TEST CONFIG */ +const config = { + SDKAPiUrl: 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sdk', + TenderlyForkUrl: 'https://virtual.mainnet.rpc.tenderly.co/cc7432cd-f037-4aa8-a05f-ae6d8cefba39', + DPMAddress: '0x551eb8395093fde4b9eef017c93593a3c7a75138', + walletAddress: '0xbEf4befb4F230F43905313077e3824d7386E09F8', + collateralTokenSymbol: CommonTokenSymbols.WETH, + collateralAmount: '0.0198', + debtTokenSymbol: CommonTokenSymbols.DAI, + debtAmount: '26', + sendTransactionEnabled: true, +} + +describe.skip('Refinance AaveV3 Spark | SDK', () => { + it('should allow refinance Maker -> Spark with same pair', async () => { + // SDK + const sdk = makeSDK({ apiURL: config.SDKAPiUrl }) + + // Chain + const chain: Maybe = await sdk.chains.getChain({ + chainInfo: ChainFamilyMap.Ethereum.Mainnet, + }) + + assert(chain, 'Chain not found') + + // User + const walletAddress = Address.createFromEthereum({ + value: config.walletAddress as AddressValue, + }) + const user: User = await sdk.users.getUser({ + chainInfo: chain.chainInfo, + walletAddress: walletAddress, + }) + expect(user).toBeDefined() + expect(user.wallet.address).toEqual(walletAddress) + expect(user.chainInfo).toEqual(chain.chainInfo) + + // Positions Manager + const positionsManager = PositionsManager.createFrom({ + address: Address.createFromEthereum({ + value: config.DPMAddress as AddressValue, + }), + }) + + // Tokens + const debtToken: Maybe = await chain.tokens.getTokenBySymbol({ + symbol: config.debtTokenSymbol, + }) + assert(debtToken, `${config.debtTokenSymbol} not found`) + + const collateralToken: Maybe = await chain.tokens.getTokenBySymbol({ + symbol: config.collateralTokenSymbol, + }) + assert(collateralToken, `${config.collateralTokenSymbol} not found`) + + const aaveV3 = await chain.protocols.getProtocol({ name: ProtocolName.AAVEv3 }) + assert(aaveV3, 'AaveV3 protocol not found') + + if (!isAaveV3Protocol(aaveV3)) { + assert(false, 'AaveV3 protocol type is not lending') + } + + const aaveV3PoolId = AaveV3LendingPoolId.createFrom({ + protocol: aaveV3, + collateralToken: collateralToken, + debtToken: debtToken, + emodeType: EmodeType.None, + }) + + const aaveV3Pool = await aaveV3.getLendingPool({ + poolId: aaveV3PoolId, + }) + assert(aaveV3Pool, 'AaveV3 pool not found') + + if (!isAaveV3LendingPool(aaveV3Pool)) { + assert(false, 'AaveV3 pool type is not lending') + } + + // Source position + const morphoPosition = AaveV3Position.createFrom({ + type: PositionType.Multiply, + id: AaveV3PositionId.createFrom({ + id: 'AaveV3Position', + }), + debtAmount: TokenAmount.createFrom({ + token: debtToken, + amount: config.debtAmount, + }), + collateralAmount: TokenAmount.createFrom({ + token: collateralToken, + amount: config.collateralAmount, + }), + pool: aaveV3Pool, + }) + + // Target protocol + const spark: Maybe = await chain.protocols.getProtocol({ + name: ProtocolName.Spark, + }) + assert(spark, 'Spark not found') + + if (!isSparkProtocol(spark)) { + assert(false, 'Protocol type is not Spark') + } + + const poolId = SparkLendingPoolId.createFrom({ + protocol: spark, + collateralToken: collateralToken, + debtToken: debtToken, + emodeType: EmodeType.None, + }) + + const sparkPool = await spark.getLendingPool({ + poolId, + }) + + assert(sparkPool, 'Pool not found') + + if (!isSparkLendingPoolId(sparkPool.id)) { + assert(false, 'Pool ID is not a Spark one') + } + + if (!isLendingPool(sparkPool)) { + assert(false, 'Spark pool type is not lending') + } + + const refinanceParameters = RefinanceParameters.createFrom({ + sourcePosition: morphoPosition, + targetPool: sparkPool, + slippage: Percentage.createFrom({ value: 0.2 }), + }) + + const refinanceSimulation: ISimulation = + await sdk.simulator.refinance.simulateRefinancePosition(refinanceParameters) + + expect(refinanceSimulation).toBeDefined() + + expect(refinanceSimulation.sourcePosition?.id).toEqual(morphoPosition.id) + expect(refinanceSimulation.targetPosition.pool.id).toEqual(sparkPool.id) + + const refinanceOrder: Maybe = await user.newOrder({ + positionsManager, + simulation: refinanceSimulation, + }) + + assert(refinanceOrder, 'Order not found') + + // Send transaction + console.log('Sending transaction...') + + if (config.sendTransactionEnabled) { + const privateKey = process.env.DEPLOYER_PRIVATE_KEY as Hex + const transactionUtils = new TransactionUtils({ + rpcUrl: config.TenderlyForkUrl, + walletPrivateKey: privateKey, + }) + + const receipt = await transactionUtils.sendTransaction({ + transaction: refinanceOrder.transactions[0].transaction, + }) + + console.log('Transaction sent:', receipt) + } + }) +}) diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/depositBorrowReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/depositBorrowReducer.ts index a4968649e8..a5318f0830 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/depositBorrowReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/depositBorrowReducer.ts @@ -1,31 +1,27 @@ import { borrowFromPosition, depositToPosition } from '@summerfi/sdk-common/common/utils' import { steps } from '@summerfi/sdk-common/simulation' -import { addBalance, subtractBalance, getReferencedValue } from '../../utils' +import { addBalance, subtractBalance, getValueFromReference } from '../../utils' import { ISimulationState } from '../../../interfaces/simulation' export function depositBorrowReducer( step: steps.DepositBorrowStep, state: ISimulationState, ): ISimulationState { - const afterDeposit = subtractBalance( - getReferencedValue(step.inputs.depositAmount), - state.balances, - ) - const afterBorrow = addBalance(getReferencedValue(step.inputs.borrowAmount), afterDeposit) + const depositAmount = getValueFromReference(step.inputs.depositAmount) + const borrowAmount = getValueFromReference(step.inputs.borrowAmount) + const afterDeposit = subtractBalance(depositAmount, state.balances) + const afterBorrow = addBalance(borrowAmount, afterDeposit) return { ...state, positions: { ...state.positions, [step.inputs.position.id.id]: borrowFromPosition( - depositToPosition(step.inputs.position, getReferencedValue(step.inputs.depositAmount)), - getReferencedValue(step.inputs.borrowAmount), + depositToPosition(step.inputs.position, depositAmount), + borrowAmount, ), }, - steps: { - ...state.steps, - [step.name]: step, - }, + steps: [...state.steps, step], balances: afterBorrow, } } diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/flashloanReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/flashloanReducer.ts index 50ca342708..8f5d9556e3 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/flashloanReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/flashloanReducer.ts @@ -8,10 +8,7 @@ export function flashloanReducer( ): ISimulationState { return { ...state, - steps: { - ...state.steps, - [step.name]: step, - }, + steps: [...state.steps, step], balances: addBalance(step.inputs.amount, state.balances), } } diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts index 78c5a18b3f..995f5720e6 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/importReducer.ts @@ -4,9 +4,6 @@ import { ISimulationState } from '../../../interfaces/simulation' export function importReducer(step: steps.ImportStep, state: ISimulationState): ISimulationState { return { ...state, - steps: { - ...state.steps, - [step.name]: step, - }, + steps: [...state.steps, step], } } diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts index 84df627a03..e178e5e430 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/newPositionEventReducer.ts @@ -7,9 +7,6 @@ export function newPositionEventReducer( ): ISimulationState { return { ...state, - steps: { - ...state.steps, - [step.name]: step, - }, + steps: [...state.steps, step], } } diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/openPositionReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/openPositionReducer.ts new file mode 100644 index 0000000000..95fa3b323e --- /dev/null +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/openPositionReducer.ts @@ -0,0 +1,16 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import { ISimulationState } from '../../../interfaces/simulation' + +export function openPositionReducer( + step: steps.OpenPosition, + state: ISimulationState, +): ISimulationState { + return { + ...state, + positions: { + ...state.positions, + [step.outputs.position.id.id]: step.outputs.position, + }, + steps: [...state.steps, step], + } +} diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/paybackWithdrawReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/paybackWithdrawReducer.ts index 16605be8f8..fc4d4ac80b 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/paybackWithdrawReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/paybackWithdrawReducer.ts @@ -1,30 +1,25 @@ import { depositToPosition } from '@summerfi/sdk-common/common/utils' import { steps } from '@summerfi/sdk-common/simulation' -import { addBalance, getReferencedValue, subtractBalance } from '../../utils' +import { addBalance, getValueFromReference, subtractBalance } from '../../utils' import { ISimulationState } from '../../../interfaces/simulation' export function paybackWithdrawReducer( step: steps.PaybackWithdrawStep, state: ISimulationState, ): ISimulationState { - const afterPayback = addBalance(getReferencedValue(step.inputs.paybackAmount), state.balances) + const withdrawAmount = getValueFromReference(step.inputs.withdrawAmount) + const afterPayback = addBalance(withdrawAmount, state.balances) const afterWithdraw = subtractBalance( - getReferencedValue(step.inputs.withdrawAmount), + getValueFromReference(step.inputs.withdrawAmount), afterPayback, ) return { ...state, positions: { ...state.positions, - [step.inputs.position.id.id]: depositToPosition( - step.inputs.position, - getReferencedValue(step.inputs.withdrawAmount), - ), - }, - steps: { - ...state.steps, - [step.name]: step, + [step.inputs.position.id.id]: depositToPosition(step.inputs.position, withdrawAmount), }, + steps: [...state.steps, step], balances: afterWithdraw, } } diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/pullTokenReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/pullTokenReducer.ts index 493d13a83f..e45b8e8537 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/pullTokenReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/pullTokenReducer.ts @@ -1,5 +1,5 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { addBalance, getReferencedValue } from '../../utils' +import { addBalance, getValueFromReference } from '../../utils' import { ISimulationState } from '../../../interfaces/simulation' export function pullTokenReducer( @@ -8,10 +8,7 @@ export function pullTokenReducer( ): ISimulationState { return { ...state, - steps: { - ...state.steps, - [step.name]: step, - }, - balances: addBalance(getReferencedValue(step.inputs.amount), state.balances), + steps: [...state.steps, step], + balances: addBalance(getValueFromReference(step.inputs.amount), state.balances), } } diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/repayFlashloanReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/repayFlashloanReducer.ts index 70a196865d..46e25d2e60 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/repayFlashloanReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/repayFlashloanReducer.ts @@ -8,10 +8,7 @@ export function repayFlashloanReducer( ): ISimulationState { return { ...state, - steps: { - ...state.steps, - [step.name]: step, - }, + steps: [...state.steps, step], balances: subtractBalance(step.inputs.amount, state.balances), } } diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/returnFundsReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/returnFundsReducer.ts index c37f52b471..9e95daa527 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/returnFundsReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/returnFundsReducer.ts @@ -8,10 +8,7 @@ export function returnFundsReducer( ): ISimulationState { return { ...state, - steps: { - ...state.steps, - [step.name]: step, - }, + steps: [...state.steps, step], balances: subtractBalance(getTokenBalance(step.inputs.token, state.balances), state.balances), } } diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts index 571dcbde41..daef596a5a 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts @@ -10,6 +10,7 @@ import { repayFlashloanReducer } from './repayFlashloanReducer' import { pullTokenReducer } from './pullTokenReducer' import { importReducer } from './importReducer' import { newPositionEventReducer } from './newPositionEventReducer' +import { openPositionReducer } from './openPositionReducer' const stateReducers: StateReducers = { [SimulationSteps.Flashloan]: flashloanReducer, @@ -21,6 +22,7 @@ const stateReducers: StateReducers = { [SimulationSteps.PullToken]: pullTokenReducer, [SimulationSteps.Import]: importReducer, [SimulationSteps.NewPositionEvent]: newPositionEventReducer, + [SimulationSteps.OpenPosition]: openPositionReducer, } export function stateReducer(step: steps.Steps, state: ISimulationState): ISimulationState { diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/swapReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/swapReducer.ts index de2fd80747..fdb87c4b94 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/swapReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/swapReducer.ts @@ -12,13 +12,10 @@ export function swapReducer(step: steps.SwapStep, state: ISimulationState): ISim return { ...state, - steps: { - ...state.steps, - [step.name]: step, - }, - swaps: { + steps: [...state.steps, step], + swaps: [ ...state.swaps, - [step.name]: { + { provider: step.inputs.provider, // Note: Can add routes back in later if we need them for the UI // routes: step.inputs.routes, @@ -35,7 +32,7 @@ export function swapReducer(step: steps.SwapStep, state: ISimulationState): ISim amount: fromAmountPreSummerFee.multiply(step.inputs.summerFee.toProportion()).amount, }), }, - }, + ], balances: balanceWithToToken, } } diff --git a/sdk/simulator-service/src/implementation/simulator-engine/simulator.ts b/sdk/simulator-service/src/implementation/simulator-engine/simulator.ts index 7bc78377a8..74899968d5 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/simulator.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/simulator.ts @@ -1,27 +1,30 @@ import type { ISimulationState } from '../../interfaces/simulation' import type { Tail } from '../../interfaces/helperTypes' -import type { NextFunction } from '../../interfaces' import { head, tail } from '../utils' import { processStepOutput } from './stepProcessor/stepOutputProcessors' import { stateReducer } from './reducer/stateReducers' import type { SimulationStrategy } from '@summerfi/sdk-common/simulation' import { steps } from '@summerfi/sdk-common/simulation' -import { Maybe } from '@summerfi/sdk-common/common' - -export class Simulator< - Strategy extends SimulationStrategy, - NextArray extends NextFunction[] = [], -> { +import { Maybe } from '@summerfi/sdk-common' +import { + GetReferencedValue, + NextFunction, + Paths, + ProccessedStep, + StepsAdded, +} from '../../interfaces/steps' + +export class Simulator { public schema: Strategy public originalSchema: SimulationStrategy private state: ISimulationState - private readonly nextArray: NextArray + private readonly nextArray: Readonly[]> private constructor( schema: Strategy, originalSchema: SimulationStrategy, - state: ISimulationState = { swaps: {}, balances: {}, positions: {}, steps: {} }, - nextArray: Readonly = [] as unknown as NextArray, + state: ISimulationState = { swaps: [], balances: {}, positions: {}, steps: [] }, + nextArray: Readonly[]> = [], ) { this.schema = schema this.originalSchema = originalSchema @@ -32,71 +35,72 @@ export class Simulator< static create(schema: S) { // The second argument is the same as from the first schema we will subtract steps // with each next step added we also need to keep the original schema for future reference - return new Simulator(schema, schema) + return new Simulator(schema, schema) } - public async run(): Promise { - for (let i = 0; i < this.nextArray.length; i++) { - const getReference = (path: [string, string]) => { - const [stepName, output] = path - const step: Maybe = this.state.steps[stepName] - - if (!step) { - throw new Error( - `Step not found: ${stepName} in ${this.originalSchema[i].step} at iteration ${i}`, - ) - } - - const outputs = step.outputs - - if (!outputs) { - throw new Error(`Step has no outputs: ${stepName} in ${this.originalSchema[i].step}`) - } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const value = (outputs as any)[output] - // validation if path exists - if (!value) { - throw new Error( - `Output not found: ${stepName}.outputs.${output} in ${this.originalSchema[i].step}`, - ) - } - - return { - estimatedValue: value, - path, - } - } + private getReference = (path: Paths) => { + const [stepName, output] = path + const stepNames = this.originalSchema.map((step) => step.name) + const index = stepNames.indexOf(stepName as string) + const step: Maybe = this.state.steps[index] + + if (!step) { + throw new Error(`Step not found: ${stepName}`) + } + + const outputs = step.outputs + + if (!outputs) { + throw new Error(`Step has no outputs: ${stepName}`) + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const value = (outputs as any)[output] + // validation if path exists + if (!value) { + throw new Error(`Output not found: ${stepName}.outputs.${output as string}`) + } - const nextStep = await this.nextArray[i]({ state: this.state, getReference }) + return { + estimatedValue: value, + path, + } + } + + public async run(): Promise }> { + for (let i = 0; i < this.nextArray.length; i++) { + const nextStep = await this.nextArray[i]({ + state: this.state, + getReference: this.getReference as GetReferencedValue, + }) const fullStep = await processStepOutput(nextStep) this.state = stateReducer(fullStep, this.state) } - return this.state + return { ...this.state, getReference: this.getReference as GetReferencedValue } } - public next( - next: NextFunction, + public next( + next: NextFunction, skip?: boolean, - ): - | Simulator, [...NextArray]> - | Simulator, [...NextArray, NextFunction]> { + ): Simulator, [...AddedSteps, ProccessedStep]> { const schemaHead = head(this.schema) const schemaTail = tail(this.schema) - const nextArray = [...this.nextArray, next] as const + const nextArray = [...this.nextArray, next] if (skip) { if (schemaHead.optional === false) { throw new Error(`Step is required: ${schemaHead.step}`) } - return new Simulator, [...NextArray]>( + return new Simulator, [...AddedSteps, ProccessedStep]>( schemaTail, this.originalSchema, this.state, - this.nextArray, + // TODO: We should not use any here + /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ + this.nextArray as any, ) } @@ -104,11 +108,13 @@ export class Simulator< throw new Error('No more steps to process') } - return new Simulator, [...NextArray, NextFunction]>( + return new Simulator, [...AddedSteps, ProccessedStep]>( schemaTail, this.originalSchema, this.state, - nextArray, + // TODO: We should not use any here + /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ + nextArray as any, ) } } diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/depositBorrowOutputProcessor.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/depositBorrowOutputProcessor.ts index 3954fad229..f0e6cd9557 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/depositBorrowOutputProcessor.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/depositBorrowOutputProcessor.ts @@ -1,21 +1,21 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { getReferencedValue } from '../../utils' +import { getValueFromReference } from '../../utils' import type { StepOutputProcessor } from '../../../interfaces/steps' export const depositBorrowOutputProcessor: StepOutputProcessor = async ( step, ) => { const depositAmount = step.inputs.additionalDeposit - ? getReferencedValue(step.inputs.additionalDeposit).add( - getReferencedValue(step.inputs.depositAmount), + ? getValueFromReference(step.inputs.additionalDeposit).add( + getValueFromReference(step.inputs.depositAmount), ) - : getReferencedValue(step.inputs.depositAmount) + : getValueFromReference(step.inputs.depositAmount) return { ...step, outputs: { depositAmount: depositAmount, - borrowAmount: getReferencedValue(step.inputs.borrowAmount), + borrowAmount: getValueFromReference(step.inputs.borrowAmount), }, } } diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/openPositionProcessor.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/openPositionProcessor.ts new file mode 100644 index 0000000000..92193a9fa6 --- /dev/null +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/openPositionProcessor.ts @@ -0,0 +1,12 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import type { StepOutputProcessor } from '../../../interfaces/steps' +import { newEmptyPositionFromPool } from '@summerfi/sdk-common/common/utils' + +export const openPositionProcessor: StepOutputProcessor = async (step) => { + return { + ...step, + outputs: { + position: newEmptyPositionFromPool(step.inputs.pool), + }, + } +} diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/paybackWithdrawOutputProcessor.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/paybackWithdrawOutputProcessor.ts index 404fd7183a..e07a47e71f 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/paybackWithdrawOutputProcessor.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/paybackWithdrawOutputProcessor.ts @@ -1,20 +1,20 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { getReferencedValue } from '../../utils' +import { getValueFromReference } from '../../utils' import type { StepOutputProcessor } from '../../../interfaces/steps' export const paybackWithdrawOutputProcessor: StepOutputProcessor< steps.PaybackWithdrawStep > = async (step) => { const paybackAmount = - getReferencedValue(step.inputs.paybackAmount).amount > step.inputs.position.debtAmount.amount + getValueFromReference(step.inputs.paybackAmount).amount > step.inputs.position.debtAmount.amount ? step.inputs.position.debtAmount - : getReferencedValue(step.inputs.paybackAmount) + : getValueFromReference(step.inputs.paybackAmount) const withdrawAmount = - getReferencedValue(step.inputs.withdrawAmount).amount > + getValueFromReference(step.inputs.withdrawAmount).amount > step.inputs.position.collateralAmount.amount ? step.inputs.position.collateralAmount - : getReferencedValue(step.inputs.withdrawAmount) + : getValueFromReference(step.inputs.withdrawAmount) return { ...step, diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts index f1e3cf94c4..7f175ced45 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts @@ -13,6 +13,7 @@ import { returnFundsOutputProcessor } from './returnFundsOutputProcessor' import { repayFlashloanOutputProcessor } from './repayFlashloanOutputProcessor' import { importPositionProcessor } from './importPositionProcessor' import { newPositionEventProcessor } from './newPositionEvent' +import { openPositionProcessor } from './openPositionProcessor' const stepOutputProcessors: StepOutputProcessors = { [SimulationSteps.Flashloan]: flashloanOutputProcessor, @@ -24,6 +25,7 @@ const stepOutputProcessors: StepOutputProcessors = { [SimulationSteps.PullToken]: pullTokenOutputProcessor, [SimulationSteps.Import]: importPositionProcessor, [SimulationSteps.NewPositionEvent]: newPositionEventProcessor, + [SimulationSteps.OpenPosition]: openPositionProcessor, } export async function processStepOutput(step: StepsWithoutOutputs): Promise { diff --git a/sdk/simulator-service/src/implementation/utils/EstimateSwapFromAmount.ts b/sdk/simulator-service/src/implementation/utils/EstimateSwapFromAmount.ts new file mode 100644 index 0000000000..9cff8ee0ca --- /dev/null +++ b/sdk/simulator-service/src/implementation/utils/EstimateSwapFromAmount.ts @@ -0,0 +1,52 @@ +import { TokenAmount, ITokenAmount, IToken, IPercentage } from '@summerfi/sdk-common/common' +import { ISwapManager } from '@summerfi/swap-common/interfaces' +import { BigNumber } from 'bignumber.js' +import { IOracleManager } from '@summerfi/oracle-common' + +/** + * EstimateTokenAmountAfterSwap + * @description Estimates how much you will recive after swap. + * If target token is the same as source token, we return the same amount. + * When we perform a swap, we need to account for the summer fee, + * and we assume maximum slippage. + */ +export async function estimateSwapFromAmount(params: { + receiveAtLeast: ITokenAmount + fromToken: IToken + slippage: IPercentage + swapManager: ISwapManager + oracleManager: IOracleManager +}): Promise { + const { receiveAtLeast, slippage } = params + + if (receiveAtLeast.token.equals(params.fromToken)) { + return receiveAtLeast + } + + const spotPrice = ( + await params.oracleManager.getSpotPrice({ + baseToken: receiveAtLeast.token, + quoteToken: params.fromToken, + }) + ).price + + const summerFee = await params.swapManager.getSummerFee({ + from: { token: receiveAtLeast.token }, + to: { token: params.fromToken }, + }) + + const ONE = new BigNumber(1) + /* + TargetAmt = SourceAmt * (1 - SummerFee) / (SpotPrice * (1 + Slippage)) + SourceAmt = TargetAmt * SpotPrice * (1 + Slippage) / (1 - SummerFee) + */ + const sourceAmount = receiveAtLeast + .toBN() + .multipliedBy(spotPrice.toBN().times(ONE.plus(slippage.toProportion()))) + .div(ONE.minus(summerFee.toProportion())) + + return TokenAmount.createFrom({ + amount: sourceAmount.toString(), + token: params.fromToken, + }) +} diff --git a/sdk/simulator-service/src/implementation/utils/GetRefinanceSimulationType.ts b/sdk/simulator-service/src/implementation/utils/GetRefinanceSimulationType.ts new file mode 100644 index 0000000000..1f4ba198e9 --- /dev/null +++ b/sdk/simulator-service/src/implementation/utils/GetRefinanceSimulationType.ts @@ -0,0 +1,20 @@ +import { RefinanceSimulationTypes, SimulationType } from '@summerfi/sdk-common/simulation' + +export function getRefinanceSimulationType( + hasCollateralSwap: boolean, + hasDebtSwap: boolean, +): RefinanceSimulationTypes { + if (hasCollateralSwap && hasDebtSwap) { + return SimulationType.RefinanceDifferentPair + } + + if (hasCollateralSwap) { + return SimulationType.RefinanceDifferentCollateral + } + + if (hasDebtSwap) { + return SimulationType.RefinanceDifferentDebt + } + + return SimulationType.Refinance +} diff --git a/sdk/simulator-service/src/implementation/utils/SimulatorUtils.ts b/sdk/simulator-service/src/implementation/utils/SimulatorUtils.ts index 6d663a9f0c..42a13c2c91 100644 --- a/sdk/simulator-service/src/implementation/utils/SimulatorUtils.ts +++ b/sdk/simulator-service/src/implementation/utils/SimulatorUtils.ts @@ -5,7 +5,7 @@ import type { } from '@summerfi/sdk-common/simulation' import type { Tail } from '../../interfaces/helperTypes' -export function makeStrategy(strategy: T): T { +export function makeStrategy>(strategy: T): Readonly { return strategy } @@ -16,7 +16,7 @@ export function isValueReference(value: ReferenceableField): value is Valu ) } -export function getReferencedValue(referenceableValue: ReferenceableField): T { +export function getValueFromReference(referenceableValue: ReferenceableField): T { if (isValueReference(referenceableValue)) { return referenceableValue.estimatedValue } diff --git a/sdk/simulator-service/src/implementation/utils/index.ts b/sdk/simulator-service/src/implementation/utils/index.ts index addadd9726..98a5ad27ed 100644 --- a/sdk/simulator-service/src/implementation/utils/index.ts +++ b/sdk/simulator-service/src/implementation/utils/index.ts @@ -1,3 +1,3 @@ export { getTokenBalance, addBalance, subtractBalance } from './BalanceUtils' -export { makeStrategy, isValueReference, getReferencedValue, tail, head } from './SimulatorUtils' +export { makeStrategy, isValueReference, getValueFromReference, tail, head } from './SimulatorUtils' export { getSwapStepData } from './GetSwapStepData' diff --git a/sdk/simulator-service/src/interfaces/helperTypes.ts b/sdk/simulator-service/src/interfaces/helperTypes.ts index 61d53be2e0..fd8ec83acd 100644 --- a/sdk/simulator-service/src/interfaces/helperTypes.ts +++ b/sdk/simulator-service/src/interfaces/helperTypes.ts @@ -7,7 +7,14 @@ export type Tail = ((...t: T) => void) extends ( ? R : never // eslint-disable-next-line @typescript-eslint/no-explicit-any -export type Head = T extends [infer H, ...any] ? H : never +export type Head = ((...t: T) => void) extends ( + h: infer R, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ...r: any +) => void + ? R + : never +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type EmptyArray = readonly [] export type Where = T extends U ? T : never export type Unpack = T extends Promise ? U : T extends Array ? Y : never diff --git a/sdk/simulator-service/src/interfaces/simulation.ts b/sdk/simulator-service/src/interfaces/simulation.ts index fd1581b6f6..3bb2b1f04d 100644 --- a/sdk/simulator-service/src/interfaces/simulation.ts +++ b/sdk/simulator-service/src/interfaces/simulation.ts @@ -1,8 +1,8 @@ -import { BalancesRecord, PositionsRecord, StepsRecord, SwapsRecord } from '../types/Types' +import { BalancesRecord, PositionsRecord, StepsArray, SwapsArray } from '../types/Types' export interface ISimulationState { - swaps: SwapsRecord + swaps: SwapsArray balances: BalancesRecord positions: PositionsRecord - steps: StepsRecord + steps: StepsArray } diff --git a/sdk/simulator-service/src/interfaces/steps.ts b/sdk/simulator-service/src/interfaces/steps.ts index adcea67930..5cdbb59890 100644 --- a/sdk/simulator-service/src/interfaces/steps.ts +++ b/sdk/simulator-service/src/interfaces/steps.ts @@ -1,5 +1,10 @@ -import { SimulationStrategy, ValueReference, steps } from '@summerfi/sdk-common/simulation' -import { EmptyArray, Where } from './helperTypes' +import { + SimulationStrategy, + ValueReference, + steps, + StrategyStep, +} from '@summerfi/sdk-common/simulation' +import { EmptyArray, Head, Where } from './helperTypes' import { ISimulationState } from './simulation' export type StepOutputProcessor = (step: Omit) => Promise @@ -15,13 +20,43 @@ export type StateReducers = { [Type in steps.Steps['type']]: StateReducer> } +export type NextStep> = Promise< + Omit['step'] }>, 'outputs'> & { name: Head['name'] } +> + +export type StepsAdded = { name: string; step: steps.Steps }[] +export type ProccessedStep> = { + name: Head['name'] + step: Where['step'] }> +} + +export type Paths = Exclude< + { + [Step in keyof StepsStore]: { + [OutputKey in keyof StepsStore[Step]['step']['outputs']]: [ + StepsStore[Step]['name'], + OutputKey, + ] + }[keyof StepsStore[Step]['step']['outputs']] + }[number], + [string, never] +> + +export type GetReferencedValue =

>( + path: P, +) => ValueReference< + Pick['step']['outputs'], P[1]>[keyof Pick< + Where['step']['outputs'], + P[1] + >] +> + export type NextFunction< - Schema extends SimulationStrategy, - Name extends string = string, -> = Schema extends EmptyArray + Strategy extends SimulationStrategy, + StepsStore extends StepsAdded, +> = Strategy extends EmptyArray ? never : (ctx: { state: ISimulationState - // eslint-disable-next-line @typescript-eslint/no-explicit-any - getReference: (path: [string, string]) => ValueReference - }) => Promise, 'outputs'>> + getReference: GetReferencedValue + }) => NextStep diff --git a/sdk/simulator-service/src/strategies/import/Strategy.ts b/sdk/simulator-service/src/strategies/import/Strategy.ts index 5c08399787..c47f330ef3 100644 --- a/sdk/simulator-service/src/strategies/import/Strategy.ts +++ b/sdk/simulator-service/src/strategies/import/Strategy.ts @@ -3,6 +3,7 @@ import { makeStrategy } from '../../implementation/utils' export const importPositionStrategy = makeStrategy([ { + name: 'Import', step: SimulationSteps.Import, optional: false, }, diff --git a/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts b/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts index 9065be3e1d..de3ee27ddd 100644 --- a/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts +++ b/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts @@ -3,27 +3,18 @@ import { ISimulation, RefinanceSimulationTypes, SimulationSteps, - SimulationType, TokenTransferTargetType, getValueFromReference, } from '@summerfi/sdk-common/simulation' import { Simulator } from '../../implementation/simulator-engine' -import { - TokenAmount, - Percentage, - IToken, - ITokenAmount, - IPercentage, -} from '@summerfi/sdk-common/common' -import { newEmptyPositionFromPool } from '@summerfi/sdk-common/common/utils' +import { TokenAmount, Percentage, CommonTokenSymbols } from '@summerfi/sdk-common/common' import { IRefinanceParameters } from '@summerfi/sdk-common/orders' import { isLendingPool } from '@summerfi/sdk-common/protocols' import { refinanceLendingToLendingAnyPairStrategy } from './Strategy' import { type IRefinanceDependencies } from '../common/Types' import { getSwapStepData } from '../../implementation/utils/GetSwapStepData' -import { ISwapManager } from '@summerfi/swap-common/interfaces' -import { BigNumber } from 'bignumber.js' -import { IOracleManager } from '@summerfi/oracle-common' +import { getRefinanceSimulationType } from '../../implementation/utils/GetRefinanceSimulationType' +import { estimateSwapFromAmount } from '../../implementation/utils/EstimateSwapFromAmount' export async function refinanceLendingToLendingAnyPair( args: IRefinanceParameters, @@ -49,9 +40,6 @@ export async function refinanceLendingToLendingAnyPair( throw new Error('Target pool is not a lending pool') } - console.log(sourcePool) - console.log(targetPool) - const FLASHLOAN_MARGIN = 1.001 const flashloanAmount = position.debtAmount.multiply(FLASHLOAN_MARGIN) const simulator = Simulator.create(refinanceLendingToLendingAnyPairStrategy) @@ -65,11 +53,14 @@ export async function refinanceLendingToLendingAnyPair( type: SimulationSteps.Flashloan, inputs: { amount: flashloanAmount, - provider: FlashloanProvider.Maker, + provider: + flashloanAmount.token.symbol === CommonTokenSymbols.DAI + ? FlashloanProvider.Maker + : FlashloanProvider.Balancer, }, })) .next(async () => ({ - name: 'PaybackWithdrawFromSource', + name: 'PaybackWithdrawFromSourcePosition', type: SimulationSteps.PaybackWithdraw, inputs: { paybackAmount: TokenAmount.createFrom({ @@ -78,11 +69,12 @@ export async function refinanceLendingToLendingAnyPair( }), withdrawAmount: position.collateralAmount, position: position, + withdrawTargetType: TokenTransferTargetType.PositionsManager, }, })) .next( async () => ({ - name: 'CollateralSwap', + name: 'SwapCollateralFromSourcePosition', type: SimulationSteps.Swap, inputs: await getSwapStepData({ chainInfo: position.pool.id.protocol.chainInfo, @@ -95,13 +87,20 @@ export async function refinanceLendingToLendingAnyPair( }), isCollateralSwapSkipped, ) + .next(async () => ({ + name: 'OpenTargetPosition', + type: SimulationSteps.OpenPosition, + inputs: { + pool: targetPool, + }, + })) .next(async (ctx) => ({ - name: 'DepositBorrowToTarget', + name: 'DepositBorrowToTargetPosition', type: SimulationSteps.DepositBorrow, inputs: { // refactor borrowAmount: isDebtSwapSkipped - ? ctx.getReference(['PaybackWithdrawFromSource', 'paybackAmount']) + ? ctx.getReference(['SwapCollateralFromSourcePosition', 'received']) : await estimateSwapFromAmount({ receiveAtLeast: flashloanAmount, fromToken: targetPool.debtToken, @@ -111,19 +110,19 @@ export async function refinanceLendingToLendingAnyPair( }), depositAmount: isCollateralSwapSkipped ? position.collateralAmount - : ctx.getReference(['CollateralSwap', 'received']), - position: newEmptyPositionFromPool(targetPool), + : ctx.getReference(['SwapCollateralFromSourcePosition', 'received']), + position: getValueFromReference(ctx.getReference(['OpenTargetPosition', 'position'])), borrowTargetType: TokenTransferTargetType.PositionsManager, }, })) .next( async (ctx) => ({ - name: 'DebtSwap', + name: 'SwapDebtFromTargetPosition', type: SimulationSteps.Swap, inputs: await getSwapStepData({ chainInfo: position.pool.id.protocol.chainInfo, fromAmount: getValueFromReference( - ctx.getReference(['DepositBorrowToTarget', 'borrowAmount']), + ctx.getReference(['DepositBorrowToTargetPosition', 'borrowAmount']), ), toToken: flashloanAmount.token, slippage: Percentage.createFrom({ value: args.slippage.value }), @@ -170,8 +169,11 @@ export async function refinanceLendingToLendingAnyPair( }) .run() - const targetPosition = Object.values(simulation.positions).find((p) => - p.pool.id.protocol.equals(targetPool.id.protocol), + const targetPositionId = getValueFromReference( + simulation.getReference(['OpenTargetPosition', 'position']), + ) + const targetPosition = Object.values(simulation.positions).find( + (p) => p.id.id === targetPositionId.id.id, ) if (!targetPosition) { @@ -179,78 +181,10 @@ export async function refinanceLendingToLendingAnyPair( } return { - simulationType: getSimulationType(!isCollateralSwapSkipped, !isDebtSwapSkipped), + simulationType: getRefinanceSimulationType(!isCollateralSwapSkipped, !isDebtSwapSkipped), sourcePosition: position, targetPosition, - swaps: Object.values(simulation.swaps), - steps: Object.values(simulation.steps), + swaps: simulation.swaps, + steps: simulation.steps, } satisfies ISimulation } - -function getSimulationType( - hasCollateralSwap: boolean, - hasDebtSwap: boolean, -): RefinanceSimulationTypes { - if (hasCollateralSwap && hasDebtSwap) { - return SimulationType.RefinanceDifferentPair - } - - if (hasCollateralSwap) { - return SimulationType.RefinanceDifferentCollateral - } - - if (hasDebtSwap) { - return SimulationType.RefinanceDifferentDebt - } - - return SimulationType.Refinance -} - -/** - * EstimateTokenAmountAfterSwap - * @description Estimates how much you will recive after swap. - * If target token is the same as source token, we return the same amount. - * When we perform a swap, we need to account for the summer fee, - * and we assume maximum slippage. - */ -async function estimateSwapFromAmount(params: { - receiveAtLeast: ITokenAmount - fromToken: IToken - slippage: IPercentage - swapManager: ISwapManager - oracleManager: IOracleManager -}): Promise { - const { receiveAtLeast, slippage } = params - - if (receiveAtLeast.token.equals(params.fromToken)) { - return receiveAtLeast - } - - const spotPrice = ( - await params.oracleManager.getSpotPrice({ - baseToken: receiveAtLeast.token, - quoteToken: params.fromToken, - }) - ).price - - const summerFee = await params.swapManager.getSummerFee({ - from: { token: receiveAtLeast.token }, - to: { token: params.fromToken }, - }) - - const ONE = new BigNumber(1) - /* - TargetAmt = SourceAmt * (1 - SummerFee) / (SpotPrice * (1 + Slippage)) - SourceAmt = TargetAmt * SpotPrice * (1 + Slippage) / (1 - SummerFee) - */ - - const sourceAmount = receiveAtLeast - .toBN() - .multipliedBy(spotPrice.toBN().times(ONE.plus(slippage.toProportion()))) - .div(ONE.minus(summerFee.toProportion())) - - return TokenAmount.createFrom({ - amount: sourceAmount.toString(), - token: params.fromToken, - }) -} diff --git a/sdk/simulator-service/src/strategies/refinanceAnyPair/Strategy.ts b/sdk/simulator-service/src/strategies/refinanceAnyPair/Strategy.ts index 7e78bbc5c2..f97670b62a 100644 --- a/sdk/simulator-service/src/strategies/refinanceAnyPair/Strategy.ts +++ b/sdk/simulator-service/src/strategies/refinanceAnyPair/Strategy.ts @@ -3,35 +3,48 @@ import { makeStrategy } from '../../implementation/utils' export const refinanceLendingToLendingAnyPairStrategy = makeStrategy([ { + name: 'Flashloan', step: SimulationSteps.Flashloan, optional: false, }, { + name: 'PaybackWithdrawFromSourcePosition', step: SimulationSteps.PaybackWithdraw, optional: false, }, { + name: 'SwapCollateralFromSourcePosition', step: SimulationSteps.Swap, optional: true, }, { + name: 'OpenTargetPosition', + step: SimulationSteps.OpenPosition, + optional: false, + }, + { + name: 'DepositBorrowToTargetPosition', step: SimulationSteps.DepositBorrow, optional: false, }, { + name: 'SwapDebtFromTargetPosition', step: SimulationSteps.Swap, optional: true, }, { + name: 'RepayFlashloan', step: SimulationSteps.RepayFlashloan, optional: false, }, { + name: 'ReturnFunds', step: SimulationSteps.ReturnFunds, optional: true, }, { + name: 'NewPositionEvent', step: SimulationSteps.NewPositionEvent, optional: false, }, -]) +] as const) diff --git a/sdk/simulator-service/src/strategies/refinanceNoDebt/RefinanceLendingToLendingNoDebt.ts b/sdk/simulator-service/src/strategies/refinanceNoDebt/RefinanceLendingToLendingNoDebt.ts index f36424978b..d56c51a195 100644 --- a/sdk/simulator-service/src/strategies/refinanceNoDebt/RefinanceLendingToLendingNoDebt.ts +++ b/sdk/simulator-service/src/strategies/refinanceNoDebt/RefinanceLendingToLendingNoDebt.ts @@ -3,10 +3,10 @@ import { SimulationSteps, SimulationType, TokenTransferTargetType, + getValueFromReference, } from '@summerfi/sdk-common/simulation' import { Simulator } from '../../implementation/simulator-engine' import { Percentage, TokenAmount } from '@summerfi/sdk-common/common' -import { newEmptyPositionFromPool } from '@summerfi/sdk-common/common/utils' import { IRefinanceParameters } from '@summerfi/sdk-common/orders' import { isLendingPool } from '@summerfi/sdk-common/protocols' import { refinanceLendingToLendingNoDebtStrategy } from './Strategy' @@ -45,17 +45,18 @@ export async function refinanceLendingToLendingNoDebt( const simulation = await simulator .next(async () => ({ - name: 'PaybackWithdrawFromSource', + name: 'PaybackWithdrawFromSourcePosition', type: SimulationSteps.PaybackWithdraw, inputs: { paybackAmount: zeroAmount, withdrawAmount: position.collateralAmount, position: position, + withdrawTargetType: TokenTransferTargetType.PositionsManager, }, })) .next( async () => ({ - name: 'CollateralSwap', + name: 'SwapCollateralFromSourcePosition', type: SimulationSteps.Swap, inputs: await getSwapStepData({ chainInfo: position.pool.id.protocol.chainInfo, @@ -68,25 +69,31 @@ export async function refinanceLendingToLendingNoDebt( }), isCollateralSwapSkipped, ) + .next(async () => ({ + name: 'OpenTargetPosition', + type: SimulationSteps.OpenPosition, + inputs: { + pool: targetPool, + }, + })) .next(async (ctx) => ({ - name: 'DepositBorrowToTarget', + name: 'DepositBorrowToTargetPosition', type: SimulationSteps.DepositBorrow, inputs: { depositAmount: isCollateralSwapSkipped ? position.collateralAmount - : ctx.getReference(['CollateralSwap', 'received']), + : ctx.getReference(['SwapCollateralFromSourcePosition', 'received']), borrowAmount: TokenAmount.createFrom({ amount: '0', token: targetPool.debtToken, }), - position: newEmptyPositionFromPool(targetPool), + position: getValueFromReference(ctx.getReference(['OpenTargetPosition', 'position'])), borrowTargetType: TokenTransferTargetType.PositionsManager, }, })) .next(async (ctx) => { - // TODO: we should have a way to get the target position more easily and realiably, - const targetPosition = Object.values(ctx.state.positions).find((p) => - p.pool.id.protocol.equals(targetPool.id.protocol), + const targetPosition = getValueFromReference( + ctx.getReference(['OpenTargetPosition', 'position']), ) if (!targetPosition) { throw new Error('Target position not found') @@ -102,8 +109,11 @@ export async function refinanceLendingToLendingNoDebt( }) .run() - const targetPosition = Object.values(simulation.positions).find((p) => - p.pool.id.protocol.equals(targetPool.id.protocol), + const targetPositionId = getValueFromReference( + simulation.getReference(['OpenTargetPosition', 'position']), + ) + const targetPosition = Object.values(simulation.positions).find( + (p) => p.id.id === targetPositionId.id.id, ) if (!targetPosition) { diff --git a/sdk/simulator-service/src/strategies/refinanceNoDebt/Strategy.ts b/sdk/simulator-service/src/strategies/refinanceNoDebt/Strategy.ts index fb39c1cc78..b95a1fe56e 100644 --- a/sdk/simulator-service/src/strategies/refinanceNoDebt/Strategy.ts +++ b/sdk/simulator-service/src/strategies/refinanceNoDebt/Strategy.ts @@ -3,19 +3,28 @@ import { makeStrategy } from '../../implementation/utils' export const refinanceLendingToLendingNoDebtStrategy = makeStrategy([ { + name: 'PaybackWithdrawFromSourcePosition', step: SimulationSteps.PaybackWithdraw, optional: false, }, { + name: 'SwapCollateralFromSourcePosition', step: SimulationSteps.Swap, optional: true, }, { + name: 'OpenTargetPosition', + step: SimulationSteps.OpenPosition, + optional: false, + }, + { + name: 'DepositBorrowToTargetPosition', step: SimulationSteps.DepositBorrow, optional: false, }, { + name: 'NewPositionEvent', step: SimulationSteps.NewPositionEvent, optional: false, }, -]) +] as const) diff --git a/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts b/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts index 9d3fe46549..1f32eef744 100644 --- a/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts +++ b/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts @@ -4,10 +4,10 @@ import { SimulationSteps, SimulationType, TokenTransferTargetType, + getValueFromReference, } from '@summerfi/sdk-common/simulation' import { Simulator } from '../../implementation/simulator-engine' import { TokenAmount } from '@summerfi/sdk-common/common' -import { newEmptyPositionFromPool } from '@summerfi/sdk-common/common/utils' import { IRefinanceParameters } from '@summerfi/sdk-common/orders' import { isLendingPool } from '@summerfi/sdk-common/protocols' import { refinanceLendingToLendingSamePairStrategy } from './Strategy' @@ -46,28 +46,39 @@ export async function refinanceLendingToLendingSamePair( type: SimulationSteps.Flashloan, inputs: { amount: flashloanAmount, - provider: FlashloanProvider.Balancer, + provider: + flashloanAmount.token.symbol === 'DAI' + ? FlashloanProvider.Maker + : FlashloanProvider.Balancer, }, })) .next(async () => ({ - name: 'PaybackWithdrawFromSource', + name: 'PaybackWithdrawFromSourcePosition', type: SimulationSteps.PaybackWithdraw, inputs: { paybackAmount: TokenAmount.createFrom({ amount: Number.MAX_SAFE_INTEGER.toString(), token: position.debtAmount.token, }), + withdrawTargetType: TokenTransferTargetType.PositionsManager, withdrawAmount: position.collateralAmount, position: position, }, })) .next(async () => ({ - name: 'DepositBorrowToTarget', + name: 'OpenTargetPosition', + type: SimulationSteps.OpenPosition, + inputs: { + pool: targetPool, + }, + })) + .next(async (ctx) => ({ + name: 'DepositBorrowToTargetPosition', type: SimulationSteps.DepositBorrow, inputs: { depositAmount: position.collateralAmount, borrowAmount: position.debtAmount, // TODO figure the debt amount - position: newEmptyPositionFromPool(targetPool), + position: getValueFromReference(ctx.getReference(['OpenTargetPosition', 'position'])), borrowTargetType: TokenTransferTargetType.PositionsManager, }, })) @@ -97,8 +108,11 @@ export async function refinanceLendingToLendingSamePair( }) .run() + const targetPositionId = getValueFromReference( + simulation.getReference(['OpenTargetPosition', 'position']), + ) const targetPosition = Object.values(simulation.positions).find( - (p) => p.pool.id.protocol === targetPool.id.protocol, + (p) => p.id.id === targetPositionId.id.id, ) if (!targetPosition) { diff --git a/sdk/simulator-service/src/strategies/refinanceSamePair/Strategy.ts b/sdk/simulator-service/src/strategies/refinanceSamePair/Strategy.ts index 4b8d6c9896..9645f4fb5a 100644 --- a/sdk/simulator-service/src/strategies/refinanceSamePair/Strategy.ts +++ b/sdk/simulator-service/src/strategies/refinanceSamePair/Strategy.ts @@ -3,23 +3,33 @@ import { makeStrategy } from '../../implementation/utils' export const refinanceLendingToLendingSamePairStrategy = makeStrategy([ { + name: 'Flashloan', step: SimulationSteps.Flashloan, optional: false, }, { + name: 'PaybackWithdrawFromSourcePosition', step: SimulationSteps.PaybackWithdraw, optional: false, }, { + name: 'OpenTargetPosition', + step: SimulationSteps.OpenPosition, + optional: false, + }, + { + name: 'DepositBorrowToTargetPosition', step: SimulationSteps.DepositBorrow, optional: false, }, { + name: 'RepayFlashloan', step: SimulationSteps.RepayFlashloan, optional: false, }, { + name: 'NewPositionEvent', step: SimulationSteps.NewPositionEvent, optional: false, }, -]) +] as const) diff --git a/sdk/simulator-service/src/types/Types.ts b/sdk/simulator-service/src/types/Types.ts index 815e55b1c6..82444b77ac 100644 --- a/sdk/simulator-service/src/types/Types.ts +++ b/sdk/simulator-service/src/types/Types.ts @@ -6,5 +6,5 @@ export type StepName = string export type BalancesRecord = Record export type PositionsRecord = Record -export type StepsRecord = Record -export type SwapsRecord = Record +export type StepsArray = steps.Steps[] +export type SwapsArray = SimulatedSwapData[] diff --git a/sdk/testing-utils/src/mocks/managers/TokensManagerMock.ts b/sdk/testing-utils/src/mocks/managers/TokensManagerMock.ts index 3f3f536b74..6f425f7aab 100644 --- a/sdk/testing-utils/src/mocks/managers/TokensManagerMock.ts +++ b/sdk/testing-utils/src/mocks/managers/TokensManagerMock.ts @@ -25,7 +25,7 @@ export class TokensManagerMock SDAI: Token.createFrom({ chainInfo: ChainFamilyMap.Ethereum.Mainnet, address: Address.createFromEthereum({ value: '0x83F20F44975D03b1b09e64809B757c47f942BEeA' }), - symbol: 'SDAI', + symbol: 'sDAI', name: 'Savings DAI', decimals: 18, }), diff --git a/sdk/tokens-service/tests/StaticTokensProvider.spec.ts b/sdk/tokens-service/tests/StaticTokensProvider.spec.ts index f345034da8..f815f3df60 100644 --- a/sdk/tokens-service/tests/StaticTokensProvider.spec.ts +++ b/sdk/tokens-service/tests/StaticTokensProvider.spec.ts @@ -2,8 +2,8 @@ import { IConfigurationProvider } from '@summerfi/configuration-provider' import { ITokensProvider } from '@summerfi/tokens-common' import { StaticTokensProvider } from '../src/implementation/static/StaticTokensProvider' import { ChainInfo } from '@summerfi/sdk-common' -import assert from 'assert' import { Address, AddressType } from '@summerfi/sdk-common/common' +import assert from 'assert' describe('StaticTokensProvider', () => { let staticTokensProvider: ITokensProvider From 73af6bfc26c1326ce7c5862dd5f0da8ed12fc530 Mon Sep 17 00:00:00 2001 From: Halaprix Date: Wed, 22 May 2024 13:45:24 +0200 Subject: [PATCH 06/37] chore: update migration and swaps handling (#282) --- .../src/point-accrual.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/background-jobs/update-rays-cron-function/src/point-accrual.ts b/background-jobs/update-rays-cron-function/src/point-accrual.ts index 567cadbbb7..4b9d062b53 100644 --- a/background-jobs/update-rays-cron-function/src/point-accrual.ts +++ b/background-jobs/update-rays-cron-function/src/point-accrual.ts @@ -37,7 +37,6 @@ export class SummerPointsService { private SECONDS_PER_YEAR = 365 * 24 * 60 * 60 private SECONDS_PER_DAY = 86400 private SECONDS_PER_HOUR = 3600 - private TWO_HOURS_IN_SECONDS = 2 * 60 * 60 private MIGRATION_POINTS_FRACTION = 0.2 private CORRELATED_SWAP_POINTS_FRACTION = 0.06 private UNCORRELATED_SWAP_POINTS_FRACTION = 0.2 @@ -231,10 +230,8 @@ export class SummerPointsService { let openPositionsPoints = 0 for (const event of position.summerEvents) { - const timeDifference = Math.min( - event.timestamp - previousTimestamp, - this.TWO_HOURS_IN_SECONDS, - ) + const timeDifference = event.timestamp - previousTimestamp + const pointsPerSecond = this.getPointsPerUsdPerSecond(event.netValueBefore) openPositionsPoints += pointsPerSecond * timeDifference * event.netValueBefore @@ -242,7 +239,7 @@ export class SummerPointsService { } // Calculate points for the time period after the last event - const timeDifference = Math.min(endTimestamp - previousTimestamp, this.TWO_HOURS_IN_SECONDS) + const timeDifference = endTimestamp - previousTimestamp const pointsPerSecond = this.getPointsPerUsdPerSecond(position.netValue) @@ -261,7 +258,8 @@ export class SummerPointsService { getMigrationPoints(events: MigrationEvent[]): number { let migrationPoints = 0 for (const event of events) { - const pointsPerYear = this.getPointsPerUsdPerYear(event.netValueAfter) + const pointsPerUsdPerYear = this.getPointsPerUsdPerYear(event.netValueAfter) + const pointsPerYear = pointsPerUsdPerYear * event.netValueAfter migrationPoints += pointsPerYear * this.MIGRATION_POINTS_FRACTION } @@ -278,7 +276,8 @@ export class SummerPointsService { getSwapPoints(swaps: RecentSwap[]): number { let points = 0 for (const swap of swaps) { - const pointsPerYear = this.getPointsPerUsdPerYear(swap.amountInUSD) + const pointsPerUsdPerYear = this.getPointsPerUsdPerYear(swap.amountInUSD) + const pointsPerYear = pointsPerUsdPerYear * swap.amountInUSD const isCorrelatedAsset = this.isCorrelatedAsset(swap.assetIn.symbol, swap.assetOut.symbol) const fraction = isCorrelatedAsset ? this.CORRELATED_SWAP_POINTS_FRACTION From b04bb0c0b117fe8c9cba3039b22545c005f384bd Mon Sep 17 00:00:00 2001 From: Piotr Witek <739075+piotrwitek@users.noreply.github.com> Date: Wed, 22 May 2024 15:02:29 +0200 Subject: [PATCH 07/37] Added protocol plugins reexports (#283) Added protocol plugins reexports --- sdk/sdk-client/src/protocol-plugins-reexport.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sdk/sdk-client/src/protocol-plugins-reexport.ts b/sdk/sdk-client/src/protocol-plugins-reexport.ts index 4a3a238291..e6f12e80fe 100644 --- a/sdk/sdk-client/src/protocol-plugins-reexport.ts +++ b/sdk/sdk-client/src/protocol-plugins-reexport.ts @@ -4,20 +4,24 @@ export { MakerLendingPoolId, MakerPosition, MakerPositionId, + isMakerLendingPoolId, } from '@summerfi/protocol-plugins/plugins/maker' export { SparkLendingPoolId, SparkPosition, SparkPositionId, + isSparkLendingPoolId, } from '@summerfi/protocol-plugins/plugins/spark' export { AaveV3LendingPoolId, AaveV3Position, AaveV3PositionId, + isAaveV3LendingPoolId, } from '@summerfi/protocol-plugins/plugins/aave-v3' export { MorphoLendingPoolId, MorphoPosition, MorphoPositionId, + isMorphoLendingPoolId, } from '@summerfi/protocol-plugins/plugins/morphoblue' export { EmodeType } from '@summerfi/protocol-plugins/plugins/common' From b01a2518f654bff8da029dd63295b62ac720e03d Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Wed, 22 May 2024 16:05:09 +0200 Subject: [PATCH 08/37] feat: convert action builders to classes (#266) --- .../src/implementation/OrderPlanner.ts | 18 +- .../src/actions/BaseAction.ts | 4 +- .../src/interfaces/IAction.ts | 34 ++++ .../src/interfaces/IActionBuilder.ts | 90 ++++++++++ .../src/interfaces/IProtocolPlugin.ts | 4 +- .../src/types/StepBuilderTypes.ts | 34 ---- .../src/types/index.ts | 2 +- .../src/implementation/BaseActionBuilder.ts | 77 +++++++++ .../src/implementation/BaseProtocolPlugin.ts | 12 +- .../src/implementation/index.ts | 1 + .../AaveV3DepositBorrowActionBuilder.ts | 150 +++++++++-------- .../AaveV3OpenPositionActionBuilder.ts | 41 +++-- .../AaveV3PaybackWithdrawActionBuilder.ts | 159 ++++++++++-------- .../builders/DepositBorrowActionBuilder.ts | 20 ++- .../common/builders/FlashloanActionBuilder.ts | 27 +-- .../builders/ImportPositionActionBuilder.ts | 22 +-- .../builders/OpenPositionActionBuilder.ts | 22 +-- .../builders/PaybackWithdrawActionBuilder.ts | 20 ++- .../builders/PositionCreatedActionBuilder.ts | 30 ++-- .../common/builders/PullTokenActionBuilder.ts | 34 ++-- .../builders/RepayFlashloanActionBuilder.ts | 84 ++++----- .../builders/ReturnFundsActionBuilder.ts | 31 ++-- .../common/builders/SwapActionBuilder.ts | 66 ++++---- .../src/plugins/common/builders/index.ts | 24 ++- .../MakerImportPositionActionBuilder.ts | 47 +++--- .../MakerOpenPositionActionBuilder.ts | 23 ++- .../MakerPaybackWithdrawActionBuilder.ts | 81 ++++----- .../MorphoDepositBorrowActionBuilder.ts | 132 ++++++++------- .../MorphoOpenPositionActionBuilder.ts | 23 ++- .../MorphoPaybackWithdrawActionBuilder.ts | 110 ++++++------ .../SparkDepositBorrowActionBuilder.ts | 151 +++++++++-------- .../SparkOpenPositionActionBuilder.ts | 43 ++--- .../SparkPaybackWithdrawActionBuilder.ts | 157 +++++++++-------- .../utils/DelegateToProtocolActionBuilder.ts | 23 --- .../DepositBorrowActionBuilder.spec.ts | 6 +- .../builders/FlashloanActionBuilder.spec.ts | 2 +- .../ImportPositionActionBuilder.spec.ts | 6 +- .../OpenPositionActionBuilder.spec.ts | 6 +- .../PaybackWithdrawActionBuilder.spec.ts | 6 +- .../builders/PullTokenActionBuilder.spec.ts | 2 +- .../RepayFlashloanActionBuilder.spec.ts | 4 +- .../builders/ReturnFundsActionBuilder.spec.ts | 2 +- .../unit/builders/SwapActionBuilder.spec.ts | 2 +- .../AaveV3DepositBorrowActionBuilder.spec.ts | 8 +- .../AaveV3OpenPositionActionBuilder.spec.ts | 4 +- ...AaveV3PaybackWithdrawActionBuilder.spec.ts | 6 +- .../MakerImportPositionActionBuilder.spec.ts | 4 +- .../MakerOpenPositionActionBuilder.spec.ts | 4 +- .../MakerPaybackWithdrawActionBuilder.spec.ts | 6 +- .../MorphoDepositBorrowActionBuilder.spec.ts | 8 +- .../MorphoOpenPositionActionBuilder.spec.ts | 4 +- ...MorphoPaybackWithdrawActionBuilder.spec.ts | 6 +- .../SparkDepositBorrowActionBuilder.spec.ts | 8 +- .../SparkOpenPositionActionBuilder.spec.ts | 4 +- .../SparkPaybackWithdrawActionBuilder.spec.ts | 6 +- .../tests/utils/ProtocolPluginMock.ts | 99 +++++++---- sdk/protocol-plugins/tsconfig.json | 2 +- sdk/sdk-common/src/simulation/index.ts | 9 +- 58 files changed, 1154 insertions(+), 856 deletions(-) create mode 100644 sdk/protocol-plugins-common/src/interfaces/IAction.ts create mode 100644 sdk/protocol-plugins-common/src/interfaces/IActionBuilder.ts delete mode 100644 sdk/protocol-plugins-common/src/types/StepBuilderTypes.ts create mode 100644 sdk/protocol-plugins/src/implementation/BaseActionBuilder.ts delete mode 100644 sdk/protocol-plugins/src/plugins/utils/DelegateToProtocolActionBuilder.ts diff --git a/sdk/order-planner-common/src/implementation/OrderPlanner.ts b/sdk/order-planner-common/src/implementation/OrderPlanner.ts index 092f37e597..0eb90e6c7f 100644 --- a/sdk/order-planner-common/src/implementation/OrderPlanner.ts +++ b/sdk/order-planner-common/src/implementation/OrderPlanner.ts @@ -2,9 +2,9 @@ import { Order, type IPositionsManager, TransactionInfo } from '@summerfi/sdk-co import { ISimulation, SimulationType, steps } from '@summerfi/sdk-common/simulation' import { Maybe } from '@summerfi/sdk-common/common' import { - ActionBuilder, ActionBuildersMap, ActionCall, + IActionBuilder, IStepBuilderContext, StepBuilderContext, } from '@summerfi/protocol-plugins-common' @@ -39,7 +39,7 @@ export class OrderPlanner implements IOrderPlanner { throw new Error(`No step builder found for step type ${step.type}`) } - await stepBuilder({ + await stepBuilder.build({ context, user, positionsManager, @@ -68,11 +68,17 @@ export class OrderPlanner implements IOrderPlanner { }) } - private _getActionBuilder( + private _getActionBuilder( actionBuildersMap: ActionBuildersMap, - step: T, - ): Maybe> { - return actionBuildersMap[step.type] as ActionBuilder + step: StepType, + ): Maybe> { + const builder = actionBuildersMap[step.type] + + if (!builder) { + return undefined + } + + return new builder() as IActionBuilder } private async _generateOrder(params: { diff --git a/sdk/protocol-plugins-common/src/actions/BaseAction.ts b/sdk/protocol-plugins-common/src/actions/BaseAction.ts index dd851f8015..c17864a8c1 100644 --- a/sdk/protocol-plugins-common/src/actions/BaseAction.ts +++ b/sdk/protocol-plugins-common/src/actions/BaseAction.ts @@ -10,6 +10,7 @@ import { import { ActionConfig, ActionCall } from './Types' import { InputSlotsMapping } from '../types/InputSlotsMapping' import { AbiParametersToPrimitiveTypes } from 'abitype' +import { IAction } from '../interfaces/IAction' /** * @class Base class for all actions. It provides the basic functionality to encode the call to the action and provide @@ -22,7 +23,8 @@ export abstract class BaseAction< >, AbiParametersTypes extends AbiParametersToPrimitiveTypes = AbiParametersToPrimitiveTypes, -> { +> implements IAction +{ private readonly DefaultParamsMapping: InputSlotsMapping = [0, 0, 0, 0] /** diff --git a/sdk/protocol-plugins-common/src/interfaces/IAction.ts b/sdk/protocol-plugins-common/src/interfaces/IAction.ts new file mode 100644 index 0000000000..c5839980bc --- /dev/null +++ b/sdk/protocol-plugins-common/src/interfaces/IAction.ts @@ -0,0 +1,34 @@ +import { ActionConfig, ActionCall } from '../actions/Types' +import { InputSlotsMapping } from '../types/InputSlotsMapping' + +/** + * @class Base class for all actions. It provides the basic functionality to encode the call to the action and provide + * the versioned name of the action. + */ +export interface IAction { + /** + * @description Returns the versioned name of the action + * @returns The versioned name of the action + */ + getVersionedName(): string + + /** + * @description Encodes the call to the action. Provided so the implementer has an opportunity to pre-process + * the parameters before encoding the call. + * @param params The parameters to encode + * @param paramsMapping The mapping of the parameters to the execution storage + * @returns The encoded call to the action + */ + encodeCall(params: unknown, paramsMapping?: InputSlotsMapping): ActionCall + + /** + * @description Returns the configuration of the action + * @returns The configuration of the action + */ + get config(): ActionConfig +} + +/** + * Constructor type for an action + */ +export type IActionConstructor = new () => IAction diff --git a/sdk/protocol-plugins-common/src/interfaces/IActionBuilder.ts b/sdk/protocol-plugins-common/src/interfaces/IActionBuilder.ts new file mode 100644 index 0000000000..2b31de4f5b --- /dev/null +++ b/sdk/protocol-plugins-common/src/interfaces/IActionBuilder.ts @@ -0,0 +1,90 @@ +import { SimulationSteps, steps } from '@summerfi/sdk-common/simulation' +import { ISwapManager } from '@summerfi/swap-common/interfaces' +import { type IPositionsManager } from '@summerfi/sdk-common/orders' +import { IUser } from '@summerfi/sdk-common/user' +import { IStepBuilderContext } from './IStepBuilderContext' +import { type IProtocolPluginsRegistry } from './IProtocolPluginsRegistry' +import { IAddressBookManager } from '@summerfi/address-book-common' +import { IActionConstructor } from './IAction' + +/** + * Parameters for an action builder + */ +export type ActionBuilderParams = { + context: IStepBuilderContext + user: IUser + positionsManager: IPositionsManager + swapManager: ISwapManager + addressBookManager: IAddressBookManager + protocolsRegistry: IProtocolPluginsRegistry + step: Step +} + +/** + * Constructor for an action builder + */ +export type IActionBuilderConstructor = + new () => IActionBuilder + +/** + * Helper type to filter the steps by the simulation step type + */ +export type FilterStep< + SimulationStep extends SimulationSteps, + Step extends steps.Steps, +> = Step extends { type: SimulationStep } ? Step : never + +/** + * Map of action builders to be used to register the action builders in the protocol plugins + */ +export type ActionBuildersMap = { + [StepType in steps.Steps['type']]: IActionBuilderConstructor> +} + +/** + * Special type to indicate that the build process is delegated to the protocol + */ +export type DelegatedToProtocol = 'DelegatedToProtocol' + +/** + * Declaration of an action that the Action Builder uses internally + * + * This is used by the Strategy Definition generation tool to identify the actions that are used by the Action Builder + * + * The `isOptionalTag` is used to identify whether the action is optional (if the tag is pressent) or not. The tag itself + * will be used by the generation tool to narrow down the amount of possibilites in the Strategy Definition branching + * + * This is done through a definition given to the generation tool that will allow it to identify which strategy level + * optionals are related to the actions optionals + * + * If the action is DelegatedToProtocol, the action will be delegated to the protocol plugin. This indicates to the + * generation tool that it needs to branch for each single protocol plugin + */ +export type ActionBuilderUsedAction = { + /** Action used in the builder */ + action: IActionConstructor | DelegatedToProtocol + /** Tag to identify the action as optional */ + isOptionalTags?: string[] +} + +/** + * Interface for an action builder + * + * The actions builders are responsible for building the actions for the simulation steps, + * this is they translate the simulation steps into actual actions that can be executed + * in a transaction + */ +export interface IActionBuilder { + /** + * List of actions that are used by the action builder and whether they are optional or not + * The order of the declared action must coincide with the order of the actions in the `build` function + */ + readonly actions: ActionBuilderUsedAction[] + + /** + * Main function to build the action + * + * @param params Specific parameters for the action builder. @see ActionBuilderParams + */ + build(params: ActionBuilderParams>): Promise +} diff --git a/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts b/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts index 7dfc33e023..3a4604e85a 100644 --- a/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts +++ b/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts @@ -7,9 +7,9 @@ import { } from '@summerfi/sdk-common/protocols' import { type IProtocolPluginContext } from './IProtocolPluginContext' import { steps } from '@summerfi/sdk-common/simulation' -import { ActionBuilder, ActionBuildersMap } from '../types/StepBuilderTypes' import { IUser } from '@summerfi/sdk-common/user' import { IExternalPosition, IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' +import { IActionBuilder, ActionBuildersMap } from './IActionBuilder' /** * @interface IProtocolPlugin @@ -57,7 +57,7 @@ export interface IProtocolPlugin { * @param step The simulation step for which to get the action builder * @returns The action builder for the given step for the specific protocol, or undefined if not found */ - getActionBuilder(step: StepType): Maybe> + getActionBuilder(step: StepType): Maybe> /** IMPORT POSITION */ diff --git a/sdk/protocol-plugins-common/src/types/StepBuilderTypes.ts b/sdk/protocol-plugins-common/src/types/StepBuilderTypes.ts deleted file mode 100644 index 74edc07f41..0000000000 --- a/sdk/protocol-plugins-common/src/types/StepBuilderTypes.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { SimulationSteps, steps } from '@summerfi/sdk-common/simulation' -import { ISwapManager } from '@summerfi/swap-common/interfaces' -import { type IPositionsManager } from '@summerfi/sdk-common/orders' -import { IUser } from '@summerfi/sdk-common/user' -import { IStepBuilderContext } from '../interfaces/IStepBuilderContext' -import { type IProtocolPluginsRegistry } from '../interfaces/IProtocolPluginsRegistry' -import { IAddressBookManager } from '@summerfi/address-book-common' - -export type FilterStep< - SimulationStep extends SimulationSteps, - Step extends steps.Steps, -> = Step extends { type: SimulationStep } ? Step : never - -export type ActionBuilderParams = { - context: IStepBuilderContext - user: IUser - positionsManager: IPositionsManager - swapManager: ISwapManager - addressBookManager: IAddressBookManager - protocolsRegistry: IProtocolPluginsRegistry - step: Step -} - -export type ActionBuilderFunction = ( - params: ActionBuilderParams, -) => Promise - -export type ActionBuilder = ActionBuilderFunction< - FilterStep -> - -export type ActionBuildersMap = { - [StepType in steps.Steps['type']]: ActionBuilderFunction> -} diff --git a/sdk/protocol-plugins-common/src/types/index.ts b/sdk/protocol-plugins-common/src/types/index.ts index 57dabaccd7..aee2391b55 100644 --- a/sdk/protocol-plugins-common/src/types/index.ts +++ b/sdk/protocol-plugins-common/src/types/index.ts @@ -1,3 +1,3 @@ export * from './ActionStorageTypes' -export * from './StepBuilderTypes' +export * from '../interfaces/IActionBuilder' export * from './InputSlotsMapping' diff --git a/sdk/protocol-plugins/src/implementation/BaseActionBuilder.ts b/sdk/protocol-plugins/src/implementation/BaseActionBuilder.ts new file mode 100644 index 0000000000..cd58538236 --- /dev/null +++ b/sdk/protocol-plugins/src/implementation/BaseActionBuilder.ts @@ -0,0 +1,77 @@ +import { SimulationSteps, steps } from '@summerfi/sdk-common/simulation' +import { ProtocolName } from '@summerfi/sdk-common/protocols' +import { IAddressBookManager } from '@summerfi/address-book-common' +import { IAddress, IChainInfo } from '@summerfi/sdk-common/common' +import { getContractAddress } from '../plugins/utils/GetContractAddress' +import { + ActionBuilderParams, + ActionBuilderUsedAction, + FilterStep, + IActionBuilder, +} from '@summerfi/protocol-plugins-common' + +/** + * Base class for all action builders + * + * It provides convenience functions like `_delegateToProtocol` and establishes + * a common interface for all action builders + * + * The side effects of this class will be reflected in the IStepBuilderContext passed to it as a parameter + */ +export abstract class BaseActionBuilder + implements IActionBuilder +{ + /** @see IActionBuilder.actions */ + abstract readonly actions: ActionBuilderUsedAction[] + + /** @see IActionBuilder.build */ + public abstract build( + params: ActionBuilderParams>, + ): Promise + + /** PROTECTED */ + + /** + * Delegates the building of the action to the specific builder in the corresponding protocol plugin + * @param protocolName The name of the protocol to delegate the action to + * @param actionBuilderParams The parameters for the action builder + */ + protected async _delegateToProtocol(params: { + protocolName: ProtocolName + actionBuilderParams: ActionBuilderParams> + }): Promise { + const { protocolName } = params + const { protocolsRegistry } = params.actionBuilderParams + + const plugin = protocolsRegistry.getPlugin({ protocolName }) + if (!plugin) { + throw new Error(`No protocol plugin found for protocol ${protocolName}`) + } + + const builder = plugin.getActionBuilder(params.actionBuilderParams.step) + if (!builder) { + throw new Error(`No action builder found for protocol ${protocolName}`) + } + + return builder.build(params.actionBuilderParams) + } + + /** + * Resolves the address of a contract by its name using the address book manager + * @param addressBookManager The address book manager to use + * @param chainInfo The chain where the contract is + * @param contractName The name of the contract + * @returns The address of the contract + */ + protected async _getContractAddress(params: { + addressBookManager: IAddressBookManager + chainInfo: IChainInfo + contractName: string + }): Promise { + return getContractAddress({ + addressBookManager: params.addressBookManager, + chainInfo: params.chainInfo, + contractName: params.contractName, + }) + } +} diff --git a/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts b/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts index 2f6153912a..d150b2025c 100644 --- a/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts @@ -1,6 +1,6 @@ import { - ActionBuilder, ActionBuildersMap, + IActionBuilder, IProtocolPlugin, IProtocolPluginContext, } from '@summerfi/protocol-plugins-common' @@ -136,8 +136,14 @@ export abstract class BaseProtocolPlugin implements IProtocolPlugin { /** ACTION BUILDERS */ /** @see IProtocolPlugin.getActionBuilder */ - getActionBuilder(step: T): Maybe> { - return this.stepBuilders[step.type] as ActionBuilder + getActionBuilder(step: StepType): Maybe> { + const BuilderClass = this.stepBuilders[step.type] + + if (!BuilderClass) { + return undefined + } + + return new BuilderClass() as IActionBuilder } /** HELPERS */ diff --git a/sdk/protocol-plugins/src/implementation/index.ts b/sdk/protocol-plugins/src/implementation/index.ts index 5c734a6225..a310bd0696 100644 --- a/sdk/protocol-plugins/src/implementation/index.ts +++ b/sdk/protocol-plugins/src/implementation/index.ts @@ -1,2 +1,3 @@ export * from './ProtocolPluginsRegistry' export * from './BaseProtocolPlugin' +export * from './BaseActionBuilder' diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts index a3e19b8dcb..d050310b82 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts @@ -3,91 +3,105 @@ import { getValueFromReference, TokenTransferTargetType, } from '@summerfi/sdk-common/simulation' -import { ActionNames } from '@summerfi/deployment-types' import { IAddress } from '@summerfi/sdk-common/common' -import { ActionBuilder, ActionBuilderParams } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { SetApprovalAction } from '../../common' import { AaveV3DepositAction } from '../actions/AaveV3DepositAction' import { AaveV3BorrowAction } from '../actions/AaveV3BorrowAction' import { getContractAddress } from '../../utils/GetContractAddress' import { isAaveV3LendingPool } from '../interfaces/IAaveV3LendingPool' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const AaveV3DepositBorrowActionList: ActionNames[] = ['AaveV3Deposit', 'AaveV3Borrow'] +export class AaveV3DepositBorrowActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [ + { action: SetApprovalAction }, + { action: AaveV3DepositAction }, + { action: AaveV3BorrowAction, isOptionalTags: ['borrowAmount'] }, + ] -async function getBorrowTargetAddress( - params: ActionBuilderParams, -): Promise { - const { user, step, positionsManager, addressBookManager } = params - if (step.inputs.borrowTargetType === TokenTransferTargetType.PositionsManager) { - return positionsManager.address - } - - return getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'OperationExecutor', - }) -} - -export const AaveV3DepositBorrowActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { context, step, addressBookManager, user } = params - - if (!isAaveV3LendingPool(step.inputs.position.pool)) { - throw new Error('Invalid AaveV3 lending pool') - } + async build(params: ActionBuilderParams): Promise { + const { context, step, addressBookManager, user } = params - const aaveV3LendingPoolAddress = await getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'AaveV3LendingPool', - }) + if (!isAaveV3LendingPool(step.inputs.position.pool)) { + throw new Error('Invalid AaveV3 lending pool') + } - context.addActionCall({ - step: step, - action: new SetApprovalAction(), - arguments: { - approvalAmount: getValueFromReference(step.inputs.depositAmount), - delegate: aaveV3LendingPoolAddress, - sumAmounts: false, - }, - connectedInputs: { - depositAmount: 'approvalAmount', - }, - connectedOutputs: {}, - }) - - context.addActionCall({ - step: params.step, - action: new AaveV3DepositAction(), - arguments: { - depositAmount: getValueFromReference(step.inputs.depositAmount), - sumAmounts: false, - setAsCollateral: true, - }, - connectedInputs: { - depositAmount: 'amountToDeposit', - }, - connectedOutputs: { - depositAmount: 'depositedAmount', - }, - }) - - const borrowAmount = getValueFromReference(step.inputs.borrowAmount) + const aaveV3LendingPoolAddress = await getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'AaveV3LendingPool', + }) - if (!borrowAmount.toBN().isZero()) { context.addActionCall({ step: step, - action: new AaveV3BorrowAction(), + action: new SetApprovalAction(), + arguments: { + approvalAmount: getValueFromReference(step.inputs.depositAmount), + delegate: aaveV3LendingPoolAddress, + sumAmounts: false, + }, + connectedInputs: { + depositAmount: 'approvalAmount', + }, + connectedOutputs: {}, + }) + + context.addActionCall({ + step: params.step, + action: new AaveV3DepositAction(), arguments: { - borrowAmount: borrowAmount, - borrowTo: await getBorrowTargetAddress(params), + depositAmount: getValueFromReference(step.inputs.depositAmount), + sumAmounts: false, + setAsCollateral: true, + }, + connectedInputs: { + depositAmount: 'amountToDeposit', }, - connectedInputs: {}, connectedOutputs: { - borrowAmount: 'borrowedAmount', + depositAmount: 'depositedAmount', }, }) + + const borrowAmount = getValueFromReference(step.inputs.borrowAmount) + + if (!borrowAmount.toBN().isZero()) { + context.addActionCall({ + step: step, + action: new AaveV3BorrowAction(), + arguments: { + borrowAmount: borrowAmount, + borrowTo: await this._getBorrowTargetAddress(params), + }, + connectedInputs: {}, + connectedOutputs: { + borrowAmount: 'borrowedAmount', + }, + }) + } + } + + /** + * Resolves the target address for the borrow action based on the borrow target type + * @param params The parameters for the action builder + * @returns The address of the target contract + */ + private async _getBorrowTargetAddress( + params: ActionBuilderParams, + ): Promise { + const { user, step, positionsManager, addressBookManager } = params + + switch (step.inputs.borrowTargetType) { + case TokenTransferTargetType.PositionsManager: + return positionsManager.address + + case TokenTransferTargetType.StrategyExecutor: + return getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'OperationExecutor', + }) + default: + throw new Error(`Invalid borrow target type: ${step.inputs.borrowTargetType}`) + } } } diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3OpenPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3OpenPositionActionBuilder.ts index 66d3659129..b3ba8693f4 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3OpenPositionActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3OpenPositionActionBuilder.ts @@ -1,30 +1,29 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { ActionNames } from '@summerfi/deployment-types' - -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { isAaveV3LendingPool } from '../interfaces' import { AaveV3SetEmodeAction } from '../actions/AaveV3SetEmodeAction' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const AaveV3OpenPositionList: ActionNames[] = ['AaveV3SetEMode'] +export class AaveV3OpenPositionActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [{ action: AaveV3SetEmodeAction }] -export const AaveV3OpenPositionActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { context, step } = params + async build(params: ActionBuilderParams): Promise { + const { context, step } = params - if (!isAaveV3LendingPool(step.inputs.pool)) { - throw new Error('Invalid AaveV3 lending pool') - } + if (!isAaveV3LendingPool(step.inputs.pool)) { + throw new Error('Invalid AaveV3 lending pool') + } - const pool = step.inputs.pool + const pool = step.inputs.pool - context.addActionCall({ - step: step, - action: new AaveV3SetEmodeAction(), - arguments: { - emode: pool.id.emodeType, - }, - connectedInputs: {}, - connectedOutputs: {}, - }) + context.addActionCall({ + step: step, + action: new AaveV3SetEmodeAction(), + arguments: { + emode: pool.id.emodeType, + }, + connectedInputs: {}, + connectedOutputs: {}, + }) + } } diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3PaybackWithdrawActionBuilder.ts b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3PaybackWithdrawActionBuilder.ts index 90e3721881..443873c5cb 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3PaybackWithdrawActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3PaybackWithdrawActionBuilder.ts @@ -3,97 +3,110 @@ import { getValueFromReference, TokenTransferTargetType, } from '@summerfi/sdk-common/simulation' -import { ActionNames } from '@summerfi/deployment-types' - import { IAddress } from '@summerfi/sdk-common/common' -import { ActionBuilder, ActionBuilderParams } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { SetApprovalAction } from '../../common' import { AaveV3WithdrawAction } from '../actions/AaveV3WithdrawAction' import { AaveV3PaybackAction } from '../actions/AaveV3PaybackAction' import { getContractAddress } from '../../utils/GetContractAddress' import { isAaveV3LendingPool } from '../interfaces/IAaveV3LendingPool' import { Address } from '@summerfi/sdk-common' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const AaveV3PaybackWithdrawActionList: ActionNames[] = ['AaveV3Payback', 'AaveV3Withdraw'] +export class AaveV3PaybackWithdrawActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [ + { action: SetApprovalAction, isOptionalTags: ['paybackAmount'] }, + { action: AaveV3PaybackAction, isOptionalTags: ['paybackAmount'] }, + { action: AaveV3WithdrawAction, isOptionalTags: ['withdrawAmount'] }, + ] -async function getWithdrawTargetAddress( - params: ActionBuilderParams, -): Promise { - const { user, step, positionsManager, addressBookManager } = params - if (step.inputs.withdrawTargetType === TokenTransferTargetType.PositionsManager) { - return positionsManager.address - } + async build(params: ActionBuilderParams): Promise { + const { context, step, addressBookManager, user } = params - return getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'OperationExecutor', - }) -} + if (!isAaveV3LendingPool(step.inputs.position.pool)) { + throw new Error('Invalid AaveV3 lending pool') + } -export const AaveV3PaybackWithdrawActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { context, step, addressBookManager, user } = params + const sparkLendingPoolAddress = await getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'AavePool', + }) - if (!isAaveV3LendingPool(step.inputs.position.pool)) { - throw new Error('Invalid AaveV3 lending pool') - } + const paybackAmount = getValueFromReference(step.inputs.paybackAmount) - const sparkLendingPoolAddress = await getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'AavePool', - }) + if (!paybackAmount.toBN().isZero()) { + context.addActionCall({ + step: step, + action: new SetApprovalAction(), + arguments: { + approvalAmount: getValueFromReference(step.inputs.paybackAmount), + delegate: sparkLendingPoolAddress, + sumAmounts: false, + }, + connectedInputs: { + paybackAmount: 'approvalAmount', + }, + connectedOutputs: {}, + }) - const paybackAmount = getValueFromReference(step.inputs.paybackAmount) + context.addActionCall({ + step: params.step, + action: new AaveV3PaybackAction(), + arguments: { + paybackAmount: getValueFromReference(step.inputs.paybackAmount), + paybackAll: getValueFromReference(step.inputs.paybackAmount) + .toBN() + .gt(step.inputs.position.debtAmount.toBN()), + onBehalf: Address.ZeroAddressEthereum, + }, + connectedInputs: {}, + connectedOutputs: { + paybackAmount: 'paybackedAmount', + }, + }) + } - if (!paybackAmount.toBN().isZero()) { - context.addActionCall({ - step: step, - action: new SetApprovalAction(), - arguments: { - approvalAmount: getValueFromReference(step.inputs.paybackAmount), - delegate: sparkLendingPoolAddress, - sumAmounts: false, - }, - connectedInputs: { - paybackAmount: 'approvalAmount', - }, - connectedOutputs: {}, - }) + const withdrawAmount = getValueFromReference(step.inputs.withdrawAmount) - context.addActionCall({ - step: params.step, - action: new AaveV3PaybackAction(), - arguments: { - paybackAmount: getValueFromReference(step.inputs.paybackAmount), - paybackAll: getValueFromReference(step.inputs.paybackAmount) - .toBN() - .gt(step.inputs.position.debtAmount.toBN()), - onBehalf: Address.ZeroAddressEthereum, - }, - connectedInputs: {}, - connectedOutputs: { - paybackAmount: 'paybackedAmount', - }, - }) + if (!withdrawAmount.toBN().isZero()) { + context.addActionCall({ + step: step, + action: new AaveV3WithdrawAction(), + arguments: { + withdrawAmount: withdrawAmount, + withdrawTo: await this._getWithdrawTargetAddress(params), + }, + connectedInputs: {}, + connectedOutputs: { + withdrawAmount: 'withdrawnAmount', + }, + }) + } } - const withdrawAmount = getValueFromReference(step.inputs.withdrawAmount) + /** + * Resolves the target address for the withdraw action based on the withdraw target type + * @param params The parameters for the action builder + * @returns The address of the target contract + */ + private async _getWithdrawTargetAddress( + params: ActionBuilderParams, + ): Promise { + const { user, step, positionsManager, addressBookManager } = params - if (!withdrawAmount.toBN().isZero()) { - context.addActionCall({ - step: step, - action: new AaveV3WithdrawAction(), - arguments: { - withdrawAmount: withdrawAmount, - withdrawTo: await getWithdrawTargetAddress(params), - }, - connectedInputs: {}, - connectedOutputs: { - withdrawAmount: 'withdrawnAmount', - }, - }) + switch (step.inputs.withdrawTargetType) { + case TokenTransferTargetType.PositionsManager: + return positionsManager.address + + case TokenTransferTargetType.StrategyExecutor: + return getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'OperationExecutor', + }) + default: + throw new Error(`Invalid withdraw target type: ${step.inputs.withdrawTargetType}`) + } } } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/DepositBorrowActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/DepositBorrowActionBuilder.ts index 8dbfcf0e4f..34a0e491b3 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/DepositBorrowActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/DepositBorrowActionBuilder.ts @@ -1,12 +1,14 @@ -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { steps } from '@summerfi/sdk-common/simulation' -import { delegateToProtocolActionBuilder } from '../../utils/DelegateToProtocolActionBuilder' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const DepositBorrowActionBuilder: ActionBuilder = async ( - params, -): Promise => { - return delegateToProtocolActionBuilder({ - protocolName: params.step.inputs.position.pool.id.protocol.name, - actionBuilderParams: params, - }) +export class DepositBorrowActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [{ action: 'DelegatedToProtocol' }] + + async build(params: ActionBuilderParams): Promise { + return this._delegateToProtocol({ + protocolName: params.step.inputs.position.pool.id.protocol.name, + actionBuilderParams: params, + }) + } } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/FlashloanActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/FlashloanActionBuilder.ts index b98c1e8876..da9a98c3c7 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/FlashloanActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/FlashloanActionBuilder.ts @@ -1,14 +1,21 @@ -import { ActionNames } from '@summerfi/deployment-types' -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { steps } from '@summerfi/sdk-common/simulation' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' +import { FlashloanAction } from '../actions' -export const FlashloanActionList: ActionNames[] = ['TakeFlashloan'] +export class FlashloanActionBuilder extends BaseActionBuilder { + /** + * Special case for the declared actions: the flashloan action is indicated here although + * it is not used in the builder. This is due to the Flashloan inverstion problem in which + * the flashloan action is used when the RepayFlashloan step is built, but for the + * strategy definition we need to have the action registered at this moment + */ + readonly actions: ActionBuilderUsedAction[] = [{ action: FlashloanAction }] -export const FlashloanActionBuilder: ActionBuilder = async ( - params, -): Promise => { - // Start a new calls level until the flashloan is finished - params.context.startSubContext({ - customData: params.step.inputs, - }) + async build(params: ActionBuilderParams): Promise { + // Start a new calls level until the flashloan is finished + params.context.startSubContext({ + customData: params.step.inputs, + }) + } } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/ImportPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/ImportPositionActionBuilder.ts index 3b80b3f38c..b254feb0c5 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/ImportPositionActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/ImportPositionActionBuilder.ts @@ -1,14 +1,16 @@ -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { steps } from '@summerfi/sdk-common/simulation' -import { delegateToProtocolActionBuilder } from '../../utils/DelegateToProtocolActionBuilder' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const ImportPositionActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const externalPosition = params.step.inputs.externalPosition +export class ImportPositionActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [{ action: 'DelegatedToProtocol' }] - return delegateToProtocolActionBuilder({ - protocolName: externalPosition.position.pool.id.protocol.name, - actionBuilderParams: params, - }) + async build(params: ActionBuilderParams): Promise { + const externalPosition = params.step.inputs.externalPosition + + return this._delegateToProtocol({ + protocolName: externalPosition.position.pool.id.protocol.name, + actionBuilderParams: params, + }) + } } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/OpenPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/OpenPositionActionBuilder.ts index 2ce24cd86e..a8ef2e5034 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/OpenPositionActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/OpenPositionActionBuilder.ts @@ -1,14 +1,16 @@ -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { steps } from '@summerfi/sdk-common/simulation' -import { delegateToProtocolActionBuilder } from '../../utils/DelegateToProtocolActionBuilder' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const OpenPositionActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const pool = params.step.inputs.pool +export class OpenPositionActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [{ action: 'DelegatedToProtocol' }] - await delegateToProtocolActionBuilder({ - protocolName: pool.id.protocol.name, - actionBuilderParams: params, - }) + async build(params: ActionBuilderParams): Promise { + const pool = params.step.inputs.pool + + await this._delegateToProtocol({ + protocolName: pool.id.protocol.name, + actionBuilderParams: params, + }) + } } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/PaybackWithdrawActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/PaybackWithdrawActionBuilder.ts index 3aebbf0fcd..8083071fc1 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/PaybackWithdrawActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/PaybackWithdrawActionBuilder.ts @@ -1,12 +1,14 @@ -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { steps } from '@summerfi/sdk-common/simulation' -import { delegateToProtocolActionBuilder } from '../../utils/DelegateToProtocolActionBuilder' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const PaybackWithdrawActionBuilder: ActionBuilder = async ( - params, -): Promise => { - return delegateToProtocolActionBuilder({ - protocolName: params.step.inputs.position.pool.id.protocol.name, - actionBuilderParams: params, - }) +export class PaybackWithdrawActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [{ action: 'DelegatedToProtocol' }] + + async build(params: ActionBuilderParams): Promise { + return this._delegateToProtocol({ + protocolName: params.step.inputs.position.pool.id.protocol.name, + actionBuilderParams: params, + }) + } } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts index 4bcff20413..5269220efa 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/PositionCreatedActionBuilder.ts @@ -1,19 +1,21 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { PositionCreatedAction } from '../actions/PositionCreatedAction' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' +export class PositionCreatedActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [{ action: PositionCreatedAction }] -export const PositionCreatedActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { context, step } = params + async build(params: ActionBuilderParams): Promise { + const { context, step } = params - context.addActionCall({ - step: step, - action: new PositionCreatedAction(), - arguments: { - position: step.inputs.position, - }, - connectedInputs: {}, - connectedOutputs: {}, - }) + context.addActionCall({ + step: step, + action: new PositionCreatedAction(), + arguments: { + position: step.inputs.position, + }, + connectedInputs: {}, + connectedOutputs: {}, + }) + } } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/PullTokenActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/PullTokenActionBuilder.ts index 90ff3c00bc..489a8c1dab 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/PullTokenActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/PullTokenActionBuilder.ts @@ -1,23 +1,23 @@ import { steps, getValueFromReference } from '@summerfi/sdk-common/simulation' -import { ActionNames } from '@summerfi/deployment-types' -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { PullTokenAction } from '../actions/PullTokenAction' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const PullTokenActionList: ActionNames[] = ['PullToken'] +export class PullTokenActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [{ action: PullTokenAction }] -export const PullTokenActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { context, positionsManager, step } = params + async build(params: ActionBuilderParams): Promise { + const { context, positionsManager, step } = params - context.addActionCall({ - step: params.step, - action: new PullTokenAction(), - arguments: { - pullAmount: getValueFromReference(step.inputs.amount), - pullFrom: positionsManager.address, - }, - connectedInputs: {}, - connectedOutputs: {}, - }) + context.addActionCall({ + step: params.step, + action: new PullTokenAction(), + arguments: { + pullAmount: getValueFromReference(step.inputs.amount), + pullFrom: positionsManager.address, + }, + connectedInputs: {}, + connectedOutputs: {}, + }) + } } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/RepayFlashloanActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/RepayFlashloanActionBuilder.ts index 6f028a35ae..cc9be6402d 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/RepayFlashloanActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/RepayFlashloanActionBuilder.ts @@ -1,11 +1,9 @@ import { FlashloanProvider, steps } from '@summerfi/sdk-common/simulation' -import { ActionNames } from '@summerfi/deployment-types' -import { ActionBuilder, ActionBuilderParams } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { SendTokenAction } from '../actions/SendTokenAction' import { FlashloanAction } from '../actions/FlashloanAction' import { getContractAddress } from '../../utils/GetContractAddress' - -export const PaybackFlashloanActionList: ActionNames[] = [] +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' /* This values are coming from TakeFlashloan contract data types */ export const FlashloanProviderMap: Record = { @@ -13,43 +11,51 @@ export const FlashloanProviderMap: Record = { [FlashloanProvider.Balancer]: 1, } -export const RepayFlashloanActionBuilder: ActionBuilder = async ( - params: ActionBuilderParams, -): Promise => { - const { user, context, step, addressBookManager } = params +export class RepayFlashloanActionBuilder extends BaseActionBuilder { + /** + * Special case for this action builder: the Flashloan action is not declared in the list of used + * actions as it was already declared in the FlashloanActionBuilder. This is due to the Flashloan + * inversion problem in which the flashloan action is used when the RepayFlashloan step is built, + * but for the strategy definition we need to have the action registered at the Flashloan builder moment + */ + readonly actions: ActionBuilderUsedAction[] = [{ action: SendTokenAction }] - const operationExecutorAddress = await getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'OperationExecutor', - }) + async build(params: ActionBuilderParams): Promise { + const { user, context, step, addressBookManager } = params - context.addActionCall({ - step: step, - action: new SendTokenAction(), - arguments: { - sendAmount: step.inputs.amount, - sendTo: operationExecutorAddress, - }, - connectedInputs: {}, - connectedOutputs: {}, - }) + const operationExecutorAddress = await getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'OperationExecutor', + }) - // End the current subcontext and pass the subcontext calls to the flashloan action - const { callsBatch, customData } = context.endSubContext() - if (!customData) { - throw new Error('RepayFlashloanBuilder: customData is undefined') - } + context.addActionCall({ + step: step, + action: new SendTokenAction(), + arguments: { + sendAmount: step.inputs.amount, + sendTo: operationExecutorAddress, + }, + connectedInputs: {}, + connectedOutputs: {}, + }) - context.addActionCall({ - step: step, - action: new FlashloanAction(), - arguments: { - amount: customData.amount, - provider: FlashloanProviderMap[customData.provider], - calls: callsBatch, - }, - connectedInputs: {}, - connectedOutputs: {}, - }) + // End the current subcontext and pass the subcontext calls to the flashloan action + const { callsBatch, customData } = context.endSubContext() + if (!customData) { + throw new Error('RepayFlashloanBuilder: customData is undefined') + } + + context.addActionCall({ + step: step, + action: new FlashloanAction(), + arguments: { + amount: customData.amount, + provider: FlashloanProviderMap[customData.provider], + calls: callsBatch, + }, + connectedInputs: {}, + connectedOutputs: {}, + }) + } } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/ReturnFundsActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/ReturnFundsActionBuilder.ts index 4e69f45b54..3cc291e9d6 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/ReturnFundsActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/ReturnFundsActionBuilder.ts @@ -1,19 +1,22 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { ReturnFundsAction } from '../actions/ReturnFundsAction' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const ReturnFundsActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { context, step } = params +export class ReturnFundsActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [{ action: ReturnFundsAction }] - context.addActionCall({ - step: step, - action: new ReturnFundsAction(), - arguments: { - asset: step.inputs.token, - }, - connectedInputs: {}, - connectedOutputs: {}, - }) + async build(params: ActionBuilderParams): Promise { + const { context, step } = params + + context.addActionCall({ + step: step, + action: new ReturnFundsAction(), + arguments: { + asset: step.inputs.token, + }, + connectedInputs: {}, + connectedOutputs: {}, + }) + } } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/SwapActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/SwapActionBuilder.ts index 8a0026acef..6019098c40 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/SwapActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/SwapActionBuilder.ts @@ -1,38 +1,42 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { SwapAction } from '../actions/SwapAction' -import { getContractAddress } from '../../utils/GetContractAddress' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const SwapActionBuilder: ActionBuilder = async (params): Promise => { - const { context, user, swapManager, addressBookManager, step } = params +export class SwapActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [{ action: SwapAction }] - const swapContractAddress = await getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'Swap', - }) + async build(params: ActionBuilderParams): Promise { + const { context, user, swapManager, addressBookManager, step } = params - const swapData = await swapManager.getSwapDataExactInput({ - chainInfo: params.user.chainInfo, - fromAmount: step.inputs.inputAmountAfterFee, - toToken: step.inputs.minimumReceivedAmount.token, - recipient: swapContractAddress, - slippage: step.inputs.slippage, - }) + const swapContractAddress = await this._getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'Swap', + }) - context.addActionCall({ - step: step, - action: new SwapAction(), - arguments: { - fromAmount: step.inputs.inputAmount, - toMinimumAmount: step.inputs.minimumReceivedAmount, - fee: step.inputs.summerFee, - withData: swapData.calldata, - collectFeeInFromToken: true, - }, - connectedInputs: {}, - connectedOutputs: { - received: 'received', - }, - }) + const swapData = await swapManager.getSwapDataExactInput({ + chainInfo: params.user.chainInfo, + fromAmount: step.inputs.inputAmountAfterFee, + toToken: step.inputs.minimumReceivedAmount.token, + recipient: swapContractAddress, + slippage: step.inputs.slippage, + }) + + context.addActionCall({ + step: step, + action: new SwapAction(), + arguments: { + fromAmount: step.inputs.inputAmount, + toMinimumAmount: step.inputs.minimumReceivedAmount, + fee: step.inputs.summerFee, + withData: swapData.calldata, + collectFeeInFromToken: true, + }, + connectedInputs: {}, + connectedOutputs: { + received: 'received', + }, + }) + } } diff --git a/sdk/protocol-plugins/src/plugins/common/builders/index.ts b/sdk/protocol-plugins/src/plugins/common/builders/index.ts index 99456eab44..d56f468f26 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/index.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/index.ts @@ -1,14 +1,10 @@ -export { DepositBorrowActionBuilder } from './DepositBorrowActionBuilder' -export { FlashloanActionBuilder, FlashloanActionList } from './FlashloanActionBuilder' -export { PaybackWithdrawActionBuilder } from './PaybackWithdrawActionBuilder' -export { PullTokenActionBuilder, PullTokenActionList } from './PullTokenActionBuilder' -export { - FlashloanProviderMap, - PaybackFlashloanActionList, - RepayFlashloanActionBuilder, -} from './RepayFlashloanActionBuilder' -export { ReturnFundsActionBuilder } from './ReturnFundsActionBuilder' -export { SwapActionBuilder } from './SwapActionBuilder' -export { PositionCreatedActionBuilder } from './PositionCreatedActionBuilder' -export { ImportPositionActionBuilder } from './ImportPositionActionBuilder' -export { OpenPositionActionBuilder } from './OpenPositionActionBuilder' +export * from './DepositBorrowActionBuilder' +export * from './FlashloanActionBuilder' +export * from './PaybackWithdrawActionBuilder' +export * from './PullTokenActionBuilder' +export * from './RepayFlashloanActionBuilder' +export * from './ReturnFundsActionBuilder' +export * from './SwapActionBuilder' +export * from './PositionCreatedActionBuilder' +export * from './ImportPositionActionBuilder' +export * from './OpenPositionActionBuilder' diff --git a/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts index eafbb11486..0879f7e98a 100644 --- a/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/maker/builders/MakerImportPositionActionBuilder.ts @@ -1,31 +1,36 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { ProtocolName } from '@summerfi/sdk-common/protocols' import { isMakerLendingPoolId } from '../interfaces/IMakerLendingPoolId' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const MakerImportPositionActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { protocolsRegistry, step, user, context, positionsManager } = params +export class MakerImportPositionActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [ + // Empty on purpose, no definition needs to be generated for this builder + ] - if (!isMakerLendingPoolId(step.inputs.externalPosition.position.pool.id)) { - throw new Error('Invalid Maker lending pool id') - } + async build(params: ActionBuilderParams): Promise { + const { protocolsRegistry, step, user, context, positionsManager } = params - const makerPlugin = protocolsRegistry.getPlugin({ protocolName: ProtocolName.Maker }) - if (!makerPlugin) { - throw new Error('Maker plugin not found') - } + if (!isMakerLendingPoolId(step.inputs.externalPosition.position.pool.id)) { + throw new Error('Invalid Maker lending pool id') + } - const importPositionTransaction = await makerPlugin.getImportPositionTransaction({ - user: user, - externalPosition: step.inputs.externalPosition, - positionsManager: positionsManager, - }) + const makerPlugin = protocolsRegistry.getPlugin({ protocolName: ProtocolName.Maker }) + if (!makerPlugin) { + throw new Error('Maker plugin not found') + } - if (!importPositionTransaction) { - throw new Error('Maker: Import position transaction not found') - } + const importPositionTransaction = await makerPlugin.getImportPositionTransaction({ + user: user, + externalPosition: step.inputs.externalPosition, + positionsManager: positionsManager, + }) - context.addTransaction({ transaction: importPositionTransaction }) + if (!importPositionTransaction) { + throw new Error('Maker: Import position transaction not found') + } + + context.addTransaction({ transaction: importPositionTransaction }) + } } diff --git a/sdk/protocol-plugins/src/plugins/maker/builders/MakerOpenPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/maker/builders/MakerOpenPositionActionBuilder.ts index c0de352ce9..1440c11077 100644 --- a/sdk/protocol-plugins/src/plugins/maker/builders/MakerOpenPositionActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/maker/builders/MakerOpenPositionActionBuilder.ts @@ -1,15 +1,20 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { isMakerLendingPool } from '../interfaces/IMakerLendingPool' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const MakerOpenPositionActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { step } = params +export class MakerOpenPositionActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [ + // Empty on purpose, no definition needs to be generated for this builder + ] - if (!isMakerLendingPool(step.inputs.pool)) { - throw new Error('Invalid Maker lending pool id') - } + async build(params: ActionBuilderParams): Promise { + const { step } = params + + if (!isMakerLendingPool(step.inputs.pool)) { + throw new Error('Invalid Maker lending pool id') + } - // No-op for Maker + // No-op for Maker + } } diff --git a/sdk/protocol-plugins/src/plugins/maker/builders/MakerPaybackWithdrawActionBuilder.ts b/sdk/protocol-plugins/src/plugins/maker/builders/MakerPaybackWithdrawActionBuilder.ts index dc45d0b96e..1c2073045f 100644 --- a/sdk/protocol-plugins/src/plugins/maker/builders/MakerPaybackWithdrawActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/maker/builders/MakerPaybackWithdrawActionBuilder.ts @@ -1,60 +1,65 @@ import { getValueFromReference, steps } from '@summerfi/sdk-common/simulation' import { MakerPaybackAction } from '../actions/MakerPaybackAction' import { MakerWithdrawAction } from '../actions/MakerWithdrawAction' -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { MakerIlkToJoinMap } from '../types/MakerIlkToJoinMap' import { isMakerLendingPoolId } from '../interfaces/IMakerLendingPoolId' -import { getContractAddress } from '../../utils/GetContractAddress' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const MakerPaybackWithdrawActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { context, user, positionsManager, step, addressBookManager } = params +export class MakerPaybackWithdrawActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [ + { action: MakerPaybackAction, isOptionalTags: ['paybackAmount'] }, + { action: MakerWithdrawAction }, + ] - if (!isMakerLendingPoolId(step.inputs.position.pool.id)) { - throw new Error('Invalid Maker lending pool id') - } + async build(params: ActionBuilderParams): Promise { + const { context, user, positionsManager, step, addressBookManager } = params + + if (!isMakerLendingPoolId(step.inputs.position.pool.id)) { + throw new Error('Invalid Maker lending pool id') + } - const ilkType = step.inputs.position.pool.id.ilkType + const ilkType = step.inputs.position.pool.id.ilkType - const joinName = MakerIlkToJoinMap[ilkType] - const joinAddress = await getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: joinName, - }) + const joinName = MakerIlkToJoinMap[ilkType] + const joinAddress = await this._getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: joinName, + }) - const paybackAmount = getValueFromReference(step.inputs.paybackAmount) + const paybackAmount = getValueFromReference(step.inputs.paybackAmount) + + if (!paybackAmount.toBN().isZero()) { + context.addActionCall({ + step: params.step, + action: new MakerPaybackAction(), + arguments: { + position: step.inputs.position, + positionsManager: positionsManager, + amount: getValueFromReference(step.inputs.paybackAmount), + paybackAll: paybackAmount.toBN().gte(step.inputs.position.debtAmount.toBN()), + }, + connectedInputs: {}, + connectedOutputs: { + paybackAmount: 'amountPaidBack', + }, + }) + } - if (!paybackAmount.toBN().isZero()) { context.addActionCall({ - step: params.step, - action: new MakerPaybackAction(), + step: step, + action: new MakerWithdrawAction(), arguments: { position: step.inputs.position, positionsManager: positionsManager, - amount: getValueFromReference(step.inputs.paybackAmount), - paybackAll: paybackAmount.toBN().gte(step.inputs.position.debtAmount.toBN()), + amount: step.inputs.withdrawAmount, + joinAddress: joinAddress, }, connectedInputs: {}, connectedOutputs: { - paybackAmount: 'amountPaidBack', + withdrawAmount: 'amountWithdrawn', }, }) } - - context.addActionCall({ - step: step, - action: new MakerWithdrawAction(), - arguments: { - position: step.inputs.position, - positionsManager: positionsManager, - amount: step.inputs.withdrawAmount, - joinAddress: joinAddress, - }, - connectedInputs: {}, - connectedOutputs: { - withdrawAmount: 'amountWithdrawn', - }, - }) } diff --git a/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoDepositBorrowActionBuilder.ts b/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoDepositBorrowActionBuilder.ts index eac143fae6..3c31f23b86 100644 --- a/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoDepositBorrowActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoDepositBorrowActionBuilder.ts @@ -3,94 +3,100 @@ import { getValueFromReference, TokenTransferTargetType, } from '@summerfi/sdk-common/simulation' - import { MorphoBorrowAction } from '../actions/MorphoBorrowAction' import { MorphoDepositAction } from '../actions/MorphoDepositAction' -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { SendTokenAction, SetApprovalAction } from '../../common' import { isMorphoLendingPool } from '../interfaces/IMorphoLendingPool' -import { getContractAddress } from '../../utils/GetContractAddress' - -export const MorphoDepositBorrowActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { context, user, step, addressBookManager } = params - - if (!isMorphoLendingPool(step.inputs.position.pool)) { - throw new Error('Invalid Morpho lending pool id') - } +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' - const morphoBlueAddress = await getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'MorphoBlue', - }) +export class MorphoDepositBorrowActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [ + { action: SetApprovalAction }, + { action: MorphoDepositAction }, + { action: MorphoBorrowAction, isOptionalTags: ['borrowAmount'] }, + { action: SendTokenAction, isOptionalTags: ['borrowAmount', 'borrowTargetType'] }, + ] - context.addActionCall({ - step: step, - action: new SetApprovalAction(), - arguments: { - approvalAmount: getValueFromReference(step.inputs.depositAmount), - delegate: morphoBlueAddress, - sumAmounts: false, - }, - connectedInputs: { - depositAmount: 'approvalAmount', - }, - connectedOutputs: {}, - }) + async build(params: ActionBuilderParams): Promise { + const { context, user, step, addressBookManager } = params - context.addActionCall({ - step: params.step, - action: new MorphoDepositAction(), - arguments: { - morphoLendingPool: step.inputs.position.pool, - amount: getValueFromReference(step.inputs.depositAmount), - sumAmounts: false, - }, - connectedInputs: { - depositAmount: 'amount', - }, - connectedOutputs: { - depositAmount: 'depositedAmount', - }, - }) + if (!isMorphoLendingPool(step.inputs.position.pool)) { + throw new Error('Invalid Morpho lending pool id') + } - const borrowAmount = getValueFromReference(step.inputs.borrowAmount) + const morphoBlueAddress = await this._getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'MorphoBlue', + }) - if (!borrowAmount.toBN().isZero()) { context.addActionCall({ step: step, - action: new MorphoBorrowAction(), + action: new SetApprovalAction(), + arguments: { + approvalAmount: getValueFromReference(step.inputs.depositAmount), + delegate: morphoBlueAddress, + sumAmounts: false, + }, + connectedInputs: { + depositAmount: 'approvalAmount', + }, + connectedOutputs: {}, + }) + + context.addActionCall({ + step: params.step, + action: new MorphoDepositAction(), arguments: { morphoLendingPool: step.inputs.position.pool, - amount: borrowAmount, + amount: getValueFromReference(step.inputs.depositAmount), + sumAmounts: false, + }, + connectedInputs: { + depositAmount: 'amount', }, - connectedInputs: {}, connectedOutputs: { - borrowAmount: 'borrowedAmount', + depositAmount: 'depositedAmount', }, }) - if (step.inputs.borrowTargetType !== TokenTransferTargetType.PositionsManager) { - const operationExecutorAddress = await getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'OperationExecutor', - }) + const borrowAmount = getValueFromReference(step.inputs.borrowAmount) + if (!borrowAmount.toBN().isZero()) { context.addActionCall({ step: step, - action: new SendTokenAction(), + action: new MorphoBorrowAction(), arguments: { - sendAmount: borrowAmount, - sendTo: operationExecutorAddress, + morphoLendingPool: step.inputs.position.pool, + amount: borrowAmount, }, - connectedInputs: { - borrowAmount: 'amount', + connectedInputs: {}, + connectedOutputs: { + borrowAmount: 'borrowedAmount', }, - connectedOutputs: {}, }) + + if (step.inputs.borrowTargetType !== TokenTransferTargetType.PositionsManager) { + const operationExecutorAddress = await this._getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'OperationExecutor', + }) + + context.addActionCall({ + step: step, + action: new SendTokenAction(), + arguments: { + sendAmount: borrowAmount, + sendTo: operationExecutorAddress, + }, + connectedInputs: { + borrowAmount: 'amount', + }, + connectedOutputs: {}, + }) + } } } } diff --git a/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoOpenPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoOpenPositionActionBuilder.ts index de1bc5ea61..e256ad0d35 100644 --- a/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoOpenPositionActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoOpenPositionActionBuilder.ts @@ -1,15 +1,20 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { isMorphoLendingPool } from '../interfaces/IMorphoLendingPool' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const MorphoOpenPositionActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { step } = params +export class MorphoOpenPositionActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [ + // Empty on purpose, no definition needs to be generated for this builder + ] - if (!isMorphoLendingPool(step.inputs.pool)) { - throw new Error('Invalid Morpho lending pool id') - } + async build(params: ActionBuilderParams): Promise { + const { step } = params + + if (!isMorphoLendingPool(step.inputs.pool)) { + throw new Error('Invalid Morpho lending pool id') + } - // No-op for Morpho + // No-op for Morpho + } } diff --git a/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoPaybackWithdrawActionBuilder.ts b/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoPaybackWithdrawActionBuilder.ts index b3398b1071..6da70bc675 100644 --- a/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoPaybackWithdrawActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoPaybackWithdrawActionBuilder.ts @@ -1,71 +1,77 @@ import { getValueFromReference, steps } from '@summerfi/sdk-common/simulation' -import { ActionBuilder } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { isMorphoLendingPool } from '../interfaces/IMorphoLendingPool' import { MorphoPaybackAction, MorphoWithdrawAction } from '../actions' import { SetApprovalAction } from '../../common' -import { getContractAddress } from '../../utils/GetContractAddress' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const MorphoPaybackWithdrawActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { context, positionsManager, step, addressBookManager, user } = params +export class MorphoPaybackWithdrawActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [ + { action: SetApprovalAction, isOptionalTags: ['paybackAmount'] }, + { action: MorphoPaybackAction, isOptionalTags: ['paybackAmount'] }, + { action: MorphoWithdrawAction }, + ] - if (!isMorphoLendingPool(step.inputs.position.pool)) { - throw new Error('Invalid Morpho lending pool id') - } - - const morphoBlueAddress = await getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'MorphoBlue', - }) + async build(params: ActionBuilderParams): Promise { + const { context, positionsManager, step, addressBookManager, user } = params - const paybackAmount = getValueFromReference(step.inputs.paybackAmount) + if (!isMorphoLendingPool(step.inputs.position.pool)) { + throw new Error('Invalid Morpho lending pool id') + } - if (!paybackAmount.toBN().isZero()) { - context.addActionCall({ - step: params.step, - action: new SetApprovalAction(), - arguments: { - approvalAmount: getValueFromReference(step.inputs.paybackAmount), - delegate: morphoBlueAddress, - sumAmounts: false, - }, - connectedInputs: { - paybackAmount: 'approvalAmount', - }, - connectedOutputs: {}, + const morphoBlueAddress = await this._getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'MorphoBlue', }) + const paybackAmount = getValueFromReference(step.inputs.paybackAmount) + + if (!paybackAmount.toBN().isZero()) { + context.addActionCall({ + step: params.step, + action: new SetApprovalAction(), + arguments: { + approvalAmount: getValueFromReference(step.inputs.paybackAmount), + delegate: morphoBlueAddress, + sumAmounts: false, + }, + connectedInputs: { + paybackAmount: 'approvalAmount', + }, + connectedOutputs: {}, + }) + + context.addActionCall({ + step: params.step, + action: new MorphoPaybackAction(), + arguments: { + morphoLendingPool: step.inputs.position.pool, + amount: getValueFromReference(step.inputs.paybackAmount), + onBehalf: positionsManager.address, + paybackAll: paybackAmount.toBN().gte(step.inputs.position.debtAmount.toBN()), + }, + connectedInputs: { + paybackAmount: 'amount', + }, + connectedOutputs: { + paybackAmount: 'paybackedAmount', + }, + }) + } + context.addActionCall({ - step: params.step, - action: new MorphoPaybackAction(), + step: step, + action: new MorphoWithdrawAction(), arguments: { morphoLendingPool: step.inputs.position.pool, - amount: getValueFromReference(step.inputs.paybackAmount), - onBehalf: positionsManager.address, - paybackAll: paybackAmount.toBN().gte(step.inputs.position.debtAmount.toBN()), - }, - connectedInputs: { - paybackAmount: 'amount', + amount: step.inputs.withdrawAmount, + to: positionsManager.address, }, + connectedInputs: {}, connectedOutputs: { - paybackAmount: 'paybackedAmount', + withdrawAmount: 'withdrawnAmount', }, }) } - - context.addActionCall({ - step: step, - action: new MorphoWithdrawAction(), - arguments: { - morphoLendingPool: step.inputs.position.pool, - amount: step.inputs.withdrawAmount, - to: positionsManager.address, - }, - connectedInputs: {}, - connectedOutputs: { - withdrawAmount: 'withdrawnAmount', - }, - }) } diff --git a/sdk/protocol-plugins/src/plugins/spark/builders/SparkDepositBorrowActionBuilder.ts b/sdk/protocol-plugins/src/plugins/spark/builders/SparkDepositBorrowActionBuilder.ts index c7cc6a491f..661917f536 100644 --- a/sdk/protocol-plugins/src/plugins/spark/builders/SparkDepositBorrowActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/spark/builders/SparkDepositBorrowActionBuilder.ts @@ -3,92 +3,105 @@ import { getValueFromReference, TokenTransferTargetType, } from '@summerfi/sdk-common/simulation' -import { ActionNames } from '@summerfi/deployment-types' - import { SparkBorrowAction } from '../actions/SparkBorrowAction' import { SparkDepositAction } from '../actions/SparkDepositAction' import { IAddress } from '@summerfi/sdk-common/common' -import { ActionBuilder, ActionBuilderParams } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { SetApprovalAction } from '../../common' import { getContractAddress } from '../../utils/GetContractAddress' import { isSparkLendingPool } from '../interfaces/ISparkLendingPool' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const SparkDepositBorrowActionList: ActionNames[] = ['SparkDeposit', 'SparkBorrow'] - -async function getBorrowTargetAddress( - params: ActionBuilderParams, -): Promise { - const { user, step, positionsManager, addressBookManager } = params - if (step.inputs.borrowTargetType === TokenTransferTargetType.PositionsManager) { - return positionsManager.address - } - - return getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'OperationExecutor', - }) -} - -export const SparkDepositBorrowActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { context, user, step, addressBookManager } = params +export class SparkDepositBorrowActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [ + { action: SetApprovalAction }, + { action: SparkDepositAction }, + { action: SparkBorrowAction, isOptionalTags: ['borrowAmount'] }, + ] - if (!isSparkLendingPool(step.inputs.position.pool)) { - throw new Error('Invalid Spark lending pool') - } - - const sparkLendingPoolAddress = await getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'SparkLendingPool', - }) - - context.addActionCall({ - step: step, - action: new SetApprovalAction(), - arguments: { - approvalAmount: getValueFromReference(step.inputs.depositAmount), - delegate: sparkLendingPoolAddress, - sumAmounts: false, - }, - connectedInputs: { - depositAmount: 'approvalAmount', - }, - connectedOutputs: {}, - }) + async build(params: ActionBuilderParams): Promise { + const { context, user, step, addressBookManager } = params - context.addActionCall({ - step: params.step, - action: new SparkDepositAction(), - arguments: { - depositAmount: getValueFromReference(step.inputs.depositAmount), - sumAmounts: false, - setAsCollateral: true, - }, - connectedInputs: { - depositAmount: 'amountToDeposit', - }, - connectedOutputs: { - depositAmount: 'depositedAmount', - }, - }) + if (!isSparkLendingPool(step.inputs.position.pool)) { + throw new Error('Invalid Spark lending pool') + } - const borrowAmount = getValueFromReference(step.inputs.borrowAmount) + const sparkLendingPoolAddress = await this._getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'SparkLendingPool', + }) - if (!borrowAmount.toBN().isZero()) { context.addActionCall({ step: step, - action: new SparkBorrowAction(), + action: new SetApprovalAction(), arguments: { - borrowAmount: borrowAmount, - borrowTo: await getBorrowTargetAddress(params), + approvalAmount: getValueFromReference(step.inputs.depositAmount), + delegate: sparkLendingPoolAddress, + sumAmounts: false, + }, + connectedInputs: { + depositAmount: 'approvalAmount', + }, + connectedOutputs: {}, + }) + + context.addActionCall({ + step: params.step, + action: new SparkDepositAction(), + arguments: { + depositAmount: getValueFromReference(step.inputs.depositAmount), + sumAmounts: false, + setAsCollateral: true, + }, + connectedInputs: { + depositAmount: 'amountToDeposit', }, - connectedInputs: {}, connectedOutputs: { - borrowAmount: 'borrowedAmount', + depositAmount: 'depositedAmount', }, }) + + const borrowAmount = getValueFromReference(step.inputs.borrowAmount) + + if (!borrowAmount.toBN().isZero()) { + context.addActionCall({ + step: step, + action: new SparkBorrowAction(), + arguments: { + borrowAmount: borrowAmount, + borrowTo: await this._getBorrowTargetAddress(params), + }, + connectedInputs: {}, + connectedOutputs: { + borrowAmount: 'borrowedAmount', + }, + }) + } + } + + /** + * Resolves the target address for the borrow action based on the borrow target type + * @param params The parameters for the action builder + * @returns The address of the target contract + */ + private async _getBorrowTargetAddress( + params: ActionBuilderParams, + ): Promise { + const { user, step, positionsManager, addressBookManager } = params + + switch (step.inputs.borrowTargetType) { + case TokenTransferTargetType.PositionsManager: + return positionsManager.address + + case TokenTransferTargetType.StrategyExecutor: + return getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'OperationExecutor', + }) + default: + throw new Error(`Invalid borrow target type: ${step.inputs.borrowTargetType}`) + } } } diff --git a/sdk/protocol-plugins/src/plugins/spark/builders/SparkOpenPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/spark/builders/SparkOpenPositionActionBuilder.ts index 1186305240..c3d255c0bf 100644 --- a/sdk/protocol-plugins/src/plugins/spark/builders/SparkOpenPositionActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/spark/builders/SparkOpenPositionActionBuilder.ts @@ -1,30 +1,31 @@ import { steps } from '@summerfi/sdk-common/simulation' -import { ActionNames } from '@summerfi/deployment-types' - -import { ActionBuilder } from '@summerfi/protocol-plugins-common' import { isSparkLendingPool } from '../interfaces' import { SparkSetEmodeAction } from '../actions' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const SparkOpenPositionList: ActionNames[] = ['SparkSetEMode'] +export class SparkOpenPositionActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [ + // Empty on purpose, no definition needs to be generated for this builder + ] -export const SparkOpenPositionActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { context, step } = params + async build(params: ActionBuilderParams): Promise { + const { context, step } = params - if (!isSparkLendingPool(step.inputs.pool)) { - throw new Error('Invalid Spark lending pool') - } + if (!isSparkLendingPool(step.inputs.pool)) { + throw new Error('Invalid Spark lending pool') + } - const pool = step.inputs.pool + const pool = step.inputs.pool - context.addActionCall({ - step: step, - action: new SparkSetEmodeAction(), - arguments: { - emode: pool.id.emodeType, - }, - connectedInputs: {}, - connectedOutputs: {}, - }) + context.addActionCall({ + step: step, + action: new SparkSetEmodeAction(), + arguments: { + emode: pool.id.emodeType, + }, + connectedInputs: {}, + connectedOutputs: {}, + }) + } } diff --git a/sdk/protocol-plugins/src/plugins/spark/builders/SparkPaybackWithdrawActionBuilder.ts b/sdk/protocol-plugins/src/plugins/spark/builders/SparkPaybackWithdrawActionBuilder.ts index 18bc8081d3..e44974a72d 100644 --- a/sdk/protocol-plugins/src/plugins/spark/builders/SparkPaybackWithdrawActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/spark/builders/SparkPaybackWithdrawActionBuilder.ts @@ -3,95 +3,108 @@ import { getValueFromReference, TokenTransferTargetType, } from '@summerfi/sdk-common/simulation' -import { ActionNames } from '@summerfi/deployment-types' - import { IAddress } from '@summerfi/sdk-common/common' -import { ActionBuilder, ActionBuilderParams } from '@summerfi/protocol-plugins-common' +import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' import { SetApprovalAction } from '../../common' import { SparkWithdrawAction } from '../actions/SparkWithdrawAction' import { SparkPaybackAction } from '../actions/SparkPaybackAction' import { getContractAddress } from '../../utils/GetContractAddress' import { isSparkLendingPool } from '../interfaces/ISparkLendingPool' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' -export const SparkPaybackWithdrawActionList: ActionNames[] = ['SparkPayback', 'SparkWithdraw'] +export class SparkPaybackWithdrawActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [ + { action: SetApprovalAction, isOptionalTags: ['paybackAmount'] }, + { action: SparkPaybackAction, isOptionalTags: ['paybackAmount'] }, + { action: SparkWithdrawAction, isOptionalTags: ['withdrawAmount'] }, + ] -async function getWithdrawTargetAddress( - params: ActionBuilderParams, -): Promise { - const { user, step, positionsManager, addressBookManager } = params - if (step.inputs.withdrawTargetType === TokenTransferTargetType.PositionsManager) { - return positionsManager.address - } + async build(params: ActionBuilderParams): Promise { + const { context, step, addressBookManager, user } = params - return getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'OperationExecutor', - }) -} + if (!isSparkLendingPool(step.inputs.position.pool)) { + throw new Error('Invalid Spark lending pool') + } -export const SparkPaybackWithdrawActionBuilder: ActionBuilder = async ( - params, -): Promise => { - const { context, step, addressBookManager, user } = params + const sparkLendingPoolAddress = await this._getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'SparkLendingPool', + }) - if (!isSparkLendingPool(step.inputs.position.pool)) { - throw new Error('Invalid Spark lending pool') - } + const paybackAmount = getValueFromReference(step.inputs.paybackAmount) - const sparkLendingPoolAddress = await getContractAddress({ - addressBookManager, - chainInfo: user.chainInfo, - contractName: 'SparkLendingPool', - }) + if (!paybackAmount.toBN().isZero()) { + context.addActionCall({ + step: step, + action: new SetApprovalAction(), + arguments: { + approvalAmount: getValueFromReference(step.inputs.paybackAmount), + delegate: sparkLendingPoolAddress, + sumAmounts: false, + }, + connectedInputs: { + paybackAmount: 'approvalAmount', + }, + connectedOutputs: {}, + }) - const paybackAmount = getValueFromReference(step.inputs.paybackAmount) + context.addActionCall({ + step: params.step, + action: new SparkPaybackAction(), + arguments: { + paybackAmount: getValueFromReference(step.inputs.paybackAmount), + paybackAll: getValueFromReference(step.inputs.paybackAmount) + .toBN() + .gt(step.inputs.position.debtAmount.toBN()), + }, + connectedInputs: {}, + connectedOutputs: { + paybackAmount: 'paybackedAmount', + }, + }) + } - if (!paybackAmount.toBN().isZero()) { - context.addActionCall({ - step: step, - action: new SetApprovalAction(), - arguments: { - approvalAmount: getValueFromReference(step.inputs.paybackAmount), - delegate: sparkLendingPoolAddress, - sumAmounts: false, - }, - connectedInputs: { - paybackAmount: 'approvalAmount', - }, - connectedOutputs: {}, - }) + const withdrawAmount = getValueFromReference(step.inputs.withdrawAmount) - context.addActionCall({ - step: params.step, - action: new SparkPaybackAction(), - arguments: { - paybackAmount: getValueFromReference(step.inputs.paybackAmount), - paybackAll: getValueFromReference(step.inputs.paybackAmount) - .toBN() - .gt(step.inputs.position.debtAmount.toBN()), - }, - connectedInputs: {}, - connectedOutputs: { - paybackAmount: 'paybackedAmount', - }, - }) + if (!withdrawAmount.toBN().isZero()) { + context.addActionCall({ + step: step, + action: new SparkWithdrawAction(), + arguments: { + withdrawAmount: withdrawAmount, + withdrawTo: await this._getWithdrawTargetAddress(params), + }, + connectedInputs: {}, + connectedOutputs: { + withdrawAmount: 'withdrawnAmount', + }, + }) + } } - const withdrawAmount = getValueFromReference(step.inputs.withdrawAmount) + /** + * Resolves the target address for the withdraw action based on the withdraw target type + * @param params The parameters for the action builder + * @returns The address of the target contract + */ + private async _getWithdrawTargetAddress( + params: ActionBuilderParams, + ): Promise { + const { user, step, positionsManager, addressBookManager } = params - if (!withdrawAmount.toBN().isZero()) { - context.addActionCall({ - step: step, - action: new SparkWithdrawAction(), - arguments: { - withdrawAmount: withdrawAmount, - withdrawTo: await getWithdrawTargetAddress(params), - }, - connectedInputs: {}, - connectedOutputs: { - withdrawAmount: 'withdrawnAmount', - }, - }) + switch (step.inputs.withdrawTargetType) { + case TokenTransferTargetType.PositionsManager: + return positionsManager.address + + case TokenTransferTargetType.StrategyExecutor: + return getContractAddress({ + addressBookManager, + chainInfo: user.chainInfo, + contractName: 'OperationExecutor', + }) + default: + throw new Error(`Invalid withdraw target type: ${step.inputs.withdrawTargetType}`) + } } } diff --git a/sdk/protocol-plugins/src/plugins/utils/DelegateToProtocolActionBuilder.ts b/sdk/protocol-plugins/src/plugins/utils/DelegateToProtocolActionBuilder.ts deleted file mode 100644 index 3d08a96133..0000000000 --- a/sdk/protocol-plugins/src/plugins/utils/DelegateToProtocolActionBuilder.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ActionBuilderParams, FilterStep } from '@summerfi/protocol-plugins-common' -import { ProtocolName } from '@summerfi/sdk-common/protocols' -import { SimulationSteps, steps } from '@summerfi/sdk-common/simulation' - -export async function delegateToProtocolActionBuilder(params: { - protocolName: ProtocolName - actionBuilderParams: ActionBuilderParams> -}): Promise { - const { protocolName } = params - const { protocolsRegistry } = params.actionBuilderParams - - const plugin = protocolsRegistry.getPlugin({ protocolName }) - if (!plugin) { - throw new Error(`No protocol plugin found for protocol ${protocolName}`) - } - - const builder = plugin.getActionBuilder(params.actionBuilderParams.step) - if (!builder) { - throw new Error(`No action builder found for protocol ${protocolName}`) - } - - return builder(params.actionBuilderParams) -} diff --git a/sdk/protocol-plugins/tests/unit/builders/DepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/DepositBorrowActionBuilder.spec.ts index 3c15776ec4..65736be223 100644 --- a/sdk/protocol-plugins/tests/unit/builders/DepositBorrowActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/DepositBorrowActionBuilder.spec.ts @@ -103,7 +103,7 @@ describe('Deposit Borrow Action Builder', () => { it('should fail if no protocol plugin exists', async () => { try { - await DepositBorrowActionBuilder({ + await new DepositBorrowActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, @@ -116,7 +116,7 @@ describe('Deposit Borrow Action Builder', () => { it('should fail if no protocol builder for the step exists', async () => { try { - await DepositBorrowActionBuilder({ + await new DepositBorrowActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyBuildersProtocolRegistry, @@ -128,7 +128,7 @@ describe('Deposit Borrow Action Builder', () => { }) it('should call the proper builder', async () => { - await DepositBorrowActionBuilder({ + await new DepositBorrowActionBuilder().build({ ...builderParams, step: derivedStep, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/FlashloanActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/FlashloanActionBuilder.spec.ts index 5f55485eee..80b7827359 100644 --- a/sdk/protocol-plugins/tests/unit/builders/FlashloanActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/FlashloanActionBuilder.spec.ts @@ -37,7 +37,7 @@ describe('Flashloan Action Builder', () => { }) it('should start a new subcontext', async () => { - await FlashloanActionBuilder({ + await new FlashloanActionBuilder().build({ ...builderParams, step: derivedStep, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/ImportPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/ImportPositionActionBuilder.spec.ts index febac39244..b708483fa0 100644 --- a/sdk/protocol-plugins/tests/unit/builders/ImportPositionActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/ImportPositionActionBuilder.spec.ts @@ -109,7 +109,7 @@ describe('Deposit Borrow Action Builder', () => { it('should fail if no protocol plugin exists', async () => { try { - await ImportPositionActionBuilder({ + await new ImportPositionActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, @@ -122,7 +122,7 @@ describe('Deposit Borrow Action Builder', () => { it('should fail if no protocol builder for the step exists', async () => { try { - await ImportPositionActionBuilder({ + await new ImportPositionActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyBuildersProtocolRegistry, @@ -134,7 +134,7 @@ describe('Deposit Borrow Action Builder', () => { }) it('should call the proper builder', async () => { - await ImportPositionActionBuilder({ + await new ImportPositionActionBuilder().build({ ...builderParams, step: derivedStep, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/OpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/OpenPositionActionBuilder.spec.ts index d54e59b9b9..2977aba66e 100644 --- a/sdk/protocol-plugins/tests/unit/builders/OpenPositionActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/OpenPositionActionBuilder.spec.ts @@ -100,7 +100,7 @@ describe('Deposit Borrow Action Builder', () => { it('should fail if no protocol plugin exists', async () => { try { - await OpenPositionActionBuilder({ + await new OpenPositionActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, @@ -113,7 +113,7 @@ describe('Deposit Borrow Action Builder', () => { it('should fail if no protocol builder for the step exists', async () => { try { - await OpenPositionActionBuilder({ + await new OpenPositionActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyBuildersProtocolRegistry, @@ -125,7 +125,7 @@ describe('Deposit Borrow Action Builder', () => { }) it('should call the proper builder', async () => { - await OpenPositionActionBuilder({ + await new OpenPositionActionBuilder().build({ ...builderParams, step: derivedStep, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/PaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/PaybackWithdrawActionBuilder.spec.ts index 517ecf8b11..d7825779b8 100644 --- a/sdk/protocol-plugins/tests/unit/builders/PaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/PaybackWithdrawActionBuilder.spec.ts @@ -98,7 +98,7 @@ describe('Payback Withdraw Action Builder', () => { it('should fail if no protocol plugin exists', async () => { try { - await PaybackWithdrawActionBuilder({ + await new PaybackWithdrawActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, @@ -111,7 +111,7 @@ describe('Payback Withdraw Action Builder', () => { it('should fail if no protocol builder for the step exists', async () => { try { - await PaybackWithdrawActionBuilder({ + await new PaybackWithdrawActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyBuildersProtocolRegistry, @@ -123,7 +123,7 @@ describe('Payback Withdraw Action Builder', () => { }) it('should call the proper builder', async () => { - await PaybackWithdrawActionBuilder({ + await new PaybackWithdrawActionBuilder().build({ ...builderParams, step: derivedStep, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/PullTokenActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/PullTokenActionBuilder.spec.ts index 872cb88138..5f5941b40d 100644 --- a/sdk/protocol-plugins/tests/unit/builders/PullTokenActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/PullTokenActionBuilder.spec.ts @@ -40,7 +40,7 @@ describe('Pull TokenAction Builder', () => { it('should encode the action calldata correctly', async () => { builderParams.context.startSubContext() - await PullTokenActionBuilder({ + await new PullTokenActionBuilder().build({ ...builderParams, step: derivedStep, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/RepayFlashloanActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/RepayFlashloanActionBuilder.spec.ts index 6c69b16b19..1ff1ad9994 100644 --- a/sdk/protocol-plugins/tests/unit/builders/RepayFlashloanActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/RepayFlashloanActionBuilder.spec.ts @@ -93,7 +93,7 @@ describe('Payback Flashloan Action Builder', () => { }) try { - await RepayFlashloanActionBuilder({ + await new RepayFlashloanActionBuilder().build({ ...builderParams, step: repayFlashloanStep, }) @@ -139,7 +139,7 @@ describe('Payback Flashloan Action Builder', () => { connectedOutputs: {}, }) - await RepayFlashloanActionBuilder({ + await new RepayFlashloanActionBuilder().build({ ...builderParams, step: repayFlashloanStep, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/ReturnFundsActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/ReturnFundsActionBuilder.spec.ts index 1d340a7a44..5dc869785f 100644 --- a/sdk/protocol-plugins/tests/unit/builders/ReturnFundsActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/ReturnFundsActionBuilder.spec.ts @@ -35,7 +35,7 @@ describe('Return Funds Action Builder', () => { it('should encode the action calldata correctly', async () => { builderParams.context.startSubContext() - await ReturnFundsActionBuilder({ + await new ReturnFundsActionBuilder().build({ ...builderParams, step: derivedStep, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/SwapActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/SwapActionBuilder.spec.ts index f24f1b0e97..0f3e91f1f4 100644 --- a/sdk/protocol-plugins/tests/unit/builders/SwapActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/SwapActionBuilder.spec.ts @@ -114,7 +114,7 @@ describe('Swap Action Builder', () => { builderParams.context.startSubContext() - await SwapActionBuilder({ + await new SwapActionBuilder().build({ ...builderParams, step: derivedStep, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts index 8531258dea..08dc7152c1 100644 --- a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts @@ -127,7 +127,7 @@ describe('AaveV3 Deposit Borrow Action Builder', () => { it('should fail the position is not a AaveV3 one', async () => { try { - await AaveV3DepositBorrowActionBuilder({ + await new AaveV3DepositBorrowActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -147,7 +147,7 @@ describe('AaveV3 Deposit Borrow Action Builder', () => { it('should add all the action calls', async () => { builderParams.context.startSubContext() - await AaveV3DepositBorrowActionBuilder({ + await new AaveV3DepositBorrowActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, @@ -165,7 +165,7 @@ describe('AaveV3 Deposit Borrow Action Builder', () => { it('should not add borrow nor send token when borrow amount is 0', async () => { builderParams.context.startSubContext() - await AaveV3DepositBorrowActionBuilder({ + await new AaveV3DepositBorrowActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -191,7 +191,7 @@ describe('AaveV3 Deposit Borrow Action Builder', () => { it('should add borrow but not send token when borrow target is positions manager', async () => { builderParams.context.startSubContext() - await AaveV3DepositBorrowActionBuilder({ + await new AaveV3DepositBorrowActionBuilder().build({ ...builderParams, step: { ...derivedStep, diff --git a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3OpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3OpenPositionActionBuilder.spec.ts index 874ce0977b..daa6b6247e 100644 --- a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3OpenPositionActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3OpenPositionActionBuilder.spec.ts @@ -116,7 +116,7 @@ describe('AaveV3 Open Position Action Builder', () => { it('should fail the position is not a AaveV3 one', async () => { try { - await AaveV3OpenPositionActionBuilder({ + await new AaveV3OpenPositionActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -136,7 +136,7 @@ describe('AaveV3 Open Position Action Builder', () => { it('should add a transaction to the context', async () => { builderParams.context.startSubContext() - await AaveV3OpenPositionActionBuilder({ + await new AaveV3OpenPositionActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, diff --git a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts index 3d17c20353..1311d7b5b6 100644 --- a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts @@ -127,7 +127,7 @@ describe('AaveV3 Payback Withdraw Action Builder', () => { it('should fail the position is not a AaveV3 one', async () => { try { - await AaveV3PaybackWithdrawActionBuilder({ + await new AaveV3PaybackWithdrawActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -147,7 +147,7 @@ describe('AaveV3 Payback Withdraw Action Builder', () => { it('should add all the action calls', async () => { builderParams.context.startSubContext() - await AaveV3PaybackWithdrawActionBuilder({ + await new AaveV3PaybackWithdrawActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, @@ -165,7 +165,7 @@ describe('AaveV3 Payback Withdraw Action Builder', () => { it('should not add payback when payback amount is 0', async () => { builderParams.context.startSubContext() - await AaveV3PaybackWithdrawActionBuilder({ + await new AaveV3PaybackWithdrawActionBuilder().build({ ...builderParams, step: { ...derivedStep, diff --git a/sdk/protocol-plugins/tests/unit/builders/maker/MakerImportPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/maker/MakerImportPositionActionBuilder.spec.ts index be318185e5..11d1abd25a 100644 --- a/sdk/protocol-plugins/tests/unit/builders/maker/MakerImportPositionActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/maker/MakerImportPositionActionBuilder.spec.ts @@ -138,7 +138,7 @@ describe('Maker Import Position Action Builder', () => { it('should fail the position is not a Maker one', async () => { try { - await MakerImportPositionActionBuilder({ + await new MakerImportPositionActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -164,7 +164,7 @@ describe('Maker Import Position Action Builder', () => { it('should add a new transaction to the context', async () => { builderParams.context.startSubContext() - await MakerImportPositionActionBuilder({ + await new MakerImportPositionActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.protocolsRegistry, diff --git a/sdk/protocol-plugins/tests/unit/builders/maker/MakerOpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/maker/MakerOpenPositionActionBuilder.spec.ts index bcd2154c07..3a51a32b20 100644 --- a/sdk/protocol-plugins/tests/unit/builders/maker/MakerOpenPositionActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/maker/MakerOpenPositionActionBuilder.spec.ts @@ -122,7 +122,7 @@ describe('Maker Open Position Action Builder', () => { it('should fail the position is not a Maker one', async () => { try { - await MakerOpenPositionActionBuilder({ + await new MakerOpenPositionActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -142,7 +142,7 @@ describe('Maker Open Position Action Builder', () => { it('should not add a transaction to the context', async () => { builderParams.context.startSubContext() - await MakerOpenPositionActionBuilder({ + await new MakerOpenPositionActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, diff --git a/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts index 13d0e1bd8e..ce32551b32 100644 --- a/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts @@ -133,7 +133,7 @@ describe('Maker Payback Withdraw Action Builder', () => { it('should fail the position is not a Maker one', async () => { try { - await MakerPaybackWithdrawActionBuilder({ + await new MakerPaybackWithdrawActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -153,7 +153,7 @@ describe('Maker Payback Withdraw Action Builder', () => { it('should add all the action calls', async () => { builderParams.context.startSubContext() - await MakerPaybackWithdrawActionBuilder({ + await new MakerPaybackWithdrawActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, @@ -170,7 +170,7 @@ describe('Maker Payback Withdraw Action Builder', () => { it('should not add payback when payback amount is 0', async () => { builderParams.context.startSubContext() - await MakerPaybackWithdrawActionBuilder({ + await new MakerPaybackWithdrawActionBuilder().build({ ...builderParams, step: { ...derivedStep, diff --git a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts index c9ceb71345..be5f917756 100644 --- a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts @@ -134,7 +134,7 @@ describe('Morpho Deposit Borrow Action Builder', () => { it('should fail the position is not a Morpho one', async () => { try { - await MorphoDepositBorrowActionBuilder({ + await new MorphoDepositBorrowActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -154,7 +154,7 @@ describe('Morpho Deposit Borrow Action Builder', () => { it('should add all the action calls', async () => { builderParams.context.startSubContext() - await MorphoDepositBorrowActionBuilder({ + await new MorphoDepositBorrowActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, @@ -173,7 +173,7 @@ describe('Morpho Deposit Borrow Action Builder', () => { it('should not add borrow nor send token when borrow amount is 0', async () => { builderParams.context.startSubContext() - await MorphoDepositBorrowActionBuilder({ + await new MorphoDepositBorrowActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -199,7 +199,7 @@ describe('Morpho Deposit Borrow Action Builder', () => { it('should add borrow but not send token when borrow target is positions manager', async () => { builderParams.context.startSubContext() - await MorphoDepositBorrowActionBuilder({ + await new MorphoDepositBorrowActionBuilder().build({ ...builderParams, step: { ...derivedStep, diff --git a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoOpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoOpenPositionActionBuilder.spec.ts index e37a8402bc..ce7a3fe814 100644 --- a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoOpenPositionActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoOpenPositionActionBuilder.spec.ts @@ -122,7 +122,7 @@ describe('Morpho Open Position Action Builder', () => { it('should fail the position is not a Morpho one', async () => { try { - await MorphoOpenPositionActionBuilder({ + await new MorphoOpenPositionActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -142,7 +142,7 @@ describe('Morpho Open Position Action Builder', () => { it('should not add a transaction to the context', async () => { builderParams.context.startSubContext() - await MorphoOpenPositionActionBuilder({ + await new MorphoOpenPositionActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, diff --git a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts index 6baf51bbfe..78ff57b58a 100644 --- a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts @@ -132,7 +132,7 @@ describe('Morpho Payback Withdraw Action Builder', () => { it('should fail the position is not a Morpho one', async () => { try { - await MorphoPaybackWithdrawActionBuilder({ + await new MorphoPaybackWithdrawActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -152,7 +152,7 @@ describe('Morpho Payback Withdraw Action Builder', () => { it('should add all the action calls', async () => { builderParams.context.startSubContext() - await MorphoPaybackWithdrawActionBuilder({ + await new MorphoPaybackWithdrawActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, @@ -170,7 +170,7 @@ describe('Morpho Payback Withdraw Action Builder', () => { it('should not add payback when payback amount is 0', async () => { builderParams.context.startSubContext() - await MorphoPaybackWithdrawActionBuilder({ + await new MorphoPaybackWithdrawActionBuilder().build({ ...builderParams, step: { ...derivedStep, diff --git a/sdk/protocol-plugins/tests/unit/builders/spark/SparkDepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/spark/SparkDepositBorrowActionBuilder.spec.ts index 2c095989c1..6e9e5a2356 100644 --- a/sdk/protocol-plugins/tests/unit/builders/spark/SparkDepositBorrowActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/spark/SparkDepositBorrowActionBuilder.spec.ts @@ -127,7 +127,7 @@ describe('Spark Deposit Borrow Action Builder', () => { it('should fail the position is not a Spark one', async () => { try { - await SparkDepositBorrowActionBuilder({ + await new SparkDepositBorrowActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -147,7 +147,7 @@ describe('Spark Deposit Borrow Action Builder', () => { it('should add all the action calls', async () => { builderParams.context.startSubContext() - await SparkDepositBorrowActionBuilder({ + await new SparkDepositBorrowActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, @@ -165,7 +165,7 @@ describe('Spark Deposit Borrow Action Builder', () => { it('should not add borrow nor send token when borrow amount is 0', async () => { builderParams.context.startSubContext() - await SparkDepositBorrowActionBuilder({ + await new SparkDepositBorrowActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -191,7 +191,7 @@ describe('Spark Deposit Borrow Action Builder', () => { it('should add borrow but not send token when borrow target is positions manager', async () => { builderParams.context.startSubContext() - await SparkDepositBorrowActionBuilder({ + await new SparkDepositBorrowActionBuilder().build({ ...builderParams, step: { ...derivedStep, diff --git a/sdk/protocol-plugins/tests/unit/builders/spark/SparkOpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/spark/SparkOpenPositionActionBuilder.spec.ts index 23744076fb..e3ae6a5b9c 100644 --- a/sdk/protocol-plugins/tests/unit/builders/spark/SparkOpenPositionActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/spark/SparkOpenPositionActionBuilder.spec.ts @@ -116,7 +116,7 @@ describe('Spark Deposit Borrow Action Builder', () => { it('should fail the position is not a Spark one', async () => { try { - await SparkOpenPositionActionBuilder({ + await new SparkOpenPositionActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -136,7 +136,7 @@ describe('Spark Deposit Borrow Action Builder', () => { it('should add all the action calls', async () => { builderParams.context.startSubContext() - await SparkOpenPositionActionBuilder({ + await new SparkOpenPositionActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, diff --git a/sdk/protocol-plugins/tests/unit/builders/spark/SparkPaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/spark/SparkPaybackWithdrawActionBuilder.spec.ts index e39cd39f08..7f247571e6 100644 --- a/sdk/protocol-plugins/tests/unit/builders/spark/SparkPaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/spark/SparkPaybackWithdrawActionBuilder.spec.ts @@ -127,7 +127,7 @@ describe('Spark Payback Withdraw Action Builder', () => { it('should fail the position is not a Spark one', async () => { try { - await SparkPaybackWithdrawActionBuilder({ + await new SparkPaybackWithdrawActionBuilder().build({ ...builderParams, step: { ...derivedStep, @@ -147,7 +147,7 @@ describe('Spark Payback Withdraw Action Builder', () => { it('should add all the action calls', async () => { builderParams.context.startSubContext() - await SparkPaybackWithdrawActionBuilder({ + await new SparkPaybackWithdrawActionBuilder().build({ ...builderParams, step: derivedStep, protocolsRegistry: builderParams.emptyProtocolsRegistry, @@ -165,7 +165,7 @@ describe('Spark Payback Withdraw Action Builder', () => { it('should not add payback when payback amount is 0', async () => { builderParams.context.startSubContext() - await SparkPaybackWithdrawActionBuilder({ + await new SparkPaybackWithdrawActionBuilder().build({ ...builderParams, step: { ...derivedStep, diff --git a/sdk/protocol-plugins/tests/utils/ProtocolPluginMock.ts b/sdk/protocol-plugins/tests/utils/ProtocolPluginMock.ts index 7866c2bc6f..ca65bf81a1 100644 --- a/sdk/protocol-plugins/tests/utils/ProtocolPluginMock.ts +++ b/sdk/protocol-plugins/tests/utils/ProtocolPluginMock.ts @@ -1,8 +1,10 @@ import { ChainFamilyMap, IPosition, IPositionId, Maybe } from '@summerfi/sdk-common/common' import { SimulationSteps, steps } from '@summerfi/sdk-common/simulation' import { - ActionBuilder, + ActionBuilderParams, + ActionBuilderUsedAction, ActionBuildersMap, + IActionBuilder, IProtocolPlugin, IProtocolPluginContext, } from '@summerfi/protocol-plugins-common' @@ -19,48 +21,57 @@ import { IExternalPosition, IPositionsManager } from '@summerfi/sdk-common/order import { IUser } from '@summerfi/sdk-common/user' import { TransactionInfo } from '@summerfi/sdk-common' import { StepBuilderContextMock } from '@summerfi/testing-utils' +import { BaseActionBuilder } from '../../src' /* eslint-disable @typescript-eslint/no-unused-vars */ -export const PaybackWithdrawActionBuilderMock: ActionBuilder = async ( - params, -): Promise => { - ;(params.context as StepBuilderContextMock).setCheckpoint('PaybackWithdrawActionBuilderMock') +export class PaybackWithdrawActionBuilderMock extends BaseActionBuilder { + actions: ActionBuilderUsedAction[] = [] + async build(params: ActionBuilderParams): Promise { + ;(params.context as StepBuilderContextMock).setCheckpoint('PaybackWithdrawActionBuilderMock') + } } -export const DepositBorrowActionBuilderMock: ActionBuilder = async ( - params, -): Promise => { - ;(params.context as StepBuilderContextMock).setCheckpoint('DepositBorrowActionBuilderMock') +export class DepositBorrowActionBuilderMock extends BaseActionBuilder { + actions: ActionBuilderUsedAction[] = [] + async build(params: ActionBuilderParams): Promise { + ;(params.context as StepBuilderContextMock).setCheckpoint('DepositBorrowActionBuilderMock') + } } -export const ImportPositionActionBuilderMock: ActionBuilder = async ( - params, -): Promise => { - ;(params.context as StepBuilderContextMock).setCheckpoint('ImportPositionActionBuilderMock') +export class ImportPositionActionBuilderMock extends BaseActionBuilder { + actions: ActionBuilderUsedAction[] = [] + async build(params: ActionBuilderParams): Promise { + ;(params.context as StepBuilderContextMock).setCheckpoint('ImportPositionActionBuilderMock') + } } -export const OpenPositionActionBuilderMock: ActionBuilder = async ( - params, -): Promise => { - ;(params.context as StepBuilderContextMock).setCheckpoint('OpenPositionActionBuilderMock') +export class OpenPositionActionBuilderMock extends BaseActionBuilder { + actions: ActionBuilderUsedAction[] = [] + async build(params: ActionBuilderParams): Promise { + ;(params.context as StepBuilderContextMock).setCheckpoint('OpenPositionActionBuilderMock') + } } -export const PaybackWithdrawActionBuilderNoCheckpointMock: ActionBuilder< - steps.PaybackWithdrawStep -> = async (params): Promise => {} +export class PaybackWithdrawActionBuilderNoCheckpointMock extends BaseActionBuilder { + actions: ActionBuilderUsedAction[] = [] + async build(params: ActionBuilderParams): Promise {} +} -export const DepositBorrowActionBuilderNoCheckpointMock: ActionBuilder< - steps.DepositBorrowStep -> = async (params): Promise => {} +export class DepositBorrowActionBuilderNoCheckpointMock extends BaseActionBuilder { + actions: ActionBuilderUsedAction[] = [] + async build(params: ActionBuilderParams): Promise {} +} -export const ImportPositionActionBuilderNoCheckpointMock: ActionBuilder = async ( - params, -): Promise => {} +export class ImportPositionActionBuilderNoCheckpointMock extends BaseActionBuilder { + actions: ActionBuilderUsedAction[] = [] + async build(params: ActionBuilderParams): Promise {} +} -export const OpenPositionActionBuilderNoCheckpointMock: ActionBuilder = async ( - params, -): Promise => {} +export class OpenPositionActionBuilderNoCheckpointMock extends BaseActionBuilder { + actions: ActionBuilderUsedAction[] = [] + async build(params: ActionBuilderParams): Promise {} +} export class ProtocolPluginMock implements IProtocolPlugin { protocolName = ProtocolName.Spark @@ -91,8 +102,14 @@ export class ProtocolPluginMock implements IProtocolPlugin { return undefined as unknown as IPosition } - getActionBuilder(step: T): Maybe> { - return this.stepBuilders[step.type] as ActionBuilder + getActionBuilder(step: T): Maybe> { + const builder = this.stepBuilders[step.type] + + if (!builder) { + return undefined + } + + return new builder() as IActionBuilder } async getImportPositionTransaction(params: { @@ -128,8 +145,14 @@ export class EmptyProtocolPluginMock implements IProtocolPlugin { return undefined as unknown as IPosition } - getActionBuilder(step: T): Maybe> { - return this.stepBuilders[step.type] as ActionBuilder + getActionBuilder(step: T): Maybe> { + const builder = this.stepBuilders[step.type] + + if (!builder) { + return undefined + } + + return new builder() as IActionBuilder } async getImportPositionTransaction(params: { @@ -170,8 +193,14 @@ export class NoCheckpointProtocolPluginMock implements IProtocolPlugin { return undefined as unknown as IPosition } - getActionBuilder(step: T): Maybe> { - return this.stepBuilders[step.type] as ActionBuilder + getActionBuilder(step: T): Maybe> { + const builder = this.stepBuilders[step.type] + + if (!builder) { + return undefined + } + + return new builder() as IActionBuilder } async getImportPositionTransaction(params: { diff --git a/sdk/protocol-plugins/tsconfig.json b/sdk/protocol-plugins/tsconfig.json index 80a82c6cb5..98e8557db2 100644 --- a/sdk/protocol-plugins/tsconfig.json +++ b/sdk/protocol-plugins/tsconfig.json @@ -5,6 +5,6 @@ "outDir": "dist", "baseUrl": "." }, - "include": ["src/**/*.ts", "tests/**/*.ts", "tests/mocks/*.ts", "src/plugins/spark/types"], + "include": ["src/**/*.ts", "tests/**/*.ts", "tests/mocks/*.ts"], "exclude": ["node_modules", "dist"] } diff --git a/sdk/sdk-common/src/simulation/index.ts b/sdk/sdk-common/src/simulation/index.ts index b9a92c39ed..fdadb0446b 100644 --- a/sdk/sdk-common/src/simulation/index.ts +++ b/sdk/sdk-common/src/simulation/index.ts @@ -1,6 +1,5 @@ -export type * as steps from './Steps' +export * as steps from './Steps' export * from './Enums' -export type { ValueReference, ReferenceableField } from './ValueReference' -export { isValueReference, getValueFromReference } from './ValueReference' -export type * from './Simulation' -export type * from './SimulationStrategy' +export * from './ValueReference' +export * from './Simulation' +export * from './SimulationStrategy' From 3b6bd1c75ae4c16bf6a5d2919eddea907bbabfa8 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Wed, 22 May 2024 17:11:37 +0200 Subject: [PATCH 09/37] fix: refinance simulation debt calculation (#284) --- .../refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts b/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts index de3ee27ddd..752d6f866c 100644 --- a/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts +++ b/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts @@ -100,7 +100,7 @@ export async function refinanceLendingToLendingAnyPair( inputs: { // refactor borrowAmount: isDebtSwapSkipped - ? ctx.getReference(['SwapCollateralFromSourcePosition', 'received']) + ? position.debtAmount : await estimateSwapFromAmount({ receiveAtLeast: flashloanAmount, fromToken: targetPool.debtToken, From 0c2f8c7c8d31ae0b90f851c19cb8606654e2cb1c Mon Sep 17 00:00:00 2001 From: Halaprix Date: Thu, 23 May 2024 10:29:23 +0200 Subject: [PATCH 10/37] feat: handle closed position swap points (#286) - handle swaps from closed positions ( where `net value == 0`) - to get closed position swaps - we get all swaps fro muser entity and filter out swaps that exists in `user.positions` ( we fetch positions with `net value > 0` hence all swaps in `user.positions` are swaps in open positions ) --- .../src/point-accrual.ts | 81 +- .../queries/get-points.graphql | 150 +- .../summer-events-subgraph/schema.graphql | 9226 +++++++++-------- packages/summer-events-subgraph/src/index.ts | 5 +- 4 files changed, 4896 insertions(+), 4566 deletions(-) diff --git a/background-jobs/update-rays-cron-function/src/point-accrual.ts b/background-jobs/update-rays-cron-function/src/point-accrual.ts index 4b9d062b53..fbfbef340d 100644 --- a/background-jobs/update-rays-cron-function/src/point-accrual.ts +++ b/background-jobs/update-rays-cron-function/src/point-accrual.ts @@ -1,7 +1,8 @@ import { MigrationEvent, Position, - RecentSwap, + RecentSwapInPosition, + RecentSwapInUser, START_POINTS_TIMESTAMP, SummerPointsSubgraphClient, User, @@ -166,15 +167,20 @@ export class SummerPointsService { const pointsEarned = users.map((user) => { const swapMultiplier = this.getSwapMultiplier(user.swaps) const protocolBoostMultiplier = this.getNetValueMutliplier(user) + const closedPositionsPoints = this.getClosedPositionSwapPoints( + user, + protocolBoostMultiplier, + swapMultiplier, + ) - return user.positions.map((position) => { + const openPositionsPoints = user.positions.map((position) => { const openPositionsPoints = this.getOpenPositionsPoints( startTimestamp, position, endTimestamp, ) const migrationPoints = this.getMigrationPoints(position.migration) - const swapPoints = swapMultiplier * this.getSwapPoints(user.recentSwaps) + const swapPoints = swapMultiplier * this.getSwapPoints(position.recentSwaps) const timeOpenMultiplier = this.getTimeOpenMultiplier(position, endTimestamp) const automationProtectionMultiplier = this.getAutomationProtectionMultiplier(position) @@ -206,6 +212,7 @@ export class SummerPointsService { }, } }) + return closedPositionsPoints.concat(openPositionsPoints) }) return pointsEarned @@ -213,6 +220,69 @@ export class SummerPointsService { .sort((a, b) => b.points.openPositionsPoints - a.points.openPositionsPoints) } + /** + * Calculates the closed position swap points for a user. + * + * @remarks The closed position swap points are calculated based on the swaps that are not associated with open positions. + * + * @param user - The user object containing positions, swaps, and other relevant data. + * @param protocolBoostMultiplier - The multiplier for protocol boost points. + * @param swapMultiplier - The multiplier for swap points. + * @returns An array of objects representing the closed position swap points. + */ + private getClosedPositionSwapPoints( + user: User, + protocolBoostMultiplier: number, + swapMultiplier: number, + ) { + const userSwaps = user.recentSwaps + + const idsOfUserOpenPositions = user.positions.map((position) => position.id) + /* @dev filter out swaps that are related to an open position -> position in `user.positions` - this is enforced by `netValue_gt: 0` in subgraph query */ + const filteredSwaps = userSwaps.filter( + (swap) => !swap.position || !idsOfUserOpenPositions.includes(swap.position.id), + ) + // Group swaps by position id + const swapsByPositionId = filteredSwaps.reduce( + (acc, swap) => { + const positionId = swap.position!.id + if (!acc[positionId]) { + acc[positionId] = [] + } + acc[positionId].push(swap) + return acc + }, + {} as { [key: string]: (typeof filteredSwaps)[0][] }, + ) + + const closedPositionsPoints = Object.entries(swapsByPositionId).map(([positionId, swaps]) => { + const swapPoints = swapMultiplier * this.getSwapPoints(swaps) + const swap = swaps[0] // Assuming all swaps for a position have the same position data + + return { + positionId: positionId, + vaultId: swap.position!.account.vaultId, + protocol: swap.position!.protocol, + marketId: swap.position!.marketId, + user: user.id, + points: { + openPositionsPoints: 0, + migrationPoints: 0, + swapPoints: swapPoints, + }, + netValue: swap.position!.netValue, + multipliers: { + protocolBoostMultiplier, + swapMultiplier, + timeOpenMultiplier: 1, + automationProtectionMultiplier: 1, + lazyVaultMultiplier: 1, + }, + } + }) + return closedPositionsPoints + } + /** * Calculates the points for open positions within a given time range. * @@ -231,16 +301,13 @@ export class SummerPointsService { for (const event of position.summerEvents) { const timeDifference = event.timestamp - previousTimestamp - const pointsPerSecond = this.getPointsPerUsdPerSecond(event.netValueBefore) openPositionsPoints += pointsPerSecond * timeDifference * event.netValueBefore - previousTimestamp = event.timestamp } // Calculate points for the time period after the last event const timeDifference = endTimestamp - previousTimestamp - const pointsPerSecond = this.getPointsPerUsdPerSecond(position.netValue) openPositionsPoints += pointsPerSecond * timeDifference * position.netValue @@ -273,7 +340,7 @@ export class SummerPointsService { * @param swaps - An array of recent swaps. * @returns The total swap points. */ - getSwapPoints(swaps: RecentSwap[]): number { + getSwapPoints(swaps: RecentSwapInPosition[] | RecentSwapInUser[]): number { let points = 0 for (const swap of swaps) { const pointsPerUsdPerYear = this.getPointsPerUsdPerYear(swap.amountInUSD) diff --git a/packages/summer-events-subgraph/queries/get-points.graphql b/packages/summer-events-subgraph/queries/get-points.graphql index f9715b1017..3c3970fb34 100644 --- a/packages/summer-events-subgraph/queries/get-points.graphql +++ b/packages/summer-events-subgraph/queries/get-points.graphql @@ -1,76 +1,92 @@ query SummerPoints( - $first: Int! - $lastId: Bytes! - $pointsStartTimestamp: BigInt! - $startTimestamp: BigInt! - $endTimestamp: BigInt! + $first: Int + $lastId: Bytes + $pointsStartTimestamp: BigInt + $startTimestamp: BigInt + $endTimestamp: BigInt ) { - users( - orderBy: id - first: $first - where: { openPositions_gt: 0, id_gt: $lastId } - ) { + users(orderBy: id, first: $first, where: { openPositions_gt: 0, id_gt: $lastId }) { + id + positions(where: { netValue_gt: 0 }) { + id + protocol + marketId + account { id - positions(where: { netValue_gt: 0 }) { - account { - vaultId - address - } - id - protocol - marketId - netValue - summerEvents( - where: { timestamp_gt: $startTimestamp, timestamp_lt: $endTimestamp } - ) { - netValueBefore - netValueAfter - timestamp - } - migration: summerEvents( - where: { - timestamp_gt: $startTimestamp - timestamp_lt: $endTimestamp - kind_contains_nocase: "migrate" - } - ) { - netValueBefore - netValueAfter - timestamp - } - activeTriggers: triggers( - where: { - or: [ - { removedBlock: null, executedBlock: null } - { continuous: true, removedBlock: null } - ] - } - ) { - id - kind - } - firstEvent: summerEvents( - first: 1 - orderBy: timestamp - orderDirection: asc - ) { - timestamp - } + vaultId + } + netValue + recentSwaps: swaps(where: { timestamp_gt: $startTimestamp, timestamp_lt: $endTimestamp }) { + id + amountInUSD + assetIn { + symbol } - swaps(where: { timestamp_gt: $pointsStartTimestamp }) { - id + assetOut { + symbol } - recentSwaps: swaps( - where: { timestamp_gt: $startTimestamp, timestamp_lt: $endTimestamp } - ) { + position { + netValue + user { id - amountInUSD - assetIn { - symbol - } - assetOut { - symbol - } + } + } + } + summerEvents(where: { timestamp_gt: $startTimestamp, timestamp_lt: $endTimestamp }) { + netValueBefore + netValueAfter + timestamp + } + migration: summerEvents( + where: { + timestamp_gt: $startTimestamp + timestamp_lt: $endTimestamp + kind_contains_nocase: "migrate" + } + ) { + netValueBefore + netValueAfter + timestamp + } + activeTriggers: triggers( + where: { + or: [ + { removedBlock: null, executedBlock: null } + { continuous: true, removedBlock: null } + ] + } + ) { + id + kind + } + firstEvent: summerEvents(first: 1, orderBy: timestamp, orderDirection: asc) { + timestamp + } + } + swaps(where: { timestamp_gt: $pointsStartTimestamp }) { + id + } + recentSwaps: swaps(where: { timestamp_gt: $startTimestamp, timestamp_lt: $endTimestamp }) { + id + position { + id + account { + vaultId + } + protocol + marketId + netValue + user { + id } + } + amountInUSD + assetIn { + symbol + } + assetOut { + symbol + } } + } } diff --git a/packages/summer-events-subgraph/schema.graphql b/packages/summer-events-subgraph/schema.graphql index 5e0780cb01..9424099d74 100644 --- a/packages/summer-events-subgraph/schema.graphql +++ b/packages/summer-events-subgraph/schema.graphql @@ -4,7 +4,9 @@ is required to be annotated with this directive. """ directive @entity on OBJECT -"""Defined a Subgraph ID for an object type""" +""" +Defined a Subgraph ID for an object type +""" directive @subgraphId(id: String!) on OBJECT """ @@ -13,455 +15,547 @@ creates a virtual field on the entity that may be queried but cannot be set manu directive @derivedFrom(field: String!) on FIELD_DEFINITION type _Block_ { - """The hash of the block""" - hash: Bytes - - """The block number""" - number: Int! - - """Integer representation of the timestamp stored in blocks for the chain""" - timestamp: Int + """ + The hash of the block + """ + hash: Bytes + + """ + The block number + """ + number: Int! + + """ + Integer representation of the timestamp stored in blocks for the chain + """ + timestamp: Int } -"""The type for the top-level _meta field""" +""" +The type for the top-level _meta field +""" type _Meta_ { - """ - Information about a specific subgraph block. The hash of the block - will be null if the _meta field has a block constraint that asks for - a block number. It will be filled if the _meta field has no block constraint - and therefore asks for the latest block - - """ - block: _Block_! - - """The deployment ID""" - deployment: String! - - """If `true`, the subgraph encountered indexing errors at some past block""" - hasIndexingErrors: Boolean! + """ + Information about a specific subgraph block. The hash of the block + will be null if the _meta field has a block constraint that asks for + a block number. It will be filled if the _meta field has no block constraint + and therefore asks for the latest block + """ + block: _Block_! + + """ + The deployment ID + """ + deployment: String! + + """ + If `true`, the subgraph encountered indexing errors at some past block + """ + hasIndexingErrors: Boolean! } enum _SubgraphErrorPolicy_ { - """Data will be returned even if the subgraph has indexing errors""" - allow - - """ - If the subgraph has indexing errors, data will be omitted. The default. - """ - deny + """ + Data will be returned even if the subgraph has indexing errors + """ + allow + + """ + If the subgraph has indexing errors, data will be omitted. The default. + """ + deny } type Account { - id: Bytes! - address: Bytes! - user: User! - type: String! - vaultId: BigInt! - createPositionEvents(skip: Int = 0, first: Int = 100, orderBy: CreatePositionEvent_orderBy, orderDirection: OrderDirection, where: CreatePositionEvent_filter): [CreatePositionEvent!]! - summerEvents(skip: Int = 0, first: Int = 100, orderBy: SummerEvent_orderBy, orderDirection: OrderDirection, where: SummerEvent_filter): [SummerEvent!]! - feePaids(skip: Int = 0, first: Int = 100, orderBy: FeePaid_orderBy, orderDirection: OrderDirection, where: FeePaid_filter): [FeePaid!]! - automationEvents(skip: Int = 0, first: Int = 100, orderBy: TriggerEvent_orderBy, orderDirection: OrderDirection, where: TriggerEvent_filter): [TriggerEvent!]! - swaps(skip: Int = 0, first: Int = 100, orderBy: AssetSwap_orderBy, orderDirection: OrderDirection, where: AssetSwap_filter): [AssetSwap!]! - positions(skip: Int = 0, first: Int = 100, orderBy: Position_orderBy, orderDirection: OrderDirection, where: Position_filter): [Position!]! - latestCreatePositionEvent: CreatePositionEvent + id: Bytes! + address: Bytes! + user: User! + type: String! + vaultId: BigInt! + createPositionEvents( + skip: Int = 0 + first: Int = 100 + orderBy: CreatePositionEvent_orderBy + orderDirection: OrderDirection + where: CreatePositionEvent_filter + ): [CreatePositionEvent!]! + summerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: SummerEvent_orderBy + orderDirection: OrderDirection + where: SummerEvent_filter + ): [SummerEvent!]! + feePaids( + skip: Int = 0 + first: Int = 100 + orderBy: FeePaid_orderBy + orderDirection: OrderDirection + where: FeePaid_filter + ): [FeePaid!]! + automationEvents( + skip: Int = 0 + first: Int = 100 + orderBy: TriggerEvent_orderBy + orderDirection: OrderDirection + where: TriggerEvent_filter + ): [TriggerEvent!]! + swaps( + skip: Int = 0 + first: Int = 100 + orderBy: AssetSwap_orderBy + orderDirection: OrderDirection + where: AssetSwap_filter + ): [AssetSwap!]! + positions( + skip: Int = 0 + first: Int = 100 + orderBy: Position_orderBy + orderDirection: OrderDirection + where: Position_filter + ): [Position!]! + latestCreatePositionEvent: CreatePositionEvent } input Account_filter { - id: Bytes - id_not: Bytes - id_gt: Bytes - id_lt: Bytes - id_gte: Bytes - id_lte: Bytes - id_in: [Bytes!] - id_not_in: [Bytes!] - id_contains: Bytes - id_not_contains: Bytes - address: Bytes - address_not: Bytes - address_gt: Bytes - address_lt: Bytes - address_gte: Bytes - address_lte: Bytes - address_in: [Bytes!] - address_not_in: [Bytes!] - address_contains: Bytes - address_not_contains: Bytes - user: String - user_not: String - user_gt: String - user_lt: String - user_gte: String - user_lte: String - user_in: [String!] - user_not_in: [String!] - user_contains: String - user_contains_nocase: String - user_not_contains: String - user_not_contains_nocase: String - user_starts_with: String - user_starts_with_nocase: String - user_not_starts_with: String - user_not_starts_with_nocase: String - user_ends_with: String - user_ends_with_nocase: String - user_not_ends_with: String - user_not_ends_with_nocase: String - user_: User_filter - type: String - type_not: String - type_gt: String - type_lt: String - type_gte: String - type_lte: String - type_in: [String!] - type_not_in: [String!] - type_contains: String - type_contains_nocase: String - type_not_contains: String - type_not_contains_nocase: String - type_starts_with: String - type_starts_with_nocase: String - type_not_starts_with: String - type_not_starts_with_nocase: String - type_ends_with: String - type_ends_with_nocase: String - type_not_ends_with: String - type_not_ends_with_nocase: String - vaultId: BigInt - vaultId_not: BigInt - vaultId_gt: BigInt - vaultId_lt: BigInt - vaultId_gte: BigInt - vaultId_lte: BigInt - vaultId_in: [BigInt!] - vaultId_not_in: [BigInt!] - createPositionEvents_: CreatePositionEvent_filter - summerEvents_: SummerEvent_filter - feePaids_: FeePaid_filter - automationEvents_: TriggerEvent_filter - swaps_: AssetSwap_filter - positions_: Position_filter - latestCreatePositionEvent: String - latestCreatePositionEvent_not: String - latestCreatePositionEvent_gt: String - latestCreatePositionEvent_lt: String - latestCreatePositionEvent_gte: String - latestCreatePositionEvent_lte: String - latestCreatePositionEvent_in: [String!] - latestCreatePositionEvent_not_in: [String!] - latestCreatePositionEvent_contains: String - latestCreatePositionEvent_contains_nocase: String - latestCreatePositionEvent_not_contains: String - latestCreatePositionEvent_not_contains_nocase: String - latestCreatePositionEvent_starts_with: String - latestCreatePositionEvent_starts_with_nocase: String - latestCreatePositionEvent_not_starts_with: String - latestCreatePositionEvent_not_starts_with_nocase: String - latestCreatePositionEvent_ends_with: String - latestCreatePositionEvent_ends_with_nocase: String - latestCreatePositionEvent_not_ends_with: String - latestCreatePositionEvent_not_ends_with_nocase: String - latestCreatePositionEvent_: CreatePositionEvent_filter - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [Account_filter] - or: [Account_filter] + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + address: Bytes + address_not: Bytes + address_gt: Bytes + address_lt: Bytes + address_gte: Bytes + address_lte: Bytes + address_in: [Bytes!] + address_not_in: [Bytes!] + address_contains: Bytes + address_not_contains: Bytes + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + type: String + type_not: String + type_gt: String + type_lt: String + type_gte: String + type_lte: String + type_in: [String!] + type_not_in: [String!] + type_contains: String + type_contains_nocase: String + type_not_contains: String + type_not_contains_nocase: String + type_starts_with: String + type_starts_with_nocase: String + type_not_starts_with: String + type_not_starts_with_nocase: String + type_ends_with: String + type_ends_with_nocase: String + type_not_ends_with: String + type_not_ends_with_nocase: String + vaultId: BigInt + vaultId_not: BigInt + vaultId_gt: BigInt + vaultId_lt: BigInt + vaultId_gte: BigInt + vaultId_lte: BigInt + vaultId_in: [BigInt!] + vaultId_not_in: [BigInt!] + createPositionEvents_: CreatePositionEvent_filter + summerEvents_: SummerEvent_filter + feePaids_: FeePaid_filter + automationEvents_: TriggerEvent_filter + swaps_: AssetSwap_filter + positions_: Position_filter + latestCreatePositionEvent: String + latestCreatePositionEvent_not: String + latestCreatePositionEvent_gt: String + latestCreatePositionEvent_lt: String + latestCreatePositionEvent_gte: String + latestCreatePositionEvent_lte: String + latestCreatePositionEvent_in: [String!] + latestCreatePositionEvent_not_in: [String!] + latestCreatePositionEvent_contains: String + latestCreatePositionEvent_contains_nocase: String + latestCreatePositionEvent_not_contains: String + latestCreatePositionEvent_not_contains_nocase: String + latestCreatePositionEvent_starts_with: String + latestCreatePositionEvent_starts_with_nocase: String + latestCreatePositionEvent_not_starts_with: String + latestCreatePositionEvent_not_starts_with_nocase: String + latestCreatePositionEvent_ends_with: String + latestCreatePositionEvent_ends_with_nocase: String + latestCreatePositionEvent_not_ends_with: String + latestCreatePositionEvent_not_ends_with_nocase: String + latestCreatePositionEvent_: CreatePositionEvent_filter + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [Account_filter] + or: [Account_filter] } enum Account_orderBy { - id - address - user - user__id - user__openPositions - type - vaultId - createPositionEvents - summerEvents - feePaids - automationEvents - swaps - positions - latestCreatePositionEvent - latestCreatePositionEvent__id - latestCreatePositionEvent__blockNumber - latestCreatePositionEvent__timestamp - latestCreatePositionEvent__txHash - latestCreatePositionEvent__logIndex - latestCreatePositionEvent__protocol - latestCreatePositionEvent__positionType - latestCreatePositionEvent__marketId + id + address + user + user__id + user__openPositions + type + vaultId + createPositionEvents + summerEvents + feePaids + automationEvents + swaps + positions + latestCreatePositionEvent + latestCreatePositionEvent__id + latestCreatePositionEvent__blockNumber + latestCreatePositionEvent__timestamp + latestCreatePositionEvent__txHash + latestCreatePositionEvent__logIndex + latestCreatePositionEvent__protocol + latestCreatePositionEvent__positionType + latestCreatePositionEvent__marketId } type AssetSwap { - id: Bytes! - assetIn: Token! - assetOut: Token! - amountIn: BigInt! - amountOut: BigInt! - assetInPrice: BigDecimal! - oracle: String! - amountInUSD: BigDecimal! - mainEventHash: SummerEvent - user: User! - proxy: Account! - timestamp: BigInt! - block: BigInt! + id: Bytes! + assetIn: Token! + assetOut: Token! + amountIn: BigInt! + amountOut: BigInt! + assetInPrice: BigDecimal! + oracle: String! + amountInUSD: BigDecimal! + mainEventHash: SummerEvent + user: User! + proxy: Account! + position: Position + timestamp: BigInt! + block: BigInt! } input AssetSwap_filter { - id: Bytes - id_not: Bytes - id_gt: Bytes - id_lt: Bytes - id_gte: Bytes - id_lte: Bytes - id_in: [Bytes!] - id_not_in: [Bytes!] - id_contains: Bytes - id_not_contains: Bytes - assetIn: String - assetIn_not: String - assetIn_gt: String - assetIn_lt: String - assetIn_gte: String - assetIn_lte: String - assetIn_in: [String!] - assetIn_not_in: [String!] - assetIn_contains: String - assetIn_contains_nocase: String - assetIn_not_contains: String - assetIn_not_contains_nocase: String - assetIn_starts_with: String - assetIn_starts_with_nocase: String - assetIn_not_starts_with: String - assetIn_not_starts_with_nocase: String - assetIn_ends_with: String - assetIn_ends_with_nocase: String - assetIn_not_ends_with: String - assetIn_not_ends_with_nocase: String - assetIn_: Token_filter - assetOut: String - assetOut_not: String - assetOut_gt: String - assetOut_lt: String - assetOut_gte: String - assetOut_lte: String - assetOut_in: [String!] - assetOut_not_in: [String!] - assetOut_contains: String - assetOut_contains_nocase: String - assetOut_not_contains: String - assetOut_not_contains_nocase: String - assetOut_starts_with: String - assetOut_starts_with_nocase: String - assetOut_not_starts_with: String - assetOut_not_starts_with_nocase: String - assetOut_ends_with: String - assetOut_ends_with_nocase: String - assetOut_not_ends_with: String - assetOut_not_ends_with_nocase: String - assetOut_: Token_filter - amountIn: BigInt - amountIn_not: BigInt - amountIn_gt: BigInt - amountIn_lt: BigInt - amountIn_gte: BigInt - amountIn_lte: BigInt - amountIn_in: [BigInt!] - amountIn_not_in: [BigInt!] - amountOut: BigInt - amountOut_not: BigInt - amountOut_gt: BigInt - amountOut_lt: BigInt - amountOut_gte: BigInt - amountOut_lte: BigInt - amountOut_in: [BigInt!] - amountOut_not_in: [BigInt!] - assetInPrice: BigDecimal - assetInPrice_not: BigDecimal - assetInPrice_gt: BigDecimal - assetInPrice_lt: BigDecimal - assetInPrice_gte: BigDecimal - assetInPrice_lte: BigDecimal - assetInPrice_in: [BigDecimal!] - assetInPrice_not_in: [BigDecimal!] - oracle: String - oracle_not: String - oracle_gt: String - oracle_lt: String - oracle_gte: String - oracle_lte: String - oracle_in: [String!] - oracle_not_in: [String!] - oracle_contains: String - oracle_contains_nocase: String - oracle_not_contains: String - oracle_not_contains_nocase: String - oracle_starts_with: String - oracle_starts_with_nocase: String - oracle_not_starts_with: String - oracle_not_starts_with_nocase: String - oracle_ends_with: String - oracle_ends_with_nocase: String - oracle_not_ends_with: String - oracle_not_ends_with_nocase: String - amountInUSD: BigDecimal - amountInUSD_not: BigDecimal - amountInUSD_gt: BigDecimal - amountInUSD_lt: BigDecimal - amountInUSD_gte: BigDecimal - amountInUSD_lte: BigDecimal - amountInUSD_in: [BigDecimal!] - amountInUSD_not_in: [BigDecimal!] - mainEventHash: String - mainEventHash_not: String - mainEventHash_gt: String - mainEventHash_lt: String - mainEventHash_gte: String - mainEventHash_lte: String - mainEventHash_in: [String!] - mainEventHash_not_in: [String!] - mainEventHash_contains: String - mainEventHash_contains_nocase: String - mainEventHash_not_contains: String - mainEventHash_not_contains_nocase: String - mainEventHash_starts_with: String - mainEventHash_starts_with_nocase: String - mainEventHash_not_starts_with: String - mainEventHash_not_starts_with_nocase: String - mainEventHash_ends_with: String - mainEventHash_ends_with_nocase: String - mainEventHash_not_ends_with: String - mainEventHash_not_ends_with_nocase: String - mainEventHash_: SummerEvent_filter - user: String - user_not: String - user_gt: String - user_lt: String - user_gte: String - user_lte: String - user_in: [String!] - user_not_in: [String!] - user_contains: String - user_contains_nocase: String - user_not_contains: String - user_not_contains_nocase: String - user_starts_with: String - user_starts_with_nocase: String - user_not_starts_with: String - user_not_starts_with_nocase: String - user_ends_with: String - user_ends_with_nocase: String - user_not_ends_with: String - user_not_ends_with_nocase: String - user_: User_filter - proxy: String - proxy_not: String - proxy_gt: String - proxy_lt: String - proxy_gte: String - proxy_lte: String - proxy_in: [String!] - proxy_not_in: [String!] - proxy_contains: String - proxy_contains_nocase: String - proxy_not_contains: String - proxy_not_contains_nocase: String - proxy_starts_with: String - proxy_starts_with_nocase: String - proxy_not_starts_with: String - proxy_not_starts_with_nocase: String - proxy_ends_with: String - proxy_ends_with_nocase: String - proxy_not_ends_with: String - proxy_not_ends_with_nocase: String - proxy_: Account_filter - timestamp: BigInt - timestamp_not: BigInt - timestamp_gt: BigInt - timestamp_lt: BigInt - timestamp_gte: BigInt - timestamp_lte: BigInt - timestamp_in: [BigInt!] - timestamp_not_in: [BigInt!] - block: BigInt - block_not: BigInt - block_gt: BigInt - block_lt: BigInt - block_gte: BigInt - block_lte: BigInt - block_in: [BigInt!] - block_not_in: [BigInt!] - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [AssetSwap_filter] - or: [AssetSwap_filter] + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + assetIn: String + assetIn_not: String + assetIn_gt: String + assetIn_lt: String + assetIn_gte: String + assetIn_lte: String + assetIn_in: [String!] + assetIn_not_in: [String!] + assetIn_contains: String + assetIn_contains_nocase: String + assetIn_not_contains: String + assetIn_not_contains_nocase: String + assetIn_starts_with: String + assetIn_starts_with_nocase: String + assetIn_not_starts_with: String + assetIn_not_starts_with_nocase: String + assetIn_ends_with: String + assetIn_ends_with_nocase: String + assetIn_not_ends_with: String + assetIn_not_ends_with_nocase: String + assetIn_: Token_filter + assetOut: String + assetOut_not: String + assetOut_gt: String + assetOut_lt: String + assetOut_gte: String + assetOut_lte: String + assetOut_in: [String!] + assetOut_not_in: [String!] + assetOut_contains: String + assetOut_contains_nocase: String + assetOut_not_contains: String + assetOut_not_contains_nocase: String + assetOut_starts_with: String + assetOut_starts_with_nocase: String + assetOut_not_starts_with: String + assetOut_not_starts_with_nocase: String + assetOut_ends_with: String + assetOut_ends_with_nocase: String + assetOut_not_ends_with: String + assetOut_not_ends_with_nocase: String + assetOut_: Token_filter + amountIn: BigInt + amountIn_not: BigInt + amountIn_gt: BigInt + amountIn_lt: BigInt + amountIn_gte: BigInt + amountIn_lte: BigInt + amountIn_in: [BigInt!] + amountIn_not_in: [BigInt!] + amountOut: BigInt + amountOut_not: BigInt + amountOut_gt: BigInt + amountOut_lt: BigInt + amountOut_gte: BigInt + amountOut_lte: BigInt + amountOut_in: [BigInt!] + amountOut_not_in: [BigInt!] + assetInPrice: BigDecimal + assetInPrice_not: BigDecimal + assetInPrice_gt: BigDecimal + assetInPrice_lt: BigDecimal + assetInPrice_gte: BigDecimal + assetInPrice_lte: BigDecimal + assetInPrice_in: [BigDecimal!] + assetInPrice_not_in: [BigDecimal!] + oracle: String + oracle_not: String + oracle_gt: String + oracle_lt: String + oracle_gte: String + oracle_lte: String + oracle_in: [String!] + oracle_not_in: [String!] + oracle_contains: String + oracle_contains_nocase: String + oracle_not_contains: String + oracle_not_contains_nocase: String + oracle_starts_with: String + oracle_starts_with_nocase: String + oracle_not_starts_with: String + oracle_not_starts_with_nocase: String + oracle_ends_with: String + oracle_ends_with_nocase: String + oracle_not_ends_with: String + oracle_not_ends_with_nocase: String + amountInUSD: BigDecimal + amountInUSD_not: BigDecimal + amountInUSD_gt: BigDecimal + amountInUSD_lt: BigDecimal + amountInUSD_gte: BigDecimal + amountInUSD_lte: BigDecimal + amountInUSD_in: [BigDecimal!] + amountInUSD_not_in: [BigDecimal!] + mainEventHash: String + mainEventHash_not: String + mainEventHash_gt: String + mainEventHash_lt: String + mainEventHash_gte: String + mainEventHash_lte: String + mainEventHash_in: [String!] + mainEventHash_not_in: [String!] + mainEventHash_contains: String + mainEventHash_contains_nocase: String + mainEventHash_not_contains: String + mainEventHash_not_contains_nocase: String + mainEventHash_starts_with: String + mainEventHash_starts_with_nocase: String + mainEventHash_not_starts_with: String + mainEventHash_not_starts_with_nocase: String + mainEventHash_ends_with: String + mainEventHash_ends_with_nocase: String + mainEventHash_not_ends_with: String + mainEventHash_not_ends_with_nocase: String + mainEventHash_: SummerEvent_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + proxy: String + proxy_not: String + proxy_gt: String + proxy_lt: String + proxy_gte: String + proxy_lte: String + proxy_in: [String!] + proxy_not_in: [String!] + proxy_contains: String + proxy_contains_nocase: String + proxy_not_contains: String + proxy_not_contains_nocase: String + proxy_starts_with: String + proxy_starts_with_nocase: String + proxy_not_starts_with: String + proxy_not_starts_with_nocase: String + proxy_ends_with: String + proxy_ends_with_nocase: String + proxy_not_ends_with: String + proxy_not_ends_with_nocase: String + proxy_: Account_filter + position: String + position_not: String + position_gt: String + position_lt: String + position_gte: String + position_lte: String + position_in: [String!] + position_not_in: [String!] + position_contains: String + position_contains_nocase: String + position_not_contains: String + position_not_contains_nocase: String + position_starts_with: String + position_starts_with_nocase: String + position_not_starts_with: String + position_not_starts_with_nocase: String + position_ends_with: String + position_ends_with_nocase: String + position_not_ends_with: String + position_not_ends_with_nocase: String + position_: Position_filter + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + block: BigInt + block_not: BigInt + block_gt: BigInt + block_lt: BigInt + block_gte: BigInt + block_lte: BigInt + block_in: [BigInt!] + block_not_in: [BigInt!] + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [AssetSwap_filter] + or: [AssetSwap_filter] } enum AssetSwap_orderBy { - id - assetIn - assetIn__id - assetIn__address - assetIn__symbol - assetIn__decimals - assetIn__precision - assetOut - assetOut__id - assetOut__address - assetOut__symbol - assetOut__decimals - assetOut__precision - amountIn - amountOut - assetInPrice - oracle - amountInUSD - mainEventHash - mainEventHash__id - mainEventHash__blockNumber - mainEventHash__timestamp - mainEventHash__txHash - mainEventHash__logIndex - mainEventHash__sender - mainEventHash__kind - mainEventHash__depositedUSD - mainEventHash__withdrawnUSD - mainEventHash__deltaUSD - mainEventHash__feePaidUSD - mainEventHash__protocol - mainEventHash__marketId - mainEventHash__debtBefore - mainEventHash__debtInUSDBefore - mainEventHash__debtAfter - mainEventHash__debtInUSDAfter - mainEventHash__collateralBefore - mainEventHash__collateralInUSDBefore - mainEventHash__collateralAfter - mainEventHash__collateralInUSDAfter - mainEventHash__supplyBefore - mainEventHash__supplyInUSDBefore - mainEventHash__supplyAfter - mainEventHash__supplyInUSDAfter - mainEventHash__netValueBefore - mainEventHash__netValueAfter - mainEventHash__collateralTokenPriceInUSD - mainEventHash__debtTokenPriceInUSD - mainEventHash__supplyTokenPriceInUSD - user - user__id - user__openPositions - proxy - proxy__id - proxy__address - proxy__type - proxy__vaultId - timestamp - block + id + assetIn + assetIn__id + assetIn__address + assetIn__symbol + assetIn__decimals + assetIn__precision + assetOut + assetOut__id + assetOut__address + assetOut__symbol + assetOut__decimals + assetOut__precision + amountIn + amountOut + assetInPrice + oracle + amountInUSD + mainEventHash + mainEventHash__id + mainEventHash__blockNumber + mainEventHash__timestamp + mainEventHash__txHash + mainEventHash__logIndex + mainEventHash__sender + mainEventHash__kind + mainEventHash__depositedUSD + mainEventHash__withdrawnUSD + mainEventHash__deltaUSD + mainEventHash__feePaidUSD + mainEventHash__protocol + mainEventHash__marketId + mainEventHash__debtBefore + mainEventHash__debtInUSDBefore + mainEventHash__debtAfter + mainEventHash__debtInUSDAfter + mainEventHash__collateralBefore + mainEventHash__collateralInUSDBefore + mainEventHash__collateralAfter + mainEventHash__collateralInUSDAfter + mainEventHash__supplyBefore + mainEventHash__supplyInUSDBefore + mainEventHash__supplyAfter + mainEventHash__supplyInUSDAfter + mainEventHash__netValueBefore + mainEventHash__netValueAfter + mainEventHash__collateralTokenPriceInUSD + mainEventHash__debtTokenPriceInUSD + mainEventHash__supplyTokenPriceInUSD + user + user__id + user__openPositions + proxy + proxy__id + proxy__address + proxy__type + proxy__vaultId + position + position__id + position__protocol + position__marketId + position__positionType + position__cumulativeDepositedUSD + position__cumulativeWithdrawnUSD + position__cumulativeDeltaUSD + position__cumulativeFeesUSD + position__debt + position__debtInUSD + position__collateral + position__collateralInUSD + position__supply + position__supplyInUSD + position__netValue + position___ajnaBucket + timestamp + block } scalar BigDecimal @@ -469,4225 +563,4377 @@ scalar BigDecimal scalar BigInt input Block_height { - hash: Bytes - number: Int - number_gte: Int + hash: Bytes + number: Int + number_gte: Int } input BlockChangedFilter { - number_gte: Int! + number_gte: Int! } scalar Bytes type CreatePositionEvent { - id: Bytes! - blockNumber: BigInt! - timestamp: BigInt! - txHash: Bytes! - logIndex: BigInt! - protocol: String! - positionType: String! - debtToken: Token! - collateralToken: Token! - marketId: String - user: User! - account: Account! + id: Bytes! + blockNumber: BigInt! + timestamp: BigInt! + txHash: Bytes! + logIndex: BigInt! + protocol: String! + positionType: String! + debtToken: Token! + collateralToken: Token! + marketId: String + user: User! + account: Account! } input CreatePositionEvent_filter { - id: Bytes - id_not: Bytes - id_gt: Bytes - id_lt: Bytes - id_gte: Bytes - id_lte: Bytes - id_in: [Bytes!] - id_not_in: [Bytes!] - id_contains: Bytes - id_not_contains: Bytes - blockNumber: BigInt - blockNumber_not: BigInt - blockNumber_gt: BigInt - blockNumber_lt: BigInt - blockNumber_gte: BigInt - blockNumber_lte: BigInt - blockNumber_in: [BigInt!] - blockNumber_not_in: [BigInt!] - timestamp: BigInt - timestamp_not: BigInt - timestamp_gt: BigInt - timestamp_lt: BigInt - timestamp_gte: BigInt - timestamp_lte: BigInt - timestamp_in: [BigInt!] - timestamp_not_in: [BigInt!] - txHash: Bytes - txHash_not: Bytes - txHash_gt: Bytes - txHash_lt: Bytes - txHash_gte: Bytes - txHash_lte: Bytes - txHash_in: [Bytes!] - txHash_not_in: [Bytes!] - txHash_contains: Bytes - txHash_not_contains: Bytes - logIndex: BigInt - logIndex_not: BigInt - logIndex_gt: BigInt - logIndex_lt: BigInt - logIndex_gte: BigInt - logIndex_lte: BigInt - logIndex_in: [BigInt!] - logIndex_not_in: [BigInt!] - protocol: String - protocol_not: String - protocol_gt: String - protocol_lt: String - protocol_gte: String - protocol_lte: String - protocol_in: [String!] - protocol_not_in: [String!] - protocol_contains: String - protocol_contains_nocase: String - protocol_not_contains: String - protocol_not_contains_nocase: String - protocol_starts_with: String - protocol_starts_with_nocase: String - protocol_not_starts_with: String - protocol_not_starts_with_nocase: String - protocol_ends_with: String - protocol_ends_with_nocase: String - protocol_not_ends_with: String - protocol_not_ends_with_nocase: String - positionType: String - positionType_not: String - positionType_gt: String - positionType_lt: String - positionType_gte: String - positionType_lte: String - positionType_in: [String!] - positionType_not_in: [String!] - positionType_contains: String - positionType_contains_nocase: String - positionType_not_contains: String - positionType_not_contains_nocase: String - positionType_starts_with: String - positionType_starts_with_nocase: String - positionType_not_starts_with: String - positionType_not_starts_with_nocase: String - positionType_ends_with: String - positionType_ends_with_nocase: String - positionType_not_ends_with: String - positionType_not_ends_with_nocase: String - debtToken: String - debtToken_not: String - debtToken_gt: String - debtToken_lt: String - debtToken_gte: String - debtToken_lte: String - debtToken_in: [String!] - debtToken_not_in: [String!] - debtToken_contains: String - debtToken_contains_nocase: String - debtToken_not_contains: String - debtToken_not_contains_nocase: String - debtToken_starts_with: String - debtToken_starts_with_nocase: String - debtToken_not_starts_with: String - debtToken_not_starts_with_nocase: String - debtToken_ends_with: String - debtToken_ends_with_nocase: String - debtToken_not_ends_with: String - debtToken_not_ends_with_nocase: String - debtToken_: Token_filter - collateralToken: String - collateralToken_not: String - collateralToken_gt: String - collateralToken_lt: String - collateralToken_gte: String - collateralToken_lte: String - collateralToken_in: [String!] - collateralToken_not_in: [String!] - collateralToken_contains: String - collateralToken_contains_nocase: String - collateralToken_not_contains: String - collateralToken_not_contains_nocase: String - collateralToken_starts_with: String - collateralToken_starts_with_nocase: String - collateralToken_not_starts_with: String - collateralToken_not_starts_with_nocase: String - collateralToken_ends_with: String - collateralToken_ends_with_nocase: String - collateralToken_not_ends_with: String - collateralToken_not_ends_with_nocase: String - collateralToken_: Token_filter - marketId: String - marketId_not: String - marketId_gt: String - marketId_lt: String - marketId_gte: String - marketId_lte: String - marketId_in: [String!] - marketId_not_in: [String!] - marketId_contains: String - marketId_contains_nocase: String - marketId_not_contains: String - marketId_not_contains_nocase: String - marketId_starts_with: String - marketId_starts_with_nocase: String - marketId_not_starts_with: String - marketId_not_starts_with_nocase: String - marketId_ends_with: String - marketId_ends_with_nocase: String - marketId_not_ends_with: String - marketId_not_ends_with_nocase: String - user: String - user_not: String - user_gt: String - user_lt: String - user_gte: String - user_lte: String - user_in: [String!] - user_not_in: [String!] - user_contains: String - user_contains_nocase: String - user_not_contains: String - user_not_contains_nocase: String - user_starts_with: String - user_starts_with_nocase: String - user_not_starts_with: String - user_not_starts_with_nocase: String - user_ends_with: String - user_ends_with_nocase: String - user_not_ends_with: String - user_not_ends_with_nocase: String - user_: User_filter - account: String - account_not: String - account_gt: String - account_lt: String - account_gte: String - account_lte: String - account_in: [String!] - account_not_in: [String!] - account_contains: String - account_contains_nocase: String - account_not_contains: String - account_not_contains_nocase: String - account_starts_with: String - account_starts_with_nocase: String - account_not_starts_with: String - account_not_starts_with_nocase: String - account_ends_with: String - account_ends_with_nocase: String - account_not_ends_with: String - account_not_ends_with_nocase: String - account_: Account_filter - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [CreatePositionEvent_filter] - or: [CreatePositionEvent_filter] + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + blockNumber: BigInt + blockNumber_not: BigInt + blockNumber_gt: BigInt + blockNumber_lt: BigInt + blockNumber_gte: BigInt + blockNumber_lte: BigInt + blockNumber_in: [BigInt!] + blockNumber_not_in: [BigInt!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + txHash: Bytes + txHash_not: Bytes + txHash_gt: Bytes + txHash_lt: Bytes + txHash_gte: Bytes + txHash_lte: Bytes + txHash_in: [Bytes!] + txHash_not_in: [Bytes!] + txHash_contains: Bytes + txHash_not_contains: Bytes + logIndex: BigInt + logIndex_not: BigInt + logIndex_gt: BigInt + logIndex_lt: BigInt + logIndex_gte: BigInt + logIndex_lte: BigInt + logIndex_in: [BigInt!] + logIndex_not_in: [BigInt!] + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + positionType: String + positionType_not: String + positionType_gt: String + positionType_lt: String + positionType_gte: String + positionType_lte: String + positionType_in: [String!] + positionType_not_in: [String!] + positionType_contains: String + positionType_contains_nocase: String + positionType_not_contains: String + positionType_not_contains_nocase: String + positionType_starts_with: String + positionType_starts_with_nocase: String + positionType_not_starts_with: String + positionType_not_starts_with_nocase: String + positionType_ends_with: String + positionType_ends_with_nocase: String + positionType_not_ends_with: String + positionType_not_ends_with_nocase: String + debtToken: String + debtToken_not: String + debtToken_gt: String + debtToken_lt: String + debtToken_gte: String + debtToken_lte: String + debtToken_in: [String!] + debtToken_not_in: [String!] + debtToken_contains: String + debtToken_contains_nocase: String + debtToken_not_contains: String + debtToken_not_contains_nocase: String + debtToken_starts_with: String + debtToken_starts_with_nocase: String + debtToken_not_starts_with: String + debtToken_not_starts_with_nocase: String + debtToken_ends_with: String + debtToken_ends_with_nocase: String + debtToken_not_ends_with: String + debtToken_not_ends_with_nocase: String + debtToken_: Token_filter + collateralToken: String + collateralToken_not: String + collateralToken_gt: String + collateralToken_lt: String + collateralToken_gte: String + collateralToken_lte: String + collateralToken_in: [String!] + collateralToken_not_in: [String!] + collateralToken_contains: String + collateralToken_contains_nocase: String + collateralToken_not_contains: String + collateralToken_not_contains_nocase: String + collateralToken_starts_with: String + collateralToken_starts_with_nocase: String + collateralToken_not_starts_with: String + collateralToken_not_starts_with_nocase: String + collateralToken_ends_with: String + collateralToken_ends_with_nocase: String + collateralToken_not_ends_with: String + collateralToken_not_ends_with_nocase: String + collateralToken_: Token_filter + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [CreatePositionEvent_filter] + or: [CreatePositionEvent_filter] } enum CreatePositionEvent_orderBy { - id - blockNumber - timestamp - txHash - logIndex - protocol - positionType - debtToken - debtToken__id - debtToken__address - debtToken__symbol - debtToken__decimals - debtToken__precision - collateralToken - collateralToken__id - collateralToken__address - collateralToken__symbol - collateralToken__decimals - collateralToken__precision - marketId - user - user__id - user__openPositions - account - account__id - account__address - account__type - account__vaultId + id + blockNumber + timestamp + txHash + logIndex + protocol + positionType + debtToken + debtToken__id + debtToken__address + debtToken__symbol + debtToken__decimals + debtToken__precision + collateralToken + collateralToken__id + collateralToken__address + collateralToken__symbol + collateralToken__decimals + collateralToken__precision + marketId + user + user__id + user__openPositions + account + account__id + account__address + account__type + account__vaultId } type FeePaid { - id: ID! - block: BigInt! - timestamp: BigInt! - transactionHash: Bytes! - logIndex: BigInt! - sender: Bytes! - beneficiary: Bytes! - amount: BigDecimal! - amountInFeeToken: BigInt - feeTokenPrice: BigDecimal - oracle: String! - feeToken: Token - mainEventHash: SummerEvent - user: User! - proxy: Account! + id: ID! + block: BigInt! + timestamp: BigInt! + transactionHash: Bytes! + logIndex: BigInt! + sender: Bytes! + beneficiary: Bytes! + amount: BigDecimal! + amountInFeeToken: BigInt + feeTokenPrice: BigDecimal + oracle: String! + feeToken: Token + mainEventHash: SummerEvent + user: User! + proxy: Account! } input FeePaid_filter { - id: ID - id_not: ID - id_gt: ID - id_lt: ID - id_gte: ID - id_lte: ID - id_in: [ID!] - id_not_in: [ID!] - block: BigInt - block_not: BigInt - block_gt: BigInt - block_lt: BigInt - block_gte: BigInt - block_lte: BigInt - block_in: [BigInt!] - block_not_in: [BigInt!] - timestamp: BigInt - timestamp_not: BigInt - timestamp_gt: BigInt - timestamp_lt: BigInt - timestamp_gte: BigInt - timestamp_lte: BigInt - timestamp_in: [BigInt!] - timestamp_not_in: [BigInt!] - transactionHash: Bytes - transactionHash_not: Bytes - transactionHash_gt: Bytes - transactionHash_lt: Bytes - transactionHash_gte: Bytes - transactionHash_lte: Bytes - transactionHash_in: [Bytes!] - transactionHash_not_in: [Bytes!] - transactionHash_contains: Bytes - transactionHash_not_contains: Bytes - logIndex: BigInt - logIndex_not: BigInt - logIndex_gt: BigInt - logIndex_lt: BigInt - logIndex_gte: BigInt - logIndex_lte: BigInt - logIndex_in: [BigInt!] - logIndex_not_in: [BigInt!] - sender: Bytes - sender_not: Bytes - sender_gt: Bytes - sender_lt: Bytes - sender_gte: Bytes - sender_lte: Bytes - sender_in: [Bytes!] - sender_not_in: [Bytes!] - sender_contains: Bytes - sender_not_contains: Bytes - beneficiary: Bytes - beneficiary_not: Bytes - beneficiary_gt: Bytes - beneficiary_lt: Bytes - beneficiary_gte: Bytes - beneficiary_lte: Bytes - beneficiary_in: [Bytes!] - beneficiary_not_in: [Bytes!] - beneficiary_contains: Bytes - beneficiary_not_contains: Bytes - amount: BigDecimal - amount_not: BigDecimal - amount_gt: BigDecimal - amount_lt: BigDecimal - amount_gte: BigDecimal - amount_lte: BigDecimal - amount_in: [BigDecimal!] - amount_not_in: [BigDecimal!] - amountInFeeToken: BigInt - amountInFeeToken_not: BigInt - amountInFeeToken_gt: BigInt - amountInFeeToken_lt: BigInt - amountInFeeToken_gte: BigInt - amountInFeeToken_lte: BigInt - amountInFeeToken_in: [BigInt!] - amountInFeeToken_not_in: [BigInt!] - feeTokenPrice: BigDecimal - feeTokenPrice_not: BigDecimal - feeTokenPrice_gt: BigDecimal - feeTokenPrice_lt: BigDecimal - feeTokenPrice_gte: BigDecimal - feeTokenPrice_lte: BigDecimal - feeTokenPrice_in: [BigDecimal!] - feeTokenPrice_not_in: [BigDecimal!] - oracle: String - oracle_not: String - oracle_gt: String - oracle_lt: String - oracle_gte: String - oracle_lte: String - oracle_in: [String!] - oracle_not_in: [String!] - oracle_contains: String - oracle_contains_nocase: String - oracle_not_contains: String - oracle_not_contains_nocase: String - oracle_starts_with: String - oracle_starts_with_nocase: String - oracle_not_starts_with: String - oracle_not_starts_with_nocase: String - oracle_ends_with: String - oracle_ends_with_nocase: String - oracle_not_ends_with: String - oracle_not_ends_with_nocase: String - feeToken: String - feeToken_not: String - feeToken_gt: String - feeToken_lt: String - feeToken_gte: String - feeToken_lte: String - feeToken_in: [String!] - feeToken_not_in: [String!] - feeToken_contains: String - feeToken_contains_nocase: String - feeToken_not_contains: String - feeToken_not_contains_nocase: String - feeToken_starts_with: String - feeToken_starts_with_nocase: String - feeToken_not_starts_with: String - feeToken_not_starts_with_nocase: String - feeToken_ends_with: String - feeToken_ends_with_nocase: String - feeToken_not_ends_with: String - feeToken_not_ends_with_nocase: String - feeToken_: Token_filter - mainEventHash: String - mainEventHash_not: String - mainEventHash_gt: String - mainEventHash_lt: String - mainEventHash_gte: String - mainEventHash_lte: String - mainEventHash_in: [String!] - mainEventHash_not_in: [String!] - mainEventHash_contains: String - mainEventHash_contains_nocase: String - mainEventHash_not_contains: String - mainEventHash_not_contains_nocase: String - mainEventHash_starts_with: String - mainEventHash_starts_with_nocase: String - mainEventHash_not_starts_with: String - mainEventHash_not_starts_with_nocase: String - mainEventHash_ends_with: String - mainEventHash_ends_with_nocase: String - mainEventHash_not_ends_with: String - mainEventHash_not_ends_with_nocase: String - mainEventHash_: SummerEvent_filter - user: String - user_not: String - user_gt: String - user_lt: String - user_gte: String - user_lte: String - user_in: [String!] - user_not_in: [String!] - user_contains: String - user_contains_nocase: String - user_not_contains: String - user_not_contains_nocase: String - user_starts_with: String - user_starts_with_nocase: String - user_not_starts_with: String - user_not_starts_with_nocase: String - user_ends_with: String - user_ends_with_nocase: String - user_not_ends_with: String - user_not_ends_with_nocase: String - user_: User_filter - proxy: String - proxy_not: String - proxy_gt: String - proxy_lt: String - proxy_gte: String - proxy_lte: String - proxy_in: [String!] - proxy_not_in: [String!] - proxy_contains: String - proxy_contains_nocase: String - proxy_not_contains: String - proxy_not_contains_nocase: String - proxy_starts_with: String - proxy_starts_with_nocase: String - proxy_not_starts_with: String - proxy_not_starts_with_nocase: String - proxy_ends_with: String - proxy_ends_with_nocase: String - proxy_not_ends_with: String - proxy_not_ends_with_nocase: String - proxy_: Account_filter - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [FeePaid_filter] - or: [FeePaid_filter] + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + block: BigInt + block_not: BigInt + block_gt: BigInt + block_lt: BigInt + block_gte: BigInt + block_lte: BigInt + block_in: [BigInt!] + block_not_in: [BigInt!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + transactionHash: Bytes + transactionHash_not: Bytes + transactionHash_gt: Bytes + transactionHash_lt: Bytes + transactionHash_gte: Bytes + transactionHash_lte: Bytes + transactionHash_in: [Bytes!] + transactionHash_not_in: [Bytes!] + transactionHash_contains: Bytes + transactionHash_not_contains: Bytes + logIndex: BigInt + logIndex_not: BigInt + logIndex_gt: BigInt + logIndex_lt: BigInt + logIndex_gte: BigInt + logIndex_lte: BigInt + logIndex_in: [BigInt!] + logIndex_not_in: [BigInt!] + sender: Bytes + sender_not: Bytes + sender_gt: Bytes + sender_lt: Bytes + sender_gte: Bytes + sender_lte: Bytes + sender_in: [Bytes!] + sender_not_in: [Bytes!] + sender_contains: Bytes + sender_not_contains: Bytes + beneficiary: Bytes + beneficiary_not: Bytes + beneficiary_gt: Bytes + beneficiary_lt: Bytes + beneficiary_gte: Bytes + beneficiary_lte: Bytes + beneficiary_in: [Bytes!] + beneficiary_not_in: [Bytes!] + beneficiary_contains: Bytes + beneficiary_not_contains: Bytes + amount: BigDecimal + amount_not: BigDecimal + amount_gt: BigDecimal + amount_lt: BigDecimal + amount_gte: BigDecimal + amount_lte: BigDecimal + amount_in: [BigDecimal!] + amount_not_in: [BigDecimal!] + amountInFeeToken: BigInt + amountInFeeToken_not: BigInt + amountInFeeToken_gt: BigInt + amountInFeeToken_lt: BigInt + amountInFeeToken_gte: BigInt + amountInFeeToken_lte: BigInt + amountInFeeToken_in: [BigInt!] + amountInFeeToken_not_in: [BigInt!] + feeTokenPrice: BigDecimal + feeTokenPrice_not: BigDecimal + feeTokenPrice_gt: BigDecimal + feeTokenPrice_lt: BigDecimal + feeTokenPrice_gte: BigDecimal + feeTokenPrice_lte: BigDecimal + feeTokenPrice_in: [BigDecimal!] + feeTokenPrice_not_in: [BigDecimal!] + oracle: String + oracle_not: String + oracle_gt: String + oracle_lt: String + oracle_gte: String + oracle_lte: String + oracle_in: [String!] + oracle_not_in: [String!] + oracle_contains: String + oracle_contains_nocase: String + oracle_not_contains: String + oracle_not_contains_nocase: String + oracle_starts_with: String + oracle_starts_with_nocase: String + oracle_not_starts_with: String + oracle_not_starts_with_nocase: String + oracle_ends_with: String + oracle_ends_with_nocase: String + oracle_not_ends_with: String + oracle_not_ends_with_nocase: String + feeToken: String + feeToken_not: String + feeToken_gt: String + feeToken_lt: String + feeToken_gte: String + feeToken_lte: String + feeToken_in: [String!] + feeToken_not_in: [String!] + feeToken_contains: String + feeToken_contains_nocase: String + feeToken_not_contains: String + feeToken_not_contains_nocase: String + feeToken_starts_with: String + feeToken_starts_with_nocase: String + feeToken_not_starts_with: String + feeToken_not_starts_with_nocase: String + feeToken_ends_with: String + feeToken_ends_with_nocase: String + feeToken_not_ends_with: String + feeToken_not_ends_with_nocase: String + feeToken_: Token_filter + mainEventHash: String + mainEventHash_not: String + mainEventHash_gt: String + mainEventHash_lt: String + mainEventHash_gte: String + mainEventHash_lte: String + mainEventHash_in: [String!] + mainEventHash_not_in: [String!] + mainEventHash_contains: String + mainEventHash_contains_nocase: String + mainEventHash_not_contains: String + mainEventHash_not_contains_nocase: String + mainEventHash_starts_with: String + mainEventHash_starts_with_nocase: String + mainEventHash_not_starts_with: String + mainEventHash_not_starts_with_nocase: String + mainEventHash_ends_with: String + mainEventHash_ends_with_nocase: String + mainEventHash_not_ends_with: String + mainEventHash_not_ends_with_nocase: String + mainEventHash_: SummerEvent_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + proxy: String + proxy_not: String + proxy_gt: String + proxy_lt: String + proxy_gte: String + proxy_lte: String + proxy_in: [String!] + proxy_not_in: [String!] + proxy_contains: String + proxy_contains_nocase: String + proxy_not_contains: String + proxy_not_contains_nocase: String + proxy_starts_with: String + proxy_starts_with_nocase: String + proxy_not_starts_with: String + proxy_not_starts_with_nocase: String + proxy_ends_with: String + proxy_ends_with_nocase: String + proxy_not_ends_with: String + proxy_not_ends_with_nocase: String + proxy_: Account_filter + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [FeePaid_filter] + or: [FeePaid_filter] } enum FeePaid_orderBy { - id - block - timestamp - transactionHash - logIndex - sender - beneficiary - amount - amountInFeeToken - feeTokenPrice - oracle - feeToken - feeToken__id - feeToken__address - feeToken__symbol - feeToken__decimals - feeToken__precision - mainEventHash - mainEventHash__id - mainEventHash__blockNumber - mainEventHash__timestamp - mainEventHash__txHash - mainEventHash__logIndex - mainEventHash__sender - mainEventHash__kind - mainEventHash__depositedUSD - mainEventHash__withdrawnUSD - mainEventHash__deltaUSD - mainEventHash__feePaidUSD - mainEventHash__protocol - mainEventHash__marketId - mainEventHash__debtBefore - mainEventHash__debtInUSDBefore - mainEventHash__debtAfter - mainEventHash__debtInUSDAfter - mainEventHash__collateralBefore - mainEventHash__collateralInUSDBefore - mainEventHash__collateralAfter - mainEventHash__collateralInUSDAfter - mainEventHash__supplyBefore - mainEventHash__supplyInUSDBefore - mainEventHash__supplyAfter - mainEventHash__supplyInUSDAfter - mainEventHash__netValueBefore - mainEventHash__netValueAfter - mainEventHash__collateralTokenPriceInUSD - mainEventHash__debtTokenPriceInUSD - mainEventHash__supplyTokenPriceInUSD - user - user__id - user__openPositions - proxy - proxy__id - proxy__address - proxy__type - proxy__vaultId + id + block + timestamp + transactionHash + logIndex + sender + beneficiary + amount + amountInFeeToken + feeTokenPrice + oracle + feeToken + feeToken__id + feeToken__address + feeToken__symbol + feeToken__decimals + feeToken__precision + mainEventHash + mainEventHash__id + mainEventHash__blockNumber + mainEventHash__timestamp + mainEventHash__txHash + mainEventHash__logIndex + mainEventHash__sender + mainEventHash__kind + mainEventHash__depositedUSD + mainEventHash__withdrawnUSD + mainEventHash__deltaUSD + mainEventHash__feePaidUSD + mainEventHash__protocol + mainEventHash__marketId + mainEventHash__debtBefore + mainEventHash__debtInUSDBefore + mainEventHash__debtAfter + mainEventHash__debtInUSDAfter + mainEventHash__collateralBefore + mainEventHash__collateralInUSDBefore + mainEventHash__collateralAfter + mainEventHash__collateralInUSDAfter + mainEventHash__supplyBefore + mainEventHash__supplyInUSDBefore + mainEventHash__supplyAfter + mainEventHash__supplyInUSDAfter + mainEventHash__netValueBefore + mainEventHash__netValueAfter + mainEventHash__collateralTokenPriceInUSD + mainEventHash__debtTokenPriceInUSD + mainEventHash__supplyTokenPriceInUSD + user + user__id + user__openPositions + proxy + proxy__id + proxy__address + proxy__type + proxy__vaultId } type Ilk { - id: Bytes! - blockNumber: BigInt! - token: Token! - rate: BigDecimal! + id: Bytes! + blockNumber: BigInt! + token: Token! + oracle: Bytes + rate: BigDecimal! } input Ilk_filter { - id: Bytes - id_not: Bytes - id_gt: Bytes - id_lt: Bytes - id_gte: Bytes - id_lte: Bytes - id_in: [Bytes!] - id_not_in: [Bytes!] - id_contains: Bytes - id_not_contains: Bytes - blockNumber: BigInt - blockNumber_not: BigInt - blockNumber_gt: BigInt - blockNumber_lt: BigInt - blockNumber_gte: BigInt - blockNumber_lte: BigInt - blockNumber_in: [BigInt!] - blockNumber_not_in: [BigInt!] - token: String - token_not: String - token_gt: String - token_lt: String - token_gte: String - token_lte: String - token_in: [String!] - token_not_in: [String!] - token_contains: String - token_contains_nocase: String - token_not_contains: String - token_not_contains_nocase: String - token_starts_with: String - token_starts_with_nocase: String - token_not_starts_with: String - token_not_starts_with_nocase: String - token_ends_with: String - token_ends_with_nocase: String - token_not_ends_with: String - token_not_ends_with_nocase: String - token_: Token_filter - rate: BigDecimal - rate_not: BigDecimal - rate_gt: BigDecimal - rate_lt: BigDecimal - rate_gte: BigDecimal - rate_lte: BigDecimal - rate_in: [BigDecimal!] - rate_not_in: [BigDecimal!] - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [Ilk_filter] - or: [Ilk_filter] + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + blockNumber: BigInt + blockNumber_not: BigInt + blockNumber_gt: BigInt + blockNumber_lt: BigInt + blockNumber_gte: BigInt + blockNumber_lte: BigInt + blockNumber_in: [BigInt!] + blockNumber_not_in: [BigInt!] + token: String + token_not: String + token_gt: String + token_lt: String + token_gte: String + token_lte: String + token_in: [String!] + token_not_in: [String!] + token_contains: String + token_contains_nocase: String + token_not_contains: String + token_not_contains_nocase: String + token_starts_with: String + token_starts_with_nocase: String + token_not_starts_with: String + token_not_starts_with_nocase: String + token_ends_with: String + token_ends_with_nocase: String + token_not_ends_with: String + token_not_ends_with_nocase: String + token_: Token_filter + oracle: Bytes + oracle_not: Bytes + oracle_gt: Bytes + oracle_lt: Bytes + oracle_gte: Bytes + oracle_lte: Bytes + oracle_in: [Bytes!] + oracle_not_in: [Bytes!] + oracle_contains: Bytes + oracle_not_contains: Bytes + rate: BigDecimal + rate_not: BigDecimal + rate_gt: BigDecimal + rate_lt: BigDecimal + rate_gte: BigDecimal + rate_lte: BigDecimal + rate_in: [BigDecimal!] + rate_not_in: [BigDecimal!] + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [Ilk_filter] + or: [Ilk_filter] } enum Ilk_orderBy { - id - blockNumber - token - token__id - token__address - token__symbol - token__decimals - token__precision - rate + id + blockNumber + token + token__id + token__address + token__symbol + token__decimals + token__precision + oracle + rate } """ 8 bytes signed integer - """ scalar Int8 type MakerUrn { - id: Bytes! - cdp: BigInt! - ilk: Bytes! - urn: Bytes! + id: Bytes! + cdp: BigInt! + ilk: Bytes! + urn: Bytes! } input MakerUrn_filter { - id: Bytes - id_not: Bytes - id_gt: Bytes - id_lt: Bytes - id_gte: Bytes - id_lte: Bytes - id_in: [Bytes!] - id_not_in: [Bytes!] - id_contains: Bytes - id_not_contains: Bytes - cdp: BigInt - cdp_not: BigInt - cdp_gt: BigInt - cdp_lt: BigInt - cdp_gte: BigInt - cdp_lte: BigInt - cdp_in: [BigInt!] - cdp_not_in: [BigInt!] - ilk: Bytes - ilk_not: Bytes - ilk_gt: Bytes - ilk_lt: Bytes - ilk_gte: Bytes - ilk_lte: Bytes - ilk_in: [Bytes!] - ilk_not_in: [Bytes!] - ilk_contains: Bytes - ilk_not_contains: Bytes - urn: Bytes - urn_not: Bytes - urn_gt: Bytes - urn_lt: Bytes - urn_gte: Bytes - urn_lte: Bytes - urn_in: [Bytes!] - urn_not_in: [Bytes!] - urn_contains: Bytes - urn_not_contains: Bytes - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [MakerUrn_filter] - or: [MakerUrn_filter] + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + cdp: BigInt + cdp_not: BigInt + cdp_gt: BigInt + cdp_lt: BigInt + cdp_gte: BigInt + cdp_lte: BigInt + cdp_in: [BigInt!] + cdp_not_in: [BigInt!] + ilk: Bytes + ilk_not: Bytes + ilk_gt: Bytes + ilk_lt: Bytes + ilk_gte: Bytes + ilk_lte: Bytes + ilk_in: [Bytes!] + ilk_not_in: [Bytes!] + ilk_contains: Bytes + ilk_not_contains: Bytes + urn: Bytes + urn_not: Bytes + urn_gt: Bytes + urn_lt: Bytes + urn_gte: Bytes + urn_lte: Bytes + urn_in: [Bytes!] + urn_not_in: [Bytes!] + urn_contains: Bytes + urn_not_contains: Bytes + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [MakerUrn_filter] + or: [MakerUrn_filter] } enum MakerUrn_orderBy { - id - cdp - ilk - urn + id + cdp + ilk + urn } type Market { - id: ID! - protocol: String! - marketId: String! - supported: Boolean! + id: ID! + protocol: String! + marketId: String! + supported: Boolean! } input Market_filter { - id: ID - id_not: ID - id_gt: ID - id_lt: ID - id_gte: ID - id_lte: ID - id_in: [ID!] - id_not_in: [ID!] - protocol: String - protocol_not: String - protocol_gt: String - protocol_lt: String - protocol_gte: String - protocol_lte: String - protocol_in: [String!] - protocol_not_in: [String!] - protocol_contains: String - protocol_contains_nocase: String - protocol_not_contains: String - protocol_not_contains_nocase: String - protocol_starts_with: String - protocol_starts_with_nocase: String - protocol_not_starts_with: String - protocol_not_starts_with_nocase: String - protocol_ends_with: String - protocol_ends_with_nocase: String - protocol_not_ends_with: String - protocol_not_ends_with_nocase: String - marketId: String - marketId_not: String - marketId_gt: String - marketId_lt: String - marketId_gte: String - marketId_lte: String - marketId_in: [String!] - marketId_not_in: [String!] - marketId_contains: String - marketId_contains_nocase: String - marketId_not_contains: String - marketId_not_contains_nocase: String - marketId_starts_with: String - marketId_starts_with_nocase: String - marketId_not_starts_with: String - marketId_not_starts_with_nocase: String - marketId_ends_with: String - marketId_ends_with_nocase: String - marketId_not_ends_with: String - marketId_not_ends_with_nocase: String - supported: Boolean - supported_not: Boolean - supported_in: [Boolean!] - supported_not_in: [Boolean!] - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [Market_filter] - or: [Market_filter] + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + supported: Boolean + supported_not: Boolean + supported_in: [Boolean!] + supported_not_in: [Boolean!] + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [Market_filter] + or: [Market_filter] } enum Market_orderBy { - id - protocol - marketId - supported + id + protocol + marketId + supported } -"""Defines the order direction, either ascending or descending""" +""" +Defines the order direction, either ascending or descending +""" enum OrderDirection { - asc - desc + asc + desc } type Position { - id: ID! - account: Account! - user: User! - protocol: String! - marketId: String! - positionType: String - cumulativeDepositedUSD: BigDecimal! - cumulativeWithdrawnUSD: BigDecimal! - cumulativeDeltaUSD: BigDecimal! - cumulativeFeesUSD: BigDecimal! - debt: BigDecimal! - debtInUSD: BigDecimal! - collateral: BigDecimal! - collateralInUSD: BigDecimal! - supply: BigDecimal! - supplyInUSD: BigDecimal! - netValue: BigDecimal! - summerEvents(skip: Int = 0, first: Int = 100, orderBy: SummerEvent_orderBy, orderDirection: OrderDirection, where: SummerEvent_filter): [SummerEvent!]! - triggers(skip: Int = 0, first: Int = 100, orderBy: Trigger_orderBy, orderDirection: OrderDirection, where: Trigger_filter): [Trigger!]! - lastEvent: SummerEvent - _ajnaBucket: BigInt! + id: ID! + account: Account! + user: User! + protocol: String! + marketId: String! + positionType: String + cumulativeDepositedUSD: BigDecimal! + cumulativeWithdrawnUSD: BigDecimal! + cumulativeDeltaUSD: BigDecimal! + cumulativeFeesUSD: BigDecimal! + debt: BigDecimal! + debtInUSD: BigDecimal! + collateral: BigDecimal! + collateralInUSD: BigDecimal! + supply: BigDecimal! + supplyInUSD: BigDecimal! + netValue: BigDecimal! + summerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: SummerEvent_orderBy + orderDirection: OrderDirection + where: SummerEvent_filter + ): [SummerEvent!]! + triggers( + skip: Int = 0 + first: Int = 100 + orderBy: Trigger_orderBy + orderDirection: OrderDirection + where: Trigger_filter + ): [Trigger!]! + swaps( + skip: Int = 0 + first: Int = 100 + orderBy: AssetSwap_orderBy + orderDirection: OrderDirection + where: AssetSwap_filter + ): [AssetSwap!]! + lastEvent: SummerEvent + _ajnaBucket: BigInt! } input Position_filter { - id: ID - id_not: ID - id_gt: ID - id_lt: ID - id_gte: ID - id_lte: ID - id_in: [ID!] - id_not_in: [ID!] - account: String - account_not: String - account_gt: String - account_lt: String - account_gte: String - account_lte: String - account_in: [String!] - account_not_in: [String!] - account_contains: String - account_contains_nocase: String - account_not_contains: String - account_not_contains_nocase: String - account_starts_with: String - account_starts_with_nocase: String - account_not_starts_with: String - account_not_starts_with_nocase: String - account_ends_with: String - account_ends_with_nocase: String - account_not_ends_with: String - account_not_ends_with_nocase: String - account_: Account_filter - user: String - user_not: String - user_gt: String - user_lt: String - user_gte: String - user_lte: String - user_in: [String!] - user_not_in: [String!] - user_contains: String - user_contains_nocase: String - user_not_contains: String - user_not_contains_nocase: String - user_starts_with: String - user_starts_with_nocase: String - user_not_starts_with: String - user_not_starts_with_nocase: String - user_ends_with: String - user_ends_with_nocase: String - user_not_ends_with: String - user_not_ends_with_nocase: String - user_: User_filter - protocol: String - protocol_not: String - protocol_gt: String - protocol_lt: String - protocol_gte: String - protocol_lte: String - protocol_in: [String!] - protocol_not_in: [String!] - protocol_contains: String - protocol_contains_nocase: String - protocol_not_contains: String - protocol_not_contains_nocase: String - protocol_starts_with: String - protocol_starts_with_nocase: String - protocol_not_starts_with: String - protocol_not_starts_with_nocase: String - protocol_ends_with: String - protocol_ends_with_nocase: String - protocol_not_ends_with: String - protocol_not_ends_with_nocase: String - marketId: String - marketId_not: String - marketId_gt: String - marketId_lt: String - marketId_gte: String - marketId_lte: String - marketId_in: [String!] - marketId_not_in: [String!] - marketId_contains: String - marketId_contains_nocase: String - marketId_not_contains: String - marketId_not_contains_nocase: String - marketId_starts_with: String - marketId_starts_with_nocase: String - marketId_not_starts_with: String - marketId_not_starts_with_nocase: String - marketId_ends_with: String - marketId_ends_with_nocase: String - marketId_not_ends_with: String - marketId_not_ends_with_nocase: String - positionType: String - positionType_not: String - positionType_gt: String - positionType_lt: String - positionType_gte: String - positionType_lte: String - positionType_in: [String!] - positionType_not_in: [String!] - positionType_contains: String - positionType_contains_nocase: String - positionType_not_contains: String - positionType_not_contains_nocase: String - positionType_starts_with: String - positionType_starts_with_nocase: String - positionType_not_starts_with: String - positionType_not_starts_with_nocase: String - positionType_ends_with: String - positionType_ends_with_nocase: String - positionType_not_ends_with: String - positionType_not_ends_with_nocase: String - cumulativeDepositedUSD: BigDecimal - cumulativeDepositedUSD_not: BigDecimal - cumulativeDepositedUSD_gt: BigDecimal - cumulativeDepositedUSD_lt: BigDecimal - cumulativeDepositedUSD_gte: BigDecimal - cumulativeDepositedUSD_lte: BigDecimal - cumulativeDepositedUSD_in: [BigDecimal!] - cumulativeDepositedUSD_not_in: [BigDecimal!] - cumulativeWithdrawnUSD: BigDecimal - cumulativeWithdrawnUSD_not: BigDecimal - cumulativeWithdrawnUSD_gt: BigDecimal - cumulativeWithdrawnUSD_lt: BigDecimal - cumulativeWithdrawnUSD_gte: BigDecimal - cumulativeWithdrawnUSD_lte: BigDecimal - cumulativeWithdrawnUSD_in: [BigDecimal!] - cumulativeWithdrawnUSD_not_in: [BigDecimal!] - cumulativeDeltaUSD: BigDecimal - cumulativeDeltaUSD_not: BigDecimal - cumulativeDeltaUSD_gt: BigDecimal - cumulativeDeltaUSD_lt: BigDecimal - cumulativeDeltaUSD_gte: BigDecimal - cumulativeDeltaUSD_lte: BigDecimal - cumulativeDeltaUSD_in: [BigDecimal!] - cumulativeDeltaUSD_not_in: [BigDecimal!] - cumulativeFeesUSD: BigDecimal - cumulativeFeesUSD_not: BigDecimal - cumulativeFeesUSD_gt: BigDecimal - cumulativeFeesUSD_lt: BigDecimal - cumulativeFeesUSD_gte: BigDecimal - cumulativeFeesUSD_lte: BigDecimal - cumulativeFeesUSD_in: [BigDecimal!] - cumulativeFeesUSD_not_in: [BigDecimal!] - debt: BigDecimal - debt_not: BigDecimal - debt_gt: BigDecimal - debt_lt: BigDecimal - debt_gte: BigDecimal - debt_lte: BigDecimal - debt_in: [BigDecimal!] - debt_not_in: [BigDecimal!] - debtInUSD: BigDecimal - debtInUSD_not: BigDecimal - debtInUSD_gt: BigDecimal - debtInUSD_lt: BigDecimal - debtInUSD_gte: BigDecimal - debtInUSD_lte: BigDecimal - debtInUSD_in: [BigDecimal!] - debtInUSD_not_in: [BigDecimal!] - collateral: BigDecimal - collateral_not: BigDecimal - collateral_gt: BigDecimal - collateral_lt: BigDecimal - collateral_gte: BigDecimal - collateral_lte: BigDecimal - collateral_in: [BigDecimal!] - collateral_not_in: [BigDecimal!] - collateralInUSD: BigDecimal - collateralInUSD_not: BigDecimal - collateralInUSD_gt: BigDecimal - collateralInUSD_lt: BigDecimal - collateralInUSD_gte: BigDecimal - collateralInUSD_lte: BigDecimal - collateralInUSD_in: [BigDecimal!] - collateralInUSD_not_in: [BigDecimal!] - supply: BigDecimal - supply_not: BigDecimal - supply_gt: BigDecimal - supply_lt: BigDecimal - supply_gte: BigDecimal - supply_lte: BigDecimal - supply_in: [BigDecimal!] - supply_not_in: [BigDecimal!] - supplyInUSD: BigDecimal - supplyInUSD_not: BigDecimal - supplyInUSD_gt: BigDecimal - supplyInUSD_lt: BigDecimal - supplyInUSD_gte: BigDecimal - supplyInUSD_lte: BigDecimal - supplyInUSD_in: [BigDecimal!] - supplyInUSD_not_in: [BigDecimal!] - netValue: BigDecimal - netValue_not: BigDecimal - netValue_gt: BigDecimal - netValue_lt: BigDecimal - netValue_gte: BigDecimal - netValue_lte: BigDecimal - netValue_in: [BigDecimal!] - netValue_not_in: [BigDecimal!] - summerEvents_: SummerEvent_filter - triggers_: Trigger_filter - lastEvent: String - lastEvent_not: String - lastEvent_gt: String - lastEvent_lt: String - lastEvent_gte: String - lastEvent_lte: String - lastEvent_in: [String!] - lastEvent_not_in: [String!] - lastEvent_contains: String - lastEvent_contains_nocase: String - lastEvent_not_contains: String - lastEvent_not_contains_nocase: String - lastEvent_starts_with: String - lastEvent_starts_with_nocase: String - lastEvent_not_starts_with: String - lastEvent_not_starts_with_nocase: String - lastEvent_ends_with: String - lastEvent_ends_with_nocase: String - lastEvent_not_ends_with: String - lastEvent_not_ends_with_nocase: String - lastEvent_: SummerEvent_filter - _ajnaBucket: BigInt - _ajnaBucket_not: BigInt - _ajnaBucket_gt: BigInt - _ajnaBucket_lt: BigInt - _ajnaBucket_gte: BigInt - _ajnaBucket_lte: BigInt - _ajnaBucket_in: [BigInt!] - _ajnaBucket_not_in: [BigInt!] - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [Position_filter] - or: [Position_filter] + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + positionType: String + positionType_not: String + positionType_gt: String + positionType_lt: String + positionType_gte: String + positionType_lte: String + positionType_in: [String!] + positionType_not_in: [String!] + positionType_contains: String + positionType_contains_nocase: String + positionType_not_contains: String + positionType_not_contains_nocase: String + positionType_starts_with: String + positionType_starts_with_nocase: String + positionType_not_starts_with: String + positionType_not_starts_with_nocase: String + positionType_ends_with: String + positionType_ends_with_nocase: String + positionType_not_ends_with: String + positionType_not_ends_with_nocase: String + cumulativeDepositedUSD: BigDecimal + cumulativeDepositedUSD_not: BigDecimal + cumulativeDepositedUSD_gt: BigDecimal + cumulativeDepositedUSD_lt: BigDecimal + cumulativeDepositedUSD_gte: BigDecimal + cumulativeDepositedUSD_lte: BigDecimal + cumulativeDepositedUSD_in: [BigDecimal!] + cumulativeDepositedUSD_not_in: [BigDecimal!] + cumulativeWithdrawnUSD: BigDecimal + cumulativeWithdrawnUSD_not: BigDecimal + cumulativeWithdrawnUSD_gt: BigDecimal + cumulativeWithdrawnUSD_lt: BigDecimal + cumulativeWithdrawnUSD_gte: BigDecimal + cumulativeWithdrawnUSD_lte: BigDecimal + cumulativeWithdrawnUSD_in: [BigDecimal!] + cumulativeWithdrawnUSD_not_in: [BigDecimal!] + cumulativeDeltaUSD: BigDecimal + cumulativeDeltaUSD_not: BigDecimal + cumulativeDeltaUSD_gt: BigDecimal + cumulativeDeltaUSD_lt: BigDecimal + cumulativeDeltaUSD_gte: BigDecimal + cumulativeDeltaUSD_lte: BigDecimal + cumulativeDeltaUSD_in: [BigDecimal!] + cumulativeDeltaUSD_not_in: [BigDecimal!] + cumulativeFeesUSD: BigDecimal + cumulativeFeesUSD_not: BigDecimal + cumulativeFeesUSD_gt: BigDecimal + cumulativeFeesUSD_lt: BigDecimal + cumulativeFeesUSD_gte: BigDecimal + cumulativeFeesUSD_lte: BigDecimal + cumulativeFeesUSD_in: [BigDecimal!] + cumulativeFeesUSD_not_in: [BigDecimal!] + debt: BigDecimal + debt_not: BigDecimal + debt_gt: BigDecimal + debt_lt: BigDecimal + debt_gte: BigDecimal + debt_lte: BigDecimal + debt_in: [BigDecimal!] + debt_not_in: [BigDecimal!] + debtInUSD: BigDecimal + debtInUSD_not: BigDecimal + debtInUSD_gt: BigDecimal + debtInUSD_lt: BigDecimal + debtInUSD_gte: BigDecimal + debtInUSD_lte: BigDecimal + debtInUSD_in: [BigDecimal!] + debtInUSD_not_in: [BigDecimal!] + collateral: BigDecimal + collateral_not: BigDecimal + collateral_gt: BigDecimal + collateral_lt: BigDecimal + collateral_gte: BigDecimal + collateral_lte: BigDecimal + collateral_in: [BigDecimal!] + collateral_not_in: [BigDecimal!] + collateralInUSD: BigDecimal + collateralInUSD_not: BigDecimal + collateralInUSD_gt: BigDecimal + collateralInUSD_lt: BigDecimal + collateralInUSD_gte: BigDecimal + collateralInUSD_lte: BigDecimal + collateralInUSD_in: [BigDecimal!] + collateralInUSD_not_in: [BigDecimal!] + supply: BigDecimal + supply_not: BigDecimal + supply_gt: BigDecimal + supply_lt: BigDecimal + supply_gte: BigDecimal + supply_lte: BigDecimal + supply_in: [BigDecimal!] + supply_not_in: [BigDecimal!] + supplyInUSD: BigDecimal + supplyInUSD_not: BigDecimal + supplyInUSD_gt: BigDecimal + supplyInUSD_lt: BigDecimal + supplyInUSD_gte: BigDecimal + supplyInUSD_lte: BigDecimal + supplyInUSD_in: [BigDecimal!] + supplyInUSD_not_in: [BigDecimal!] + netValue: BigDecimal + netValue_not: BigDecimal + netValue_gt: BigDecimal + netValue_lt: BigDecimal + netValue_gte: BigDecimal + netValue_lte: BigDecimal + netValue_in: [BigDecimal!] + netValue_not_in: [BigDecimal!] + summerEvents_: SummerEvent_filter + triggers_: Trigger_filter + swaps_: AssetSwap_filter + lastEvent: String + lastEvent_not: String + lastEvent_gt: String + lastEvent_lt: String + lastEvent_gte: String + lastEvent_lte: String + lastEvent_in: [String!] + lastEvent_not_in: [String!] + lastEvent_contains: String + lastEvent_contains_nocase: String + lastEvent_not_contains: String + lastEvent_not_contains_nocase: String + lastEvent_starts_with: String + lastEvent_starts_with_nocase: String + lastEvent_not_starts_with: String + lastEvent_not_starts_with_nocase: String + lastEvent_ends_with: String + lastEvent_ends_with_nocase: String + lastEvent_not_ends_with: String + lastEvent_not_ends_with_nocase: String + lastEvent_: SummerEvent_filter + _ajnaBucket: BigInt + _ajnaBucket_not: BigInt + _ajnaBucket_gt: BigInt + _ajnaBucket_lt: BigInt + _ajnaBucket_gte: BigInt + _ajnaBucket_lte: BigInt + _ajnaBucket_in: [BigInt!] + _ajnaBucket_not_in: [BigInt!] + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [Position_filter] + or: [Position_filter] } enum Position_orderBy { - id - account - account__id - account__address - account__type - account__vaultId - user - user__id - user__openPositions - protocol - marketId - positionType - cumulativeDepositedUSD - cumulativeWithdrawnUSD - cumulativeDeltaUSD - cumulativeFeesUSD - debt - debtInUSD - collateral - collateralInUSD - supply - supplyInUSD - netValue - summerEvents - triggers - lastEvent - lastEvent__id - lastEvent__blockNumber - lastEvent__timestamp - lastEvent__txHash - lastEvent__logIndex - lastEvent__sender - lastEvent__kind - lastEvent__depositedUSD - lastEvent__withdrawnUSD - lastEvent__deltaUSD - lastEvent__feePaidUSD - lastEvent__protocol - lastEvent__marketId - lastEvent__debtBefore - lastEvent__debtInUSDBefore - lastEvent__debtAfter - lastEvent__debtInUSDAfter - lastEvent__collateralBefore - lastEvent__collateralInUSDBefore - lastEvent__collateralAfter - lastEvent__collateralInUSDAfter - lastEvent__supplyBefore - lastEvent__supplyInUSDBefore - lastEvent__supplyAfter - lastEvent__supplyInUSDAfter - lastEvent__netValueBefore - lastEvent__netValueAfter - lastEvent__collateralTokenPriceInUSD - lastEvent__debtTokenPriceInUSD - lastEvent__supplyTokenPriceInUSD - _ajnaBucket + id + account + account__id + account__address + account__type + account__vaultId + user + user__id + user__openPositions + protocol + marketId + positionType + cumulativeDepositedUSD + cumulativeWithdrawnUSD + cumulativeDeltaUSD + cumulativeFeesUSD + debt + debtInUSD + collateral + collateralInUSD + supply + supplyInUSD + netValue + summerEvents + triggers + swaps + lastEvent + lastEvent__id + lastEvent__blockNumber + lastEvent__timestamp + lastEvent__txHash + lastEvent__logIndex + lastEvent__sender + lastEvent__kind + lastEvent__depositedUSD + lastEvent__withdrawnUSD + lastEvent__deltaUSD + lastEvent__feePaidUSD + lastEvent__protocol + lastEvent__marketId + lastEvent__debtBefore + lastEvent__debtInUSDBefore + lastEvent__debtAfter + lastEvent__debtInUSDAfter + lastEvent__collateralBefore + lastEvent__collateralInUSDBefore + lastEvent__collateralAfter + lastEvent__collateralInUSDAfter + lastEvent__supplyBefore + lastEvent__supplyInUSDBefore + lastEvent__supplyAfter + lastEvent__supplyInUSDAfter + lastEvent__netValueBefore + lastEvent__netValueAfter + lastEvent__collateralTokenPriceInUSD + lastEvent__debtTokenPriceInUSD + lastEvent__supplyTokenPriceInUSD + _ajnaBucket } type Query { - storage( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Storage - storages( - skip: Int = 0 - first: Int = 100 - orderBy: Storage_orderBy - orderDirection: OrderDirection - where: Storage_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Storage!]! - snapshot( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Snapshot - snapshots( - skip: Int = 0 - first: Int = 100 - orderBy: Snapshot_orderBy - orderDirection: OrderDirection - where: Snapshot_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Snapshot!]! - user( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): User - users( - skip: Int = 0 - first: Int = 100 - orderBy: User_orderBy - orderDirection: OrderDirection - where: User_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [User!]! - summerEvent( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): SummerEvent - summerEvents( - skip: Int = 0 - first: Int = 100 - orderBy: SummerEvent_orderBy - orderDirection: OrderDirection - where: SummerEvent_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [SummerEvent!]! - createPositionEvent( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): CreatePositionEvent - createPositionEvents( - skip: Int = 0 - first: Int = 100 - orderBy: CreatePositionEvent_orderBy - orderDirection: OrderDirection - where: CreatePositionEvent_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [CreatePositionEvent!]! - account( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Account - accounts( - skip: Int = 0 - first: Int = 100 - orderBy: Account_orderBy - orderDirection: OrderDirection - where: Account_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Account!]! - position( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Position - positions( - skip: Int = 0 - first: Int = 100 - orderBy: Position_orderBy - orderDirection: OrderDirection - where: Position_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Position!]! - feePaid( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): FeePaid - feePaids( - skip: Int = 0 - first: Int = 100 - orderBy: FeePaid_orderBy - orderDirection: OrderDirection - where: FeePaid_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [FeePaid!]! - assetSwap( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): AssetSwap - assetSwaps( - skip: Int = 0 - first: Int = 100 - orderBy: AssetSwap_orderBy - orderDirection: OrderDirection - where: AssetSwap_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [AssetSwap!]! - transfer( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Transfer - transfers( - skip: Int = 0 - first: Int = 100 - orderBy: Transfer_orderBy - orderDirection: OrderDirection - where: Transfer_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Transfer!]! - token( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Token - tokens( - skip: Int = 0 - first: Int = 100 - orderBy: Token_orderBy - orderDirection: OrderDirection - where: Token_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Token!]! - triggerEvent( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): TriggerEvent - triggerEvents( - skip: Int = 0 - first: Int = 100 - orderBy: TriggerEvent_orderBy - orderDirection: OrderDirection - where: TriggerEvent_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [TriggerEvent!]! - trigger( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Trigger - triggers( - skip: Int = 0 - first: Int = 100 - orderBy: Trigger_orderBy - orderDirection: OrderDirection - where: Trigger_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Trigger!]! - makerUrn( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): MakerUrn - makerUrns( - skip: Int = 0 - first: Int = 100 - orderBy: MakerUrn_orderBy - orderDirection: OrderDirection - where: MakerUrn_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [MakerUrn!]! - ilk( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Ilk - ilks( - skip: Int = 0 - first: Int = 100 - orderBy: Ilk_orderBy - orderDirection: OrderDirection - where: Ilk_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Ilk!]! - tokenPrice( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): TokenPrice - tokenPrices( - skip: Int = 0 - first: Int = 100 - orderBy: TokenPrice_orderBy - orderDirection: OrderDirection - where: TokenPrice_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [TokenPrice!]! - market( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Market - markets( - skip: Int = 0 - first: Int = 100 - orderBy: Market_orderBy - orderDirection: OrderDirection - where: Market_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Market!]! - - """Access to subgraph metadata""" - _meta(block: Block_height): _Meta_ + storage( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Storage + storages( + skip: Int = 0 + first: Int = 100 + orderBy: Storage_orderBy + orderDirection: OrderDirection + where: Storage_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Storage!]! + snapshot( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Snapshot + snapshots( + skip: Int = 0 + first: Int = 100 + orderBy: Snapshot_orderBy + orderDirection: OrderDirection + where: Snapshot_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Snapshot!]! + user( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): User + users( + skip: Int = 0 + first: Int = 100 + orderBy: User_orderBy + orderDirection: OrderDirection + where: User_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [User!]! + summerEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): SummerEvent + summerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: SummerEvent_orderBy + orderDirection: OrderDirection + where: SummerEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [SummerEvent!]! + createPositionEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): CreatePositionEvent + createPositionEvents( + skip: Int = 0 + first: Int = 100 + orderBy: CreatePositionEvent_orderBy + orderDirection: OrderDirection + where: CreatePositionEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [CreatePositionEvent!]! + account( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Account + accounts( + skip: Int = 0 + first: Int = 100 + orderBy: Account_orderBy + orderDirection: OrderDirection + where: Account_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Account!]! + position( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Position + positions( + skip: Int = 0 + first: Int = 100 + orderBy: Position_orderBy + orderDirection: OrderDirection + where: Position_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Position!]! + feePaid( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): FeePaid + feePaids( + skip: Int = 0 + first: Int = 100 + orderBy: FeePaid_orderBy + orderDirection: OrderDirection + where: FeePaid_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [FeePaid!]! + assetSwap( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): AssetSwap + assetSwaps( + skip: Int = 0 + first: Int = 100 + orderBy: AssetSwap_orderBy + orderDirection: OrderDirection + where: AssetSwap_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [AssetSwap!]! + transfer( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Transfer + transfers( + skip: Int = 0 + first: Int = 100 + orderBy: Transfer_orderBy + orderDirection: OrderDirection + where: Transfer_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Transfer!]! + token( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Token + tokens( + skip: Int = 0 + first: Int = 100 + orderBy: Token_orderBy + orderDirection: OrderDirection + where: Token_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Token!]! + triggerEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): TriggerEvent + triggerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: TriggerEvent_orderBy + orderDirection: OrderDirection + where: TriggerEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [TriggerEvent!]! + trigger( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Trigger + triggers( + skip: Int = 0 + first: Int = 100 + orderBy: Trigger_orderBy + orderDirection: OrderDirection + where: Trigger_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Trigger!]! + makerUrn( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): MakerUrn + makerUrns( + skip: Int = 0 + first: Int = 100 + orderBy: MakerUrn_orderBy + orderDirection: OrderDirection + where: MakerUrn_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [MakerUrn!]! + ilk( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Ilk + ilks( + skip: Int = 0 + first: Int = 100 + orderBy: Ilk_orderBy + orderDirection: OrderDirection + where: Ilk_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Ilk!]! + tokenPrice( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): TokenPrice + tokenPrices( + skip: Int = 0 + first: Int = 100 + orderBy: TokenPrice_orderBy + orderDirection: OrderDirection + where: TokenPrice_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [TokenPrice!]! + market( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Market + markets( + skip: Int = 0 + first: Int = 100 + orderBy: Market_orderBy + orderDirection: OrderDirection + where: Market_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Market!]! + + """ + Access to subgraph metadata + """ + _meta(block: Block_height): _Meta_ } type Snapshot { - id: ID! - timestamp: BigInt! - netValue: BigDecimal! - positionCount: BigInt! - closedPositions: BigInt! - year: BigInt! - month: BigInt! - day: BigInt! - hour: BigInt! + id: ID! + timestamp: BigInt! + netValue: BigDecimal! + positionCount: BigInt! + closedPositions: BigInt! + year: BigInt! + month: BigInt! + day: BigInt! + hour: BigInt! } input Snapshot_filter { - id: ID - id_not: ID - id_gt: ID - id_lt: ID - id_gte: ID - id_lte: ID - id_in: [ID!] - id_not_in: [ID!] - timestamp: BigInt - timestamp_not: BigInt - timestamp_gt: BigInt - timestamp_lt: BigInt - timestamp_gte: BigInt - timestamp_lte: BigInt - timestamp_in: [BigInt!] - timestamp_not_in: [BigInt!] - netValue: BigDecimal - netValue_not: BigDecimal - netValue_gt: BigDecimal - netValue_lt: BigDecimal - netValue_gte: BigDecimal - netValue_lte: BigDecimal - netValue_in: [BigDecimal!] - netValue_not_in: [BigDecimal!] - positionCount: BigInt - positionCount_not: BigInt - positionCount_gt: BigInt - positionCount_lt: BigInt - positionCount_gte: BigInt - positionCount_lte: BigInt - positionCount_in: [BigInt!] - positionCount_not_in: [BigInt!] - closedPositions: BigInt - closedPositions_not: BigInt - closedPositions_gt: BigInt - closedPositions_lt: BigInt - closedPositions_gte: BigInt - closedPositions_lte: BigInt - closedPositions_in: [BigInt!] - closedPositions_not_in: [BigInt!] - year: BigInt - year_not: BigInt - year_gt: BigInt - year_lt: BigInt - year_gte: BigInt - year_lte: BigInt - year_in: [BigInt!] - year_not_in: [BigInt!] - month: BigInt - month_not: BigInt - month_gt: BigInt - month_lt: BigInt - month_gte: BigInt - month_lte: BigInt - month_in: [BigInt!] - month_not_in: [BigInt!] - day: BigInt - day_not: BigInt - day_gt: BigInt - day_lt: BigInt - day_gte: BigInt - day_lte: BigInt - day_in: [BigInt!] - day_not_in: [BigInt!] - hour: BigInt - hour_not: BigInt - hour_gt: BigInt - hour_lt: BigInt - hour_gte: BigInt - hour_lte: BigInt - hour_in: [BigInt!] - hour_not_in: [BigInt!] - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [Snapshot_filter] - or: [Snapshot_filter] + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + netValue: BigDecimal + netValue_not: BigDecimal + netValue_gt: BigDecimal + netValue_lt: BigDecimal + netValue_gte: BigDecimal + netValue_lte: BigDecimal + netValue_in: [BigDecimal!] + netValue_not_in: [BigDecimal!] + positionCount: BigInt + positionCount_not: BigInt + positionCount_gt: BigInt + positionCount_lt: BigInt + positionCount_gte: BigInt + positionCount_lte: BigInt + positionCount_in: [BigInt!] + positionCount_not_in: [BigInt!] + closedPositions: BigInt + closedPositions_not: BigInt + closedPositions_gt: BigInt + closedPositions_lt: BigInt + closedPositions_gte: BigInt + closedPositions_lte: BigInt + closedPositions_in: [BigInt!] + closedPositions_not_in: [BigInt!] + year: BigInt + year_not: BigInt + year_gt: BigInt + year_lt: BigInt + year_gte: BigInt + year_lte: BigInt + year_in: [BigInt!] + year_not_in: [BigInt!] + month: BigInt + month_not: BigInt + month_gt: BigInt + month_lt: BigInt + month_gte: BigInt + month_lte: BigInt + month_in: [BigInt!] + month_not_in: [BigInt!] + day: BigInt + day_not: BigInt + day_gt: BigInt + day_lt: BigInt + day_gte: BigInt + day_lte: BigInt + day_in: [BigInt!] + day_not_in: [BigInt!] + hour: BigInt + hour_not: BigInt + hour_gt: BigInt + hour_lt: BigInt + hour_gte: BigInt + hour_lte: BigInt + hour_in: [BigInt!] + hour_not_in: [BigInt!] + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [Snapshot_filter] + or: [Snapshot_filter] } enum Snapshot_orderBy { - id - timestamp - netValue - positionCount - closedPositions - year - month - day - hour + id + timestamp + netValue + positionCount + closedPositions + year + month + day + hour } """ Oasis App user - """ type Storage { - id: ID! - positions(skip: Int = 0, first: Int = 100, orderBy: Position_orderBy, orderDirection: OrderDirection, where: Position_filter): [Position!]! + id: ID! + positions( + skip: Int = 0 + first: Int = 100 + orderBy: Position_orderBy + orderDirection: OrderDirection + where: Position_filter + ): [Position!]! } input Storage_filter { - id: ID - id_not: ID - id_gt: ID - id_lt: ID - id_gte: ID - id_lte: ID - id_in: [ID!] - id_not_in: [ID!] - positions: [String!] - positions_not: [String!] - positions_contains: [String!] - positions_contains_nocase: [String!] - positions_not_contains: [String!] - positions_not_contains_nocase: [String!] - positions_: Position_filter - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [Storage_filter] - or: [Storage_filter] + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + positions: [String!] + positions_not: [String!] + positions_contains: [String!] + positions_contains_nocase: [String!] + positions_not_contains: [String!] + positions_not_contains_nocase: [String!] + positions_: Position_filter + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [Storage_filter] + or: [Storage_filter] } enum Storage_orderBy { - id - positions + id + positions } type Subscription { - storage( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Storage - storages( - skip: Int = 0 - first: Int = 100 - orderBy: Storage_orderBy - orderDirection: OrderDirection - where: Storage_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Storage!]! - snapshot( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Snapshot - snapshots( - skip: Int = 0 - first: Int = 100 - orderBy: Snapshot_orderBy - orderDirection: OrderDirection - where: Snapshot_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Snapshot!]! - user( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): User - users( - skip: Int = 0 - first: Int = 100 - orderBy: User_orderBy - orderDirection: OrderDirection - where: User_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [User!]! - summerEvent( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): SummerEvent - summerEvents( - skip: Int = 0 - first: Int = 100 - orderBy: SummerEvent_orderBy - orderDirection: OrderDirection - where: SummerEvent_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [SummerEvent!]! - createPositionEvent( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): CreatePositionEvent - createPositionEvents( - skip: Int = 0 - first: Int = 100 - orderBy: CreatePositionEvent_orderBy - orderDirection: OrderDirection - where: CreatePositionEvent_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [CreatePositionEvent!]! - account( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Account - accounts( - skip: Int = 0 - first: Int = 100 - orderBy: Account_orderBy - orderDirection: OrderDirection - where: Account_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Account!]! - position( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Position - positions( - skip: Int = 0 - first: Int = 100 - orderBy: Position_orderBy - orderDirection: OrderDirection - where: Position_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Position!]! - feePaid( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): FeePaid - feePaids( - skip: Int = 0 - first: Int = 100 - orderBy: FeePaid_orderBy - orderDirection: OrderDirection - where: FeePaid_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [FeePaid!]! - assetSwap( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): AssetSwap - assetSwaps( - skip: Int = 0 - first: Int = 100 - orderBy: AssetSwap_orderBy - orderDirection: OrderDirection - where: AssetSwap_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [AssetSwap!]! - transfer( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Transfer - transfers( - skip: Int = 0 - first: Int = 100 - orderBy: Transfer_orderBy - orderDirection: OrderDirection - where: Transfer_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Transfer!]! - token( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Token - tokens( - skip: Int = 0 - first: Int = 100 - orderBy: Token_orderBy - orderDirection: OrderDirection - where: Token_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Token!]! - triggerEvent( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): TriggerEvent - triggerEvents( - skip: Int = 0 - first: Int = 100 - orderBy: TriggerEvent_orderBy - orderDirection: OrderDirection - where: TriggerEvent_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [TriggerEvent!]! - trigger( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Trigger - triggers( - skip: Int = 0 - first: Int = 100 - orderBy: Trigger_orderBy - orderDirection: OrderDirection - where: Trigger_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Trigger!]! - makerUrn( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): MakerUrn - makerUrns( - skip: Int = 0 - first: Int = 100 - orderBy: MakerUrn_orderBy - orderDirection: OrderDirection - where: MakerUrn_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [MakerUrn!]! - ilk( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Ilk - ilks( - skip: Int = 0 - first: Int = 100 - orderBy: Ilk_orderBy - orderDirection: OrderDirection - where: Ilk_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Ilk!]! - tokenPrice( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): TokenPrice - tokenPrices( - skip: Int = 0 - first: Int = 100 - orderBy: TokenPrice_orderBy - orderDirection: OrderDirection - where: TokenPrice_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [TokenPrice!]! - market( - id: ID! - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): Market - markets( - skip: Int = 0 - first: Int = 100 - orderBy: Market_orderBy - orderDirection: OrderDirection - where: Market_filter - - """ - The block at which the query should be executed. Can either be a `{ hash: - Bytes }` value containing a block hash, a `{ number: Int }` containing the - block number, or a `{ number_gte: Int }` containing the minimum block - number. In the case of `number_gte`, the query will be executed on the - latest block only if the subgraph has progressed to or past the minimum - block number. Defaults to the latest block when omitted. - """ - block: Block_height - - """ - Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. - """ - subgraphError: _SubgraphErrorPolicy_! = deny - ): [Market!]! - - """Access to subgraph metadata""" - _meta(block: Block_height): _Meta_ + storage( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Storage + storages( + skip: Int = 0 + first: Int = 100 + orderBy: Storage_orderBy + orderDirection: OrderDirection + where: Storage_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Storage!]! + snapshot( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Snapshot + snapshots( + skip: Int = 0 + first: Int = 100 + orderBy: Snapshot_orderBy + orderDirection: OrderDirection + where: Snapshot_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Snapshot!]! + user( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): User + users( + skip: Int = 0 + first: Int = 100 + orderBy: User_orderBy + orderDirection: OrderDirection + where: User_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [User!]! + summerEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): SummerEvent + summerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: SummerEvent_orderBy + orderDirection: OrderDirection + where: SummerEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [SummerEvent!]! + createPositionEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): CreatePositionEvent + createPositionEvents( + skip: Int = 0 + first: Int = 100 + orderBy: CreatePositionEvent_orderBy + orderDirection: OrderDirection + where: CreatePositionEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [CreatePositionEvent!]! + account( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Account + accounts( + skip: Int = 0 + first: Int = 100 + orderBy: Account_orderBy + orderDirection: OrderDirection + where: Account_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Account!]! + position( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Position + positions( + skip: Int = 0 + first: Int = 100 + orderBy: Position_orderBy + orderDirection: OrderDirection + where: Position_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Position!]! + feePaid( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): FeePaid + feePaids( + skip: Int = 0 + first: Int = 100 + orderBy: FeePaid_orderBy + orderDirection: OrderDirection + where: FeePaid_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [FeePaid!]! + assetSwap( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): AssetSwap + assetSwaps( + skip: Int = 0 + first: Int = 100 + orderBy: AssetSwap_orderBy + orderDirection: OrderDirection + where: AssetSwap_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [AssetSwap!]! + transfer( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Transfer + transfers( + skip: Int = 0 + first: Int = 100 + orderBy: Transfer_orderBy + orderDirection: OrderDirection + where: Transfer_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Transfer!]! + token( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Token + tokens( + skip: Int = 0 + first: Int = 100 + orderBy: Token_orderBy + orderDirection: OrderDirection + where: Token_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Token!]! + triggerEvent( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): TriggerEvent + triggerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: TriggerEvent_orderBy + orderDirection: OrderDirection + where: TriggerEvent_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [TriggerEvent!]! + trigger( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Trigger + triggers( + skip: Int = 0 + first: Int = 100 + orderBy: Trigger_orderBy + orderDirection: OrderDirection + where: Trigger_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Trigger!]! + makerUrn( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): MakerUrn + makerUrns( + skip: Int = 0 + first: Int = 100 + orderBy: MakerUrn_orderBy + orderDirection: OrderDirection + where: MakerUrn_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [MakerUrn!]! + ilk( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Ilk + ilks( + skip: Int = 0 + first: Int = 100 + orderBy: Ilk_orderBy + orderDirection: OrderDirection + where: Ilk_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Ilk!]! + tokenPrice( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): TokenPrice + tokenPrices( + skip: Int = 0 + first: Int = 100 + orderBy: TokenPrice_orderBy + orderDirection: OrderDirection + where: TokenPrice_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [TokenPrice!]! + market( + id: ID! + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): Market + markets( + skip: Int = 0 + first: Int = 100 + orderBy: Market_orderBy + orderDirection: OrderDirection + where: Market_filter + + """ + The block at which the query should be executed. Can either be a `{ hash: + Bytes }` value containing a block hash, a `{ number: Int }` containing the + block number, or a `{ number_gte: Int }` containing the minimum block + number. In the case of `number_gte`, the query will be executed on the + latest block only if the subgraph has progressed to or past the minimum + block number. Defaults to the latest block when omitted. + """ + block: Block_height + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): [Market!]! + + """ + Access to subgraph metadata + """ + _meta(block: Block_height): _Meta_ } type SummerEvent { - id: Bytes! - blockNumber: BigInt! - timestamp: BigInt! - txHash: Bytes! - logIndex: BigInt! - sender: Bytes! - kind: String! - account: Account! - user: User! - position: Position! - depositedUSD: BigDecimal! - withdrawnUSD: BigDecimal! - deltaUSD: BigDecimal! - feePaidUSD: BigDecimal! - depositTransfers(skip: Int = 0, first: Int = 100, orderBy: Transfer_orderBy, orderDirection: OrderDirection, where: Transfer_filter): [Transfer!]! - withdrawTransfers(skip: Int = 0, first: Int = 100, orderBy: Transfer_orderBy, orderDirection: OrderDirection, where: Transfer_filter): [Transfer!]! - protocol: String! - marketId: String! - feePaids(skip: Int = 0, first: Int = 100, orderBy: FeePaid_orderBy, orderDirection: OrderDirection, where: FeePaid_filter): [FeePaid!]! - swaps(skip: Int = 0, first: Int = 100, orderBy: AssetSwap_orderBy, orderDirection: OrderDirection, where: AssetSwap_filter): [AssetSwap!]! - automationEvents(skip: Int = 0, first: Int = 100, orderBy: TriggerEvent_orderBy, orderDirection: OrderDirection, where: TriggerEvent_filter): [TriggerEvent!]! - debtBefore: BigDecimal! - debtInUSDBefore: BigDecimal! - debtAfter: BigDecimal! - debtInUSDAfter: BigDecimal! - collateralBefore: BigDecimal! - collateralInUSDBefore: BigDecimal! - collateralAfter: BigDecimal! - collateralInUSDAfter: BigDecimal! - supplyBefore: BigDecimal! - supplyInUSDBefore: BigDecimal! - supplyAfter: BigDecimal! - supplyInUSDAfter: BigDecimal! - netValueBefore: BigDecimal! - netValueAfter: BigDecimal! - collateralTokenPriceInUSD: BigDecimal! - debtTokenPriceInUSD: BigDecimal! - supplyTokenPriceInUSD: BigDecimal! + id: Bytes! + blockNumber: BigInt! + timestamp: BigInt! + txHash: Bytes! + logIndex: BigInt! + sender: Bytes! + kind: String! + account: Account! + user: User! + position: Position! + depositedUSD: BigDecimal! + withdrawnUSD: BigDecimal! + deltaUSD: BigDecimal! + feePaidUSD: BigDecimal! + depositTransfers( + skip: Int = 0 + first: Int = 100 + orderBy: Transfer_orderBy + orderDirection: OrderDirection + where: Transfer_filter + ): [Transfer!]! + withdrawTransfers( + skip: Int = 0 + first: Int = 100 + orderBy: Transfer_orderBy + orderDirection: OrderDirection + where: Transfer_filter + ): [Transfer!]! + protocol: String! + marketId: String! + feePaids( + skip: Int = 0 + first: Int = 100 + orderBy: FeePaid_orderBy + orderDirection: OrderDirection + where: FeePaid_filter + ): [FeePaid!]! + swaps( + skip: Int = 0 + first: Int = 100 + orderBy: AssetSwap_orderBy + orderDirection: OrderDirection + where: AssetSwap_filter + ): [AssetSwap!]! + automationEvents( + skip: Int = 0 + first: Int = 100 + orderBy: TriggerEvent_orderBy + orderDirection: OrderDirection + where: TriggerEvent_filter + ): [TriggerEvent!]! + debtBefore: BigDecimal! + debtInUSDBefore: BigDecimal! + debtAfter: BigDecimal! + debtInUSDAfter: BigDecimal! + collateralBefore: BigDecimal! + collateralInUSDBefore: BigDecimal! + collateralAfter: BigDecimal! + collateralInUSDAfter: BigDecimal! + supplyBefore: BigDecimal! + supplyInUSDBefore: BigDecimal! + supplyAfter: BigDecimal! + supplyInUSDAfter: BigDecimal! + netValueBefore: BigDecimal! + netValueAfter: BigDecimal! + collateralTokenPriceInUSD: BigDecimal! + debtTokenPriceInUSD: BigDecimal! + supplyTokenPriceInUSD: BigDecimal! } input SummerEvent_filter { - id: Bytes - id_not: Bytes - id_gt: Bytes - id_lt: Bytes - id_gte: Bytes - id_lte: Bytes - id_in: [Bytes!] - id_not_in: [Bytes!] - id_contains: Bytes - id_not_contains: Bytes - blockNumber: BigInt - blockNumber_not: BigInt - blockNumber_gt: BigInt - blockNumber_lt: BigInt - blockNumber_gte: BigInt - blockNumber_lte: BigInt - blockNumber_in: [BigInt!] - blockNumber_not_in: [BigInt!] - timestamp: BigInt - timestamp_not: BigInt - timestamp_gt: BigInt - timestamp_lt: BigInt - timestamp_gte: BigInt - timestamp_lte: BigInt - timestamp_in: [BigInt!] - timestamp_not_in: [BigInt!] - txHash: Bytes - txHash_not: Bytes - txHash_gt: Bytes - txHash_lt: Bytes - txHash_gte: Bytes - txHash_lte: Bytes - txHash_in: [Bytes!] - txHash_not_in: [Bytes!] - txHash_contains: Bytes - txHash_not_contains: Bytes - logIndex: BigInt - logIndex_not: BigInt - logIndex_gt: BigInt - logIndex_lt: BigInt - logIndex_gte: BigInt - logIndex_lte: BigInt - logIndex_in: [BigInt!] - logIndex_not_in: [BigInt!] - sender: Bytes - sender_not: Bytes - sender_gt: Bytes - sender_lt: Bytes - sender_gte: Bytes - sender_lte: Bytes - sender_in: [Bytes!] - sender_not_in: [Bytes!] - sender_contains: Bytes - sender_not_contains: Bytes - kind: String - kind_not: String - kind_gt: String - kind_lt: String - kind_gte: String - kind_lte: String - kind_in: [String!] - kind_not_in: [String!] - kind_contains: String - kind_contains_nocase: String - kind_not_contains: String - kind_not_contains_nocase: String - kind_starts_with: String - kind_starts_with_nocase: String - kind_not_starts_with: String - kind_not_starts_with_nocase: String - kind_ends_with: String - kind_ends_with_nocase: String - kind_not_ends_with: String - kind_not_ends_with_nocase: String - account: String - account_not: String - account_gt: String - account_lt: String - account_gte: String - account_lte: String - account_in: [String!] - account_not_in: [String!] - account_contains: String - account_contains_nocase: String - account_not_contains: String - account_not_contains_nocase: String - account_starts_with: String - account_starts_with_nocase: String - account_not_starts_with: String - account_not_starts_with_nocase: String - account_ends_with: String - account_ends_with_nocase: String - account_not_ends_with: String - account_not_ends_with_nocase: String - account_: Account_filter - user: String - user_not: String - user_gt: String - user_lt: String - user_gte: String - user_lte: String - user_in: [String!] - user_not_in: [String!] - user_contains: String - user_contains_nocase: String - user_not_contains: String - user_not_contains_nocase: String - user_starts_with: String - user_starts_with_nocase: String - user_not_starts_with: String - user_not_starts_with_nocase: String - user_ends_with: String - user_ends_with_nocase: String - user_not_ends_with: String - user_not_ends_with_nocase: String - user_: User_filter - position: String - position_not: String - position_gt: String - position_lt: String - position_gte: String - position_lte: String - position_in: [String!] - position_not_in: [String!] - position_contains: String - position_contains_nocase: String - position_not_contains: String - position_not_contains_nocase: String - position_starts_with: String - position_starts_with_nocase: String - position_not_starts_with: String - position_not_starts_with_nocase: String - position_ends_with: String - position_ends_with_nocase: String - position_not_ends_with: String - position_not_ends_with_nocase: String - position_: Position_filter - depositedUSD: BigDecimal - depositedUSD_not: BigDecimal - depositedUSD_gt: BigDecimal - depositedUSD_lt: BigDecimal - depositedUSD_gte: BigDecimal - depositedUSD_lte: BigDecimal - depositedUSD_in: [BigDecimal!] - depositedUSD_not_in: [BigDecimal!] - withdrawnUSD: BigDecimal - withdrawnUSD_not: BigDecimal - withdrawnUSD_gt: BigDecimal - withdrawnUSD_lt: BigDecimal - withdrawnUSD_gte: BigDecimal - withdrawnUSD_lte: BigDecimal - withdrawnUSD_in: [BigDecimal!] - withdrawnUSD_not_in: [BigDecimal!] - deltaUSD: BigDecimal - deltaUSD_not: BigDecimal - deltaUSD_gt: BigDecimal - deltaUSD_lt: BigDecimal - deltaUSD_gte: BigDecimal - deltaUSD_lte: BigDecimal - deltaUSD_in: [BigDecimal!] - deltaUSD_not_in: [BigDecimal!] - feePaidUSD: BigDecimal - feePaidUSD_not: BigDecimal - feePaidUSD_gt: BigDecimal - feePaidUSD_lt: BigDecimal - feePaidUSD_gte: BigDecimal - feePaidUSD_lte: BigDecimal - feePaidUSD_in: [BigDecimal!] - feePaidUSD_not_in: [BigDecimal!] - depositTransfers: [String!] - depositTransfers_not: [String!] - depositTransfers_contains: [String!] - depositTransfers_contains_nocase: [String!] - depositTransfers_not_contains: [String!] - depositTransfers_not_contains_nocase: [String!] - depositTransfers_: Transfer_filter - withdrawTransfers: [String!] - withdrawTransfers_not: [String!] - withdrawTransfers_contains: [String!] - withdrawTransfers_contains_nocase: [String!] - withdrawTransfers_not_contains: [String!] - withdrawTransfers_not_contains_nocase: [String!] - withdrawTransfers_: Transfer_filter - protocol: String - protocol_not: String - protocol_gt: String - protocol_lt: String - protocol_gte: String - protocol_lte: String - protocol_in: [String!] - protocol_not_in: [String!] - protocol_contains: String - protocol_contains_nocase: String - protocol_not_contains: String - protocol_not_contains_nocase: String - protocol_starts_with: String - protocol_starts_with_nocase: String - protocol_not_starts_with: String - protocol_not_starts_with_nocase: String - protocol_ends_with: String - protocol_ends_with_nocase: String - protocol_not_ends_with: String - protocol_not_ends_with_nocase: String - marketId: String - marketId_not: String - marketId_gt: String - marketId_lt: String - marketId_gte: String - marketId_lte: String - marketId_in: [String!] - marketId_not_in: [String!] - marketId_contains: String - marketId_contains_nocase: String - marketId_not_contains: String - marketId_not_contains_nocase: String - marketId_starts_with: String - marketId_starts_with_nocase: String - marketId_not_starts_with: String - marketId_not_starts_with_nocase: String - marketId_ends_with: String - marketId_ends_with_nocase: String - marketId_not_ends_with: String - marketId_not_ends_with_nocase: String - feePaids_: FeePaid_filter - swaps_: AssetSwap_filter - automationEvents_: TriggerEvent_filter - debtBefore: BigDecimal - debtBefore_not: BigDecimal - debtBefore_gt: BigDecimal - debtBefore_lt: BigDecimal - debtBefore_gte: BigDecimal - debtBefore_lte: BigDecimal - debtBefore_in: [BigDecimal!] - debtBefore_not_in: [BigDecimal!] - debtInUSDBefore: BigDecimal - debtInUSDBefore_not: BigDecimal - debtInUSDBefore_gt: BigDecimal - debtInUSDBefore_lt: BigDecimal - debtInUSDBefore_gte: BigDecimal - debtInUSDBefore_lte: BigDecimal - debtInUSDBefore_in: [BigDecimal!] - debtInUSDBefore_not_in: [BigDecimal!] - debtAfter: BigDecimal - debtAfter_not: BigDecimal - debtAfter_gt: BigDecimal - debtAfter_lt: BigDecimal - debtAfter_gte: BigDecimal - debtAfter_lte: BigDecimal - debtAfter_in: [BigDecimal!] - debtAfter_not_in: [BigDecimal!] - debtInUSDAfter: BigDecimal - debtInUSDAfter_not: BigDecimal - debtInUSDAfter_gt: BigDecimal - debtInUSDAfter_lt: BigDecimal - debtInUSDAfter_gte: BigDecimal - debtInUSDAfter_lte: BigDecimal - debtInUSDAfter_in: [BigDecimal!] - debtInUSDAfter_not_in: [BigDecimal!] - collateralBefore: BigDecimal - collateralBefore_not: BigDecimal - collateralBefore_gt: BigDecimal - collateralBefore_lt: BigDecimal - collateralBefore_gte: BigDecimal - collateralBefore_lte: BigDecimal - collateralBefore_in: [BigDecimal!] - collateralBefore_not_in: [BigDecimal!] - collateralInUSDBefore: BigDecimal - collateralInUSDBefore_not: BigDecimal - collateralInUSDBefore_gt: BigDecimal - collateralInUSDBefore_lt: BigDecimal - collateralInUSDBefore_gte: BigDecimal - collateralInUSDBefore_lte: BigDecimal - collateralInUSDBefore_in: [BigDecimal!] - collateralInUSDBefore_not_in: [BigDecimal!] - collateralAfter: BigDecimal - collateralAfter_not: BigDecimal - collateralAfter_gt: BigDecimal - collateralAfter_lt: BigDecimal - collateralAfter_gte: BigDecimal - collateralAfter_lte: BigDecimal - collateralAfter_in: [BigDecimal!] - collateralAfter_not_in: [BigDecimal!] - collateralInUSDAfter: BigDecimal - collateralInUSDAfter_not: BigDecimal - collateralInUSDAfter_gt: BigDecimal - collateralInUSDAfter_lt: BigDecimal - collateralInUSDAfter_gte: BigDecimal - collateralInUSDAfter_lte: BigDecimal - collateralInUSDAfter_in: [BigDecimal!] - collateralInUSDAfter_not_in: [BigDecimal!] - supplyBefore: BigDecimal - supplyBefore_not: BigDecimal - supplyBefore_gt: BigDecimal - supplyBefore_lt: BigDecimal - supplyBefore_gte: BigDecimal - supplyBefore_lte: BigDecimal - supplyBefore_in: [BigDecimal!] - supplyBefore_not_in: [BigDecimal!] - supplyInUSDBefore: BigDecimal - supplyInUSDBefore_not: BigDecimal - supplyInUSDBefore_gt: BigDecimal - supplyInUSDBefore_lt: BigDecimal - supplyInUSDBefore_gte: BigDecimal - supplyInUSDBefore_lte: BigDecimal - supplyInUSDBefore_in: [BigDecimal!] - supplyInUSDBefore_not_in: [BigDecimal!] - supplyAfter: BigDecimal - supplyAfter_not: BigDecimal - supplyAfter_gt: BigDecimal - supplyAfter_lt: BigDecimal - supplyAfter_gte: BigDecimal - supplyAfter_lte: BigDecimal - supplyAfter_in: [BigDecimal!] - supplyAfter_not_in: [BigDecimal!] - supplyInUSDAfter: BigDecimal - supplyInUSDAfter_not: BigDecimal - supplyInUSDAfter_gt: BigDecimal - supplyInUSDAfter_lt: BigDecimal - supplyInUSDAfter_gte: BigDecimal - supplyInUSDAfter_lte: BigDecimal - supplyInUSDAfter_in: [BigDecimal!] - supplyInUSDAfter_not_in: [BigDecimal!] - netValueBefore: BigDecimal - netValueBefore_not: BigDecimal - netValueBefore_gt: BigDecimal - netValueBefore_lt: BigDecimal - netValueBefore_gte: BigDecimal - netValueBefore_lte: BigDecimal - netValueBefore_in: [BigDecimal!] - netValueBefore_not_in: [BigDecimal!] - netValueAfter: BigDecimal - netValueAfter_not: BigDecimal - netValueAfter_gt: BigDecimal - netValueAfter_lt: BigDecimal - netValueAfter_gte: BigDecimal - netValueAfter_lte: BigDecimal - netValueAfter_in: [BigDecimal!] - netValueAfter_not_in: [BigDecimal!] - collateralTokenPriceInUSD: BigDecimal - collateralTokenPriceInUSD_not: BigDecimal - collateralTokenPriceInUSD_gt: BigDecimal - collateralTokenPriceInUSD_lt: BigDecimal - collateralTokenPriceInUSD_gte: BigDecimal - collateralTokenPriceInUSD_lte: BigDecimal - collateralTokenPriceInUSD_in: [BigDecimal!] - collateralTokenPriceInUSD_not_in: [BigDecimal!] - debtTokenPriceInUSD: BigDecimal - debtTokenPriceInUSD_not: BigDecimal - debtTokenPriceInUSD_gt: BigDecimal - debtTokenPriceInUSD_lt: BigDecimal - debtTokenPriceInUSD_gte: BigDecimal - debtTokenPriceInUSD_lte: BigDecimal - debtTokenPriceInUSD_in: [BigDecimal!] - debtTokenPriceInUSD_not_in: [BigDecimal!] - supplyTokenPriceInUSD: BigDecimal - supplyTokenPriceInUSD_not: BigDecimal - supplyTokenPriceInUSD_gt: BigDecimal - supplyTokenPriceInUSD_lt: BigDecimal - supplyTokenPriceInUSD_gte: BigDecimal - supplyTokenPriceInUSD_lte: BigDecimal - supplyTokenPriceInUSD_in: [BigDecimal!] - supplyTokenPriceInUSD_not_in: [BigDecimal!] - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [SummerEvent_filter] - or: [SummerEvent_filter] + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + blockNumber: BigInt + blockNumber_not: BigInt + blockNumber_gt: BigInt + blockNumber_lt: BigInt + blockNumber_gte: BigInt + blockNumber_lte: BigInt + blockNumber_in: [BigInt!] + blockNumber_not_in: [BigInt!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + txHash: Bytes + txHash_not: Bytes + txHash_gt: Bytes + txHash_lt: Bytes + txHash_gte: Bytes + txHash_lte: Bytes + txHash_in: [Bytes!] + txHash_not_in: [Bytes!] + txHash_contains: Bytes + txHash_not_contains: Bytes + logIndex: BigInt + logIndex_not: BigInt + logIndex_gt: BigInt + logIndex_lt: BigInt + logIndex_gte: BigInt + logIndex_lte: BigInt + logIndex_in: [BigInt!] + logIndex_not_in: [BigInt!] + sender: Bytes + sender_not: Bytes + sender_gt: Bytes + sender_lt: Bytes + sender_gte: Bytes + sender_lte: Bytes + sender_in: [Bytes!] + sender_not_in: [Bytes!] + sender_contains: Bytes + sender_not_contains: Bytes + kind: String + kind_not: String + kind_gt: String + kind_lt: String + kind_gte: String + kind_lte: String + kind_in: [String!] + kind_not_in: [String!] + kind_contains: String + kind_contains_nocase: String + kind_not_contains: String + kind_not_contains_nocase: String + kind_starts_with: String + kind_starts_with_nocase: String + kind_not_starts_with: String + kind_not_starts_with_nocase: String + kind_ends_with: String + kind_ends_with_nocase: String + kind_not_ends_with: String + kind_not_ends_with_nocase: String + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + position: String + position_not: String + position_gt: String + position_lt: String + position_gte: String + position_lte: String + position_in: [String!] + position_not_in: [String!] + position_contains: String + position_contains_nocase: String + position_not_contains: String + position_not_contains_nocase: String + position_starts_with: String + position_starts_with_nocase: String + position_not_starts_with: String + position_not_starts_with_nocase: String + position_ends_with: String + position_ends_with_nocase: String + position_not_ends_with: String + position_not_ends_with_nocase: String + position_: Position_filter + depositedUSD: BigDecimal + depositedUSD_not: BigDecimal + depositedUSD_gt: BigDecimal + depositedUSD_lt: BigDecimal + depositedUSD_gte: BigDecimal + depositedUSD_lte: BigDecimal + depositedUSD_in: [BigDecimal!] + depositedUSD_not_in: [BigDecimal!] + withdrawnUSD: BigDecimal + withdrawnUSD_not: BigDecimal + withdrawnUSD_gt: BigDecimal + withdrawnUSD_lt: BigDecimal + withdrawnUSD_gte: BigDecimal + withdrawnUSD_lte: BigDecimal + withdrawnUSD_in: [BigDecimal!] + withdrawnUSD_not_in: [BigDecimal!] + deltaUSD: BigDecimal + deltaUSD_not: BigDecimal + deltaUSD_gt: BigDecimal + deltaUSD_lt: BigDecimal + deltaUSD_gte: BigDecimal + deltaUSD_lte: BigDecimal + deltaUSD_in: [BigDecimal!] + deltaUSD_not_in: [BigDecimal!] + feePaidUSD: BigDecimal + feePaidUSD_not: BigDecimal + feePaidUSD_gt: BigDecimal + feePaidUSD_lt: BigDecimal + feePaidUSD_gte: BigDecimal + feePaidUSD_lte: BigDecimal + feePaidUSD_in: [BigDecimal!] + feePaidUSD_not_in: [BigDecimal!] + depositTransfers: [String!] + depositTransfers_not: [String!] + depositTransfers_contains: [String!] + depositTransfers_contains_nocase: [String!] + depositTransfers_not_contains: [String!] + depositTransfers_not_contains_nocase: [String!] + depositTransfers_: Transfer_filter + withdrawTransfers: [String!] + withdrawTransfers_not: [String!] + withdrawTransfers_contains: [String!] + withdrawTransfers_contains_nocase: [String!] + withdrawTransfers_not_contains: [String!] + withdrawTransfers_not_contains_nocase: [String!] + withdrawTransfers_: Transfer_filter + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + feePaids_: FeePaid_filter + swaps_: AssetSwap_filter + automationEvents_: TriggerEvent_filter + debtBefore: BigDecimal + debtBefore_not: BigDecimal + debtBefore_gt: BigDecimal + debtBefore_lt: BigDecimal + debtBefore_gte: BigDecimal + debtBefore_lte: BigDecimal + debtBefore_in: [BigDecimal!] + debtBefore_not_in: [BigDecimal!] + debtInUSDBefore: BigDecimal + debtInUSDBefore_not: BigDecimal + debtInUSDBefore_gt: BigDecimal + debtInUSDBefore_lt: BigDecimal + debtInUSDBefore_gte: BigDecimal + debtInUSDBefore_lte: BigDecimal + debtInUSDBefore_in: [BigDecimal!] + debtInUSDBefore_not_in: [BigDecimal!] + debtAfter: BigDecimal + debtAfter_not: BigDecimal + debtAfter_gt: BigDecimal + debtAfter_lt: BigDecimal + debtAfter_gte: BigDecimal + debtAfter_lte: BigDecimal + debtAfter_in: [BigDecimal!] + debtAfter_not_in: [BigDecimal!] + debtInUSDAfter: BigDecimal + debtInUSDAfter_not: BigDecimal + debtInUSDAfter_gt: BigDecimal + debtInUSDAfter_lt: BigDecimal + debtInUSDAfter_gte: BigDecimal + debtInUSDAfter_lte: BigDecimal + debtInUSDAfter_in: [BigDecimal!] + debtInUSDAfter_not_in: [BigDecimal!] + collateralBefore: BigDecimal + collateralBefore_not: BigDecimal + collateralBefore_gt: BigDecimal + collateralBefore_lt: BigDecimal + collateralBefore_gte: BigDecimal + collateralBefore_lte: BigDecimal + collateralBefore_in: [BigDecimal!] + collateralBefore_not_in: [BigDecimal!] + collateralInUSDBefore: BigDecimal + collateralInUSDBefore_not: BigDecimal + collateralInUSDBefore_gt: BigDecimal + collateralInUSDBefore_lt: BigDecimal + collateralInUSDBefore_gte: BigDecimal + collateralInUSDBefore_lte: BigDecimal + collateralInUSDBefore_in: [BigDecimal!] + collateralInUSDBefore_not_in: [BigDecimal!] + collateralAfter: BigDecimal + collateralAfter_not: BigDecimal + collateralAfter_gt: BigDecimal + collateralAfter_lt: BigDecimal + collateralAfter_gte: BigDecimal + collateralAfter_lte: BigDecimal + collateralAfter_in: [BigDecimal!] + collateralAfter_not_in: [BigDecimal!] + collateralInUSDAfter: BigDecimal + collateralInUSDAfter_not: BigDecimal + collateralInUSDAfter_gt: BigDecimal + collateralInUSDAfter_lt: BigDecimal + collateralInUSDAfter_gte: BigDecimal + collateralInUSDAfter_lte: BigDecimal + collateralInUSDAfter_in: [BigDecimal!] + collateralInUSDAfter_not_in: [BigDecimal!] + supplyBefore: BigDecimal + supplyBefore_not: BigDecimal + supplyBefore_gt: BigDecimal + supplyBefore_lt: BigDecimal + supplyBefore_gte: BigDecimal + supplyBefore_lte: BigDecimal + supplyBefore_in: [BigDecimal!] + supplyBefore_not_in: [BigDecimal!] + supplyInUSDBefore: BigDecimal + supplyInUSDBefore_not: BigDecimal + supplyInUSDBefore_gt: BigDecimal + supplyInUSDBefore_lt: BigDecimal + supplyInUSDBefore_gte: BigDecimal + supplyInUSDBefore_lte: BigDecimal + supplyInUSDBefore_in: [BigDecimal!] + supplyInUSDBefore_not_in: [BigDecimal!] + supplyAfter: BigDecimal + supplyAfter_not: BigDecimal + supplyAfter_gt: BigDecimal + supplyAfter_lt: BigDecimal + supplyAfter_gte: BigDecimal + supplyAfter_lte: BigDecimal + supplyAfter_in: [BigDecimal!] + supplyAfter_not_in: [BigDecimal!] + supplyInUSDAfter: BigDecimal + supplyInUSDAfter_not: BigDecimal + supplyInUSDAfter_gt: BigDecimal + supplyInUSDAfter_lt: BigDecimal + supplyInUSDAfter_gte: BigDecimal + supplyInUSDAfter_lte: BigDecimal + supplyInUSDAfter_in: [BigDecimal!] + supplyInUSDAfter_not_in: [BigDecimal!] + netValueBefore: BigDecimal + netValueBefore_not: BigDecimal + netValueBefore_gt: BigDecimal + netValueBefore_lt: BigDecimal + netValueBefore_gte: BigDecimal + netValueBefore_lte: BigDecimal + netValueBefore_in: [BigDecimal!] + netValueBefore_not_in: [BigDecimal!] + netValueAfter: BigDecimal + netValueAfter_not: BigDecimal + netValueAfter_gt: BigDecimal + netValueAfter_lt: BigDecimal + netValueAfter_gte: BigDecimal + netValueAfter_lte: BigDecimal + netValueAfter_in: [BigDecimal!] + netValueAfter_not_in: [BigDecimal!] + collateralTokenPriceInUSD: BigDecimal + collateralTokenPriceInUSD_not: BigDecimal + collateralTokenPriceInUSD_gt: BigDecimal + collateralTokenPriceInUSD_lt: BigDecimal + collateralTokenPriceInUSD_gte: BigDecimal + collateralTokenPriceInUSD_lte: BigDecimal + collateralTokenPriceInUSD_in: [BigDecimal!] + collateralTokenPriceInUSD_not_in: [BigDecimal!] + debtTokenPriceInUSD: BigDecimal + debtTokenPriceInUSD_not: BigDecimal + debtTokenPriceInUSD_gt: BigDecimal + debtTokenPriceInUSD_lt: BigDecimal + debtTokenPriceInUSD_gte: BigDecimal + debtTokenPriceInUSD_lte: BigDecimal + debtTokenPriceInUSD_in: [BigDecimal!] + debtTokenPriceInUSD_not_in: [BigDecimal!] + supplyTokenPriceInUSD: BigDecimal + supplyTokenPriceInUSD_not: BigDecimal + supplyTokenPriceInUSD_gt: BigDecimal + supplyTokenPriceInUSD_lt: BigDecimal + supplyTokenPriceInUSD_gte: BigDecimal + supplyTokenPriceInUSD_lte: BigDecimal + supplyTokenPriceInUSD_in: [BigDecimal!] + supplyTokenPriceInUSD_not_in: [BigDecimal!] + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [SummerEvent_filter] + or: [SummerEvent_filter] } enum SummerEvent_orderBy { - id - blockNumber - timestamp - txHash - logIndex - sender - kind - account - account__id - account__address - account__type - account__vaultId - user - user__id - user__openPositions - position - position__id - position__protocol - position__marketId - position__positionType - position__cumulativeDepositedUSD - position__cumulativeWithdrawnUSD - position__cumulativeDeltaUSD - position__cumulativeFeesUSD - position__debt - position__debtInUSD - position__collateral - position__collateralInUSD - position__supply - position__supplyInUSD - position__netValue - position___ajnaBucket - depositedUSD - withdrawnUSD - deltaUSD - feePaidUSD - depositTransfers - withdrawTransfers - protocol - marketId - feePaids - swaps - automationEvents - debtBefore - debtInUSDBefore - debtAfter - debtInUSDAfter - collateralBefore - collateralInUSDBefore - collateralAfter - collateralInUSDAfter - supplyBefore - supplyInUSDBefore - supplyAfter - supplyInUSDAfter - netValueBefore - netValueAfter - collateralTokenPriceInUSD - debtTokenPriceInUSD - supplyTokenPriceInUSD + id + blockNumber + timestamp + txHash + logIndex + sender + kind + account + account__id + account__address + account__type + account__vaultId + user + user__id + user__openPositions + position + position__id + position__protocol + position__marketId + position__positionType + position__cumulativeDepositedUSD + position__cumulativeWithdrawnUSD + position__cumulativeDeltaUSD + position__cumulativeFeesUSD + position__debt + position__debtInUSD + position__collateral + position__collateralInUSD + position__supply + position__supplyInUSD + position__netValue + position___ajnaBucket + depositedUSD + withdrawnUSD + deltaUSD + feePaidUSD + depositTransfers + withdrawTransfers + protocol + marketId + feePaids + swaps + automationEvents + debtBefore + debtInUSDBefore + debtAfter + debtInUSDAfter + collateralBefore + collateralInUSDBefore + collateralAfter + collateralInUSDAfter + supplyBefore + supplyInUSDBefore + supplyAfter + supplyInUSDAfter + netValueBefore + netValueAfter + collateralTokenPriceInUSD + debtTokenPriceInUSD + supplyTokenPriceInUSD } type Token { - id: Bytes! - address: Bytes! - symbol: String! - decimals: BigInt! - precision: BigInt! + id: Bytes! + address: Bytes! + symbol: String! + decimals: BigInt! + precision: BigInt! } input Token_filter { - id: Bytes - id_not: Bytes - id_gt: Bytes - id_lt: Bytes - id_gte: Bytes - id_lte: Bytes - id_in: [Bytes!] - id_not_in: [Bytes!] - id_contains: Bytes - id_not_contains: Bytes - address: Bytes - address_not: Bytes - address_gt: Bytes - address_lt: Bytes - address_gte: Bytes - address_lte: Bytes - address_in: [Bytes!] - address_not_in: [Bytes!] - address_contains: Bytes - address_not_contains: Bytes - symbol: String - symbol_not: String - symbol_gt: String - symbol_lt: String - symbol_gte: String - symbol_lte: String - symbol_in: [String!] - symbol_not_in: [String!] - symbol_contains: String - symbol_contains_nocase: String - symbol_not_contains: String - symbol_not_contains_nocase: String - symbol_starts_with: String - symbol_starts_with_nocase: String - symbol_not_starts_with: String - symbol_not_starts_with_nocase: String - symbol_ends_with: String - symbol_ends_with_nocase: String - symbol_not_ends_with: String - symbol_not_ends_with_nocase: String - decimals: BigInt - decimals_not: BigInt - decimals_gt: BigInt - decimals_lt: BigInt - decimals_gte: BigInt - decimals_lte: BigInt - decimals_in: [BigInt!] - decimals_not_in: [BigInt!] - precision: BigInt - precision_not: BigInt - precision_gt: BigInt - precision_lt: BigInt - precision_gte: BigInt - precision_lte: BigInt - precision_in: [BigInt!] - precision_not_in: [BigInt!] - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [Token_filter] - or: [Token_filter] + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + address: Bytes + address_not: Bytes + address_gt: Bytes + address_lt: Bytes + address_gte: Bytes + address_lte: Bytes + address_in: [Bytes!] + address_not_in: [Bytes!] + address_contains: Bytes + address_not_contains: Bytes + symbol: String + symbol_not: String + symbol_gt: String + symbol_lt: String + symbol_gte: String + symbol_lte: String + symbol_in: [String!] + symbol_not_in: [String!] + symbol_contains: String + symbol_contains_nocase: String + symbol_not_contains: String + symbol_not_contains_nocase: String + symbol_starts_with: String + symbol_starts_with_nocase: String + symbol_not_starts_with: String + symbol_not_starts_with_nocase: String + symbol_ends_with: String + symbol_ends_with_nocase: String + symbol_not_ends_with: String + symbol_not_ends_with_nocase: String + decimals: BigInt + decimals_not: BigInt + decimals_gt: BigInt + decimals_lt: BigInt + decimals_gte: BigInt + decimals_lte: BigInt + decimals_in: [BigInt!] + decimals_not_in: [BigInt!] + precision: BigInt + precision_not: BigInt + precision_gt: BigInt + precision_lt: BigInt + precision_gte: BigInt + precision_lte: BigInt + precision_in: [BigInt!] + precision_not_in: [BigInt!] + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [Token_filter] + or: [Token_filter] } enum Token_orderBy { - id - address - symbol - decimals - precision + id + address + symbol + decimals + precision } type TokenPrice { - id: Bytes! - token: Token! - blockNumber: BigInt! - price: BigDecimal! - oracle: String! + id: Bytes! + token: Token! + blockNumber: BigInt! + price: BigDecimal! + oracle: String! } input TokenPrice_filter { - id: Bytes - id_not: Bytes - id_gt: Bytes - id_lt: Bytes - id_gte: Bytes - id_lte: Bytes - id_in: [Bytes!] - id_not_in: [Bytes!] - id_contains: Bytes - id_not_contains: Bytes - token: String - token_not: String - token_gt: String - token_lt: String - token_gte: String - token_lte: String - token_in: [String!] - token_not_in: [String!] - token_contains: String - token_contains_nocase: String - token_not_contains: String - token_not_contains_nocase: String - token_starts_with: String - token_starts_with_nocase: String - token_not_starts_with: String - token_not_starts_with_nocase: String - token_ends_with: String - token_ends_with_nocase: String - token_not_ends_with: String - token_not_ends_with_nocase: String - token_: Token_filter - blockNumber: BigInt - blockNumber_not: BigInt - blockNumber_gt: BigInt - blockNumber_lt: BigInt - blockNumber_gte: BigInt - blockNumber_lte: BigInt - blockNumber_in: [BigInt!] - blockNumber_not_in: [BigInt!] - price: BigDecimal - price_not: BigDecimal - price_gt: BigDecimal - price_lt: BigDecimal - price_gte: BigDecimal - price_lte: BigDecimal - price_in: [BigDecimal!] - price_not_in: [BigDecimal!] - oracle: String - oracle_not: String - oracle_gt: String - oracle_lt: String - oracle_gte: String - oracle_lte: String - oracle_in: [String!] - oracle_not_in: [String!] - oracle_contains: String - oracle_contains_nocase: String - oracle_not_contains: String - oracle_not_contains_nocase: String - oracle_starts_with: String - oracle_starts_with_nocase: String - oracle_not_starts_with: String - oracle_not_starts_with_nocase: String - oracle_ends_with: String - oracle_ends_with_nocase: String - oracle_not_ends_with: String - oracle_not_ends_with_nocase: String - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [TokenPrice_filter] - or: [TokenPrice_filter] + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + token: String + token_not: String + token_gt: String + token_lt: String + token_gte: String + token_lte: String + token_in: [String!] + token_not_in: [String!] + token_contains: String + token_contains_nocase: String + token_not_contains: String + token_not_contains_nocase: String + token_starts_with: String + token_starts_with_nocase: String + token_not_starts_with: String + token_not_starts_with_nocase: String + token_ends_with: String + token_ends_with_nocase: String + token_not_ends_with: String + token_not_ends_with_nocase: String + token_: Token_filter + blockNumber: BigInt + blockNumber_not: BigInt + blockNumber_gt: BigInt + blockNumber_lt: BigInt + blockNumber_gte: BigInt + blockNumber_lte: BigInt + blockNumber_in: [BigInt!] + blockNumber_not_in: [BigInt!] + price: BigDecimal + price_not: BigDecimal + price_gt: BigDecimal + price_lt: BigDecimal + price_gte: BigDecimal + price_lte: BigDecimal + price_in: [BigDecimal!] + price_not_in: [BigDecimal!] + oracle: String + oracle_not: String + oracle_gt: String + oracle_lt: String + oracle_gte: String + oracle_lte: String + oracle_in: [String!] + oracle_not_in: [String!] + oracle_contains: String + oracle_contains_nocase: String + oracle_not_contains: String + oracle_not_contains_nocase: String + oracle_starts_with: String + oracle_starts_with_nocase: String + oracle_not_starts_with: String + oracle_not_starts_with_nocase: String + oracle_ends_with: String + oracle_ends_with_nocase: String + oracle_not_ends_with: String + oracle_not_ends_with_nocase: String + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [TokenPrice_filter] + or: [TokenPrice_filter] } enum TokenPrice_orderBy { - id - token - token__id - token__address - token__symbol - token__decimals - token__precision - blockNumber - price - oracle + id + token + token__id + token__address + token__symbol + token__decimals + token__precision + blockNumber + price + oracle } type Transfer { - id: Bytes! - event: SummerEvent! - from: Bytes! - to: Bytes! - token: Token! - amount: BigDecimal! - priceInUSD: BigDecimal! - oracle: String! - amountUSD: BigDecimal! - txHash: String! + id: Bytes! + event: SummerEvent! + from: Bytes! + to: Bytes! + token: Token! + amount: BigDecimal! + priceInUSD: BigDecimal! + oracle: String! + amountUSD: BigDecimal! + txHash: String! } input Transfer_filter { - id: Bytes - id_not: Bytes - id_gt: Bytes - id_lt: Bytes - id_gte: Bytes - id_lte: Bytes - id_in: [Bytes!] - id_not_in: [Bytes!] - id_contains: Bytes - id_not_contains: Bytes - event: String - event_not: String - event_gt: String - event_lt: String - event_gte: String - event_lte: String - event_in: [String!] - event_not_in: [String!] - event_contains: String - event_contains_nocase: String - event_not_contains: String - event_not_contains_nocase: String - event_starts_with: String - event_starts_with_nocase: String - event_not_starts_with: String - event_not_starts_with_nocase: String - event_ends_with: String - event_ends_with_nocase: String - event_not_ends_with: String - event_not_ends_with_nocase: String - event_: SummerEvent_filter - from: Bytes - from_not: Bytes - from_gt: Bytes - from_lt: Bytes - from_gte: Bytes - from_lte: Bytes - from_in: [Bytes!] - from_not_in: [Bytes!] - from_contains: Bytes - from_not_contains: Bytes - to: Bytes - to_not: Bytes - to_gt: Bytes - to_lt: Bytes - to_gte: Bytes - to_lte: Bytes - to_in: [Bytes!] - to_not_in: [Bytes!] - to_contains: Bytes - to_not_contains: Bytes - token: String - token_not: String - token_gt: String - token_lt: String - token_gte: String - token_lte: String - token_in: [String!] - token_not_in: [String!] - token_contains: String - token_contains_nocase: String - token_not_contains: String - token_not_contains_nocase: String - token_starts_with: String - token_starts_with_nocase: String - token_not_starts_with: String - token_not_starts_with_nocase: String - token_ends_with: String - token_ends_with_nocase: String - token_not_ends_with: String - token_not_ends_with_nocase: String - token_: Token_filter - amount: BigDecimal - amount_not: BigDecimal - amount_gt: BigDecimal - amount_lt: BigDecimal - amount_gte: BigDecimal - amount_lte: BigDecimal - amount_in: [BigDecimal!] - amount_not_in: [BigDecimal!] - priceInUSD: BigDecimal - priceInUSD_not: BigDecimal - priceInUSD_gt: BigDecimal - priceInUSD_lt: BigDecimal - priceInUSD_gte: BigDecimal - priceInUSD_lte: BigDecimal - priceInUSD_in: [BigDecimal!] - priceInUSD_not_in: [BigDecimal!] - oracle: String - oracle_not: String - oracle_gt: String - oracle_lt: String - oracle_gte: String - oracle_lte: String - oracle_in: [String!] - oracle_not_in: [String!] - oracle_contains: String - oracle_contains_nocase: String - oracle_not_contains: String - oracle_not_contains_nocase: String - oracle_starts_with: String - oracle_starts_with_nocase: String - oracle_not_starts_with: String - oracle_not_starts_with_nocase: String - oracle_ends_with: String - oracle_ends_with_nocase: String - oracle_not_ends_with: String - oracle_not_ends_with_nocase: String - amountUSD: BigDecimal - amountUSD_not: BigDecimal - amountUSD_gt: BigDecimal - amountUSD_lt: BigDecimal - amountUSD_gte: BigDecimal - amountUSD_lte: BigDecimal - amountUSD_in: [BigDecimal!] - amountUSD_not_in: [BigDecimal!] - txHash: String - txHash_not: String - txHash_gt: String - txHash_lt: String - txHash_gte: String - txHash_lte: String - txHash_in: [String!] - txHash_not_in: [String!] - txHash_contains: String - txHash_contains_nocase: String - txHash_not_contains: String - txHash_not_contains_nocase: String - txHash_starts_with: String - txHash_starts_with_nocase: String - txHash_not_starts_with: String - txHash_not_starts_with_nocase: String - txHash_ends_with: String - txHash_ends_with_nocase: String - txHash_not_ends_with: String - txHash_not_ends_with_nocase: String - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [Transfer_filter] - or: [Transfer_filter] + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + event: String + event_not: String + event_gt: String + event_lt: String + event_gte: String + event_lte: String + event_in: [String!] + event_not_in: [String!] + event_contains: String + event_contains_nocase: String + event_not_contains: String + event_not_contains_nocase: String + event_starts_with: String + event_starts_with_nocase: String + event_not_starts_with: String + event_not_starts_with_nocase: String + event_ends_with: String + event_ends_with_nocase: String + event_not_ends_with: String + event_not_ends_with_nocase: String + event_: SummerEvent_filter + from: Bytes + from_not: Bytes + from_gt: Bytes + from_lt: Bytes + from_gte: Bytes + from_lte: Bytes + from_in: [Bytes!] + from_not_in: [Bytes!] + from_contains: Bytes + from_not_contains: Bytes + to: Bytes + to_not: Bytes + to_gt: Bytes + to_lt: Bytes + to_gte: Bytes + to_lte: Bytes + to_in: [Bytes!] + to_not_in: [Bytes!] + to_contains: Bytes + to_not_contains: Bytes + token: String + token_not: String + token_gt: String + token_lt: String + token_gte: String + token_lte: String + token_in: [String!] + token_not_in: [String!] + token_contains: String + token_contains_nocase: String + token_not_contains: String + token_not_contains_nocase: String + token_starts_with: String + token_starts_with_nocase: String + token_not_starts_with: String + token_not_starts_with_nocase: String + token_ends_with: String + token_ends_with_nocase: String + token_not_ends_with: String + token_not_ends_with_nocase: String + token_: Token_filter + amount: BigDecimal + amount_not: BigDecimal + amount_gt: BigDecimal + amount_lt: BigDecimal + amount_gte: BigDecimal + amount_lte: BigDecimal + amount_in: [BigDecimal!] + amount_not_in: [BigDecimal!] + priceInUSD: BigDecimal + priceInUSD_not: BigDecimal + priceInUSD_gt: BigDecimal + priceInUSD_lt: BigDecimal + priceInUSD_gte: BigDecimal + priceInUSD_lte: BigDecimal + priceInUSD_in: [BigDecimal!] + priceInUSD_not_in: [BigDecimal!] + oracle: String + oracle_not: String + oracle_gt: String + oracle_lt: String + oracle_gte: String + oracle_lte: String + oracle_in: [String!] + oracle_not_in: [String!] + oracle_contains: String + oracle_contains_nocase: String + oracle_not_contains: String + oracle_not_contains_nocase: String + oracle_starts_with: String + oracle_starts_with_nocase: String + oracle_not_starts_with: String + oracle_not_starts_with_nocase: String + oracle_ends_with: String + oracle_ends_with_nocase: String + oracle_not_ends_with: String + oracle_not_ends_with_nocase: String + amountUSD: BigDecimal + amountUSD_not: BigDecimal + amountUSD_gt: BigDecimal + amountUSD_lt: BigDecimal + amountUSD_gte: BigDecimal + amountUSD_lte: BigDecimal + amountUSD_in: [BigDecimal!] + amountUSD_not_in: [BigDecimal!] + txHash: String + txHash_not: String + txHash_gt: String + txHash_lt: String + txHash_gte: String + txHash_lte: String + txHash_in: [String!] + txHash_not_in: [String!] + txHash_contains: String + txHash_contains_nocase: String + txHash_not_contains: String + txHash_not_contains_nocase: String + txHash_starts_with: String + txHash_starts_with_nocase: String + txHash_not_starts_with: String + txHash_not_starts_with_nocase: String + txHash_ends_with: String + txHash_ends_with_nocase: String + txHash_not_ends_with: String + txHash_not_ends_with_nocase: String + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [Transfer_filter] + or: [Transfer_filter] } enum Transfer_orderBy { - id - event - event__id - event__blockNumber - event__timestamp - event__txHash - event__logIndex - event__sender - event__kind - event__depositedUSD - event__withdrawnUSD - event__deltaUSD - event__feePaidUSD - event__protocol - event__marketId - event__debtBefore - event__debtInUSDBefore - event__debtAfter - event__debtInUSDAfter - event__collateralBefore - event__collateralInUSDBefore - event__collateralAfter - event__collateralInUSDAfter - event__supplyBefore - event__supplyInUSDBefore - event__supplyAfter - event__supplyInUSDAfter - event__netValueBefore - event__netValueAfter - event__collateralTokenPriceInUSD - event__debtTokenPriceInUSD - event__supplyTokenPriceInUSD - from - to - token - token__id - token__address - token__symbol - token__decimals - token__precision - amount - priceInUSD - oracle - amountUSD - txHash + id + event + event__id + event__blockNumber + event__timestamp + event__txHash + event__logIndex + event__sender + event__kind + event__depositedUSD + event__withdrawnUSD + event__deltaUSD + event__feePaidUSD + event__protocol + event__marketId + event__debtBefore + event__debtInUSDBefore + event__debtAfter + event__debtInUSDAfter + event__collateralBefore + event__collateralInUSDBefore + event__collateralAfter + event__collateralInUSDAfter + event__supplyBefore + event__supplyInUSDBefore + event__supplyAfter + event__supplyInUSDAfter + event__netValueBefore + event__netValueAfter + event__collateralTokenPriceInUSD + event__debtTokenPriceInUSD + event__supplyTokenPriceInUSD + from + to + token + token__id + token__address + token__symbol + token__decimals + token__precision + amount + priceInUSD + oracle + amountUSD + txHash } type Trigger { - id: ID! - account: Account! - user: User! - commandAddress: Bytes! - triggerType: BigInt! - kind: String! - triggerData: Bytes! - continuous: Boolean! - decodedData: [String!]! - decodedDataNames: [String!]! - addedBlock: BigInt! - addedTransaction: Bytes! - addedLogIndex: BigInt! - addedTimestamp: BigInt! - removedBlock: BigInt - removedTransaction: Bytes - removedLogIndex: BigInt - removedTimestamp: BigInt - executedBlock: BigInt - executedTransaction: Bytes - executedLogIndex: BigInt - executedTimestamp: BigInt - version: BigInt! - tokens(skip: Int = 0, first: Int = 100, orderBy: Token_orderBy, orderDirection: OrderDirection, where: Token_filter): [Token!] - protocol: String! - marketId: String! - position: Position! - operationName: String + id: ID! + account: Account! + user: User! + commandAddress: Bytes! + triggerType: BigInt! + kind: String! + triggerData: Bytes! + continuous: Boolean! + decodedData: [String!]! + decodedDataNames: [String!]! + addedBlock: BigInt! + addedTransaction: Bytes! + addedLogIndex: BigInt! + addedTimestamp: BigInt! + removedBlock: BigInt + removedTransaction: Bytes + removedLogIndex: BigInt + removedTimestamp: BigInt + executedBlock: BigInt + executedTransaction: Bytes + executedLogIndex: BigInt + executedTimestamp: BigInt + version: BigInt! + tokens( + skip: Int = 0 + first: Int = 100 + orderBy: Token_orderBy + orderDirection: OrderDirection + where: Token_filter + ): [Token!] + protocol: String! + marketId: String! + position: Position! + operationName: String } input Trigger_filter { - id: ID - id_not: ID - id_gt: ID - id_lt: ID - id_gte: ID - id_lte: ID - id_in: [ID!] - id_not_in: [ID!] - account: String - account_not: String - account_gt: String - account_lt: String - account_gte: String - account_lte: String - account_in: [String!] - account_not_in: [String!] - account_contains: String - account_contains_nocase: String - account_not_contains: String - account_not_contains_nocase: String - account_starts_with: String - account_starts_with_nocase: String - account_not_starts_with: String - account_not_starts_with_nocase: String - account_ends_with: String - account_ends_with_nocase: String - account_not_ends_with: String - account_not_ends_with_nocase: String - account_: Account_filter - user: String - user_not: String - user_gt: String - user_lt: String - user_gte: String - user_lte: String - user_in: [String!] - user_not_in: [String!] - user_contains: String - user_contains_nocase: String - user_not_contains: String - user_not_contains_nocase: String - user_starts_with: String - user_starts_with_nocase: String - user_not_starts_with: String - user_not_starts_with_nocase: String - user_ends_with: String - user_ends_with_nocase: String - user_not_ends_with: String - user_not_ends_with_nocase: String - user_: User_filter - commandAddress: Bytes - commandAddress_not: Bytes - commandAddress_gt: Bytes - commandAddress_lt: Bytes - commandAddress_gte: Bytes - commandAddress_lte: Bytes - commandAddress_in: [Bytes!] - commandAddress_not_in: [Bytes!] - commandAddress_contains: Bytes - commandAddress_not_contains: Bytes - triggerType: BigInt - triggerType_not: BigInt - triggerType_gt: BigInt - triggerType_lt: BigInt - triggerType_gte: BigInt - triggerType_lte: BigInt - triggerType_in: [BigInt!] - triggerType_not_in: [BigInt!] - kind: String - kind_not: String - kind_gt: String - kind_lt: String - kind_gte: String - kind_lte: String - kind_in: [String!] - kind_not_in: [String!] - kind_contains: String - kind_contains_nocase: String - kind_not_contains: String - kind_not_contains_nocase: String - kind_starts_with: String - kind_starts_with_nocase: String - kind_not_starts_with: String - kind_not_starts_with_nocase: String - kind_ends_with: String - kind_ends_with_nocase: String - kind_not_ends_with: String - kind_not_ends_with_nocase: String - triggerData: Bytes - triggerData_not: Bytes - triggerData_gt: Bytes - triggerData_lt: Bytes - triggerData_gte: Bytes - triggerData_lte: Bytes - triggerData_in: [Bytes!] - triggerData_not_in: [Bytes!] - triggerData_contains: Bytes - triggerData_not_contains: Bytes - continuous: Boolean - continuous_not: Boolean - continuous_in: [Boolean!] - continuous_not_in: [Boolean!] - decodedData: [String!] - decodedData_not: [String!] - decodedData_contains: [String!] - decodedData_contains_nocase: [String!] - decodedData_not_contains: [String!] - decodedData_not_contains_nocase: [String!] - decodedDataNames: [String!] - decodedDataNames_not: [String!] - decodedDataNames_contains: [String!] - decodedDataNames_contains_nocase: [String!] - decodedDataNames_not_contains: [String!] - decodedDataNames_not_contains_nocase: [String!] - addedBlock: BigInt - addedBlock_not: BigInt - addedBlock_gt: BigInt - addedBlock_lt: BigInt - addedBlock_gte: BigInt - addedBlock_lte: BigInt - addedBlock_in: [BigInt!] - addedBlock_not_in: [BigInt!] - addedTransaction: Bytes - addedTransaction_not: Bytes - addedTransaction_gt: Bytes - addedTransaction_lt: Bytes - addedTransaction_gte: Bytes - addedTransaction_lte: Bytes - addedTransaction_in: [Bytes!] - addedTransaction_not_in: [Bytes!] - addedTransaction_contains: Bytes - addedTransaction_not_contains: Bytes - addedLogIndex: BigInt - addedLogIndex_not: BigInt - addedLogIndex_gt: BigInt - addedLogIndex_lt: BigInt - addedLogIndex_gte: BigInt - addedLogIndex_lte: BigInt - addedLogIndex_in: [BigInt!] - addedLogIndex_not_in: [BigInt!] - addedTimestamp: BigInt - addedTimestamp_not: BigInt - addedTimestamp_gt: BigInt - addedTimestamp_lt: BigInt - addedTimestamp_gte: BigInt - addedTimestamp_lte: BigInt - addedTimestamp_in: [BigInt!] - addedTimestamp_not_in: [BigInt!] - removedBlock: BigInt - removedBlock_not: BigInt - removedBlock_gt: BigInt - removedBlock_lt: BigInt - removedBlock_gte: BigInt - removedBlock_lte: BigInt - removedBlock_in: [BigInt!] - removedBlock_not_in: [BigInt!] - removedTransaction: Bytes - removedTransaction_not: Bytes - removedTransaction_gt: Bytes - removedTransaction_lt: Bytes - removedTransaction_gte: Bytes - removedTransaction_lte: Bytes - removedTransaction_in: [Bytes!] - removedTransaction_not_in: [Bytes!] - removedTransaction_contains: Bytes - removedTransaction_not_contains: Bytes - removedLogIndex: BigInt - removedLogIndex_not: BigInt - removedLogIndex_gt: BigInt - removedLogIndex_lt: BigInt - removedLogIndex_gte: BigInt - removedLogIndex_lte: BigInt - removedLogIndex_in: [BigInt!] - removedLogIndex_not_in: [BigInt!] - removedTimestamp: BigInt - removedTimestamp_not: BigInt - removedTimestamp_gt: BigInt - removedTimestamp_lt: BigInt - removedTimestamp_gte: BigInt - removedTimestamp_lte: BigInt - removedTimestamp_in: [BigInt!] - removedTimestamp_not_in: [BigInt!] - executedBlock: BigInt - executedBlock_not: BigInt - executedBlock_gt: BigInt - executedBlock_lt: BigInt - executedBlock_gte: BigInt - executedBlock_lte: BigInt - executedBlock_in: [BigInt!] - executedBlock_not_in: [BigInt!] - executedTransaction: Bytes - executedTransaction_not: Bytes - executedTransaction_gt: Bytes - executedTransaction_lt: Bytes - executedTransaction_gte: Bytes - executedTransaction_lte: Bytes - executedTransaction_in: [Bytes!] - executedTransaction_not_in: [Bytes!] - executedTransaction_contains: Bytes - executedTransaction_not_contains: Bytes - executedLogIndex: BigInt - executedLogIndex_not: BigInt - executedLogIndex_gt: BigInt - executedLogIndex_lt: BigInt - executedLogIndex_gte: BigInt - executedLogIndex_lte: BigInt - executedLogIndex_in: [BigInt!] - executedLogIndex_not_in: [BigInt!] - executedTimestamp: BigInt - executedTimestamp_not: BigInt - executedTimestamp_gt: BigInt - executedTimestamp_lt: BigInt - executedTimestamp_gte: BigInt - executedTimestamp_lte: BigInt - executedTimestamp_in: [BigInt!] - executedTimestamp_not_in: [BigInt!] - version: BigInt - version_not: BigInt - version_gt: BigInt - version_lt: BigInt - version_gte: BigInt - version_lte: BigInt - version_in: [BigInt!] - version_not_in: [BigInt!] - tokens: [String!] - tokens_not: [String!] - tokens_contains: [String!] - tokens_contains_nocase: [String!] - tokens_not_contains: [String!] - tokens_not_contains_nocase: [String!] - tokens_: Token_filter - protocol: String - protocol_not: String - protocol_gt: String - protocol_lt: String - protocol_gte: String - protocol_lte: String - protocol_in: [String!] - protocol_not_in: [String!] - protocol_contains: String - protocol_contains_nocase: String - protocol_not_contains: String - protocol_not_contains_nocase: String - protocol_starts_with: String - protocol_starts_with_nocase: String - protocol_not_starts_with: String - protocol_not_starts_with_nocase: String - protocol_ends_with: String - protocol_ends_with_nocase: String - protocol_not_ends_with: String - protocol_not_ends_with_nocase: String - marketId: String - marketId_not: String - marketId_gt: String - marketId_lt: String - marketId_gte: String - marketId_lte: String - marketId_in: [String!] - marketId_not_in: [String!] - marketId_contains: String - marketId_contains_nocase: String - marketId_not_contains: String - marketId_not_contains_nocase: String - marketId_starts_with: String - marketId_starts_with_nocase: String - marketId_not_starts_with: String - marketId_not_starts_with_nocase: String - marketId_ends_with: String - marketId_ends_with_nocase: String - marketId_not_ends_with: String - marketId_not_ends_with_nocase: String - position: String - position_not: String - position_gt: String - position_lt: String - position_gte: String - position_lte: String - position_in: [String!] - position_not_in: [String!] - position_contains: String - position_contains_nocase: String - position_not_contains: String - position_not_contains_nocase: String - position_starts_with: String - position_starts_with_nocase: String - position_not_starts_with: String - position_not_starts_with_nocase: String - position_ends_with: String - position_ends_with_nocase: String - position_not_ends_with: String - position_not_ends_with_nocase: String - position_: Position_filter - operationName: String - operationName_not: String - operationName_gt: String - operationName_lt: String - operationName_gte: String - operationName_lte: String - operationName_in: [String!] - operationName_not_in: [String!] - operationName_contains: String - operationName_contains_nocase: String - operationName_not_contains: String - operationName_not_contains_nocase: String - operationName_starts_with: String - operationName_starts_with_nocase: String - operationName_not_starts_with: String - operationName_not_starts_with_nocase: String - operationName_ends_with: String - operationName_ends_with_nocase: String - operationName_not_ends_with: String - operationName_not_ends_with_nocase: String - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [Trigger_filter] - or: [Trigger_filter] + id: ID + id_not: ID + id_gt: ID + id_lt: ID + id_gte: ID + id_lte: ID + id_in: [ID!] + id_not_in: [ID!] + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + commandAddress: Bytes + commandAddress_not: Bytes + commandAddress_gt: Bytes + commandAddress_lt: Bytes + commandAddress_gte: Bytes + commandAddress_lte: Bytes + commandAddress_in: [Bytes!] + commandAddress_not_in: [Bytes!] + commandAddress_contains: Bytes + commandAddress_not_contains: Bytes + triggerType: BigInt + triggerType_not: BigInt + triggerType_gt: BigInt + triggerType_lt: BigInt + triggerType_gte: BigInt + triggerType_lte: BigInt + triggerType_in: [BigInt!] + triggerType_not_in: [BigInt!] + kind: String + kind_not: String + kind_gt: String + kind_lt: String + kind_gte: String + kind_lte: String + kind_in: [String!] + kind_not_in: [String!] + kind_contains: String + kind_contains_nocase: String + kind_not_contains: String + kind_not_contains_nocase: String + kind_starts_with: String + kind_starts_with_nocase: String + kind_not_starts_with: String + kind_not_starts_with_nocase: String + kind_ends_with: String + kind_ends_with_nocase: String + kind_not_ends_with: String + kind_not_ends_with_nocase: String + triggerData: Bytes + triggerData_not: Bytes + triggerData_gt: Bytes + triggerData_lt: Bytes + triggerData_gte: Bytes + triggerData_lte: Bytes + triggerData_in: [Bytes!] + triggerData_not_in: [Bytes!] + triggerData_contains: Bytes + triggerData_not_contains: Bytes + continuous: Boolean + continuous_not: Boolean + continuous_in: [Boolean!] + continuous_not_in: [Boolean!] + decodedData: [String!] + decodedData_not: [String!] + decodedData_contains: [String!] + decodedData_contains_nocase: [String!] + decodedData_not_contains: [String!] + decodedData_not_contains_nocase: [String!] + decodedDataNames: [String!] + decodedDataNames_not: [String!] + decodedDataNames_contains: [String!] + decodedDataNames_contains_nocase: [String!] + decodedDataNames_not_contains: [String!] + decodedDataNames_not_contains_nocase: [String!] + addedBlock: BigInt + addedBlock_not: BigInt + addedBlock_gt: BigInt + addedBlock_lt: BigInt + addedBlock_gte: BigInt + addedBlock_lte: BigInt + addedBlock_in: [BigInt!] + addedBlock_not_in: [BigInt!] + addedTransaction: Bytes + addedTransaction_not: Bytes + addedTransaction_gt: Bytes + addedTransaction_lt: Bytes + addedTransaction_gte: Bytes + addedTransaction_lte: Bytes + addedTransaction_in: [Bytes!] + addedTransaction_not_in: [Bytes!] + addedTransaction_contains: Bytes + addedTransaction_not_contains: Bytes + addedLogIndex: BigInt + addedLogIndex_not: BigInt + addedLogIndex_gt: BigInt + addedLogIndex_lt: BigInt + addedLogIndex_gte: BigInt + addedLogIndex_lte: BigInt + addedLogIndex_in: [BigInt!] + addedLogIndex_not_in: [BigInt!] + addedTimestamp: BigInt + addedTimestamp_not: BigInt + addedTimestamp_gt: BigInt + addedTimestamp_lt: BigInt + addedTimestamp_gte: BigInt + addedTimestamp_lte: BigInt + addedTimestamp_in: [BigInt!] + addedTimestamp_not_in: [BigInt!] + removedBlock: BigInt + removedBlock_not: BigInt + removedBlock_gt: BigInt + removedBlock_lt: BigInt + removedBlock_gte: BigInt + removedBlock_lte: BigInt + removedBlock_in: [BigInt!] + removedBlock_not_in: [BigInt!] + removedTransaction: Bytes + removedTransaction_not: Bytes + removedTransaction_gt: Bytes + removedTransaction_lt: Bytes + removedTransaction_gte: Bytes + removedTransaction_lte: Bytes + removedTransaction_in: [Bytes!] + removedTransaction_not_in: [Bytes!] + removedTransaction_contains: Bytes + removedTransaction_not_contains: Bytes + removedLogIndex: BigInt + removedLogIndex_not: BigInt + removedLogIndex_gt: BigInt + removedLogIndex_lt: BigInt + removedLogIndex_gte: BigInt + removedLogIndex_lte: BigInt + removedLogIndex_in: [BigInt!] + removedLogIndex_not_in: [BigInt!] + removedTimestamp: BigInt + removedTimestamp_not: BigInt + removedTimestamp_gt: BigInt + removedTimestamp_lt: BigInt + removedTimestamp_gte: BigInt + removedTimestamp_lte: BigInt + removedTimestamp_in: [BigInt!] + removedTimestamp_not_in: [BigInt!] + executedBlock: BigInt + executedBlock_not: BigInt + executedBlock_gt: BigInt + executedBlock_lt: BigInt + executedBlock_gte: BigInt + executedBlock_lte: BigInt + executedBlock_in: [BigInt!] + executedBlock_not_in: [BigInt!] + executedTransaction: Bytes + executedTransaction_not: Bytes + executedTransaction_gt: Bytes + executedTransaction_lt: Bytes + executedTransaction_gte: Bytes + executedTransaction_lte: Bytes + executedTransaction_in: [Bytes!] + executedTransaction_not_in: [Bytes!] + executedTransaction_contains: Bytes + executedTransaction_not_contains: Bytes + executedLogIndex: BigInt + executedLogIndex_not: BigInt + executedLogIndex_gt: BigInt + executedLogIndex_lt: BigInt + executedLogIndex_gte: BigInt + executedLogIndex_lte: BigInt + executedLogIndex_in: [BigInt!] + executedLogIndex_not_in: [BigInt!] + executedTimestamp: BigInt + executedTimestamp_not: BigInt + executedTimestamp_gt: BigInt + executedTimestamp_lt: BigInt + executedTimestamp_gte: BigInt + executedTimestamp_lte: BigInt + executedTimestamp_in: [BigInt!] + executedTimestamp_not_in: [BigInt!] + version: BigInt + version_not: BigInt + version_gt: BigInt + version_lt: BigInt + version_gte: BigInt + version_lte: BigInt + version_in: [BigInt!] + version_not_in: [BigInt!] + tokens: [String!] + tokens_not: [String!] + tokens_contains: [String!] + tokens_contains_nocase: [String!] + tokens_not_contains: [String!] + tokens_not_contains_nocase: [String!] + tokens_: Token_filter + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + position: String + position_not: String + position_gt: String + position_lt: String + position_gte: String + position_lte: String + position_in: [String!] + position_not_in: [String!] + position_contains: String + position_contains_nocase: String + position_not_contains: String + position_not_contains_nocase: String + position_starts_with: String + position_starts_with_nocase: String + position_not_starts_with: String + position_not_starts_with_nocase: String + position_ends_with: String + position_ends_with_nocase: String + position_not_ends_with: String + position_not_ends_with_nocase: String + position_: Position_filter + operationName: String + operationName_not: String + operationName_gt: String + operationName_lt: String + operationName_gte: String + operationName_lte: String + operationName_in: [String!] + operationName_not_in: [String!] + operationName_contains: String + operationName_contains_nocase: String + operationName_not_contains: String + operationName_not_contains_nocase: String + operationName_starts_with: String + operationName_starts_with_nocase: String + operationName_not_starts_with: String + operationName_not_starts_with_nocase: String + operationName_ends_with: String + operationName_ends_with_nocase: String + operationName_not_ends_with: String + operationName_not_ends_with_nocase: String + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [Trigger_filter] + or: [Trigger_filter] } enum Trigger_orderBy { - id - account - account__id - account__address - account__type - account__vaultId - user - user__id - user__openPositions - commandAddress - triggerType - kind - triggerData - continuous - decodedData - decodedDataNames - addedBlock - addedTransaction - addedLogIndex - addedTimestamp - removedBlock - removedTransaction - removedLogIndex - removedTimestamp - executedBlock - executedTransaction - executedLogIndex - executedTimestamp - version - tokens - protocol - marketId - position - position__id - position__protocol - position__marketId - position__positionType - position__cumulativeDepositedUSD - position__cumulativeWithdrawnUSD - position__cumulativeDeltaUSD - position__cumulativeFeesUSD - position__debt - position__debtInUSD - position__collateral - position__collateralInUSD - position__supply - position__supplyInUSD - position__netValue - position___ajnaBucket - operationName + id + account + account__id + account__address + account__type + account__vaultId + user + user__id + user__openPositions + commandAddress + triggerType + kind + triggerData + continuous + decodedData + decodedDataNames + addedBlock + addedTransaction + addedLogIndex + addedTimestamp + removedBlock + removedTransaction + removedLogIndex + removedTimestamp + executedBlock + executedTransaction + executedLogIndex + executedTimestamp + version + tokens + protocol + marketId + position + position__id + position__protocol + position__marketId + position__positionType + position__cumulativeDepositedUSD + position__cumulativeWithdrawnUSD + position__cumulativeDeltaUSD + position__cumulativeFeesUSD + position__debt + position__debtInUSD + position__collateral + position__collateralInUSD + position__supply + position__supplyInUSD + position__netValue + position___ajnaBucket + operationName } type TriggerEvent { - id: Bytes! - eventType: String! - trigger: Trigger! - account: Account! - user: User! - mainEventHash: SummerEvent - protocol: String! - marketId: String! - position: Position! - block: BigInt! - transactionHash: Bytes! - logIndex: BigInt! - timestamp: BigInt! + id: Bytes! + eventType: String! + trigger: Trigger! + account: Account! + user: User! + mainEventHash: SummerEvent + protocol: String! + marketId: String! + position: Position! + block: BigInt! + transactionHash: Bytes! + logIndex: BigInt! + timestamp: BigInt! } input TriggerEvent_filter { - id: Bytes - id_not: Bytes - id_gt: Bytes - id_lt: Bytes - id_gte: Bytes - id_lte: Bytes - id_in: [Bytes!] - id_not_in: [Bytes!] - id_contains: Bytes - id_not_contains: Bytes - eventType: String - eventType_not: String - eventType_gt: String - eventType_lt: String - eventType_gte: String - eventType_lte: String - eventType_in: [String!] - eventType_not_in: [String!] - eventType_contains: String - eventType_contains_nocase: String - eventType_not_contains: String - eventType_not_contains_nocase: String - eventType_starts_with: String - eventType_starts_with_nocase: String - eventType_not_starts_with: String - eventType_not_starts_with_nocase: String - eventType_ends_with: String - eventType_ends_with_nocase: String - eventType_not_ends_with: String - eventType_not_ends_with_nocase: String - trigger: String - trigger_not: String - trigger_gt: String - trigger_lt: String - trigger_gte: String - trigger_lte: String - trigger_in: [String!] - trigger_not_in: [String!] - trigger_contains: String - trigger_contains_nocase: String - trigger_not_contains: String - trigger_not_contains_nocase: String - trigger_starts_with: String - trigger_starts_with_nocase: String - trigger_not_starts_with: String - trigger_not_starts_with_nocase: String - trigger_ends_with: String - trigger_ends_with_nocase: String - trigger_not_ends_with: String - trigger_not_ends_with_nocase: String - trigger_: Trigger_filter - account: String - account_not: String - account_gt: String - account_lt: String - account_gte: String - account_lte: String - account_in: [String!] - account_not_in: [String!] - account_contains: String - account_contains_nocase: String - account_not_contains: String - account_not_contains_nocase: String - account_starts_with: String - account_starts_with_nocase: String - account_not_starts_with: String - account_not_starts_with_nocase: String - account_ends_with: String - account_ends_with_nocase: String - account_not_ends_with: String - account_not_ends_with_nocase: String - account_: Account_filter - user: String - user_not: String - user_gt: String - user_lt: String - user_gte: String - user_lte: String - user_in: [String!] - user_not_in: [String!] - user_contains: String - user_contains_nocase: String - user_not_contains: String - user_not_contains_nocase: String - user_starts_with: String - user_starts_with_nocase: String - user_not_starts_with: String - user_not_starts_with_nocase: String - user_ends_with: String - user_ends_with_nocase: String - user_not_ends_with: String - user_not_ends_with_nocase: String - user_: User_filter - mainEventHash: String - mainEventHash_not: String - mainEventHash_gt: String - mainEventHash_lt: String - mainEventHash_gte: String - mainEventHash_lte: String - mainEventHash_in: [String!] - mainEventHash_not_in: [String!] - mainEventHash_contains: String - mainEventHash_contains_nocase: String - mainEventHash_not_contains: String - mainEventHash_not_contains_nocase: String - mainEventHash_starts_with: String - mainEventHash_starts_with_nocase: String - mainEventHash_not_starts_with: String - mainEventHash_not_starts_with_nocase: String - mainEventHash_ends_with: String - mainEventHash_ends_with_nocase: String - mainEventHash_not_ends_with: String - mainEventHash_not_ends_with_nocase: String - mainEventHash_: SummerEvent_filter - protocol: String - protocol_not: String - protocol_gt: String - protocol_lt: String - protocol_gte: String - protocol_lte: String - protocol_in: [String!] - protocol_not_in: [String!] - protocol_contains: String - protocol_contains_nocase: String - protocol_not_contains: String - protocol_not_contains_nocase: String - protocol_starts_with: String - protocol_starts_with_nocase: String - protocol_not_starts_with: String - protocol_not_starts_with_nocase: String - protocol_ends_with: String - protocol_ends_with_nocase: String - protocol_not_ends_with: String - protocol_not_ends_with_nocase: String - marketId: String - marketId_not: String - marketId_gt: String - marketId_lt: String - marketId_gte: String - marketId_lte: String - marketId_in: [String!] - marketId_not_in: [String!] - marketId_contains: String - marketId_contains_nocase: String - marketId_not_contains: String - marketId_not_contains_nocase: String - marketId_starts_with: String - marketId_starts_with_nocase: String - marketId_not_starts_with: String - marketId_not_starts_with_nocase: String - marketId_ends_with: String - marketId_ends_with_nocase: String - marketId_not_ends_with: String - marketId_not_ends_with_nocase: String - position: String - position_not: String - position_gt: String - position_lt: String - position_gte: String - position_lte: String - position_in: [String!] - position_not_in: [String!] - position_contains: String - position_contains_nocase: String - position_not_contains: String - position_not_contains_nocase: String - position_starts_with: String - position_starts_with_nocase: String - position_not_starts_with: String - position_not_starts_with_nocase: String - position_ends_with: String - position_ends_with_nocase: String - position_not_ends_with: String - position_not_ends_with_nocase: String - position_: Position_filter - block: BigInt - block_not: BigInt - block_gt: BigInt - block_lt: BigInt - block_gte: BigInt - block_lte: BigInt - block_in: [BigInt!] - block_not_in: [BigInt!] - transactionHash: Bytes - transactionHash_not: Bytes - transactionHash_gt: Bytes - transactionHash_lt: Bytes - transactionHash_gte: Bytes - transactionHash_lte: Bytes - transactionHash_in: [Bytes!] - transactionHash_not_in: [Bytes!] - transactionHash_contains: Bytes - transactionHash_not_contains: Bytes - logIndex: BigInt - logIndex_not: BigInt - logIndex_gt: BigInt - logIndex_lt: BigInt - logIndex_gte: BigInt - logIndex_lte: BigInt - logIndex_in: [BigInt!] - logIndex_not_in: [BigInt!] - timestamp: BigInt - timestamp_not: BigInt - timestamp_gt: BigInt - timestamp_lt: BigInt - timestamp_gte: BigInt - timestamp_lte: BigInt - timestamp_in: [BigInt!] - timestamp_not_in: [BigInt!] - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [TriggerEvent_filter] - or: [TriggerEvent_filter] + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + eventType: String + eventType_not: String + eventType_gt: String + eventType_lt: String + eventType_gte: String + eventType_lte: String + eventType_in: [String!] + eventType_not_in: [String!] + eventType_contains: String + eventType_contains_nocase: String + eventType_not_contains: String + eventType_not_contains_nocase: String + eventType_starts_with: String + eventType_starts_with_nocase: String + eventType_not_starts_with: String + eventType_not_starts_with_nocase: String + eventType_ends_with: String + eventType_ends_with_nocase: String + eventType_not_ends_with: String + eventType_not_ends_with_nocase: String + trigger: String + trigger_not: String + trigger_gt: String + trigger_lt: String + trigger_gte: String + trigger_lte: String + trigger_in: [String!] + trigger_not_in: [String!] + trigger_contains: String + trigger_contains_nocase: String + trigger_not_contains: String + trigger_not_contains_nocase: String + trigger_starts_with: String + trigger_starts_with_nocase: String + trigger_not_starts_with: String + trigger_not_starts_with_nocase: String + trigger_ends_with: String + trigger_ends_with_nocase: String + trigger_not_ends_with: String + trigger_not_ends_with_nocase: String + trigger_: Trigger_filter + account: String + account_not: String + account_gt: String + account_lt: String + account_gte: String + account_lte: String + account_in: [String!] + account_not_in: [String!] + account_contains: String + account_contains_nocase: String + account_not_contains: String + account_not_contains_nocase: String + account_starts_with: String + account_starts_with_nocase: String + account_not_starts_with: String + account_not_starts_with_nocase: String + account_ends_with: String + account_ends_with_nocase: String + account_not_ends_with: String + account_not_ends_with_nocase: String + account_: Account_filter + user: String + user_not: String + user_gt: String + user_lt: String + user_gte: String + user_lte: String + user_in: [String!] + user_not_in: [String!] + user_contains: String + user_contains_nocase: String + user_not_contains: String + user_not_contains_nocase: String + user_starts_with: String + user_starts_with_nocase: String + user_not_starts_with: String + user_not_starts_with_nocase: String + user_ends_with: String + user_ends_with_nocase: String + user_not_ends_with: String + user_not_ends_with_nocase: String + user_: User_filter + mainEventHash: String + mainEventHash_not: String + mainEventHash_gt: String + mainEventHash_lt: String + mainEventHash_gte: String + mainEventHash_lte: String + mainEventHash_in: [String!] + mainEventHash_not_in: [String!] + mainEventHash_contains: String + mainEventHash_contains_nocase: String + mainEventHash_not_contains: String + mainEventHash_not_contains_nocase: String + mainEventHash_starts_with: String + mainEventHash_starts_with_nocase: String + mainEventHash_not_starts_with: String + mainEventHash_not_starts_with_nocase: String + mainEventHash_ends_with: String + mainEventHash_ends_with_nocase: String + mainEventHash_not_ends_with: String + mainEventHash_not_ends_with_nocase: String + mainEventHash_: SummerEvent_filter + protocol: String + protocol_not: String + protocol_gt: String + protocol_lt: String + protocol_gte: String + protocol_lte: String + protocol_in: [String!] + protocol_not_in: [String!] + protocol_contains: String + protocol_contains_nocase: String + protocol_not_contains: String + protocol_not_contains_nocase: String + protocol_starts_with: String + protocol_starts_with_nocase: String + protocol_not_starts_with: String + protocol_not_starts_with_nocase: String + protocol_ends_with: String + protocol_ends_with_nocase: String + protocol_not_ends_with: String + protocol_not_ends_with_nocase: String + marketId: String + marketId_not: String + marketId_gt: String + marketId_lt: String + marketId_gte: String + marketId_lte: String + marketId_in: [String!] + marketId_not_in: [String!] + marketId_contains: String + marketId_contains_nocase: String + marketId_not_contains: String + marketId_not_contains_nocase: String + marketId_starts_with: String + marketId_starts_with_nocase: String + marketId_not_starts_with: String + marketId_not_starts_with_nocase: String + marketId_ends_with: String + marketId_ends_with_nocase: String + marketId_not_ends_with: String + marketId_not_ends_with_nocase: String + position: String + position_not: String + position_gt: String + position_lt: String + position_gte: String + position_lte: String + position_in: [String!] + position_not_in: [String!] + position_contains: String + position_contains_nocase: String + position_not_contains: String + position_not_contains_nocase: String + position_starts_with: String + position_starts_with_nocase: String + position_not_starts_with: String + position_not_starts_with_nocase: String + position_ends_with: String + position_ends_with_nocase: String + position_not_ends_with: String + position_not_ends_with_nocase: String + position_: Position_filter + block: BigInt + block_not: BigInt + block_gt: BigInt + block_lt: BigInt + block_gte: BigInt + block_lte: BigInt + block_in: [BigInt!] + block_not_in: [BigInt!] + transactionHash: Bytes + transactionHash_not: Bytes + transactionHash_gt: Bytes + transactionHash_lt: Bytes + transactionHash_gte: Bytes + transactionHash_lte: Bytes + transactionHash_in: [Bytes!] + transactionHash_not_in: [Bytes!] + transactionHash_contains: Bytes + transactionHash_not_contains: Bytes + logIndex: BigInt + logIndex_not: BigInt + logIndex_gt: BigInt + logIndex_lt: BigInt + logIndex_gte: BigInt + logIndex_lte: BigInt + logIndex_in: [BigInt!] + logIndex_not_in: [BigInt!] + timestamp: BigInt + timestamp_not: BigInt + timestamp_gt: BigInt + timestamp_lt: BigInt + timestamp_gte: BigInt + timestamp_lte: BigInt + timestamp_in: [BigInt!] + timestamp_not_in: [BigInt!] + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [TriggerEvent_filter] + or: [TriggerEvent_filter] } enum TriggerEvent_orderBy { - id - eventType - trigger - trigger__id - trigger__commandAddress - trigger__triggerType - trigger__kind - trigger__triggerData - trigger__continuous - trigger__addedBlock - trigger__addedTransaction - trigger__addedLogIndex - trigger__addedTimestamp - trigger__removedBlock - trigger__removedTransaction - trigger__removedLogIndex - trigger__removedTimestamp - trigger__executedBlock - trigger__executedTransaction - trigger__executedLogIndex - trigger__executedTimestamp - trigger__version - trigger__protocol - trigger__marketId - trigger__operationName - account - account__id - account__address - account__type - account__vaultId - user - user__id - user__openPositions - mainEventHash - mainEventHash__id - mainEventHash__blockNumber - mainEventHash__timestamp - mainEventHash__txHash - mainEventHash__logIndex - mainEventHash__sender - mainEventHash__kind - mainEventHash__depositedUSD - mainEventHash__withdrawnUSD - mainEventHash__deltaUSD - mainEventHash__feePaidUSD - mainEventHash__protocol - mainEventHash__marketId - mainEventHash__debtBefore - mainEventHash__debtInUSDBefore - mainEventHash__debtAfter - mainEventHash__debtInUSDAfter - mainEventHash__collateralBefore - mainEventHash__collateralInUSDBefore - mainEventHash__collateralAfter - mainEventHash__collateralInUSDAfter - mainEventHash__supplyBefore - mainEventHash__supplyInUSDBefore - mainEventHash__supplyAfter - mainEventHash__supplyInUSDAfter - mainEventHash__netValueBefore - mainEventHash__netValueAfter - mainEventHash__collateralTokenPriceInUSD - mainEventHash__debtTokenPriceInUSD - mainEventHash__supplyTokenPriceInUSD - protocol - marketId - position - position__id - position__protocol - position__marketId - position__positionType - position__cumulativeDepositedUSD - position__cumulativeWithdrawnUSD - position__cumulativeDeltaUSD - position__cumulativeFeesUSD - position__debt - position__debtInUSD - position__collateral - position__collateralInUSD - position__supply - position__supplyInUSD - position__netValue - position___ajnaBucket - block - transactionHash - logIndex - timestamp + id + eventType + trigger + trigger__id + trigger__commandAddress + trigger__triggerType + trigger__kind + trigger__triggerData + trigger__continuous + trigger__addedBlock + trigger__addedTransaction + trigger__addedLogIndex + trigger__addedTimestamp + trigger__removedBlock + trigger__removedTransaction + trigger__removedLogIndex + trigger__removedTimestamp + trigger__executedBlock + trigger__executedTransaction + trigger__executedLogIndex + trigger__executedTimestamp + trigger__version + trigger__protocol + trigger__marketId + trigger__operationName + account + account__id + account__address + account__type + account__vaultId + user + user__id + user__openPositions + mainEventHash + mainEventHash__id + mainEventHash__blockNumber + mainEventHash__timestamp + mainEventHash__txHash + mainEventHash__logIndex + mainEventHash__sender + mainEventHash__kind + mainEventHash__depositedUSD + mainEventHash__withdrawnUSD + mainEventHash__deltaUSD + mainEventHash__feePaidUSD + mainEventHash__protocol + mainEventHash__marketId + mainEventHash__debtBefore + mainEventHash__debtInUSDBefore + mainEventHash__debtAfter + mainEventHash__debtInUSDAfter + mainEventHash__collateralBefore + mainEventHash__collateralInUSDBefore + mainEventHash__collateralAfter + mainEventHash__collateralInUSDAfter + mainEventHash__supplyBefore + mainEventHash__supplyInUSDBefore + mainEventHash__supplyAfter + mainEventHash__supplyInUSDAfter + mainEventHash__netValueBefore + mainEventHash__netValueAfter + mainEventHash__collateralTokenPriceInUSD + mainEventHash__debtTokenPriceInUSD + mainEventHash__supplyTokenPriceInUSD + protocol + marketId + position + position__id + position__protocol + position__marketId + position__positionType + position__cumulativeDepositedUSD + position__cumulativeWithdrawnUSD + position__cumulativeDeltaUSD + position__cumulativeFeesUSD + position__debt + position__debtInUSD + position__collateral + position__collateralInUSD + position__supply + position__supplyInUSD + position__netValue + position___ajnaBucket + block + transactionHash + logIndex + timestamp } type User { - """ msg.sender address """ - id: Bytes! - accounts(skip: Int = 0, first: Int = 100, orderBy: Account_orderBy, orderDirection: OrderDirection, where: Account_filter): [Account!]! - feePaids(skip: Int = 0, first: Int = 100, orderBy: FeePaid_orderBy, orderDirection: OrderDirection, where: FeePaid_filter): [FeePaid!]! - summerEvents(skip: Int = 0, first: Int = 100, orderBy: SummerEvent_orderBy, orderDirection: OrderDirection, where: SummerEvent_filter): [SummerEvent!]! - createPositionEvents(skip: Int = 0, first: Int = 100, orderBy: CreatePositionEvent_orderBy, orderDirection: OrderDirection, where: CreatePositionEvent_filter): [CreatePositionEvent!]! - automationEvents(skip: Int = 0, first: Int = 100, orderBy: TriggerEvent_orderBy, orderDirection: OrderDirection, where: TriggerEvent_filter): [TriggerEvent!]! - positions(skip: Int = 0, first: Int = 100, orderBy: Position_orderBy, orderDirection: OrderDirection, where: Position_filter): [Position!]! - swaps(skip: Int = 0, first: Int = 100, orderBy: AssetSwap_orderBy, orderDirection: OrderDirection, where: AssetSwap_filter): [AssetSwap!]! - openPositions: BigInt! + """ + msg.sender address + """ + id: Bytes! + accounts( + skip: Int = 0 + first: Int = 100 + orderBy: Account_orderBy + orderDirection: OrderDirection + where: Account_filter + ): [Account!]! + feePaids( + skip: Int = 0 + first: Int = 100 + orderBy: FeePaid_orderBy + orderDirection: OrderDirection + where: FeePaid_filter + ): [FeePaid!]! + summerEvents( + skip: Int = 0 + first: Int = 100 + orderBy: SummerEvent_orderBy + orderDirection: OrderDirection + where: SummerEvent_filter + ): [SummerEvent!]! + createPositionEvents( + skip: Int = 0 + first: Int = 100 + orderBy: CreatePositionEvent_orderBy + orderDirection: OrderDirection + where: CreatePositionEvent_filter + ): [CreatePositionEvent!]! + automationEvents( + skip: Int = 0 + first: Int = 100 + orderBy: TriggerEvent_orderBy + orderDirection: OrderDirection + where: TriggerEvent_filter + ): [TriggerEvent!]! + positions( + skip: Int = 0 + first: Int = 100 + orderBy: Position_orderBy + orderDirection: OrderDirection + where: Position_filter + ): [Position!]! + swaps( + skip: Int = 0 + first: Int = 100 + orderBy: AssetSwap_orderBy + orderDirection: OrderDirection + where: AssetSwap_filter + ): [AssetSwap!]! + openPositions: BigInt! } input User_filter { - id: Bytes - id_not: Bytes - id_gt: Bytes - id_lt: Bytes - id_gte: Bytes - id_lte: Bytes - id_in: [Bytes!] - id_not_in: [Bytes!] - id_contains: Bytes - id_not_contains: Bytes - accounts_: Account_filter - feePaids_: FeePaid_filter - summerEvents_: SummerEvent_filter - createPositionEvents_: CreatePositionEvent_filter - automationEvents_: TriggerEvent_filter - positions_: Position_filter - swaps_: AssetSwap_filter - openPositions: BigInt - openPositions_not: BigInt - openPositions_gt: BigInt - openPositions_lt: BigInt - openPositions_gte: BigInt - openPositions_lte: BigInt - openPositions_in: [BigInt!] - openPositions_not_in: [BigInt!] - - """Filter for the block changed event.""" - _change_block: BlockChangedFilter - and: [User_filter] - or: [User_filter] + id: Bytes + id_not: Bytes + id_gt: Bytes + id_lt: Bytes + id_gte: Bytes + id_lte: Bytes + id_in: [Bytes!] + id_not_in: [Bytes!] + id_contains: Bytes + id_not_contains: Bytes + accounts_: Account_filter + feePaids_: FeePaid_filter + summerEvents_: SummerEvent_filter + createPositionEvents_: CreatePositionEvent_filter + automationEvents_: TriggerEvent_filter + positions_: Position_filter + swaps_: AssetSwap_filter + openPositions: BigInt + openPositions_not: BigInt + openPositions_gt: BigInt + openPositions_lt: BigInt + openPositions_gte: BigInt + openPositions_lte: BigInt + openPositions_in: [BigInt!] + openPositions_not_in: [BigInt!] + + """ + Filter for the block changed event. + """ + _change_block: BlockChangedFilter + and: [User_filter] + or: [User_filter] } enum User_orderBy { - id - accounts - feePaids - summerEvents - createPositionEvents - automationEvents - positions - swaps - openPositions + id + accounts + feePaids + summerEvents + createPositionEvents + automationEvents + positions + swaps + openPositions } - diff --git a/packages/summer-events-subgraph/src/index.ts b/packages/summer-events-subgraph/src/index.ts index da38279959..f0768a44e8 100644 --- a/packages/summer-events-subgraph/src/index.ts +++ b/packages/summer-events-subgraph/src/index.ts @@ -34,11 +34,12 @@ export interface GetUsersPointsParams { endTimestamp: number // In seconds. } -export type ArrayElement = ArrayType[number] +type ArrayElement = ArrayType[number] export type User = ArrayElement export type Position = ArrayElement export type MigrationEvent = ArrayElement -export type RecentSwap = ArrayElement +export type RecentSwapInPosition = ArrayElement +export type RecentSwapInUser = ArrayElement export type UsersData = SummerPointsQuery['users'] export interface GetUsersPointsResult { From 937d4ac5522fa4abb3dc4eff7557c6d6e3a7223b Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Thu, 23 May 2024 11:25:23 +0200 Subject: [PATCH 11/37] fix: support weth for aavelike borrow (#287) --- .../helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts index 8fae171d03..eae3d2718b 100644 --- a/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts @@ -18,7 +18,7 @@ import { import { AllowedProtocolNames } from './AAVEv3LikeBuilderTypes' import { BigNumber } from 'bignumber.js' import { PRECISION_BI, UNCAPPED_SUPPLY } from '../../constants/AaveV3LikeConstants' -import { CommonTokenSymbols, IChainInfo, IToken } from '@summerfi/sdk-common/common' +import { IChainInfo, IToken } from '@summerfi/sdk-common/common' import { ICollateralInfo } from '@summerfi/sdk-common/protocols' import { ChainContractsProvider, GenericAbiMap } from '../../../utils/ChainContractProvider' import { IProtocolPluginContext } from '@summerfi/protocol-plugins-common' @@ -209,10 +209,6 @@ export abstract class AAVEv3LikeBaseProtocolPlugin< caps: { borrowCap }, data: { totalVariableDebt, totalStableDebt, variableBorrowRate }, } = asset - if (quoteToken.symbol === CommonTokenSymbols.WETH) { - // WETH can be used as collateral on AaveV3 but not borrowed. - return - } try { const RESERVE_FACTOR_TO_PERCENTAGE_DIVISOR = 10000n From e3927c256886772441378e475b822a412cb9090e Mon Sep 17 00:00:00 2001 From: Halaprix Date: Thu, 23 May 2024 13:44:26 +0200 Subject: [PATCH 12/37] feat: add migration points check (#288) --- .../update-rays-cron-function/src/index.ts | 221 +++++++++++++++++- .../src/point-accrual.ts | 5 +- .../queries/get-points.graphql | 3 + 3 files changed, 219 insertions(+), 10 deletions(-) diff --git a/background-jobs/update-rays-cron-function/src/index.ts b/background-jobs/update-rays-cron-function/src/index.ts index 030d3b60b7..7e57fc403b 100644 --- a/background-jobs/update-rays-cron-function/src/index.ts +++ b/background-jobs/update-rays-cron-function/src/index.ts @@ -1,21 +1,65 @@ import type { Context, EventBridgeEvent } from 'aws-lambda' import { Logger } from '@aws-lambda-powertools/logger' -import { getRaysDB } from '@summerfi/rays-db' +import { Database, getRaysDB } from '@summerfi/rays-db' import process from 'node:process' import { getSummerPointsSubgraphClient } from '@summerfi/summer-events-subgraph' import { ChainId } from '@summerfi/serverless-shared' -import { SummerPointsService } from './point-accrual' +import { PositionPoints, SummerPointsService } from './point-accrual' import { positionIdResolver } from './position-id-resolver' +import { Kysely } from 'kysely' const logger = new Logger({ serviceName: 'update-rays-cron-function' }) const LOCK_ID = 'update_points_lock' const LAST_RUN_ID = 'update_points_last_run' -const eligibilityConditionType = 'POSITION_OPEN_TIME' -const eligibilityConditionDescription = 'The position must be open for at least 30 days' -const eligibilityConditionMetadata = { - minDays: 30, +const FOURTEEN_DAYS_IN_MILLISECONDS = 14 * 24 * 60 * 60 * 1000 +const SIXTY_DAYS_IN_MILLISECONDS = 60 * 24 * 60 * 60 +const THIRTY_DAYS_IN_MILLISECONDS = 30 * 24 * 60 * 60 * 1000 + +enum EligibilityConditionType { + POSITION_OPEN_TIME = 'POSITION_OPEN_TIME', + POINTS_EXPIRED = 'POINTS_EXPIRED', + BECOME_SUMMER_USER = 'BECOME_SUMMER_USER', +} +type Eligibility = { + type: EligibilityConditionType + description: string + metadata: Record> +} + +const eligibilityConditions: Record = { + [EligibilityConditionType.POSITION_OPEN_TIME]: { + type: EligibilityConditionType.POSITION_OPEN_TIME, + description: 'The position must be open for at least 30 days', + metadata: { + minDays: 30, + }, + }, + [EligibilityConditionType.POINTS_EXPIRED]: { + type: EligibilityConditionType.POINTS_EXPIRED, + description: 'The points have expired', + metadata: {}, + }, + [EligibilityConditionType.BECOME_SUMMER_USER]: { + type: EligibilityConditionType.BECOME_SUMMER_USER, + description: 'Must use summer for at least 14 days with at least 500 USD', + metadata: { + minDays: 14, + minUsd: 500, + bonus: { + powerFeatureEnabled: 1000, + }, + possibleMultipliers: { + 3: { + requirements: 'Position open in first month', + }, + 2: { + requirements: 'Position open in second month', + }, + }, + }, + }, } export const handler = async ( @@ -127,6 +171,8 @@ export const handler = async ( const sortedPoints = points.sort((a, b) => a.positionId.localeCompare(b.positionId)) + await checkMigrationEligibility(db, sortedPoints) + await checkOpenedPositionEligibility(db, sortedPoints) // split points by 30 item chunks const chunkedPoints = [] for (let i = 0; i < sortedPoints.length; i += 30) { @@ -232,9 +278,9 @@ export const handler = async ( const eligibilityCondition = await db .insertInto('eligibilityCondition') .values({ - type: eligibilityConditionType, - description: eligibilityConditionDescription, - metadata: JSON.stringify(eligibilityConditionMetadata), + type: eligibilityConditions.POSITION_OPEN_TIME.type, + description: eligibilityConditions.POSITION_OPEN_TIME.description, + metadata: JSON.stringify(eligibilityConditions.POSITION_OPEN_TIME.metadata), dueDate: dueDate, }) .returningAll() @@ -411,3 +457,160 @@ export const handler = async ( } export default handler + +/** + * Checks the migration eligibility for point distributions. + * @param db - The database instance. + * @param positionPoints - The position points. + */ +async function checkMigrationEligibility(db: Kysely, positionPoints: PositionPoints) { + const existingPointDistributionsWithEligibilityCondition = await db + .selectFrom('pointsDistribution') + .where('positionId', '!=', null) + .leftJoin( + 'eligibilityCondition', + 'eligibilityCondition.id', + 'pointsDistribution.eligibilityConditionId', + ) + .leftJoin('position', 'position.id', 'pointsDistribution.positionId') + .selectAll() + .execute() + + if (existingPointDistributionsWithEligibilityCondition.length > 0) { + existingPointDistributionsWithEligibilityCondition.forEach(async (point) => { + if ( + point.dueDate && + point.type == eligibilityConditions.POSITION_OPEN_TIME.type && + point.dueDate < new Date() + ) { + const positionInSnapshot = positionPoints.find((p) => p.positionId === point.externalId) + if (!positionInSnapshot || positionInSnapshot.netValue <= 0) { + await db.deleteFrom('pointsDistribution').where('id', '=', point.id).execute() + await db + .deleteFrom('eligibilityCondition') + .where('id', '=', point.eligibilityConditionId) + .execute() + } else if (positionInSnapshot.netValue > 0) { + await db + .updateTable('pointsDistribution') + .set({ eligibilityConditionId: null }) + .where('id', '=', point.id) + .execute() + await db + .deleteFrom('eligibilityCondition') + .where('id', '=', point.eligibilityConditionId) + .execute() + } + } + }) + } +} + +/** + * This function checks the eligibility of opened positions. + * + * @param {Kysely} db - The Kysely database instance. + * @param {PositionPoints[]} positionPoints - An array of position points. + * + * The function performs the following steps: + * 1. Fetches all points distributions that have an associated eligibility condition but no associated position id. + * 2. For each user with such a points distribution: + * a. If the due date has not passed and the type of the eligibility condition is `BECOME_SUMMER_USER`: + * i. Fetches all positions of the user that are eligible for a check. A position is eligible if its net value is greater than or equal to 500, it was created before 14 days ago, and it belongs to the current user. + * ii. If there are no eligible positions, the function returns. + * iii. Otherwise, it fetches user points distributions of certain types. + * iv. Updates each of them by setting the `eligibilityConditionId` to `null` and multiplying the points by a multiplier that depends on when the oldest eligible position was created. + * b. If the due date has passed and the type of the eligibility condition is `BECOME_SUMMER_USER`, it deletes all points distributions and the eligibility condition associated with the user. + */ +async function checkOpenedPositionEligibility( + db: Kysely, + positionPoints: PositionPoints, +) { + // get all points distributions without an associated position id but with an eligibility condition + const existingUsersWithEligibilityCondition = await db + .selectFrom('pointsDistribution') + .where('eligibilityConditionId', '!=', null) + .where('positionId', '==', null) + .leftJoin( + 'eligibilityCondition', + 'eligibilityCondition.id', + 'pointsDistribution.eligibilityConditionId', + ) + .leftJoin('userAddress', 'userAddress.id', 'pointsDistribution.userAddressId') + .selectAll() + .execute() + + if (existingUsersWithEligibilityCondition.length > 0) { + existingUsersWithEligibilityCondition.forEach(async (user) => { + if ( + user.dueDate && + user.type == eligibilityConditions.BECOME_SUMMER_USER.type && + user.dueDate >= new Date() + ) { + // get all the positions of the user that are eligible for a check (exist in current points distribution) + const eligiblePositionsFromPointsAccrual = positionPoints + .filter( + (p) => + p.netValue >= 500 && + p.positionCreated * 1000 < Date.now() - FOURTEEN_DAYS_IN_MILLISECONDS, + ) + .filter((p) => p.user === user.address) + .sort((a, b) => a.positionCreated - b.positionCreated) + if (eligiblePositionsFromPointsAccrual.length == 0) { + return + } else { + const oldestEligiblePosition = eligiblePositionsFromPointsAccrual[0] + const becomeSummerUserMultiplier = getBecomeSummerUserMultiplier( + oldestEligiblePosition.positionCreated, + ) + + const pointsDistributions = await db + .selectFrom('pointsDistribution') + .where('userAddressId', '=', user.id) + .where((eb) => eb('type', '=', 'Snapshot_General').or('type', '=', 'Snapshot_Defi')) + .selectAll() + .execute() + pointsDistributions.forEach(async (pointsDistribution) => { + await db + .updateTable('pointsDistribution') + .set({ + eligibilityConditionId: null, + points: +pointsDistribution.points * becomeSummerUserMultiplier, + }) + .where('id', '=', pointsDistribution.id) + .execute() + }) + } + } else if ( + user.dueDate && + user.type == eligibilityConditions.BECOME_SUMMER_USER.type && + user.dueDate < new Date() + ) { + // if the due date is exceeded we delete all the points distribution and the eligibility condition + await db + .deleteFrom('pointsDistribution') + .where('eligibilityConditionId', '=', user.eligibilityConditionId) + .execute() + await db + .deleteFrom('eligibilityCondition') + .where('id', '=', user.eligibilityConditionId) + .execute() + } + }) + } +} + +/** + * Calculates the multiplier for becoming a summer user based on the position creation date. + * @param positionCreated The timestamp (in seconds) of when the position was created. + * @returns The multiplier value. + */ +function getBecomeSummerUserMultiplier(positionCreated: number) { + let multiplier = 1 + if (positionCreated * 1000 > Date.now() - THIRTY_DAYS_IN_MILLISECONDS) { + multiplier = 3 + } else if (positionCreated * 1000 > Date.now() - SIXTY_DAYS_IN_MILLISECONDS) { + multiplier = 2 + } + return multiplier +} diff --git a/background-jobs/update-rays-cron-function/src/point-accrual.ts b/background-jobs/update-rays-cron-function/src/point-accrual.ts index fbfbef340d..07a30b9c31 100644 --- a/background-jobs/update-rays-cron-function/src/point-accrual.ts +++ b/background-jobs/update-rays-cron-function/src/point-accrual.ts @@ -10,12 +10,13 @@ import { } from '@summerfi/summer-events-subgraph' import { Logger } from '@aws-lambda-powertools/logger' -type PositionPoints = { +export type PositionPoints = { positionId: string vaultId: number user: string protocol: string marketId: string + positionCreated: number points: { openPositionsPoints: number migrationPoints: number @@ -196,6 +197,7 @@ export class SummerPointsService { positionId: position.id, protocol: position.protocol, marketId: position.marketId, + positionCreated: position.firstEvent[0].timestamp, user: user.id, points: { openPositionsPoints: totalMultiplier * openPositionsPoints, @@ -264,6 +266,7 @@ export class SummerPointsService { vaultId: swap.position!.account.vaultId, protocol: swap.position!.protocol, marketId: swap.position!.marketId, + positionCreated: swap.position!.firstEvent[0].timestamp, user: user.id, points: { openPositionsPoints: 0, diff --git a/packages/summer-events-subgraph/queries/get-points.graphql b/packages/summer-events-subgraph/queries/get-points.graphql index 3c3970fb34..633b5c16ac 100644 --- a/packages/summer-events-subgraph/queries/get-points.graphql +++ b/packages/summer-events-subgraph/queries/get-points.graphql @@ -79,6 +79,9 @@ query SummerPoints( user { id } + firstEvent: summerEvents(first: 1, orderBy: timestamp, orderDirection: asc) { + timestamp + } } amountInUSD assetIn { From 2c8cfab6fcf48e4f83697d4c25e40885df855b00 Mon Sep 17 00:00:00 2001 From: Halaprix Date: Thu, 23 May 2024 17:02:03 +0200 Subject: [PATCH 13/37] fix: update sql operators (#291) --- background-jobs/update-rays-cron-function/src/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/background-jobs/update-rays-cron-function/src/index.ts b/background-jobs/update-rays-cron-function/src/index.ts index 7e57fc403b..a5b7d6fac6 100644 --- a/background-jobs/update-rays-cron-function/src/index.ts +++ b/background-jobs/update-rays-cron-function/src/index.ts @@ -466,7 +466,7 @@ export default handler async function checkMigrationEligibility(db: Kysely, positionPoints: PositionPoints) { const existingPointDistributionsWithEligibilityCondition = await db .selectFrom('pointsDistribution') - .where('positionId', '!=', null) + .where('positionId', '<>', null) .leftJoin( 'eligibilityCondition', 'eligibilityCondition.id', @@ -529,8 +529,8 @@ async function checkOpenedPositionEligibility( // get all points distributions without an associated position id but with an eligibility condition const existingUsersWithEligibilityCondition = await db .selectFrom('pointsDistribution') - .where('eligibilityConditionId', '!=', null) - .where('positionId', '==', null) + .where('eligibilityConditionId', '<>', null) + .where('positionId', '=', null) .leftJoin( 'eligibilityCondition', 'eligibilityCondition.id', From 9d643bc14a3b48c3370ed2988632dea3d8b40dd4 Mon Sep 17 00:00:00 2001 From: Piotr Witek <739075+piotrwitek@users.noreply.github.com> Date: Fri, 24 May 2024 08:43:57 +0200 Subject: [PATCH 14/37] Update npm packages build and publish npm packages (#285) - improved npm packages build scripts - updated viem dependencies to locked version to be the same across the sdk - added new re-exports - publish sdk npm packages - added missing exports in the sdk common package --- package.json | 2 +- packages/serverless-shared/package.json | 1 - pnpm-lock.yaml | 38 ++++++++++++------- sdk/sdk-client/bundle/package.json | 10 +++-- sdk/sdk-client/package.json | 2 +- .../src/protocol-plugins-reexport.ts | 4 ++ sdk/sdk-common/bundle/package.json | 7 ++-- sdk/sdk-common/package.json | 2 +- sdk/sdk-common/src/common/aliases/HexData.ts | 4 +- sdk/sdk-common/src/index.ts | 7 ++-- sdk/sdk-common/tsconfig.build.json | 3 +- 11 files changed, 50 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index 2af3bad0a4..b1da9a687f 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "dependencies": { "bignumber.js": "^9.1.2", "kysely": "^0.27.3", - "viem": "^2.9.19", + "viem": "2.9.19", "zod": "^3.22.4" } } diff --git a/packages/serverless-shared/package.json b/packages/serverless-shared/package.json index b44b739802..59c915a565 100644 --- a/packages/serverless-shared/package.json +++ b/packages/serverless-shared/package.json @@ -12,7 +12,6 @@ "lint:fix": "eslint . --fix" }, "dependencies": { - "viem": "^2.9.19", "zod": "^3.22.4" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3aa15a5834..2ad3669669 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,7 +15,7 @@ importers: specifier: ^0.27.3 version: 0.27.3 viem: - specifier: ^2.9.19 + specifier: 2.9.19 version: 2.9.19(typescript@5.4.5)(zod@3.22.4) zod: specifier: ^3.22.4 @@ -642,9 +642,6 @@ importers: packages/serverless-shared: dependencies: - viem: - specifier: ^2.9.19 - version: 2.10.8(typescript@5.4.5)(zod@3.22.4) zod: specifier: ^3.22.4 version: 3.22.4 @@ -734,7 +731,7 @@ importers: version: link:../triggers-shared viem: specifier: ^2.9.19 - version: 2.9.19(typescript@5.4.5)(zod@3.22.4) + version: 2.12.0(typescript@5.4.5)(zod@3.22.4) devDependencies: '@summerfi/eslint-config': specifier: workspace:* @@ -1205,12 +1202,24 @@ importers: '@trpc/client': specifier: 11.0.0-next-beta.264 version: 11.0.0-next-beta.264(@trpc/server@11.0.0-next-beta.264) + '@trpc/server': + specifier: 11.0.0-next-beta.264 + version: 11.0.0-next-beta.264 + abitype: + specifier: ^1.0.2 + version: 1.0.2(typescript@5.4.5)(zod@3.22.4) + bignumber.js: + specifier: ^9.1.2 + version: 9.1.2 superjson: specifier: ^1.13.3 version: 1.13.3 viem: - specifier: ^2.7.9 + specifier: 2.9.19 version: 2.9.19(typescript@5.4.5)(zod@3.22.4) + zod: + specifier: ^3.22.4 + version: 3.22.4 sdk/sdk-common: dependencies: @@ -1233,12 +1242,15 @@ importers: sdk/sdk-common/bundle: dependencies: + bignumber.js: + specifier: ^9.1.2 + version: 9.1.2 superjson: specifier: ^1.13.3 version: 1.13.3 - viem: - specifier: ^2.2.0 - version: 2.9.19(typescript@5.4.5)(zod@3.22.4) + zod: + specifier: ^3.22.4 + version: 3.22.4 sdk/sdk-e2e: devDependencies: @@ -1878,7 +1890,7 @@ importers: version: link:../../packages/triggers-shared viem: specifier: ^2.9.19 - version: 2.9.19(typescript@5.4.5)(zod@3.22.4) + version: 2.12.0(typescript@5.4.5)(zod@3.22.4) zod: specifier: ^3.22.4 version: 3.22.4 @@ -2032,7 +2044,7 @@ importers: version: 3.3.2 viem: specifier: ^2.9.19 - version: 2.9.19(typescript@5.4.5)(zod@3.22.4) + version: 2.12.0(typescript@5.4.5)(zod@3.22.4) zod: specifier: ^3.22.4 version: 3.22.4 @@ -17827,8 +17839,8 @@ packages: - zod dev: false - /viem@2.10.8(typescript@5.4.5)(zod@3.22.4): - resolution: {integrity: sha512-ttCXlDmjjcZ8M/eJezXFzDtHj+RFOjEQ3elmXnCC7suXo/y8CuIM1LrIoyUFk7LKIE5E+bzmWUErS4u/MQBtpQ==} + /viem@2.12.0(typescript@5.4.5)(zod@3.22.4): + resolution: {integrity: sha512-XBvORspE4x2/gfy7idH6IVFwkJiXirygFCU3lxUH6fttsj8zufLtgiokfvZF/LAZUEDvdxSgL08whSYgffM2fw==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: diff --git a/sdk/sdk-client/bundle/package.json b/sdk/sdk-client/bundle/package.json index 84b16fae5e..1118207a3f 100644 --- a/sdk/sdk-client/bundle/package.json +++ b/sdk/sdk-client/bundle/package.json @@ -1,13 +1,17 @@ { - "name": "@summer_fi/summerfi-sdk-client", - "version": "0.2.0", + "name": "summerfi-sdk-client", + "version": "0.2.6", "module": "dist/index.js", "types": "dist/index.d.ts", "packageManager": "yarn@1.22.21", "scripts": {}, "dependencies": { + "abitype": "^1.0.2", + "bignumber.js": "^9.1.2", "@trpc/client": "11.0.0-next-beta.264", + "@trpc/server": "11.0.0-next-beta.264", "superjson": "^1.13.3", - "viem": "^2.7.9" + "viem": "2.9.19", + "zod": "^3.22.4" } } diff --git a/sdk/sdk-client/package.json b/sdk/sdk-client/package.json index 1ab5fd6f3f..ccecf48276 100644 --- a/sdk/sdk-client/package.json +++ b/sdk/sdk-client/package.json @@ -17,7 +17,7 @@ "build": "tsc -b -v tsconfig.build.json", "lint": "eslint .", "lint:fix": "eslint . --fix", - "bundle:npm": "esbuild src/index.ts --platform=neutral --target=es2020 --conditions= --main-fields=main --bundle --sourcemap --outfile=bundle/dist/index.js --external:crypto --external:tls --external:https --external:net --external:http --external:stream --external:zlib --external:assert --keep-names && tsc --emitDeclarationOnly --outDir bundle/dist -p tsconfig.build.json", + "bundle:npm": "rm -rf bundle/dist bundle/tsconfig.build.tsbuildinfo && esbuild src/index.ts --platform=neutral --target=es2020 --conditions= --main-fields=main --bundle --sourcemap --outfile=bundle/dist/index.js --keep-names --external:crypto --external:tls --external:https --external:net --external:http --external:stream --external:zlib --external:assert --external:superjson --external:zod --external:bignumber.js --external:\"@trpc/client\" --external:abitype --external:viem && tsc --emitDeclarationOnly --outDir bundle/dist -p tsconfig.build.json", "publish:npm": "pnpm bundle:npm && cd bundle && npm publish && cd .." }, "dependencies": { diff --git a/sdk/sdk-client/src/protocol-plugins-reexport.ts b/sdk/sdk-client/src/protocol-plugins-reexport.ts index e6f12e80fe..bd29a635ed 100644 --- a/sdk/sdk-client/src/protocol-plugins-reexport.ts +++ b/sdk/sdk-client/src/protocol-plugins-reexport.ts @@ -2,24 +2,28 @@ export { MakerLendingPoolId, + type IMakerLendingPoolId, MakerPosition, MakerPositionId, isMakerLendingPoolId, } from '@summerfi/protocol-plugins/plugins/maker' export { SparkLendingPoolId, + type ISparkLendingPoolId, SparkPosition, SparkPositionId, isSparkLendingPoolId, } from '@summerfi/protocol-plugins/plugins/spark' export { AaveV3LendingPoolId, + type IAaveV3LendingPoolId, AaveV3Position, AaveV3PositionId, isAaveV3LendingPoolId, } from '@summerfi/protocol-plugins/plugins/aave-v3' export { MorphoLendingPoolId, + type IMorphoLendingPoolId, MorphoPosition, MorphoPositionId, isMorphoLendingPoolId, diff --git a/sdk/sdk-common/bundle/package.json b/sdk/sdk-common/bundle/package.json index 12b06a36c4..dcfa0b7513 100644 --- a/sdk/sdk-common/bundle/package.json +++ b/sdk/sdk-common/bundle/package.json @@ -1,13 +1,14 @@ { - "name": "@summer_fi/summerfi-sdk-common", - "version": "0.1.4", + "name": "summerfi-sdk-common", + "version": "0.2.5", "module": "dist/index.js", "types": "dist/index.d.ts", "packageManager": "yarn@1.22.21", "scripts": {}, "dependencies": { + "bignumber.js": "^9.1.2", "superjson": "^1.13.3", - "viem": "^2.2.0" + "zod": "^3.22.4" }, "devDependencies": {} } diff --git a/sdk/sdk-common/package.json b/sdk/sdk-common/package.json index 6a5588c357..f472962da6 100644 --- a/sdk/sdk-common/package.json +++ b/sdk/sdk-common/package.json @@ -22,7 +22,7 @@ "lint": "eslint .", "lint:fix": "eslint . --fix", "check-circular": "madge --circular --extensions ts ./src", - "bundle:npm": "esbuild src/index.ts --platform=neutral --target=es2020 --conditions= --main-fields=main --bundle --sourcemap --outfile=bundle/dist/index.js --keep-names && tsc --emitDeclarationOnly --outDir bundle/dist -p tsconfig.build.json", + "bundle:npm": "rm -rf bundle/dist bundle/tsconfig.build.tsbuildinfo && esbuild src/index.ts --platform=neutral --target=es2020 --conditions= --main-fields=main --bundle --sourcemap --outfile=bundle/dist/index.js --keep-names --external:superjson --external:zod --external:bignumber.js && tsc --emitDeclarationOnly --outDir bundle/dist -p tsconfig.build.json", "publish:npm": "pnpm bundle:npm && cd bundle && npm publish && cd .." }, "dependencies": { diff --git a/sdk/sdk-common/src/common/aliases/HexData.ts b/sdk/sdk-common/src/common/aliases/HexData.ts index c20ed0d549..88a5a2c2aa 100644 --- a/sdk/sdk-common/src/common/aliases/HexData.ts +++ b/sdk/sdk-common/src/common/aliases/HexData.ts @@ -1,3 +1 @@ -import { Hex } from 'viem' - -export type HexData = Hex +export type HexData = `0x${string}` diff --git a/sdk/sdk-common/src/index.ts b/sdk/sdk-common/src/index.ts index 36ac5e548a..ef32872afd 100644 --- a/sdk/sdk-common/src/index.ts +++ b/sdk/sdk-common/src/index.ts @@ -1,9 +1,10 @@ export * from './common' export * from './exchange' +export * from './oracle' export * from './orders' export * from './protocols' -export * from './simulation' -export * from './user' export * from './services' +export * from './simulation' +export * from './swap' export * from './tokens' -export * from './oracle' +export * from './user' diff --git a/sdk/sdk-common/tsconfig.build.json b/sdk/sdk-common/tsconfig.build.json index cd6ed31755..270d45a1e5 100644 --- a/sdk/sdk-common/tsconfig.build.json +++ b/sdk/sdk-common/tsconfig.build.json @@ -3,7 +3,8 @@ // include tests and use module paths in tests but build without tests "extends": "./tsconfig.json", "compilerOptions": { - "rootDir": "src" + "rootDir": "src", + "baseUrl": "." }, "include": ["src/**/*.ts"], "exclude": ["node_modules"] From 16ca1c3693e62546b1ab14748b59cd39666270f1 Mon Sep 17 00:00:00 2001 From: Halaprix Date: Fri, 24 May 2024 09:39:18 +0200 Subject: [PATCH 15/37] feat: Group and chunk user points for efficient processing (#292) This Pull Request introduces an enhancement to the way we handle user points in our system. Previously, we processed user points individually, which was not efficient when dealing with large volumes of data. In this PR, we have implemented a new approach where we first group the points by user. This ensures that all points for a specific user are processed together, improving the coherence of our data handling. Furthermore, we have introduced a chunking mechanism. The chunking mechanism divides the grouped points into chunks of 30 or more. The key aspect of this chunking mechanism is that it ensures all points for a user are in the same chunk. This means that the chunk size doesn't have to be strictly 30 but the first possible size above 30 that can accommodate all points for the last processed user. This new approach not only improves the efficiency of our data processing but also ensures that all points for a specific user are handled together, thereby maintaining user-specific context. Changes include: - Grouping points by user before processing - Dividing grouped points into chunks of size 30 or more - Ensuring all points for a user are in the same chunk - Adjusting chunk size to accommodate all points for the last processed user This PR is expected to significantly improve the efficiency and reliability of our user points handling process. --- .../update-rays-cron-function/src/index.ts | 41 ++++++++++++++++--- .../src/point-accrual.ts | 22 +++++++++- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/background-jobs/update-rays-cron-function/src/index.ts b/background-jobs/update-rays-cron-function/src/index.ts index a5b7d6fac6..b11316ed48 100644 --- a/background-jobs/update-rays-cron-function/src/index.ts +++ b/background-jobs/update-rays-cron-function/src/index.ts @@ -173,11 +173,9 @@ export const handler = async ( await checkMigrationEligibility(db, sortedPoints) await checkOpenedPositionEligibility(db, sortedPoints) - // split points by 30 item chunks - const chunkedPoints = [] - for (let i = 0; i < sortedPoints.length; i += 30) { - chunkedPoints.push(sortedPoints.slice(i, i + 30)) - } + + const chunkedPoints: PositionPoints[] = createChunksOfUserPointsDistributions(sortedPoints, 30) + for (let i = 0; i < chunkedPoints.length; i++) { logger.info(`Processing: Chunk ${i} of ${chunkedPoints.length}`) const chunk = chunkedPoints[i] @@ -458,6 +456,39 @@ export const handler = async ( export default handler +/** + * Creates chunks of user points distributions based on a given chunk length. + * + * @remarks This function is used to create chunks of user points distributions based on a given chunk length + * and the fact each points distributions per user can't be split between chunks. + * + * @param sortedPoints - An array of points sorted by user. + * @param chunkLength - The desired length of each chunk. + * @returns An array of chunks, where each chunk contains points for each user. + */ +function createChunksOfUserPointsDistributions(sortedPoints: PositionPoints, chunkLength: number) { + // Create a map where the keys are the users and the values are arrays of points for each user. + const pointsByUser = new Map() + for (const point of sortedPoints) { + const userPoints = pointsByUser.get(point.user) || [] + userPoints.push(point) + pointsByUser.set(point.user, userPoints) + } + const chunkedPoints: PositionPoints[] = [] + let currentChunk: PositionPoints = [] + for (const userPoints of pointsByUser.values()) { + if (currentChunk.length + userPoints.length >= chunkLength) { + chunkedPoints.push(currentChunk) + currentChunk = [] + } + currentChunk.push(...userPoints) + } + if (currentChunk.length > 0) { + chunkedPoints.push(currentChunk) + } + return chunkedPoints +} + /** * Checks the migration eligibility for point distributions. * @param db - The database instance. diff --git a/background-jobs/update-rays-cron-function/src/point-accrual.ts b/background-jobs/update-rays-cron-function/src/point-accrual.ts index 07a30b9c31..6068e2185c 100644 --- a/background-jobs/update-rays-cron-function/src/point-accrual.ts +++ b/background-jobs/update-rays-cron-function/src/point-accrual.ts @@ -9,7 +9,27 @@ import { UsersData, } from '@summerfi/summer-events-subgraph' import { Logger } from '@aws-lambda-powertools/logger' - +export type PositionPointsItem = { + positionId: string + vaultId: number + user: string + protocol: string + marketId: string + positionCreated: number + points: { + openPositionsPoints: number + migrationPoints: number + swapPoints: number + } + netValue: number + multipliers: { + protocolBoostMultiplier: number + swapMultiplier: number + timeOpenMultiplier: number + automationProtectionMultiplier: number + lazyVaultMultiplier: number + } +} export type PositionPoints = { positionId: string vaultId: number From d8fa7f2ca2fafce9381dea4c0aa8e7423a925437 Mon Sep 17 00:00:00 2001 From: Halaprix Date: Fri, 24 May 2024 11:59:46 +0200 Subject: [PATCH 16/37] feat: Implement atomic transactions in SummerPointsService using Kysely (#293) This Pull Request introduces an enhancement to the SummerPointsService by implementing atomic transactions using the Kysely library. This ensures that all database operations within a single transaction are treated as a single unit of work, thereby improving data consistency and reliability. The PR includes the use of Kysely's .transaction() method to start a new transaction. Within this transaction, all operations are performed, and if any operation fails, the entire transaction is rolled back, ensuring that the database remains in a consistent state. Changes include: Implementation of atomic transactions using Kysely's .transaction() method Ensuring all database operations within a transaction are treated as a single unit of work Rollback of entire transaction if any operation fails This PR is expected to enhance the reliability and consistency of data operations within the `SummerPointsService`. --- .../update-rays-cron-function/src/index.ts | 369 ++++++++++-------- 1 file changed, 197 insertions(+), 172 deletions(-) diff --git a/background-jobs/update-rays-cron-function/src/index.ts b/background-jobs/update-rays-cron-function/src/index.ts index b11316ed48..fe964dcc45 100644 --- a/background-jobs/update-rays-cron-function/src/index.ts +++ b/background-jobs/update-rays-cron-function/src/index.ts @@ -166,81 +166,68 @@ export const handler = async ( } const points = await pointAccuralService.accruePoints(startTimestamp, endTimestamp) - - logger.info(`Got: ${points.length} positions to update in the database`) - const sortedPoints = points.sort((a, b) => a.positionId.localeCompare(b.positionId)) await checkMigrationEligibility(db, sortedPoints) await checkOpenedPositionEligibility(db, sortedPoints) + await insertAllMissingUsers(sortedPoints, db) const chunkedPoints: PositionPoints[] = createChunksOfUserPointsDistributions(sortedPoints, 30) + await db.transaction().execute(async (transaction) => { + for (let i = 0; i < chunkedPoints.length; i++) { + logger.info(`Processing: Chunk ${i} of ${chunkedPoints.length}`) + const chunk = chunkedPoints[i] + const addressesForChunk = chunk.map((c) => c.user) + const positionsForChunk = chunk.map((c) => c.positionId) + + const userAddresses = await db + .selectFrom('userAddress') + .where('address', 'in', addressesForChunk) + .selectAll() + .execute() + const positions = await db + .selectFrom('position') + .where('externalId', 'in', positionsForChunk) + .selectAll() + .execute() - for (let i = 0; i < chunkedPoints.length; i++) { - logger.info(`Processing: Chunk ${i} of ${chunkedPoints.length}`) - const chunk = chunkedPoints[i] - const addressesForChunk = chunk.map((c) => c.user) - const positionsForChunk = chunk.map((c) => c.positionId) - - const userAddresses = await db - .selectFrom('userAddress') - .where('address', 'in', addressesForChunk) - .selectAll() - .execute() - const positions = await db - .selectFrom('position') - .where('externalId', 'in', positionsForChunk) - .selectAll() - .execute() - - const usersMultipliers = await db - .selectFrom('multiplier') - .innerJoin('userAddress', 'multiplier.userAddressId', 'userAddress.id') - .where('userAddress.address', 'in', addressesForChunk) - .select([ - 'multiplier.value', - 'multiplier.type', - 'multiplier.id', - 'multiplier.userAddressId', - 'multiplier.positionId', - ]) - .execute() - - const positionsMultipliers = await db - .selectFrom('multiplier') - .innerJoin('position', 'multiplier.positionId', 'position.id') - .where('position.externalId', 'in', positionsForChunk) - .select([ - 'multiplier.value', - 'multiplier.type', - 'multiplier.id', - 'multiplier.userAddressId', - 'multiplier.positionId', - ]) - .execute() - - await Promise.all( - chunk.map(async (record) => { - let userAddress = userAddresses.find((ua) => ua.address === record.user) + const usersMultipliers = await db + .selectFrom('multiplier') + .innerJoin('userAddress', 'multiplier.userAddressId', 'userAddress.id') + .where('userAddress.address', 'in', addressesForChunk) + .select([ + 'multiplier.value', + 'multiplier.type', + 'multiplier.id', + 'multiplier.userAddressId', + 'multiplier.positionId', + ]) + .execute() + + const positionsMultipliers = await db + .selectFrom('multiplier') + .innerJoin('position', 'multiplier.positionId', 'position.id') + .where('position.externalId', 'in', positionsForChunk) + .select([ + 'multiplier.value', + 'multiplier.type', + 'multiplier.id', + 'multiplier.userAddressId', + 'multiplier.positionId', + ]) + .execute() + for (const record of chunk) { + const userAddress = userAddresses.find((ua) => ua.address === record.user) if (!userAddress) { - const result = await db - .insertInto('blockchainUser') - .values({ category: null }) - .returning(['id']) - .executeTakeFirstOrThrow() - userAddress = await db - .insertInto('userAddress') - .values({ address: record.user, userId: result.id }) - .returningAll() - .executeTakeFirstOrThrow() + throw new Error('User address not found') } const positionId = positionIdResolver(record.positionId) let position = positions.find((p) => p.externalId === record.positionId) if (!position) { - position = await db + position = await transaction .insertInto('position') .values({ externalId: record.positionId, @@ -257,7 +244,7 @@ export const handler = async ( } if (record.points.openPositionsPoints > 0) { - await db + await transaction .insertInto('pointsDistribution') .values({ description: 'Points for opening a position', @@ -273,7 +260,7 @@ export const handler = async ( const dueDate = new Date(dueDateTimestamp) if (record.points.migrationPoints > 0) { - const eligibilityCondition = await db + const eligibilityCondition = await transaction .insertInto('eligibilityCondition') .values({ type: eligibilityConditions.POSITION_OPEN_TIME.type, @@ -284,7 +271,7 @@ export const handler = async ( .returningAll() .executeTakeFirstOrThrow() - await db + await transaction .insertInto('pointsDistribution') .values({ description: 'Points for migrations', @@ -297,7 +284,7 @@ export const handler = async ( } if (record.points.swapPoints > 0) { - await db + await transaction .insertInto('pointsDistribution') .values({ description: 'Points for swap', @@ -323,7 +310,7 @@ export const handler = async ( let procotolBoostMultiplier = userMultipliers.find((m) => m.type === 'PROTOCOL_BOOST') if (!procotolBoostMultiplier) { - procotolBoostMultiplier = await db + procotolBoostMultiplier = await transaction .insertInto('multiplier') .values({ userAddressId: userAddress.id, @@ -333,7 +320,7 @@ export const handler = async ( .returningAll() .executeTakeFirstOrThrow() } else { - await db + await transaction .updateTable('multiplier') .set('value', record.multipliers.protocolBoostMultiplier) .where('id', '=', procotolBoostMultiplier.id) @@ -343,7 +330,7 @@ export const handler = async ( let swapMultiplier = userMultipliers.find((m) => m.type === 'SWAP') if (!swapMultiplier) { - swapMultiplier = await db + swapMultiplier = await transaction .insertInto('multiplier') .values({ userAddressId: userAddress.id, @@ -353,7 +340,7 @@ export const handler = async ( .returningAll() .executeTakeFirstOrThrow() } else { - await db + await transaction .updateTable('multiplier') .set('value', record.multipliers.swapMultiplier) .where('id', '=', swapMultiplier.id) @@ -363,7 +350,7 @@ export const handler = async ( let timeOpenMultiplier = positionMultipliers.find((m) => m.type === 'TIME_OPEN') if (!timeOpenMultiplier) { - timeOpenMultiplier = await db + timeOpenMultiplier = await transaction .insertInto('multiplier') .values({ positionId: position.id, @@ -373,7 +360,7 @@ export const handler = async ( .returningAll() .executeTakeFirstOrThrow() } else { - await db + await transaction .updateTable('multiplier') .set('value', record.multipliers.timeOpenMultiplier) .where('id', '=', timeOpenMultiplier.id) @@ -385,7 +372,7 @@ export const handler = async ( ) if (!automationProtectionMultiplier) { - automationProtectionMultiplier = await db + automationProtectionMultiplier = await transaction .insertInto('multiplier') .values({ positionId: position.id, @@ -395,7 +382,7 @@ export const handler = async ( .returningAll() .executeTakeFirstOrThrow() } else { - await db + await transaction .updateTable('multiplier') .set('value', record.multipliers.automationProtectionMultiplier) .where('id', '=', automationProtectionMultiplier.id) @@ -404,7 +391,7 @@ export const handler = async ( const lazyVaultMultiplier = positionMultipliers.find((m) => m.type === 'LAZY_VAULT') if (!lazyVaultMultiplier) { - await db + await transaction .insertInto('multiplier') .values({ positionId: position.id, @@ -413,34 +400,34 @@ export const handler = async ( }) .execute() } else { - await db + await transaction .updateTable('multiplier') .set('value', record.multipliers.lazyVaultMultiplier) .where('id', '=', lazyVaultMultiplier.id) .execute() } - }), - ) - - logger.info(`Processed: Chunk ${i} of ${chunkedPoints.length}`) - } - - await db - .insertInto('updatePointsChangelog') - .values({ - endTimestamp: new Date(endTimestamp * 1000), - startTimestamp: new Date(startTimestamp * 1000), - metadata: { - positions: points.length, - }, - }) - .executeTakeFirstOrThrow() + } + // tutj + logger.info(`Processed: Chunk ${i} of ${chunkedPoints.length}`) + + await transaction + .insertInto('updatePointsChangelog') + .values({ + endTimestamp: new Date(endTimestamp * 1000), + startTimestamp: new Date(startTimestamp * 1000), + metadata: { + positions: points.length, + }, + }) + .executeTakeFirstOrThrow() - await db - .updateTable('updatePointsLastRun') - .set('lastTimestamp', new Date(endTimestamp * 1000)) - .where('id', '=', LAST_RUN_ID) - .execute() + await transaction + .updateTable('updatePointsLastRun') + .set('lastTimestamp', new Date(endTimestamp * 1000)) + .where('id', '=', LAST_RUN_ID) + .execute() + } + }) } catch (e) { logger.error('Failed to lock update points', { error: e }) return @@ -456,6 +443,40 @@ export const handler = async ( export default handler +/** + * Inserts missing users into the database. + * + * @param sortedPoints - The sorted points containing user information. + * @param db - The database instance. + * @returns A Promise that resolves when all missing users are inserted. + */ +async function insertAllMissingUsers(sortedPoints: PositionPoints, db: Kysely) { + const uniqueUsers = new Set(sortedPoints.map((p) => p.user)) + const userAddresses = await db + .selectFrom('userAddress') + .where('address', 'in', Array.from(uniqueUsers)) + .selectAll() + .execute() + + await db.transaction().execute(async (transaction) => { + for (const user of uniqueUsers) { + const userAddress = userAddresses.find((ua) => ua.address === user) + if (!userAddress) { + const result = await transaction + .insertInto('blockchainUser') + .values({ category: null }) + .returning(['id']) + .executeTakeFirstOrThrow() + await transaction + .insertInto('userAddress') + .values({ address: user, userId: result.id }) + .returningAll() + .executeTakeFirstOrThrow() + } + } + }) +} + /** * Creates chunks of user points distributions based on a given chunk length. * @@ -508,31 +529,33 @@ async function checkMigrationEligibility(db: Kysely, positionPoints: P .execute() if (existingPointDistributionsWithEligibilityCondition.length > 0) { - existingPointDistributionsWithEligibilityCondition.forEach(async (point) => { - if ( - point.dueDate && - point.type == eligibilityConditions.POSITION_OPEN_TIME.type && - point.dueDate < new Date() - ) { - const positionInSnapshot = positionPoints.find((p) => p.positionId === point.externalId) - if (!positionInSnapshot || positionInSnapshot.netValue <= 0) { - await db.deleteFrom('pointsDistribution').where('id', '=', point.id).execute() - await db - .deleteFrom('eligibilityCondition') - .where('id', '=', point.eligibilityConditionId) - .execute() - } else if (positionInSnapshot.netValue > 0) { - await db - .updateTable('pointsDistribution') - .set({ eligibilityConditionId: null }) - .where('id', '=', point.id) - .execute() - await db - .deleteFrom('eligibilityCondition') - .where('id', '=', point.eligibilityConditionId) - .execute() + await db.transaction().execute(async (transaction) => { + existingPointDistributionsWithEligibilityCondition.forEach(async (point) => { + if ( + point.dueDate && + point.type == eligibilityConditions.POSITION_OPEN_TIME.type && + point.dueDate < new Date() + ) { + const positionInSnapshot = positionPoints.find((p) => p.positionId === point.externalId) + if (!positionInSnapshot || positionInSnapshot.netValue <= 0) { + await transaction.deleteFrom('pointsDistribution').where('id', '=', point.id).execute() + await transaction + .deleteFrom('eligibilityCondition') + .where('id', '=', point.eligibilityConditionId) + .execute() + } else if (positionInSnapshot.netValue > 0) { + await transaction + .updateTable('pointsDistribution') + .set({ eligibilityConditionId: null }) + .where('id', '=', point.id) + .execute() + await transaction + .deleteFrom('eligibilityCondition') + .where('id', '=', point.eligibilityConditionId) + .execute() + } } - } + }) }) } } @@ -572,61 +595,63 @@ async function checkOpenedPositionEligibility( .execute() if (existingUsersWithEligibilityCondition.length > 0) { - existingUsersWithEligibilityCondition.forEach(async (user) => { - if ( - user.dueDate && - user.type == eligibilityConditions.BECOME_SUMMER_USER.type && - user.dueDate >= new Date() - ) { - // get all the positions of the user that are eligible for a check (exist in current points distribution) - const eligiblePositionsFromPointsAccrual = positionPoints - .filter( - (p) => - p.netValue >= 500 && - p.positionCreated * 1000 < Date.now() - FOURTEEN_DAYS_IN_MILLISECONDS, - ) - .filter((p) => p.user === user.address) - .sort((a, b) => a.positionCreated - b.positionCreated) - if (eligiblePositionsFromPointsAccrual.length == 0) { - return - } else { - const oldestEligiblePosition = eligiblePositionsFromPointsAccrual[0] - const becomeSummerUserMultiplier = getBecomeSummerUserMultiplier( - oldestEligiblePosition.positionCreated, - ) - - const pointsDistributions = await db - .selectFrom('pointsDistribution') - .where('userAddressId', '=', user.id) - .where((eb) => eb('type', '=', 'Snapshot_General').or('type', '=', 'Snapshot_Defi')) - .selectAll() - .execute() - pointsDistributions.forEach(async (pointsDistribution) => { - await db - .updateTable('pointsDistribution') - .set({ - eligibilityConditionId: null, - points: +pointsDistribution.points * becomeSummerUserMultiplier, - }) - .where('id', '=', pointsDistribution.id) + await db.transaction().execute(async (transaction) => { + existingUsersWithEligibilityCondition.forEach(async (user) => { + if ( + user.dueDate && + user.type == eligibilityConditions.BECOME_SUMMER_USER.type && + user.dueDate >= new Date() + ) { + // get all the positions of the user that are eligible for a check (exist in current points distribution) + const eligiblePositionsFromPointsAccrual = positionPoints + .filter( + (p) => + p.netValue >= 500 && + p.positionCreated * 1000 < Date.now() - FOURTEEN_DAYS_IN_MILLISECONDS, + ) + .filter((p) => p.user === user.address) + .sort((a, b) => a.positionCreated - b.positionCreated) + if (eligiblePositionsFromPointsAccrual.length == 0) { + return + } else { + const oldestEligiblePosition = eligiblePositionsFromPointsAccrual[0] + const becomeSummerUserMultiplier = getBecomeSummerUserMultiplier( + oldestEligiblePosition.positionCreated, + ) + + const pointsDistributions = await transaction + .selectFrom('pointsDistribution') + .where('userAddressId', '=', user.id) + .where((eb) => eb('type', '=', 'Snapshot_General').or('type', '=', 'Snapshot_Defi')) + .selectAll() .execute() - }) + pointsDistributions.forEach(async (pointsDistribution) => { + await transaction + .updateTable('pointsDistribution') + .set({ + eligibilityConditionId: null, + points: +pointsDistribution.points * becomeSummerUserMultiplier, + }) + .where('id', '=', pointsDistribution.id) + .execute() + }) + } + } else if ( + user.dueDate && + user.type == eligibilityConditions.BECOME_SUMMER_USER.type && + user.dueDate < new Date() + ) { + // if the due date is exceeded we delete all the points distribution and the eligibility condition + await transaction + .deleteFrom('pointsDistribution') + .where('eligibilityConditionId', '=', user.eligibilityConditionId) + .execute() + await transaction + .deleteFrom('eligibilityCondition') + .where('id', '=', user.eligibilityConditionId) + .execute() } - } else if ( - user.dueDate && - user.type == eligibilityConditions.BECOME_SUMMER_USER.type && - user.dueDate < new Date() - ) { - // if the due date is exceeded we delete all the points distribution and the eligibility condition - await db - .deleteFrom('pointsDistribution') - .where('eligibilityConditionId', '=', user.eligibilityConditionId) - .execute() - await db - .deleteFrom('eligibilityCondition') - .where('id', '=', user.eligibilityConditionId) - .execute() - } + }) }) } } From eb0c64617a1a0d31c96d215c7a46b16ebfc40a73 Mon Sep 17 00:00:00 2001 From: Halaprix Date: Fri, 24 May 2024 14:12:39 +0200 Subject: [PATCH 17/37] fix: fix eligibility checks (#296) --- .../update-rays-cron-function/src/index.ts | 54 ++++++++----------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/background-jobs/update-rays-cron-function/src/index.ts b/background-jobs/update-rays-cron-function/src/index.ts index fe964dcc45..caa745372b 100644 --- a/background-jobs/update-rays-cron-function/src/index.ts +++ b/background-jobs/update-rays-cron-function/src/index.ts @@ -518,27 +518,28 @@ function createChunksOfUserPointsDistributions(sortedPoints: PositionPoints, chu async function checkMigrationEligibility(db: Kysely, positionPoints: PositionPoints) { const existingPointDistributionsWithEligibilityCondition = await db .selectFrom('pointsDistribution') - .where('positionId', '<>', null) - .leftJoin( + .select(['pointsDistribution.id as pointsId']) + .innerJoin( 'eligibilityCondition', 'eligibilityCondition.id', 'pointsDistribution.eligibilityConditionId', ) - .leftJoin('position', 'position.id', 'pointsDistribution.positionId') + .innerJoin('position', 'position.id', 'pointsDistribution.positionId') + .where('eligibilityCondition.type', '=', eligibilityConditions.POSITION_OPEN_TIME.type) + .where('pointsDistribution.type', '=', 'MIGRATION') .selectAll() .execute() if (existingPointDistributionsWithEligibilityCondition.length > 0) { await db.transaction().execute(async (transaction) => { - existingPointDistributionsWithEligibilityCondition.forEach(async (point) => { - if ( - point.dueDate && - point.type == eligibilityConditions.POSITION_OPEN_TIME.type && - point.dueDate < new Date() - ) { + for (const point of existingPointDistributionsWithEligibilityCondition) { + if (point.dueDate && point.dueDate < new Date()) { const positionInSnapshot = positionPoints.find((p) => p.positionId === point.externalId) if (!positionInSnapshot || positionInSnapshot.netValue <= 0) { - await transaction.deleteFrom('pointsDistribution').where('id', '=', point.id).execute() + await transaction + .deleteFrom('pointsDistribution') + .where('id', '=', point.pointsId) + .execute() await transaction .deleteFrom('eligibilityCondition') .where('id', '=', point.eligibilityConditionId) @@ -547,7 +548,7 @@ async function checkMigrationEligibility(db: Kysely, positionPoints: P await transaction .updateTable('pointsDistribution') .set({ eligibilityConditionId: null }) - .where('id', '=', point.id) + .where('id', '=', point.pointsId) .execute() await transaction .deleteFrom('eligibilityCondition') @@ -555,7 +556,7 @@ async function checkMigrationEligibility(db: Kysely, positionPoints: P .execute() } } - }) + } }) } } @@ -583,26 +584,21 @@ async function checkOpenedPositionEligibility( // get all points distributions without an associated position id but with an eligibility condition const existingUsersWithEligibilityCondition = await db .selectFrom('pointsDistribution') - .where('eligibilityConditionId', '<>', null) - .where('positionId', '=', null) + .select(['pointsDistribution.id as pointsId']) .leftJoin( 'eligibilityCondition', 'eligibilityCondition.id', 'pointsDistribution.eligibilityConditionId', ) .leftJoin('userAddress', 'userAddress.id', 'pointsDistribution.userAddressId') + .where('eligibilityCondition.type', '=', eligibilityConditions.BECOME_SUMMER_USER.type) .selectAll() .execute() if (existingUsersWithEligibilityCondition.length > 0) { await db.transaction().execute(async (transaction) => { - existingUsersWithEligibilityCondition.forEach(async (user) => { - if ( - user.dueDate && - user.type == eligibilityConditions.BECOME_SUMMER_USER.type && - user.dueDate >= new Date() - ) { - // get all the positions of the user that are eligible for a check (exist in current points distribution) + for (const user of existingUsersWithEligibilityCondition) { + if (user.dueDate && user.dueDate >= new Date()) { const eligiblePositionsFromPointsAccrual = positionPoints .filter( (p) => @@ -618,14 +614,14 @@ async function checkOpenedPositionEligibility( const becomeSummerUserMultiplier = getBecomeSummerUserMultiplier( oldestEligiblePosition.positionCreated, ) - const pointsDistributions = await transaction .selectFrom('pointsDistribution') .where('userAddressId', '=', user.id) .where((eb) => eb('type', '=', 'Snapshot_General').or('type', '=', 'Snapshot_Defi')) .selectAll() .execute() - pointsDistributions.forEach(async (pointsDistribution) => { + for (const pointsDistribution of pointsDistributions) { + // update points distribution await transaction .updateTable('pointsDistribution') .set({ @@ -634,14 +630,10 @@ async function checkOpenedPositionEligibility( }) .where('id', '=', pointsDistribution.id) .execute() - }) + } } - } else if ( - user.dueDate && - user.type == eligibilityConditions.BECOME_SUMMER_USER.type && - user.dueDate < new Date() - ) { - // if the due date is exceeded we delete all the points distribution and the eligibility condition + } else if (user.dueDate && user.dueDate < new Date()) { + // removes all points distributions and eligibility condition - there is one due date for all retro snapshot distributions await transaction .deleteFrom('pointsDistribution') .where('eligibilityConditionId', '=', user.eligibilityConditionId) @@ -651,7 +643,7 @@ async function checkOpenedPositionEligibility( .where('id', '=', user.eligibilityConditionId) .execute() } - }) + } }) } } From b032f6616a25467a0dd51437be1205c7922e477c Mon Sep 17 00:00:00 2001 From: Halaprix Date: Fri, 24 May 2024 17:02:46 +0200 Subject: [PATCH 18/37] chore: cap max value for calcualtions at 10mln (#297) --- .../src/point-accrual.ts | 53 +++++++++---------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/background-jobs/update-rays-cron-function/src/point-accrual.ts b/background-jobs/update-rays-cron-function/src/point-accrual.ts index 6068e2185c..747194af8f 100644 --- a/background-jobs/update-rays-cron-function/src/point-accrual.ts +++ b/background-jobs/update-rays-cron-function/src/point-accrual.ts @@ -58,7 +58,7 @@ export type PositionPoints = { export class SummerPointsService { private SECONDS_PER_YEAR = 365 * 24 * 60 * 60 private SECONDS_PER_DAY = 86400 - private SECONDS_PER_HOUR = 3600 + private MIGRATION_POINTS_FRACTION = 0.2 private CORRELATED_SWAP_POINTS_FRACTION = 0.06 private UNCORRELATED_SWAP_POINTS_FRACTION = 0.2 @@ -67,6 +67,8 @@ export class SummerPointsService { private AUTOMATION_OPTIMISATION_MULTIPLIER = 1.5 private AUTOMATION_PROTECTION_MULTIPLIER = 1.1 + private NET_VALUE_CAP = 10000000 + /** * Creates an instance of SummerPointsService. * @param clients - An array of clients for fetching data from the summer points subgraph. @@ -115,6 +117,18 @@ export class SummerPointsService { return usdAmount <= x0 ? Math.pow(a * b, usdAmount) / frac : (c * Math.pow(d, usdAmount)) / frac } + /** + * Calculates the total points earned over a given period of time, based on the amount and period in seconds. + * @param _amount - The amount used to calculate the points. It will be capped at 10,000,000. + * @param periodInSeconds - The period of time in seconds. + * @returns The total points earned over the given period of time. + */ + private getPointsPerPeriodInSeconds(_amount: number, periodInSeconds: number) { + const amount = Math.min(_amount, this.NET_VALUE_CAP) + const pointsPerSecond = this.getPointsPerUsdPerSecond(amount) + return pointsPerSecond * periodInSeconds * amount + } + /** * Calculates the points per USD per second. * @@ -125,24 +139,6 @@ export class SummerPointsService { return this.getPointsPerUsdPerYear(usdAmount) / this.SECONDS_PER_YEAR } - /** - * Calculates the points per USD per day based on the given USD amount. - * @param usdAmount - The USD amount for which to calculate the points. - * @returns The points per USD per day. - */ - private getPointsPerUsdPerDay(usdAmount: number): number { - return this.getPointsPerUsdPerSecond(usdAmount) * this.SECONDS_PER_DAY - } - - /** - * Calculates the points per USD per hour based on the given USD amount. - * @param usdAmount - The USD amount for which to calculate the points. - * @returns The points per USD per hour. - */ - private getPointsPerUsdPerHour(usdAmount: number): number { - return this.getPointsPerUsdPerSecond(usdAmount) * this.SECONDS_PER_HOUR - } - /** * Calculates the swap multiplier based on the number of swaps. * @param swaps - An array of swap objects containing a timestamp. @@ -324,16 +320,13 @@ export class SummerPointsService { for (const event of position.summerEvents) { const timeDifference = event.timestamp - previousTimestamp - const pointsPerSecond = this.getPointsPerUsdPerSecond(event.netValueBefore) - openPositionsPoints += pointsPerSecond * timeDifference * event.netValueBefore + openPositionsPoints += this.getPointsPerPeriodInSeconds(event.netValueBefore, timeDifference) previousTimestamp = event.timestamp } // Calculate points for the time period after the last event const timeDifference = endTimestamp - previousTimestamp - const pointsPerSecond = this.getPointsPerUsdPerSecond(position.netValue) - - openPositionsPoints += pointsPerSecond * timeDifference * position.netValue + openPositionsPoints += this.getPointsPerPeriodInSeconds(position.netValue, timeDifference) return openPositionsPoints } @@ -348,8 +341,10 @@ export class SummerPointsService { getMigrationPoints(events: MigrationEvent[]): number { let migrationPoints = 0 for (const event of events) { - const pointsPerUsdPerYear = this.getPointsPerUsdPerYear(event.netValueAfter) - const pointsPerYear = pointsPerUsdPerYear * event.netValueAfter + const pointsPerYear = this.getPointsPerPeriodInSeconds( + event.netValueAfter, + this.SECONDS_PER_YEAR, + ) migrationPoints += pointsPerYear * this.MIGRATION_POINTS_FRACTION } @@ -366,8 +361,10 @@ export class SummerPointsService { getSwapPoints(swaps: RecentSwapInPosition[] | RecentSwapInUser[]): number { let points = 0 for (const swap of swaps) { - const pointsPerUsdPerYear = this.getPointsPerUsdPerYear(swap.amountInUSD) - const pointsPerYear = pointsPerUsdPerYear * swap.amountInUSD + const pointsPerYear = this.getPointsPerPeriodInSeconds( + swap.amountInUSD, + this.SECONDS_PER_YEAR, + ) const isCorrelatedAsset = this.isCorrelatedAsset(swap.assetIn.symbol, swap.assetOut.symbol) const fraction = isCorrelatedAsset ? this.CORRELATED_SWAP_POINTS_FRACTION From d5a93afc3d917fd447197492e32e3f9966b718f2 Mon Sep 17 00:00:00 2001 From: Piotr Witek <739075+piotrwitek@users.noreply.github.com> Date: Mon, 27 May 2024 07:04:34 +0200 Subject: [PATCH 19/37] Added new SDK stack (#300) Added new SDK stack deployment: - new stack definition that is run with "sst:deploy:sdk:staging" or "sst:deploy:sdk:prod" - new github actions that is run only manually from the selected branch - sdk will not deploy automatically from now on, only manually --- .github/workflows/deploy-sdk-production.yaml | 75 +++++++++++++++++++ .github/workflows/deploy-sdk-staging.yaml | 76 ++++++++++++++++++++ package.json | 7 +- sst.config.ts | 31 +++++--- stacks/sdk-stack.ts | 18 +++++ stacks/sdk.ts | 2 +- stacks/summer-stack.ts | 2 - 7 files changed, 198 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/deploy-sdk-production.yaml create mode 100644 .github/workflows/deploy-sdk-staging.yaml create mode 100644 stacks/sdk-stack.ts diff --git a/.github/workflows/deploy-sdk-production.yaml b/.github/workflows/deploy-sdk-production.yaml new file mode 100644 index 0000000000..a542502d1a --- /dev/null +++ b/.github/workflows/deploy-sdk-production.yaml @@ -0,0 +1,75 @@ +name: 'Deploy SDK Production' + +on: + workflow_dispatch: + +permissions: + id-token: write # This is required for requesting the JWT + contents: read # This is required for actions/checkout +jobs: + deploy: + name: Build & Deploy SDK to production using SST + environment: production + runs-on: ubuntu-latest + env: + ONE_INCH_API_KEY: ${{ secrets.ONE_INCH_API_KEY }} + ONE_INCH_API_VERSION: ${{ secrets.ONE_INCH_API_VERSION }} + ONE_INCH_API_URL: ${{ secrets.ONE_INCH_API_URL }} + ONE_INCH_ALLOWED_SWAP_PROTOCOLS: ${{ secrets.ONE_INCH_ALLOWED_SWAP_PROTOCOLS }} + ONE_INCH_SWAP_CHAIN_IDS: ${{ secrets.ONE_INCH_SWAP_CHAIN_IDS }} + ONE_INCH_API_SPOT_URL: ${{ secrets.ONE_INCH_API_SPOT_URL }} + ONE_INCH_API_SPOT_VERSION: ${{ secrets.ONE_INCH_API_SPOT_VERSION }} + ONE_INCH_API_SPOT_KEY: ${{ secrets.ONE_INCH_API_SPOT_KEY }} + MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }} + SUBGRAPH_BASE: ${{ secrets.SUBGRAPH_BASE }} + RPC_GATEWAY: ${{ secrets.RPC_GATEWAY }} + DEBANK_API_KEY: ${{ secrets.DEBANK_API_KEY }} + DEBANK_API_URL: ${{ secrets.PROD_DEBANK_API_URL }} + POWERTOOLS_LOG_LEVEL: ${{ vars.POWERTOOLS_LOG_LEVEL }} + REDIS_CACHE_URL: ${{ secrets.REDIS_CACHE_URL }} + REDIS_CACHE_USER: ${{ secrets.REDIS_CACHE_USER }} + REDIS_CACHE_PASSWORD: ${{ secrets.REDIS_CACHE_PASSWORD }} + VPC_ID: ${{ secrets.VPC_ID }} + SECURITY_GROUP_ID: ${{ secrets.SECURITY_GROUP_ID }} + RAYS_DB_WRITE_CONNECTION_STRING: ${{ secrets.RAYS_DB_WRITE_CONNECTION_STRING }} + RAYS_DB_READ_CONNECTION_STRING: ${{ secrets.RAYS_DB_READ_CONNECTION_STRING }} + steps: + - name: Git clone the repository + uses: actions/checkout@v3 + + - name: Cache turbo build setup + uses: actions/cache@v3 + with: + path: .turbo + key: ${{ runner.os }}-turbo-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-turbo- + + - uses: pnpm/action-setup@v2.0.1 + with: + version: 8.14.1 + + - name: Setup Node.js environment + uses: actions/setup-node@v3 + with: + node-version: 20 + cache: 'pnpm' + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE }} + aws-region: ${{ secrets.AWS_REGION }} + + - name: Install dependencies + run: pnpm install + + - name: Prebuild + run: pnpm prebuild + + - name: Build + run: pnpm build + + - name: Deploy app + run: | + pnpm run sst:deploy:sdk:prod diff --git a/.github/workflows/deploy-sdk-staging.yaml b/.github/workflows/deploy-sdk-staging.yaml new file mode 100644 index 0000000000..4d7b2c64b4 --- /dev/null +++ b/.github/workflows/deploy-sdk-staging.yaml @@ -0,0 +1,76 @@ +name: 'Deploy SDK Staging' + +on: + workflow_dispatch: + +permissions: + id-token: write # This is required for requesting the JWT + contents: read # This is required for actions/checkout +jobs: + deploy: + name: Build & Deploy SDK to staging using SST + environment: staging + runs-on: ubuntu-latest + env: + ONE_INCH_API_KEY: ${{ secrets.ONE_INCH_API_KEY }} + ONE_INCH_API_VERSION: ${{ secrets.ONE_INCH_API_VERSION }} + ONE_INCH_API_URL: ${{ secrets.ONE_INCH_API_URL }} + ONE_INCH_ALLOWED_SWAP_PROTOCOLS: ${{ secrets.ONE_INCH_ALLOWED_SWAP_PROTOCOLS }} + ONE_INCH_SWAP_CHAIN_IDS: ${{ secrets.ONE_INCH_SWAP_CHAIN_IDS }} + ONE_INCH_API_SPOT_URL: ${{ secrets.ONE_INCH_API_SPOT_URL }} + ONE_INCH_API_SPOT_VERSION: ${{ secrets.ONE_INCH_API_SPOT_VERSION }} + ONE_INCH_API_SPOT_KEY: ${{ secrets.ONE_INCH_API_SPOT_KEY }} + MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }} + SUBGRAPH_BASE: ${{ secrets.SUBGRAPH_BASE }} + RPC_GATEWAY: ${{ secrets.RPC_GATEWAY }} + DEBANK_API_KEY: ${{ secrets.DEBANK_API_KEY }} + DEBANK_API_URL: ${{ secrets.STAGING_DEBANK_API_URL }} + POWERTOOLS_LOG_LEVEL: ${{ vars.POWERTOOLS_LOG_LEVEL }} + REDIS_CACHE_URL: ${{ secrets.REDIS_CACHE_URL }} + REDIS_CACHE_USER: ${{ secrets.REDIS_CACHE_USER }} + REDIS_CACHE_PASSWORD: ${{ secrets.REDIS_CACHE_PASSWORD }} + VPC_ID: ${{ secrets.VPC_ID }} + SECURITY_GROUP_ID: ${{ secrets.SECURITY_GROUP_ID }} + RAYS_DB_WRITE_CONNECTION_STRING: ${{ secrets.RAYS_DB_WRITE_CONNECTION_STRING }} + RAYS_DB_READ_CONNECTION_STRING: ${{ secrets.RAYS_DB_READ_CONNECTION_STRING }} + steps: + - name: Git clone the repository + uses: actions/checkout@v3 + + - name: Cache turbo build setup + uses: actions/cache@v3 + with: + path: .turbo + key: ${{ runner.os }}-turbo-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-turbo- + + - uses: pnpm/action-setup@v2.0.1 + with: + version: 8.14.1 + + - name: Setup Node.js environment + uses: actions/setup-node@v3 + with: + node-version: 20 + cache: 'pnpm' + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE }} + # role-duration-seconds: 14390 #adjust as needed for your build time + aws-region: ${{ secrets.AWS_REGION }} + + - name: Install dependencies + run: pnpm install + + - name: Prebuild + run: pnpm prebuild + + - name: Build + run: pnpm build + + - name: Deploy app + run: | + pnpm run sst:deploy:sdk:staging diff --git a/package.json b/package.json index b1da9a687f..2ce25468bf 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,11 @@ "sst:dev": "sst dev", "sst:build": "sst build", "sst:deploy:dev": "sst deploy", - "sst:deploy:staging": "sst deploy --stage staging", - "sst:deploy:prod": "sst deploy --stage production", + "sst:deploy:staging": "sst deploy --stage staging --app summerfi-stack", + "sst:deploy:prod": "sst deploy --stage production --app summerfi-stack", + "sst:dev:sdk": "sst dev --app sdk", + "sst:deploy:sdk:staging": "sst deploy --stage staging --app sdk", + "sst:deploy:sdk:prod": "sst deploy --stage production --app sdk", "remove": "sst remove", "console": "sst console", "graph": "pnpm dlx nx graph", diff --git a/sst.config.ts b/sst.config.ts index 4bcda8ce6a..9d6c7350a2 100644 --- a/sst.config.ts +++ b/sst.config.ts @@ -1,10 +1,17 @@ import { SSTConfig } from 'sst' import { API } from './stacks/summer-stack' import { ExternalAPI } from './stacks/partners-stack' +import { SdkAPI } from './stacks/sdk-stack' import { $, chalk, echo } from 'zx' const availableStage = ['dev', 'feature', 'staging', 'production'] +enum App { + SummerfiStack = 'summerfi-stack', + Sdk = 'sdk', +} +const availableApps: string[] = [App.SummerfiStack, App.Sdk] + const getCurrentBranch = async () => { const { stdout: currentBranch } = await $`git branch --show-current` return currentBranch.trim() @@ -81,6 +88,9 @@ const runDockerCompose = async () => { export const sstConfig: SSTConfig = { async config(_input) { + // read app from cli input + const { app } = _input as { app?: string } + const currentBranch = await getCurrentBranch() const commitsToFetch = await getCommitsToFetch(currentBranch) if (commitsToFetch === null) { @@ -133,11 +143,7 @@ export const sstConfig: SSTConfig = { throw new Error('Please specify stage or set SST_USER env variable') } - if ( - _input.stage && - !availableStage.includes(_input.stage) && - !_input.stage.startsWith('dev-') - ) { + if (_input.stage && !availableStage.includes(_input.stage)) { throw new Error('Invalid stage, use one of: ' + availableStage.join(', ')) } @@ -160,8 +166,12 @@ export const sstConfig: SSTConfig = { } } + if (!app || availableApps.includes(app) === false) { + throw new Error('Invalid --app argument, use one of: ' + availableApps.join(', ')) + } + return { - name: `summerfi-stack`, + name: app, region: `${process.env.AWS_REGION}`, profile: `${process.env.AWS_PROFILE}`, stage: stage, @@ -174,8 +184,13 @@ export const sstConfig: SSTConfig = { app.setDefaultRemovalPolicy('retain') } echo`\n` - app.stack(API) - app.stack(ExternalAPI) + if (app.name === App.SummerfiStack) { + app.stack(API) + app.stack(ExternalAPI) + } + if (app.name === App.Sdk) { + app.stack(SdkAPI) + } }, } diff --git a/stacks/sdk-stack.ts b/stacks/sdk-stack.ts new file mode 100644 index 0000000000..82af50a712 --- /dev/null +++ b/stacks/sdk-stack.ts @@ -0,0 +1,18 @@ +import { Api, StackContext } from 'sst/constructs' +import { addSdkConfig } from './sdk' + +export function SdkAPI(stackContext: StackContext) { + const { stack } = stackContext + const api = new Api(stack, 'sdk', { + defaults: { + function: {}, + }, + routes: {}, + }) + + addSdkConfig(stackContext, api) + + stack.addOutputs({ + RouterEndpoint: api.url, + }) +} diff --git a/stacks/sdk.ts b/stacks/sdk.ts index 09758a36c9..0f130453f6 100644 --- a/stacks/sdk.ts +++ b/stacks/sdk.ts @@ -17,7 +17,7 @@ const { RPC_GATEWAY, } = process.env -export function addSdkConfig({ stack, api }: StackContext & { api: Api }) { +export function addSdkConfig({ stack }: StackContext, api: Api) { if ( !ONE_INCH_API_KEY || !ONE_INCH_API_VERSION || diff --git a/stacks/summer-stack.ts b/stacks/summer-stack.ts index c4da629821..6e3640d259 100644 --- a/stacks/summer-stack.ts +++ b/stacks/summer-stack.ts @@ -1,6 +1,5 @@ import { Api, StackContext } from 'sst/constructs' import { addTriggersConfig } from './triggers' -import { addSdkConfig } from './sdk' import { addMigrationsConfig } from './migrations' import { addPortfolioConfig } from './portfolio' import { addMorpho } from './morpho' @@ -41,7 +40,6 @@ export function API(stackContext: StackContext) { } addTriggersConfig(summerContext) - addSdkConfig(summerContext) addMigrationsConfig(summerContext) addPortfolioConfig(summerContext) addMorpho(summerContext) From 33b422b525d16de66bb5f559cac248cf237604ec Mon Sep 17 00:00:00 2001 From: Piotr Witek <739075+piotrwitek@users.noreply.github.com> Date: Mon, 27 May 2024 10:45:57 +0200 Subject: [PATCH 20/37] Add missing package scripts (#302) This pull request adds the missing package scripts to the project. The scripts "sst:dev", "sst:build", "sst:deploy:dev", "sst:dev:sdk", "sst:build:sdk", "sst:deploy:sdk:staging", and "sst:deploy:sdk:prod" have been added to the package.json file. This will allow for easier development, building, and deployment of the project and its SDK. --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 2ce25468bf..c6b9584558 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,13 @@ "check-circular": "turbo run check-circular --cache-dir=.turbo", "cicheck": "turbo run cicheck --cache-dir=.turbo && pnpm run coverage:total", "cicheck:dev": "turbo run cicheck --cache-dir=.turbo --output-logs=new-only --concurrency=100% --continue", - "sst:dev": "sst dev", - "sst:build": "sst build", - "sst:deploy:dev": "sst deploy", + "sst:dev": "sst dev --app summerfi-stack", + "sst:build": "sst build --app summerfi-stack", + "sst:deploy:dev": "sst deploy --app summerfi-stack", "sst:deploy:staging": "sst deploy --stage staging --app summerfi-stack", "sst:deploy:prod": "sst deploy --stage production --app summerfi-stack", "sst:dev:sdk": "sst dev --app sdk", + "sst:build:sdk": "sst build --app sdk", "sst:deploy:sdk:staging": "sst deploy --stage staging --app sdk", "sst:deploy:sdk:prod": "sst deploy --stage production --app sdk", "remove": "sst remove", From 25861b19a1c666e2471d8858df4c8df190c0347d Mon Sep 17 00:00:00 2001 From: Halaprix Date: Mon, 27 May 2024 12:32:55 +0200 Subject: [PATCH 21/37] feat: add `rays-leaderboard` endpoint and db migration (#303) - add `leaderboard` view to rays db - add pagination enabled leaderboard endpoint to fetch users with number of total accrued points --- packages/rays-db/src/database-types.ts | 6 ++ .../src/migrations/003_leaderboard.mts | 32 +++++++++++ packages/serverless-shared/src/validators.ts | 11 ++++ pnpm-lock.yaml | 48 ++++++++++++++++ stacks/rays.ts | 22 ++++++++ .../.eslintrc.cjs | 6 ++ .../jest.config.js | 15 +++++ .../package.json | 28 ++++++++++ .../src/index.ts | 56 +++++++++++++++++++ .../sst-env.d.ts | 1 + .../tsconfig.json | 9 +++ 11 files changed, 234 insertions(+) create mode 100644 packages/rays-db/src/migrations/003_leaderboard.mts create mode 100644 summerfi-api/get-rays-leaderboard-function/.eslintrc.cjs create mode 100644 summerfi-api/get-rays-leaderboard-function/jest.config.js create mode 100644 summerfi-api/get-rays-leaderboard-function/package.json create mode 100644 summerfi-api/get-rays-leaderboard-function/src/index.ts create mode 100644 summerfi-api/get-rays-leaderboard-function/sst-env.d.ts create mode 100644 summerfi-api/get-rays-leaderboard-function/tsconfig.json diff --git a/packages/rays-db/src/database-types.ts b/packages/rays-db/src/database-types.ts index 629510b00e..04d20befed 100644 --- a/packages/rays-db/src/database-types.ts +++ b/packages/rays-db/src/database-types.ts @@ -44,6 +44,11 @@ export interface EligibilityCondition { updatedAt: Generated } +export interface Leaderboard { + totalPoints: Numeric | null + userAddress: string | null +} + export interface Multiplier { createdAt: Generated description: string | null @@ -111,6 +116,7 @@ export interface UserAddress { export interface Database { blockchainUser: BlockchainUser eligibilityCondition: EligibilityCondition + leaderboard: Leaderboard multiplier: Multiplier pointsDistribution: PointsDistribution position: Position diff --git a/packages/rays-db/src/migrations/003_leaderboard.mts b/packages/rays-db/src/migrations/003_leaderboard.mts new file mode 100644 index 0000000000..4cef23a745 --- /dev/null +++ b/packages/rays-db/src/migrations/003_leaderboard.mts @@ -0,0 +1,32 @@ +import { Kysely, sql } from 'kysely' + +export async function up(db: Kysely) { + await sql` + CREATE VIEW leaderboard AS + SELECT + ua.address AS user_address, + COALESCE(SUM(cp.total_points), 0) AS total_points + FROM + user_address ua + LEFT JOIN + ( + SELECT + COALESCE(p.user_address_id, pd.user_address_id) AS user_address_id, + SUM(pd.points) AS total_points + FROM + points_distribution pd + LEFT JOIN + position p ON pd.position_id = p.id + GROUP BY + COALESCE(p.user_address_id, pd.user_address_id) + ) AS cp ON ua.id = cp.user_address_id + GROUP BY + ua.address; + `.execute(db) +} + +export async function down(db: Kysely) { + await sql` + DROP VIEW leaderboard; + `.execute(db) +} \ No newline at end of file diff --git a/packages/serverless-shared/src/validators.ts b/packages/serverless-shared/src/validators.ts index 1118711b1b..1896ab1062 100644 --- a/packages/serverless-shared/src/validators.ts +++ b/packages/serverless-shared/src/validators.ts @@ -104,3 +104,14 @@ export const percentageSchema = bigIntSchema.refine( export type LTV = z.infer export type Percentage = z.infer + +export const numberSchema = z + .string() + .refine((value) => !isNaN(Number(value)) && Number.isInteger(Number(value)), { + params: { + code: 'not-number', + }, + message: 'Must be a number without decimals', + }) + .transform((value) => Number(value)) + .or(z.number().int()) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2ad3669669..0cb80056fe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1862,6 +1862,52 @@ importers: specifier: ^29.7.0 version: 29.7.0(@types/node@20.12.7) + summerfi-api/get-rays-leaderboard-function: + dependencies: + '@aws-lambda-powertools/logger': + specifier: ^2.0.2 + version: 2.0.4 + '@aws-lambda-powertools/metrics': + specifier: ^2.0.2 + version: 2.0.4 + '@aws-lambda-powertools/tracer': + specifier: ^2.0.2 + version: 2.0.4 + '@summerfi/abstractions': + specifier: workspace:* + version: link:../../packages/abstractions + '@summerfi/rays-db': + specifier: workspace:* + version: link:../../packages/rays-db + '@summerfi/serverless-shared': + specifier: workspace:* + version: link:../../packages/serverless-shared + kysely: + specifier: ^0.27.3 + version: 0.27.3 + node-fetch: + specifier: ^3.3.2 + version: 3.3.2 + zod: + specifier: ^3.22.4 + version: 3.22.4 + devDependencies: + '@summerfi/eslint-config': + specifier: workspace:* + version: link:../../packages/eslint-config + '@summerfi/typescript-config': + specifier: workspace:* + version: link:../../packages/typescript-config + '@types/node': + specifier: ^20.11.5 + version: 20.12.7 + eslint: + specifier: ^8.56.0 + version: 8.57.0 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@20.12.7) + summerfi-api/get-triggers-function: dependencies: '@aws-lambda-powertools/logger': @@ -11936,6 +11982,7 @@ packages: is-hex-prefixed: 1.0.0 strip-hex-prefix: 1.0.0 dev: true + bundledDependencies: false /events@1.1.1: resolution: {integrity: sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==} @@ -12526,6 +12573,7 @@ packages: /glob@5.0.15: resolution: {integrity: sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==} + deprecated: Glob versions prior to v9 are no longer supported dependencies: inflight: 1.0.6 inherits: 2.0.4 diff --git a/stacks/rays.ts b/stacks/rays.ts index 607ad7218b..90526e0b56 100644 --- a/stacks/rays.ts +++ b/stacks/rays.ts @@ -31,6 +31,22 @@ export function addRaysConfig({ stack, api, vpc, app }: SummerStackContext) { }), } + const raysLeaderBoardFunctionProps: FunctionProps = { + handler: 'summerfi-api/get-rays-leaderboard-function/src/index.handler', + runtime: 'nodejs20.x', + logFormat: 'JSON', + environment: { + POWERTOOLS_LOG_LEVEL: process.env.POWERTOOLS_LOG_LEVEL || 'INFO', + RAYS_DB_CONNECTION_STRING: RAYS_DB_READ_CONNECTION_STRING, + }, + ...(vpc && { + vpc: vpc.vpc, + vpcSubnets: { + subnets: [...vpc.vpc.privateSubnets], + }, + }), + } + const updateRaysCronFunctionProps: FunctionProps = { handler: 'background-jobs/update-rays-cron-function/src/index.handler', runtime: 'nodejs20.x', @@ -47,6 +63,11 @@ export function addRaysConfig({ stack, api, vpc, app }: SummerStackContext) { }), } const raysFunction = new Function(stack, 'get-rays-function', raysFunctionProps) + const raysLeaderBoardFunction = new Function( + stack, + 'get-rays-leaderboard-function', + raysLeaderBoardFunctionProps, + ) const updateRaysCronFunction = new Function( stack, 'update-rays-cron-function', @@ -61,5 +82,6 @@ export function addRaysConfig({ stack, api, vpc, app }: SummerStackContext) { api.addRoutes(stack, { 'GET /api/rays': raysFunction, + 'GET /api/rays/leaderboard': raysLeaderBoardFunction, }) } diff --git a/summerfi-api/get-rays-leaderboard-function/.eslintrc.cjs b/summerfi-api/get-rays-leaderboard-function/.eslintrc.cjs new file mode 100644 index 0000000000..2e7192ec34 --- /dev/null +++ b/summerfi-api/get-rays-leaderboard-function/.eslintrc.cjs @@ -0,0 +1,6 @@ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + extends: ['@summerfi/eslint-config/function.cjs'], + parser: '@typescript-eslint/parser', +} diff --git a/summerfi-api/get-rays-leaderboard-function/jest.config.js b/summerfi-api/get-rays-leaderboard-function/jest.config.js new file mode 100644 index 0000000000..2fac612765 --- /dev/null +++ b/summerfi-api/get-rays-leaderboard-function/jest.config.js @@ -0,0 +1,15 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + transform: { + // '^.+\\.[tj]sx?$' to process js/ts with `ts-jest` + // '^.+\\.m?[tj]sx?$' to process js/ts/mjs/mts with `ts-jest` + '^.+\\.tsx?$': [ + 'ts-jest', + { + tsconfig: {}, + }, + ], + }, +} diff --git a/summerfi-api/get-rays-leaderboard-function/package.json b/summerfi-api/get-rays-leaderboard-function/package.json new file mode 100644 index 0000000000..50e9bd02b1 --- /dev/null +++ b/summerfi-api/get-rays-leaderboard-function/package.json @@ -0,0 +1,28 @@ +{ + "name": "@summerfi/get-rays-leaderboard-function", + "version": "0.0.1", + "scripts": { + "test": "jest --passWithNoTests", + "build": "tsc -b -v", + "lint": "eslint .", + "lint:fix": "eslint . --fix" + }, + "dependencies": { + "@aws-lambda-powertools/logger": "^2.0.2", + "@aws-lambda-powertools/metrics": "^2.0.2", + "@aws-lambda-powertools/tracer": "^2.0.2", + "@summerfi/abstractions": "workspace:*", + "@summerfi/serverless-shared": "workspace:*", + "@summerfi/rays-db": "workspace:*", + "kysely": "^0.27.3", + "node-fetch": "^3.3.2", + "zod": "^3.22.4" + }, + "devDependencies": { + "@summerfi/eslint-config": "workspace:*", + "@summerfi/typescript-config": "workspace:*", + "@types/node": "^20.11.5", + "eslint": "^8.56.0", + "jest": "^29.7.0" + } +} diff --git a/summerfi-api/get-rays-leaderboard-function/src/index.ts b/summerfi-api/get-rays-leaderboard-function/src/index.ts new file mode 100644 index 0000000000..6cbee31ace --- /dev/null +++ b/summerfi-api/get-rays-leaderboard-function/src/index.ts @@ -0,0 +1,56 @@ +import type { APIGatewayProxyEventV2, APIGatewayProxyResultV2, Context } from 'aws-lambda' +import { ResponseBadRequest, ResponseOk } from '@summerfi/serverless-shared/responses' +import { Logger } from '@aws-lambda-powertools/logger' +import { getRaysDB } from '@summerfi/rays-db' +import { numberSchema } from '@summerfi/serverless-shared' +import { z } from 'zod' + +const logger = new Logger({ serviceName: 'get-rays-function' }) + +export const queryParamsSchema = z.object({ + page: numberSchema.optional().default(1), + limit: numberSchema.optional().default(10), +}) + +export const handler = async ( + event: APIGatewayProxyEventV2, + context: Context, +): Promise => { + const { RAYS_DB_CONNECTION_STRING } = process.env + if (!RAYS_DB_CONNECTION_STRING) { + throw new Error('RAYS_DB_CONNECTION_STRING is not set') + } + console.log(RAYS_DB_CONNECTION_STRING) + logger.addContext(context) + + const parsedResult = queryParamsSchema.safeParse(event.queryStringParameters || {}) + if (!parsedResult.success) { + return ResponseBadRequest({ body: { message: parsedResult.error.message } }) + } + + const { page, limit } = parsedResult.data + const offset = (page - 1) * limit + + const dbConfig = { + connectionString: RAYS_DB_CONNECTION_STRING, + logger, + } + + const { db } = await getRaysDB(dbConfig) + + const leaderboard = await db + .selectFrom('leaderboard') + .selectAll() + .orderBy('totalPoints', 'desc') + .limit(limit) + .offset(offset) + .execute() + + return ResponseOk({ + body: { + leaderboard, + }, + }) +} + +export default handler diff --git a/summerfi-api/get-rays-leaderboard-function/sst-env.d.ts b/summerfi-api/get-rays-leaderboard-function/sst-env.d.ts new file mode 100644 index 0000000000..61de7a5d49 --- /dev/null +++ b/summerfi-api/get-rays-leaderboard-function/sst-env.d.ts @@ -0,0 +1 @@ +import '../../.sst/types' diff --git a/summerfi-api/get-rays-leaderboard-function/tsconfig.json b/summerfi-api/get-rays-leaderboard-function/tsconfig.json new file mode 100644 index 0000000000..caebdb3868 --- /dev/null +++ b/summerfi-api/get-rays-leaderboard-function/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@summerfi/typescript-config/tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "include": ["src/**/*.ts", "sst-env.d.ts"], + "exclude": ["node_modules", "**/*.spec.ts"] +} From 0169a26e357c7ae50a148ee76bdb2b6d3d53e742 Mon Sep 17 00:00:00 2001 From: Halaprix Date: Mon, 27 May 2024 12:57:14 +0200 Subject: [PATCH 22/37] chore: update-points-start-timestamp (#304) update to : ``` Epoch timestamp: 1716768000 Timestamp in milliseconds: 1716768000000 Date and time (GMT): Monday, 27 May 2024 00:00:00 ``` --- packages/summer-events-subgraph/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/summer-events-subgraph/src/index.ts b/packages/summer-events-subgraph/src/index.ts index f0768a44e8..41f8574539 100644 --- a/packages/summer-events-subgraph/src/index.ts +++ b/packages/summer-events-subgraph/src/index.ts @@ -48,7 +48,7 @@ export interface GetUsersPointsResult { export type GetUsersPoints = (params: GetUsersPointsParams) => Promise -export const START_POINTS_TIMESTAMP = 1717372800 +export const START_POINTS_TIMESTAMP = 1716768000 async function getUsersPoints( params: GetUsersPointsParams, From 135ed25ca53a5517b4eee822306131c1cd4f651c Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Mon, 27 May 2024 13:32:47 +0200 Subject: [PATCH 23/37] feat: operation definitions tool (#294) --- pnpm-lock.yaml | 51 +++++ .../src/implementation/OrderPlanner.ts | 22 +- .../src/utils/GenerateStrategyName.ts | 12 + .../tests/ProtocolManager.spec.ts | 30 +-- .../src/actions/BaseAction.ts | 22 +- .../src/interfaces/IAction.ts | 7 + .../src/interfaces/IProtocolPlugin.ts | 15 +- .../src/implementation/BaseActionBuilder.ts | 2 +- .../src/implementation/BaseProtocolPlugin.ts | 37 +++- .../implementation/ProtocolPluginsRegistry.ts | 10 +- sdk/protocol-plugins/src/index.ts | 1 + .../src/plugins/ProtocolPluginsRecord.ts | 18 ++ .../implementation/AAVEv3ProtocolPlugin.ts | 6 +- .../aave-v3/implementation/AaveV3Protocol.ts | 2 +- .../aave-v3/interfaces/IAaveV3Protocol.ts | 4 +- .../AAVEv3LikeBaseProtocolPlugin.ts | 16 +- .../aaveV3Like/AAVEv3LikeBuilderTypes.ts | 2 +- .../AAVEv3LikeProtocolDataBuilder.ts | 20 +- .../implementation/MakerProtocolPlugin.ts | 20 +- .../maker/implementation/MakerStepBuilders.ts | 2 + .../morphoblue/builders/MorphoStepBuilders.ts | 2 + .../implementation/MorphoProtocol.ts | 2 +- .../implementation/MorphoProtocolPlugin.ts | 20 +- .../morphoblue/interfaces/IMorphoProtocol.ts | 4 +- .../SparkOpenPositionActionBuilder.ts | 4 +- .../implementation/SparkProtocolPlugin.ts | 4 +- .../integration/AAVEv3ProtocolPlugin.spec.ts | 3 +- .../integration/MakerProtocolPlugin.spec.ts | 3 +- .../integration/MorphoProtocolPlugin.spec.ts | 3 +- .../integration/SparkProtocolPlugin.spec.ts | 3 +- .../tests/mocks/AAVEv3PoolIdMock.ts | 2 +- .../tests/mocks/MorphoPoolIdMock.ts | 2 +- .../actions/morpho/MorphoBorrowAction.spec.ts | 2 +- .../morpho/MorphoDepositAction.spec.ts | 2 +- .../morpho/MorphoPaybackAction.spec.ts | 2 +- .../morpho/MorphoWithdrawAction.spec.ts | 2 +- .../AaveV3DepositBorrowActionBuilder.spec.ts | 2 +- .../AaveV3OpenPositionActionBuilder.spec.ts | 2 +- ...AaveV3PaybackWithdrawActionBuilder.spec.ts | 2 +- .../MakerImportPositionActionBuilder.spec.ts | 2 +- .../MakerOpenPositionActionBuilder.spec.ts | 2 +- .../MakerPaybackWithdrawActionBuilder.spec.ts | 2 +- .../MorphoDepositBorrowActionBuilder.spec.ts | 2 +- .../MorphoOpenPositionActionBuilder.spec.ts | 4 +- ...MorphoPaybackWithdrawActionBuilder.spec.ts | 2 +- .../unit/plugins/AAVEv3ProtocolPlugin.spec.ts | 7 +- .../unit/plugins/BaseProtocolPlugin.spec.ts | 8 +- .../unit/plugins/MakerProtocolPlugin.spec.ts | 9 +- .../unit/plugins/MorphoProtocolPlugin.spec.ts | 7 +- .../unit/plugins/SparkProtocolPlugin.spec.ts | 7 +- .../tests/utils/ProtocolPluginMock.ts | 40 +++- .../utils/ProtocolsPluginRegistryMock.ts | 4 +- .../src/protocols/enums/ProtocolName.ts | 6 +- .../tests/refinanceAaveV3SparkAnyPair.test.ts | 2 +- .../tests/refinanceMorphoSparkAnyPair.test.ts | 2 +- .../context/CreateProtocolPluginsRegistry.ts | 25 +-- .../reducer/paybackWithdrawReducer.ts | 8 +- .../src/strategies/StrategyIndex.ts | 12 + sdk/simulator-service/tsconfig.json | 2 +- .../genStrategyDefinitions/.eslintrc.cjs | 7 + sdk/tools/genStrategyDefinitions/README.md | 20 ++ .../bundle/package.json | 9 + .../genStrategyDefinitions/jest.config.js | 15 ++ sdk/tools/genStrategyDefinitions/package.json | 29 +++ .../genStrategyDefinitions/src/Helpers.ts | 207 ++++++++++++++++++ sdk/tools/genStrategyDefinitions/src/Types.ts | 15 ++ sdk/tools/genStrategyDefinitions/src/index.ts | 71 ++++++ .../tsconfig.build.json | 9 + .../genStrategyDefinitions/tsconfig.json | 19 ++ .../genStrategyDefinitions/tsconfig.test.json | 9 + 70 files changed, 739 insertions(+), 189 deletions(-) create mode 100644 sdk/protocol-plugins/src/plugins/ProtocolPluginsRecord.ts create mode 100644 sdk/simulator-service/src/strategies/StrategyIndex.ts create mode 100644 sdk/tools/genStrategyDefinitions/.eslintrc.cjs create mode 100644 sdk/tools/genStrategyDefinitions/README.md create mode 100644 sdk/tools/genStrategyDefinitions/bundle/package.json create mode 100644 sdk/tools/genStrategyDefinitions/jest.config.js create mode 100644 sdk/tools/genStrategyDefinitions/package.json create mode 100644 sdk/tools/genStrategyDefinitions/src/Helpers.ts create mode 100644 sdk/tools/genStrategyDefinitions/src/Types.ts create mode 100644 sdk/tools/genStrategyDefinitions/src/index.ts create mode 100644 sdk/tools/genStrategyDefinitions/tsconfig.build.json create mode 100644 sdk/tools/genStrategyDefinitions/tsconfig.json create mode 100644 sdk/tools/genStrategyDefinitions/tsconfig.test.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0cb80056fe..ebd199f1ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1602,6 +1602,48 @@ importers: specifier: workspace:* version: link:../../packages/typescript-config + sdk/tools/genStrategyDefinitions: + dependencies: + '@summerfi/order-planner-service': + specifier: workspace:* + version: link:../../order-planner-service + '@summerfi/protocol-plugins': + specifier: workspace:* + version: link:../../protocol-plugins + '@summerfi/protocol-plugins-common': + specifier: workspace:* + version: link:../../protocol-plugins-common + '@summerfi/sdk-common': + specifier: workspace:* + version: link:../../sdk-common + '@summerfi/simulator-service': + specifier: workspace:* + version: link:../../simulator-service + devDependencies: + '@morpho-labs/gnosis-tx-builder': + specifier: ^2.0.0 + version: 2.0.0(ethers@6.11.1) + '@summerfi/eslint-config': + specifier: workspace:* + version: link:../../../packages/eslint-config + '@summerfi/jest-config': + specifier: workspace:* + version: link:../../../packages/jest-config + '@summerfi/typescript-config': + specifier: workspace:* + version: link:../../../packages/typescript-config + '@types/yargs': + specifier: ^17.0.32 + version: 17.0.32 + tsx: + specifier: ^4.7.2 + version: 4.9.3 + yargs: + specifier: ^17.7.2 + version: 17.7.2 + + sdk/tools/genStrategyDefinitions/bundle: {} + stacks: devDependencies: '@summerfi/eslint-config': @@ -7087,6 +7129,15 @@ packages: resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} dev: true + /@morpho-labs/gnosis-tx-builder@2.0.0(ethers@6.11.1): + resolution: {integrity: sha512-1xGHIe+oBOl5+AUOQgcHFRy1sFNjB5gRe03XaNbe7Rm7KY1YklU3/D0OT6EXk0ng6BuaSNO8NIGxeJXgKMMlVQ==} + engines: {node: '>=16.0'} + peerDependencies: + ethers: ^6.9.2 + dependencies: + ethers: 6.11.1 + dev: true + /@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1: resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} dependencies: diff --git a/sdk/order-planner-common/src/implementation/OrderPlanner.ts b/sdk/order-planner-common/src/implementation/OrderPlanner.ts index 0eb90e6c7f..8113c93dbf 100644 --- a/sdk/order-planner-common/src/implementation/OrderPlanner.ts +++ b/sdk/order-planner-common/src/implementation/OrderPlanner.ts @@ -1,9 +1,15 @@ import { Order, type IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' -import { ISimulation, SimulationType, steps } from '@summerfi/sdk-common/simulation' +import { + ISimulation, + SimulationSteps, + SimulationType, + steps, +} from '@summerfi/sdk-common/simulation' import { Maybe } from '@summerfi/sdk-common/common' import { ActionBuildersMap, ActionCall, + FilterStep, IActionBuilder, IStepBuilderContext, StepBuilderContext, @@ -34,7 +40,7 @@ export class OrderPlanner implements IOrderPlanner { context.startSubContext() for (const step of simulation.steps) { - const stepBuilder = this._getActionBuilder(actionBuildersMap, step) + const stepBuilder = this._getActionBuilder(actionBuildersMap, step.type) if (!stepBuilder) { throw new Error(`No step builder found for step type ${step.type}`) } @@ -68,17 +74,17 @@ export class OrderPlanner implements IOrderPlanner { }) } - private _getActionBuilder( - actionBuildersMap: ActionBuildersMap, - step: StepType, - ): Maybe> { - const builder = actionBuildersMap[step.type] + private _getActionBuilder< + StepType extends SimulationSteps, + Step extends FilterStep, + >(actionBuildersMap: ActionBuildersMap, stepType: StepType): Maybe> { + const builder = actionBuildersMap[stepType] if (!builder) { return undefined } - return new builder() as IActionBuilder + return new builder() } private async _generateOrder(params: { diff --git a/sdk/order-planner-common/src/utils/GenerateStrategyName.ts b/sdk/order-planner-common/src/utils/GenerateStrategyName.ts index 6cd3715765..1006abf536 100644 --- a/sdk/order-planner-common/src/utils/GenerateStrategyName.ts +++ b/sdk/order-planner-common/src/utils/GenerateStrategyName.ts @@ -1,5 +1,17 @@ import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' export function generateStrategyName(simulation: ISimulation): string { + // TODO: temporary workaround to use the right simulation name + if ( + simulation.simulationType === SimulationType.Refinance || + simulation.simulationType === SimulationType.RefinanceDifferentPair || + simulation.simulationType === SimulationType.RefinanceDifferentCollateral || + simulation.simulationType === SimulationType.RefinanceDifferentDebt || + simulation.simulationType === SimulationType.RefinanceNoDebt || + simulation.simulationType === SimulationType.RefinanceNoDebtDifferentCollateral + ) { + return `Refinance${simulation.sourcePosition?.pool.id.protocol.name}${simulation.targetPosition.pool.id.protocol.name}` + } + return `${simulation.simulationType}${simulation.sourcePosition?.pool.id.protocol.name}${simulation.targetPosition?.pool.id.protocol.name}` } diff --git a/sdk/protocol-manager-service/tests/ProtocolManager.spec.ts b/sdk/protocol-manager-service/tests/ProtocolManager.spec.ts index 511db74d12..3c8756c0af 100644 --- a/sdk/protocol-manager-service/tests/ProtocolManager.spec.ts +++ b/sdk/protocol-manager-service/tests/ProtocolManager.spec.ts @@ -10,7 +10,10 @@ import { AddressType, ChainInfo } from '@summerfi/sdk-common/common' import { createPublicClient, http, PublicClient } from 'viem' import { mainnet } from 'viem/chains' import { ProtocolManager } from '../src' -import { ProtocolPluginsRegistry } from '@summerfi/protocol-plugins/implementation' +import { + ProtocolPluginConstructor, + ProtocolPluginsRegistry, +} from '@summerfi/protocol-plugins/implementation' import { EmodeType, ISparkLendingPoolIdData } from '@summerfi/protocol-plugins' describe('Protocol Manager', () => { @@ -50,13 +53,12 @@ describe('Protocol Manager', () => { const ctx = await createProtocolManagerContext() class TestMockPlugin extends MockPlugin { - constructor(params: { - protocolName: ProtocolName - context: IProtocolPluginContext - __overrides?: { schema?: any; supportedChains?: any[] } - }) { - super(params) - this.protocolName = ProtocolName.Spark + constructor(params: { __overrides?: { schema?: any; supportedChains?: any[] } }) { + super({ + ...params, + protocolName: ProtocolName.Spark, + }) + this.getLendingPool = jest.fn().mockResolvedValue('mockPoolData') } } @@ -108,29 +110,27 @@ describe('Protocol Manager', () => { }) }) -export type ProtocolPluginConstructor = new (params: { - context: IProtocolPluginContext -}) => IProtocolPlugin - class MockPlugin implements IProtocolPlugin { protocolName: ProtocolName schema: any supportedChains: any[] stepBuilders: object - readonly context: IProtocolPluginContext + context?: IProtocolPluginContext constructor(params: { protocolName: ProtocolName - context: IProtocolPluginContext __overrides?: { schema?: any; supportedChains?: any[] } }) { this.protocolName = params.protocolName - this.context = params.context this.schema = params.__overrides?.schema ?? {} this.supportedChains = params.__overrides?.supportedChains ?? [] this.stepBuilders = {} } + initialize(params: { context: IProtocolPluginContext }): void { + this.context = params.context + } + getLendingPool = jest.fn() getLendingPoolInfo = jest.fn() getPosition = jest.fn() diff --git a/sdk/protocol-plugins-common/src/actions/BaseAction.ts b/sdk/protocol-plugins-common/src/actions/BaseAction.ts index c17864a8c1..1625697c9d 100644 --- a/sdk/protocol-plugins-common/src/actions/BaseAction.ts +++ b/sdk/protocol-plugins-common/src/actions/BaseAction.ts @@ -11,6 +11,7 @@ import { ActionConfig, ActionCall } from './Types' import { InputSlotsMapping } from '../types/InputSlotsMapping' import { AbiParametersToPrimitiveTypes } from 'abitype' import { IAction } from '../interfaces/IAction' +import { HexData } from '@summerfi/sdk-common' /** * @class Base class for all actions. It provides the basic functionality to encode the call to the action and provide @@ -27,10 +28,7 @@ export abstract class BaseAction< { private readonly DefaultParamsMapping: InputSlotsMapping = [0, 0, 0, 0] - /** - * @description Returns the versioned name of the action - * @returns The versioned name of the action - */ + /** @see IAction.getVersionedName */ public getVersionedName(): string { if (this.config.version === 0) { // Special case for compatiblility with v1 actions @@ -40,13 +38,12 @@ export abstract class BaseAction< } } - /** - * @description Encodes the call to the action. Provided so the implementer has an opportunity to pre-process - * the parameters before encoding the call. - * @param params The parameters to encode - * @param paramsMapping The mapping of the parameters to the execution storage - * @returns The encoded call to the action - */ + /** @see IAction.getActionHash */ + public getActionHash(): HexData { + return keccak256(toBytes(this.getVersionedName())) + } + + /** @see IAction.encodeCall */ public abstract encodeCall(params: unknown, paramsMapping?: InputSlotsMapping): ActionCall /** @@ -59,8 +56,7 @@ export abstract class BaseAction< arguments: AbiParametersTypes mapping?: InputSlotsMapping }): ActionCall { - const contractNameWithVersion = this.getVersionedName() - const targetHash = keccak256(toBytes(contractNameWithVersion)) + const targetHash = this.getActionHash() const abi = parseAbi([ 'function execute(bytes calldata data, uint8[] paramsMap) external payable returns (bytes calldata)', diff --git a/sdk/protocol-plugins-common/src/interfaces/IAction.ts b/sdk/protocol-plugins-common/src/interfaces/IAction.ts index c5839980bc..896769a0de 100644 --- a/sdk/protocol-plugins-common/src/interfaces/IAction.ts +++ b/sdk/protocol-plugins-common/src/interfaces/IAction.ts @@ -1,3 +1,4 @@ +import { HexData } from '@summerfi/sdk-common' import { ActionConfig, ActionCall } from '../actions/Types' import { InputSlotsMapping } from '../types/InputSlotsMapping' @@ -12,6 +13,12 @@ export interface IAction { */ getVersionedName(): string + /** + * @description Returns the hash of the action + * @returns The hash of the action + */ + getActionHash(): HexData + /** * @description Encodes the call to the action. Provided so the implementer has an opportunity to pre-process * the parameters before encoding the call. diff --git a/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts b/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts index 3a4604e85a..ca3df8f2c3 100644 --- a/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts +++ b/sdk/protocol-plugins-common/src/interfaces/IProtocolPlugin.ts @@ -6,10 +6,10 @@ import { ILendingPoolInfo, } from '@summerfi/sdk-common/protocols' import { type IProtocolPluginContext } from './IProtocolPluginContext' -import { steps } from '@summerfi/sdk-common/simulation' +import { SimulationSteps, steps } from '@summerfi/sdk-common/simulation' import { IUser } from '@summerfi/sdk-common/user' import { IExternalPosition, IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' -import { IActionBuilder, ActionBuildersMap } from './IActionBuilder' +import { IActionBuilder, ActionBuildersMap, FilterStep } from './IActionBuilder' /** * @interface IProtocolPlugin @@ -19,7 +19,9 @@ export interface IProtocolPlugin { protocolName: ProtocolName supportedChains: ChainInfo[] stepBuilders: Partial - context: IProtocolPluginContext + + /** INITIALIZATION */ + initialize(params: { context: IProtocolPluginContext }): void /** LENDING POOLS */ @@ -57,7 +59,12 @@ export interface IProtocolPlugin { * @param step The simulation step for which to get the action builder * @returns The action builder for the given step for the specific protocol, or undefined if not found */ - getActionBuilder(step: StepType): Maybe> + getActionBuilder< + StepType extends SimulationSteps, + Step extends FilterStep, + >( + stepType: StepType, + ): Maybe> /** IMPORT POSITION */ diff --git a/sdk/protocol-plugins/src/implementation/BaseActionBuilder.ts b/sdk/protocol-plugins/src/implementation/BaseActionBuilder.ts index cd58538236..294c0ff31f 100644 --- a/sdk/protocol-plugins/src/implementation/BaseActionBuilder.ts +++ b/sdk/protocol-plugins/src/implementation/BaseActionBuilder.ts @@ -48,7 +48,7 @@ export abstract class BaseActionBuilder throw new Error(`No protocol plugin found for protocol ${protocolName}`) } - const builder = plugin.getActionBuilder(params.actionBuilderParams.step) + const builder = plugin.getActionBuilder(params.actionBuilderParams.step.type) if (!builder) { throw new Error(`No action builder found for protocol ${protocolName}`) } diff --git a/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts b/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts index d150b2025c..752d779c93 100644 --- a/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/implementation/BaseProtocolPlugin.ts @@ -1,5 +1,6 @@ import { ActionBuildersMap, + FilterStep, IActionBuilder, IProtocolPlugin, IProtocolPluginContext, @@ -19,7 +20,7 @@ import { ILendingPoolIdData, ILendingPoolInfo, } from '@summerfi/sdk-common/protocols' -import { steps } from '@summerfi/sdk-common/simulation' +import { SimulationSteps, steps } from '@summerfi/sdk-common/simulation' import { IUser } from '@summerfi/sdk-common/user' import { getContractAddress } from '../plugins/utils/GetContractAddress' @@ -38,23 +39,34 @@ export abstract class BaseProtocolPlugin implements IProtocolPlugin { abstract readonly stepBuilders: Partial /** These properties are initialized in the constructor */ - readonly context: IProtocolPluginContext + private _context: Maybe - protected constructor(params: { context: IProtocolPluginContext }) { - this.context = params.context + /** INITIALIZATION */ - if (!this.context.provider.chain) { + /** @see IProtocolPlugin.initialize */ + initialize(params: { context: IProtocolPluginContext }) { + if (this._context) { + throw new Error('Already initialized') + } + + this._context = params.context + + if (!this._context.provider.chain) { throw new Error('ctx.provider.chain undefined') } - if (!this.context.provider.chain.id) { + if (!this._context.provider.chain.id) { throw new Error('ctx.provider.chain.id undefined') } } // Short alias for the context - protected get ctx(): IProtocolPluginContext { - return this.context + protected get context(): IProtocolPluginContext { + if (!this._context) { + throw new Error('Context not initialized') + } + + return this._context } /** VALIDATORS */ @@ -136,14 +148,17 @@ export abstract class BaseProtocolPlugin implements IProtocolPlugin { /** ACTION BUILDERS */ /** @see IProtocolPlugin.getActionBuilder */ - getActionBuilder(step: StepType): Maybe> { - const BuilderClass = this.stepBuilders[step.type] + getActionBuilder< + StepType extends SimulationSteps, + Step extends FilterStep, + >(stepType: StepType): Maybe> { + const BuilderClass = this.stepBuilders[stepType] if (!BuilderClass) { return undefined } - return new BuilderClass() as IActionBuilder + return new BuilderClass() } /** HELPERS */ diff --git a/sdk/protocol-plugins/src/implementation/ProtocolPluginsRegistry.ts b/sdk/protocol-plugins/src/implementation/ProtocolPluginsRegistry.ts index dff5352344..6d929b3edb 100644 --- a/sdk/protocol-plugins/src/implementation/ProtocolPluginsRegistry.ts +++ b/sdk/protocol-plugins/src/implementation/ProtocolPluginsRegistry.ts @@ -10,9 +10,7 @@ import { Maybe } from '@summerfi/sdk-common/common' * @typedef ProtocolPluginConstructor * @description Constructor for a protocol plugin */ -export type ProtocolPluginConstructor = new (params: { - context: IProtocolPluginContext -}) => IProtocolPlugin +export type ProtocolPluginConstructor = new () => IProtocolPlugin /** * @typedef ProtocolPluginsRecordType @@ -44,6 +42,10 @@ export class ProtocolPluginsRegistry implements IProtocolPluginsRegistry { if (!Plugin) { return } - return new Plugin({ context: this.context }) + const plugin = new Plugin() + + plugin.initialize({ context: this.context }) + + return plugin } } diff --git a/sdk/protocol-plugins/src/index.ts b/sdk/protocol-plugins/src/index.ts index d9a4808b16..3ef2f3c7ea 100644 --- a/sdk/protocol-plugins/src/index.ts +++ b/sdk/protocol-plugins/src/index.ts @@ -4,3 +4,4 @@ export * from './plugins/maker' export * from './plugins/morphoblue' export * from './plugins/common' export * from './implementation' +export * from './plugins/ProtocolPluginsRecord' diff --git a/sdk/protocol-plugins/src/plugins/ProtocolPluginsRecord.ts b/sdk/protocol-plugins/src/plugins/ProtocolPluginsRecord.ts new file mode 100644 index 0000000000..bb8bf3a4f3 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/ProtocolPluginsRecord.ts @@ -0,0 +1,18 @@ +import { ProtocolName } from '@summerfi/sdk-common/protocols' +import { ProtocolPluginsRecordType } from '../implementation/ProtocolPluginsRegistry' +import { AaveV3ProtocolPlugin } from './aave-v3/implementation/AAVEv3ProtocolPlugin' +import { MakerProtocolPlugin } from './maker/implementation/MakerProtocolPlugin' +import { MorphoProtocolPlugin } from './morphoblue/implementation/MorphoProtocolPlugin' +import { SparkProtocolPlugin } from './spark/implementation/SparkProtocolPlugin' + +/** + * Protocol plugins record + * + * Note: add here the plugins you want to use in the SDK + */ +export const ProtocolPluginsRecord: ProtocolPluginsRecordType = { + [ProtocolName.Maker]: MakerProtocolPlugin, + [ProtocolName.Spark]: SparkProtocolPlugin, + [ProtocolName.AaveV3]: AaveV3ProtocolPlugin, + [ProtocolName.MorphoBlue]: MorphoProtocolPlugin, +} diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts index bcffec4598..dd15bab9a9 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AAVEv3ProtocolPlugin.ts @@ -37,7 +37,7 @@ export class AaveV3ProtocolPlugin extends AAVEv3LikeBaseProtocolPlugin< AaveV3ContractNames, AaveV3AbiMapType > { - readonly protocolName = ProtocolName.AAVEv3 + readonly protocolName = ProtocolName.AaveV3 readonly supportedChains = valuesOfChainFamilyMap([ ChainFamilyName.Ethereum, ChainFamilyName.Base, @@ -46,10 +46,10 @@ export class AaveV3ProtocolPlugin extends AAVEv3LikeBaseProtocolPlugin< ]) readonly stepBuilders: Partial = AaveV3StepBuilders - constructor(params: { context: IProtocolPluginContext }) { + initialize(params: { context: IProtocolPluginContext }) { const contractsAbiProvider = new ChainContractsProvider(AaveV3AbiMap) - super({ + super.initialize({ ...params, contractsAbiProvider, }) diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AaveV3Protocol.ts b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AaveV3Protocol.ts index 28005df5a0..79ae6b3ec9 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AaveV3Protocol.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/implementation/AaveV3Protocol.ts @@ -7,7 +7,7 @@ import { IAaveV3Protocol, IAaveV3ProtocolData } from '../interfaces/IAaveV3Proto * @see IAaveV3ProtocolData */ export class AaveV3Protocol extends Protocol implements IAaveV3Protocol { - readonly name: ProtocolName.AAVEv3 + readonly name: ProtocolName.AaveV3 /** Factory method */ static createFrom(params: IAaveV3ProtocolData): AaveV3Protocol { diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/interfaces/IAaveV3Protocol.ts b/sdk/protocol-plugins/src/plugins/aave-v3/interfaces/IAaveV3Protocol.ts index bca24a9d8b..73a97f5435 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/interfaces/IAaveV3Protocol.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/interfaces/IAaveV3Protocol.ts @@ -16,7 +16,7 @@ import { z } from 'zod' */ export interface IAaveV3Protocol extends IProtocol, IAaveV3ProtocolData { /** AaveV3 protocol name */ - readonly name: ProtocolName.AAVEv3 + readonly name: ProtocolName.AaveV3 // Re-declaring the properties with the correct types readonly chainInfo: IChainInfo @@ -27,7 +27,7 @@ export interface IAaveV3Protocol extends IProtocol, IAaveV3ProtocolData { */ export const AaveV3ProtocolDataSchema = z.object({ ...ProtocolDataSchema.shape, - name: z.literal(ProtocolName.AAVEv3), + name: z.literal(ProtocolName.AaveV3), chainInfo: ChainInfoDataSchema, }) diff --git a/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts index eae3d2718b..991bee353d 100644 --- a/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBaseProtocolPlugin.ts @@ -42,18 +42,18 @@ export abstract class AAVEv3LikeBaseProtocolPlugin< ContractsAbiMap extends GenericAbiMap, > extends BaseProtocolPlugin { abstract readonly protocolName: AllowedProtocolNames - readonly contractsAbiProvider: ChainContractsProvider + private _contractsAbiProvider: Maybe> private _assetsList: Maybe> = undefined /** CONSTRUCTOR */ - protected constructor(params: { + initialize(params: { context: IProtocolPluginContext contractsAbiProvider: ChainContractsProvider }) { - super(params) + super.initialize(params) - this.contractsAbiProvider = params.contractsAbiProvider + this._contractsAbiProvider = params.contractsAbiProvider } /** PROTECTED */ @@ -254,4 +254,12 @@ export abstract class AAVEv3LikeBaseProtocolPlugin< throw new Error(`error in debt loop ${e}`) } } + + get contractsAbiProvider(): ChainContractsProvider { + if (!this._contractsAbiProvider) { + throw new Error('Contracts ABI provider not initialized') + } + + return this._contractsAbiProvider + } } diff --git a/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBuilderTypes.ts b/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBuilderTypes.ts index 5d30e2b713..7a9c0a1fb5 100644 --- a/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBuilderTypes.ts +++ b/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeBuilderTypes.ts @@ -34,7 +34,7 @@ type ReservesData = { export type EmodeCategory = bigint type OraclePrice = bigint -export type AllowedProtocolNames = ProtocolName.Spark | ProtocolName.AAVEv3 +export type AllowedProtocolNames = ProtocolName.Spark | ProtocolName.AaveV3 export type WithToken = T & { token: Token } export type WithReservesCaps = T & { caps: ReservesCap } export type WithReservesConfig = T & { config: ReservesConfigData } diff --git a/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeProtocolDataBuilder.ts b/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeProtocolDataBuilder.ts index 6f33c0a9e7..eb378b93b7 100644 --- a/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeProtocolDataBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/common/helpers/aaveV3Like/AAVEv3LikeProtocolDataBuilder.ts @@ -30,7 +30,7 @@ export class AaveV3LikeProtocolDataBuilder< ContractNames extends string, ContractsAbiMap extends GenericAbiMap, > { - private readonly ctx: IProtocolPluginContext + private readonly context: IProtocolPluginContext private operations: QueuedOperation[] = [] private tokensUsedAsReserves: Token[] | undefined private reservesAssetsList: Array> = [] @@ -44,7 +44,7 @@ export class AaveV3LikeProtocolDataBuilder< chainInfo: IChainInfo, chainContractsProvider: ChainContractsProvider, ) { - this.ctx = ctx + this.context = ctx this.protocolName = protocolName this.chainInfo = chainInfo this.chainContractsProvider = chainContractsProvider @@ -54,7 +54,7 @@ export class AaveV3LikeProtocolDataBuilder< AaveV3LikeProtocolDataBuilder, ContractNames, ContractsAbiMap> > { const rawTokens = await fetchReservesTokens( - this.ctx, + this.context, this.chainInfo, this.chainContractsProvider, ) @@ -62,7 +62,7 @@ export class AaveV3LikeProtocolDataBuilder< const tokensUsedAsReserves = await Promise.all( rawTokens.map(async (reservesToken) => { - const token = await this.ctx.tokensManager.getTokenByAddress({ + const token = await this.context.tokensManager.getTokenByAddress({ chainInfo: ChainFamilyMap.Ethereum.Mainnet, address: Address.createFromEthereum({ value: reservesToken.tokenAddress }), }) @@ -78,7 +78,7 @@ export class AaveV3LikeProtocolDataBuilder< WithToken, ContractNames, ContractsAbiMap - >(this.ctx, this.protocolName, this.chainInfo, this.chainContractsProvider), + >(this.context, this.protocolName, this.chainInfo, this.chainContractsProvider), this, { tokensUsedAsReserves, @@ -105,7 +105,7 @@ export class AaveV3LikeProtocolDataBuilder< operation: async () => { this._assertIsInitialised(this.tokensUsedAsReserves) const reservesCapsPerAsset = await fetchReservesCap( - this.ctx, + this.context, this.tokensUsedAsReserves!, this.chainInfo, this.chainContractsProvider, @@ -144,7 +144,7 @@ export class AaveV3LikeProtocolDataBuilder< operation: async () => { this._assertIsInitialised(this.tokensUsedAsReserves) const reservesConfigDataPerAsset = await fetchAssetConfigurationData( - this.ctx, + this.context, this.tokensUsedAsReserves, this.chainInfo, this.chainContractsProvider, @@ -212,7 +212,7 @@ export class AaveV3LikeProtocolDataBuilder< operation: async () => { this._assertIsInitialised(this.tokensUsedAsReserves) const reservesDataPerAsset = await fetchAssetReserveData( - this.ctx, + this.context, this.tokensUsedAsReserves, this.chainInfo, this.chainContractsProvider, @@ -287,7 +287,7 @@ export class AaveV3LikeProtocolDataBuilder< operation: async () => { this._assertIsInitialised(this.tokensUsedAsReserves) const emodeCategoryPerAsset = await fetchEmodeCategoriesForReserves( - this.ctx, + this.context, this.tokensUsedAsReserves, this.chainInfo, this.chainContractsProvider, @@ -322,7 +322,7 @@ export class AaveV3LikeProtocolDataBuilder< operation: async () => { this._assertIsInitialised(this.tokensUsedAsReserves) const [assetPrices] = await fetchAssetPrices( - this.ctx, + this.context, this.tokensUsedAsReserves, this.chainInfo, this.chainContractsProvider, diff --git a/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts index af44aa3084..f8e2cd1f42 100644 --- a/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/maker/implementation/MakerProtocolPlugin.ts @@ -55,8 +55,9 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { readonly CdpManagerContractName = 'CdpManager' readonly DssProxyActionsContractName = 'DssProxyActions' - constructor(params: { context: IProtocolPluginContext }) { - super(params) + /** INITIALIZATION */ + initialize(params: { context: IProtocolPluginContext }) { + super.initialize(params) if ( !this.supportedChains.some( @@ -188,7 +189,7 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { private async _getCollateralInfo(protocolData: ProtocolData) { const { osmData, joinGemBalance, collateralToken, quoteToken, dogRes, spotRes } = protocolData - const collateralPriceUSD = await this.ctx.oracleManager.getSpotPrice({ + const collateralPriceUSD = await this.context.oracleManager.getSpotPrice({ baseToken: collateralToken, }) @@ -224,7 +225,7 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { private async _getDebtInfo(protocolData: ProtocolData) { const { quoteToken, stabilityFee, vatRes } = protocolData - const priceUSD = await this.ctx.oracleManager.getSpotPrice({ + const priceUSD = await this.context.oracleManager.getSpotPrice({ baseToken: quoteToken, }) return DebtInfo.createFrom({ @@ -260,7 +261,7 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { const { osm, vatRes, jugRes, dogRes, spotRes, erc20, ilkRegistryRes } = await this._getIlkProtocolData({ chainInfo: makerLendingPoolId.protocol.chainInfo, ilkInHex }) - const DAI = await this.ctx.tokensManager.getTokenBySymbol({ + const DAI = await this.context.tokensManager.getTokenBySymbol({ chainInfo: makerLendingPoolId.protocol.chainInfo, symbol: CommonTokenSymbols.DAI, }) @@ -268,7 +269,7 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { throw new Error(`DAI token not found for chain: ${makerLendingPoolId.protocol.chainInfo}`) } - const ilkGemToken = await this.ctx.tokensManager.getTokenByAddress({ + const ilkGemToken = await this.context.tokensManager.getTokenByAddress({ chainInfo: makerLendingPoolId.protocol.chainInfo, address: Address.createFromEthereum({ value: ilkRegistryRes.gem }), }) @@ -333,7 +334,6 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { } private async _getIlkProtocolData(params: { chainInfo: IChainInfo; ilkInHex: `0x${string}` }) { - const ctx = this.ctx const makerDogDef = await this._getContractDef({ chainInfo: params.chainInfo, contractName: 'Dog', @@ -389,7 +389,7 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { 7: name, // Token name 8: symbol, // Token symbol }, - ] = await ctx.provider.multicall({ + ] = await this.context.provider.multicall({ contracts: [ { abi: makerVatDef.abi, @@ -452,13 +452,13 @@ export class MakerProtocolPlugin extends BaseProtocolPlugin { const osm = getContract({ abi: OSM_ABI, address: spotRes.priceFeedAddress.value, - client: ctx.provider, + client: this.context.provider, }) const erc20 = getContract({ abi: ERC20_ABI, address: gem, - client: ctx.provider, + client: this.context.provider, }) const ilkRegistryRes = { diff --git a/sdk/protocol-plugins/src/plugins/maker/implementation/MakerStepBuilders.ts b/sdk/protocol-plugins/src/plugins/maker/implementation/MakerStepBuilders.ts index 84ba6f58de..6e31733aae 100644 --- a/sdk/protocol-plugins/src/plugins/maker/implementation/MakerStepBuilders.ts +++ b/sdk/protocol-plugins/src/plugins/maker/implementation/MakerStepBuilders.ts @@ -2,6 +2,7 @@ import { ActionBuildersMap } from '@summerfi/protocol-plugins-common' import { MakerPaybackWithdrawActionBuilder } from '../builders/MakerPaybackWithdrawActionBuilder' import { MakerImportPositionActionBuilder } from '../builders/MakerImportPositionActionBuilder' import { SimulationSteps } from '@summerfi/sdk-common/simulation' +import { MakerOpenPositionActionBuilder } from '../builders' /** * @description Map of action builders for the Maker protocol @@ -9,4 +10,5 @@ import { SimulationSteps } from '@summerfi/sdk-common/simulation' export const MakerStepBuilders: Partial = { [SimulationSteps.PaybackWithdraw]: MakerPaybackWithdrawActionBuilder, [SimulationSteps.Import]: MakerImportPositionActionBuilder, + [SimulationSteps.OpenPosition]: MakerOpenPositionActionBuilder, } diff --git a/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoStepBuilders.ts b/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoStepBuilders.ts index 25fb35e3e0..5e63d99562 100644 --- a/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoStepBuilders.ts +++ b/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoStepBuilders.ts @@ -2,8 +2,10 @@ import { ActionBuildersMap } from '@summerfi/protocol-plugins-common' import { MorphoDepositBorrowActionBuilder } from './MorphoDepositBorrowActionBuilder' import { SimulationSteps } from '@summerfi/sdk-common/simulation' import { MorphoPaybackWithdrawActionBuilder } from './MorphoPaybackWithdrawActionBuilder' +import { MorphoOpenPositionActionBuilder } from './MorphoOpenPositionActionBuilder' export const MorphoStepBuilders: Partial = { [SimulationSteps.DepositBorrow]: MorphoDepositBorrowActionBuilder, [SimulationSteps.PaybackWithdraw]: MorphoPaybackWithdrawActionBuilder, + [SimulationSteps.OpenPosition]: MorphoOpenPositionActionBuilder, } diff --git a/sdk/protocol-plugins/src/plugins/morphoblue/implementation/MorphoProtocol.ts b/sdk/protocol-plugins/src/plugins/morphoblue/implementation/MorphoProtocol.ts index 6e5c9c9b00..e37ae920d2 100644 --- a/sdk/protocol-plugins/src/plugins/morphoblue/implementation/MorphoProtocol.ts +++ b/sdk/protocol-plugins/src/plugins/morphoblue/implementation/MorphoProtocol.ts @@ -7,7 +7,7 @@ import { SerializationService } from '@summerfi/sdk-common/services' * @see IMorphoProtocol */ export class MorphoProtocol extends Protocol implements IMorphoProtocol { - readonly name: ProtocolName.Morpho + readonly name: ProtocolName.MorphoBlue /** Factory method */ static createFrom(params: IMorphoProtocolData): MorphoProtocol { diff --git a/sdk/protocol-plugins/src/plugins/morphoblue/implementation/MorphoProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/morphoblue/implementation/MorphoProtocolPlugin.ts index 323cdab4e1..02dfcf3d6b 100644 --- a/sdk/protocol-plugins/src/plugins/morphoblue/implementation/MorphoProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/morphoblue/implementation/MorphoProtocolPlugin.ts @@ -49,12 +49,12 @@ import { MorphoMarketParameters } from '../types' export class MorphoProtocolPlugin extends BaseProtocolPlugin { static readonly MorphoBlueContractName = 'MorphoBlue' - readonly protocolName: ProtocolName.Morpho = ProtocolName.Morpho + readonly protocolName: ProtocolName.MorphoBlue = ProtocolName.MorphoBlue readonly supportedChains = valuesOfChainFamilyMap([ChainFamilyName.Ethereum]) readonly stepBuilders: Partial = MorphoStepBuilders - constructor(params: { context: IProtocolPluginContext }) { - super(params) + initialize(params: { context: IProtocolPluginContext }) { + super.initialize(params) if ( !this.supportedChains.some( @@ -171,7 +171,7 @@ export class MorphoProtocolPlugin extends BaseProtocolPlugin { const collateralToken = morphoLendingPool.collateralToken const liquidationPenalty = this._getLiquidationPenalty(morphoLendingPool) - const collateralPriceUSD = await this.ctx.oracleManager.getSpotPrice({ + const collateralPriceUSD = await this.context.oracleManager.getSpotPrice({ baseToken: collateralToken, }) @@ -205,7 +205,7 @@ export class MorphoProtocolPlugin extends BaseProtocolPlugin { const { morphoLendingPool, marketInfo, marketCollateralPriceInDebt } = params const debtToken = morphoLendingPool.debtToken - const priceUSD = await this.ctx.oracleManager.getSpotPrice({ + const priceUSD = await this.context.oracleManager.getSpotPrice({ baseToken: debtToken, }) @@ -238,7 +238,7 @@ export class MorphoProtocolPlugin extends BaseProtocolPlugin { * @returns The market oracle price */ private async _getMarketOraclePrice(morphoLendingPool: IMorphoLendingPool): Promise { - const [price] = await this.ctx.provider.multicall({ + const [price] = await this.context.provider.multicall({ contracts: [ { abi: morphoBlueOracleAbi, @@ -274,7 +274,7 @@ export class MorphoProtocolPlugin extends BaseProtocolPlugin { }) const marketParamsId = morphoLendingPool.id.marketId - const [marketInfo] = await this.ctx.provider.multicall({ + const [marketInfo] = await this.context.provider.multicall({ contracts: [ { abi: morphoBlueAbi, @@ -319,7 +319,7 @@ export class MorphoProtocolPlugin extends BaseProtocolPlugin { }) const marketParamsId = morphoLendingPoolId.marketId - const [marketParameters] = await this.ctx.provider.multicall({ + const [marketParameters] = await this.context.provider.multicall({ contracts: [ { abi: morphoBlueAbi, @@ -331,7 +331,7 @@ export class MorphoProtocolPlugin extends BaseProtocolPlugin { allowFailure: false, }) - const debtToken = await this.ctx.tokensManager.getTokenByAddress({ + const debtToken = await this.context.tokensManager.getTokenByAddress({ address: Address.createFromEthereum({ value: marketParameters[0] }), chainInfo: morphoLendingPoolId.protocol.chainInfo, }) @@ -342,7 +342,7 @@ export class MorphoProtocolPlugin extends BaseProtocolPlugin { ) } - const collateralToken = await this.ctx.tokensManager.getTokenByAddress({ + const collateralToken = await this.context.tokensManager.getTokenByAddress({ address: Address.createFromEthereum({ value: marketParameters[1] }), chainInfo: morphoLendingPoolId.protocol.chainInfo, }) diff --git a/sdk/protocol-plugins/src/plugins/morphoblue/interfaces/IMorphoProtocol.ts b/sdk/protocol-plugins/src/plugins/morphoblue/interfaces/IMorphoProtocol.ts index 93996a9390..e395622197 100644 --- a/sdk/protocol-plugins/src/plugins/morphoblue/interfaces/IMorphoProtocol.ts +++ b/sdk/protocol-plugins/src/plugins/morphoblue/interfaces/IMorphoProtocol.ts @@ -13,7 +13,7 @@ import { z } from 'zod' */ export interface IMorphoProtocol extends IMorphoProtocolData, IProtocol { /** Morpho protocol name */ - readonly name: ProtocolName.Morpho + readonly name: ProtocolName.MorphoBlue // Re-declare the properties with the correct types readonly chainInfo: IChainInfo @@ -24,7 +24,7 @@ export interface IMorphoProtocol extends IMorphoProtocolData, IProtocol { */ export const MorphoProtocolDataSchema = z.object({ ...ProtocolDataSchema.shape, - name: z.literal(ProtocolName.Morpho), + name: z.literal(ProtocolName.MorphoBlue), }) /** diff --git a/sdk/protocol-plugins/src/plugins/spark/builders/SparkOpenPositionActionBuilder.ts b/sdk/protocol-plugins/src/plugins/spark/builders/SparkOpenPositionActionBuilder.ts index c3d255c0bf..25c55c93c2 100644 --- a/sdk/protocol-plugins/src/plugins/spark/builders/SparkOpenPositionActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/spark/builders/SparkOpenPositionActionBuilder.ts @@ -5,9 +5,7 @@ import { ActionBuilderParams, ActionBuilderUsedAction } from '@summerfi/protocol import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' export class SparkOpenPositionActionBuilder extends BaseActionBuilder { - readonly actions: ActionBuilderUsedAction[] = [ - // Empty on purpose, no definition needs to be generated for this builder - ] + readonly actions: ActionBuilderUsedAction[] = [{ action: SparkSetEmodeAction }] async build(params: ActionBuilderParams): Promise { const { context, step } = params diff --git a/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts b/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts index 5f5002dafb..6aeb6579ce 100644 --- a/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts +++ b/sdk/protocol-plugins/src/plugins/spark/implementation/SparkProtocolPlugin.ts @@ -41,10 +41,10 @@ export class SparkProtocolPlugin extends AAVEv3LikeBaseProtocolPlugin< readonly supportedChains = valuesOfChainFamilyMap([ChainFamilyName.Ethereum]) readonly stepBuilders: Partial = SparkStepBuilders - constructor(params: { context: IProtocolPluginContext }) { + initialize(params: { context: IProtocolPluginContext }) { const contractsAbiProvider = new ChainContractsProvider(SparkAbiMap) - super({ + super.initialize({ ...params, contractsAbiProvider, }) diff --git a/sdk/protocol-plugins/tests/integration/AAVEv3ProtocolPlugin.spec.ts b/sdk/protocol-plugins/tests/integration/AAVEv3ProtocolPlugin.spec.ts index 31f578c625..ad31d5d1df 100644 --- a/sdk/protocol-plugins/tests/integration/AAVEv3ProtocolPlugin.spec.ts +++ b/sdk/protocol-plugins/tests/integration/AAVEv3ProtocolPlugin.spec.ts @@ -13,7 +13,8 @@ describe('AAVEv3 Protocol Plugin (Integration)', () => { beforeAll(async () => { ctx = await createProtocolPluginContext(ChainFamilyMap.Ethereum.Mainnet) validAaveV3PoolId = await getAaveV3PoolIdMock() - aaveV3ProtocolPlugin = new AaveV3ProtocolPlugin({ + aaveV3ProtocolPlugin = new AaveV3ProtocolPlugin() + aaveV3ProtocolPlugin.initialize({ context: ctx, }) }) diff --git a/sdk/protocol-plugins/tests/integration/MakerProtocolPlugin.spec.ts b/sdk/protocol-plugins/tests/integration/MakerProtocolPlugin.spec.ts index b008433f41..10a65ac137 100644 --- a/sdk/protocol-plugins/tests/integration/MakerProtocolPlugin.spec.ts +++ b/sdk/protocol-plugins/tests/integration/MakerProtocolPlugin.spec.ts @@ -29,7 +29,8 @@ describe('Maker Protocol Plugin (Integration)', () => { beforeAll(async () => { ctx = await createProtocolPluginContext(ChainFamilyMap.Ethereum.Mainnet) validMakerPoolId = await getMakerPoolIdMock() - makerProtocolPlugin = new MakerProtocolPlugin({ + makerProtocolPlugin = new MakerProtocolPlugin() + makerProtocolPlugin.initialize({ context: ctx, }) ;(ctx.oracleManager as OracleManagerMock).setSpotPrice({ diff --git a/sdk/protocol-plugins/tests/integration/MorphoProtocolPlugin.spec.ts b/sdk/protocol-plugins/tests/integration/MorphoProtocolPlugin.spec.ts index 73be85798a..3ad597b191 100644 --- a/sdk/protocol-plugins/tests/integration/MorphoProtocolPlugin.spec.ts +++ b/sdk/protocol-plugins/tests/integration/MorphoProtocolPlugin.spec.ts @@ -14,7 +14,8 @@ describe.only('Protocol Plugin | Integration | Morpho', () => { beforeAll(async () => { ctx = await createProtocolPluginContext(ChainFamilyMap.Ethereum.Mainnet) - morphoProtocolPlugin = new MorphoProtocolPlugin({ + morphoProtocolPlugin = new MorphoProtocolPlugin() + morphoProtocolPlugin.initialize({ context: ctx, }) }) diff --git a/sdk/protocol-plugins/tests/integration/SparkProtocolPlugin.spec.ts b/sdk/protocol-plugins/tests/integration/SparkProtocolPlugin.spec.ts index a80318084a..f29964656b 100644 --- a/sdk/protocol-plugins/tests/integration/SparkProtocolPlugin.spec.ts +++ b/sdk/protocol-plugins/tests/integration/SparkProtocolPlugin.spec.ts @@ -21,7 +21,8 @@ describe.only('Spark Protocol Plugin (Integration)', () => { beforeAll(async () => { ctx = await createProtocolPluginContext(ChainFamilyMap.Ethereum.Mainnet) validSparkPoolId = await getSparkPoolIdMock() - sparkProtocolPlugin = new SparkProtocolPlugin({ + sparkProtocolPlugin = new SparkProtocolPlugin() + sparkProtocolPlugin.initialize({ context: ctx, }) }) diff --git a/sdk/protocol-plugins/tests/mocks/AAVEv3PoolIdMock.ts b/sdk/protocol-plugins/tests/mocks/AAVEv3PoolIdMock.ts index af1e16f156..a14bf38c86 100644 --- a/sdk/protocol-plugins/tests/mocks/AAVEv3PoolIdMock.ts +++ b/sdk/protocol-plugins/tests/mocks/AAVEv3PoolIdMock.ts @@ -21,7 +21,7 @@ export async function getAaveV3PoolIdMock(): Promise { return AaveV3LendingPoolId.createFrom({ protocol: AaveV3Protocol.createFrom({ - name: ProtocolName.AAVEv3, + name: ProtocolName.AaveV3, chainInfo, }), debtToken: DAI, diff --git a/sdk/protocol-plugins/tests/mocks/MorphoPoolIdMock.ts b/sdk/protocol-plugins/tests/mocks/MorphoPoolIdMock.ts index 91c9f33a45..0a5ffbbf1a 100644 --- a/sdk/protocol-plugins/tests/mocks/MorphoPoolIdMock.ts +++ b/sdk/protocol-plugins/tests/mocks/MorphoPoolIdMock.ts @@ -16,7 +16,7 @@ import { export const morphoPoolIdMock: IMorphoLendingPoolId = MorphoLendingPoolId.createFrom({ protocol: MorphoProtocol.createFrom({ - name: ProtocolName.Morpho, + name: ProtocolName.MorphoBlue, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }), marketId: '0xc54d7acf14de29e0e5527cabd7a576506870346a78a11a6762e2cca66322ec41', diff --git a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoBorrowAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoBorrowAction.spec.ts index eeaebf1e3f..7a899859c1 100644 --- a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoBorrowAction.spec.ts +++ b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoBorrowAction.spec.ts @@ -39,7 +39,7 @@ describe('MorphoBorrowAction Action', () => { const tokenAmount = TokenAmount.createFrom({ token: DAI, amount: '578' }) const morphoProtocol = MorphoProtocol.createFrom({ - name: ProtocolName.Morpho, + name: ProtocolName.MorphoBlue, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }) diff --git a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoDepositAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoDepositAction.spec.ts index 0743a0a74e..31b8b0914c 100644 --- a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoDepositAction.spec.ts +++ b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoDepositAction.spec.ts @@ -39,7 +39,7 @@ describe('MorphoDepositAction Action', () => { const tokenAmount = TokenAmount.createFrom({ token: DAI, amount: '578' }) const morphoProtocol = MorphoProtocol.createFrom({ - name: ProtocolName.Morpho, + name: ProtocolName.MorphoBlue, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }) diff --git a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoPaybackAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoPaybackAction.spec.ts index c4b0cbe58c..71e68be6de 100644 --- a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoPaybackAction.spec.ts +++ b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoPaybackAction.spec.ts @@ -43,7 +43,7 @@ describe('MorphoPaybackAction Action', () => { const tokenAmount = TokenAmount.createFrom({ token: DAI, amount: '578' }) const morphoProtocol = MorphoProtocol.createFrom({ - name: ProtocolName.Morpho, + name: ProtocolName.MorphoBlue, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }) diff --git a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoWithdrawAction.spec.ts b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoWithdrawAction.spec.ts index 45545d2b4d..13a8c693c1 100644 --- a/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoWithdrawAction.spec.ts +++ b/sdk/protocol-plugins/tests/unit/actions/morpho/MorphoWithdrawAction.spec.ts @@ -43,7 +43,7 @@ describe('MorphoWithdrawAction Action', () => { const tokenAmount = TokenAmount.createFrom({ token: DAI, amount: '578' }) const morphoProtocol = MorphoProtocol.createFrom({ - name: ProtocolName.Morpho, + name: ProtocolName.MorphoBlue, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts index 08dc7152c1..37591bff59 100644 --- a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts @@ -59,7 +59,7 @@ describe('AaveV3 Deposit Borrow Action Builder', () => { }) const protocol = AaveV3Protocol.createFrom({ - name: ProtocolName.AAVEv3, + name: ProtocolName.AaveV3, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3OpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3OpenPositionActionBuilder.spec.ts index daa6b6247e..c84c41ed38 100644 --- a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3OpenPositionActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3OpenPositionActionBuilder.spec.ts @@ -58,7 +58,7 @@ describe('AaveV3 Open Position Action Builder', () => { }) const protocol = AaveV3Protocol.createFrom({ - name: ProtocolName.AAVEv3, + name: ProtocolName.AaveV3, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts index 1311d7b5b6..8c31b47a36 100644 --- a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts @@ -59,7 +59,7 @@ describe('AaveV3 Payback Withdraw Action Builder', () => { }) const protocol = AaveV3Protocol.createFrom({ - name: ProtocolName.AAVEv3, + name: ProtocolName.AaveV3, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/maker/MakerImportPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/maker/MakerImportPositionActionBuilder.spec.ts index 11d1abd25a..a21734882a 100644 --- a/sdk/protocol-plugins/tests/unit/builders/maker/MakerImportPositionActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/maker/MakerImportPositionActionBuilder.spec.ts @@ -103,7 +103,7 @@ describe('Maker Import Position Action Builder', () => { id: MorphoLendingPoolId.createFrom({ marketId: '0x1234', protocol: MorphoProtocol.createFrom({ - name: ProtocolName.Morpho, + name: ProtocolName.MorphoBlue, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }), }), diff --git a/sdk/protocol-plugins/tests/unit/builders/maker/MakerOpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/maker/MakerOpenPositionActionBuilder.spec.ts index 3a51a32b20..593e2b51dd 100644 --- a/sdk/protocol-plugins/tests/unit/builders/maker/MakerOpenPositionActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/maker/MakerOpenPositionActionBuilder.spec.ts @@ -92,7 +92,7 @@ describe('Maker Open Position Action Builder', () => { id: MorphoLendingPoolId.createFrom({ marketId: '0x1234', protocol: MorphoProtocol.createFrom({ - name: ProtocolName.Morpho, + name: ProtocolName.MorphoBlue, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }), }), diff --git a/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts index ce32551b32..1d7c045225 100644 --- a/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts @@ -98,7 +98,7 @@ describe('Maker Payback Withdraw Action Builder', () => { id: MorphoLendingPoolId.createFrom({ marketId: '0x1234', protocol: MorphoProtocol.createFrom({ - name: ProtocolName.Morpho, + name: ProtocolName.MorphoBlue, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }), }), diff --git a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts index be5f917756..6d63b4a36e 100644 --- a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts @@ -62,7 +62,7 @@ describe('Morpho Deposit Borrow Action Builder', () => { }) const protocol = MorphoProtocol.createFrom({ - name: ProtocolName.Morpho, + name: ProtocolName.MorphoBlue, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoOpenPositionActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoOpenPositionActionBuilder.spec.ts index ce7a3fe814..76913c2708 100644 --- a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoOpenPositionActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoOpenPositionActionBuilder.spec.ts @@ -9,7 +9,7 @@ import { Token, TokenAmount, } from '@summerfi/sdk-common/common' -import { SimulationSteps, TokenTransferTargetType, steps } from '@summerfi/sdk-common/simulation' +import { SimulationSteps, steps } from '@summerfi/sdk-common/simulation' import { SetupBuilderReturnType, setupBuilderParams } from '../../../utils/SetupBuilderParams' import { PoolType, ProtocolName } from '@summerfi/sdk-common/protocols' import { getErrorMessage } from '@summerfi/testing-utils' @@ -60,7 +60,7 @@ describe('Morpho Open Position Action Builder', () => { }) const protocol = MorphoProtocol.createFrom({ - name: ProtocolName.Morpho, + name: ProtocolName.MorphoBlue, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }) diff --git a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts index 78ff57b58a..0b71224781 100644 --- a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts @@ -60,7 +60,7 @@ describe('Morpho Payback Withdraw Action Builder', () => { }) const protocol = MorphoProtocol.createFrom({ - name: ProtocolName.Morpho, + name: ProtocolName.MorphoBlue, chainInfo: ChainFamilyMap.Ethereum.Mainnet, }) diff --git a/sdk/protocol-plugins/tests/unit/plugins/AAVEv3ProtocolPlugin.spec.ts b/sdk/protocol-plugins/tests/unit/plugins/AAVEv3ProtocolPlugin.spec.ts index 2064e3eb03..e7db08fc58 100644 --- a/sdk/protocol-plugins/tests/unit/plugins/AAVEv3ProtocolPlugin.spec.ts +++ b/sdk/protocol-plugins/tests/unit/plugins/AAVEv3ProtocolPlugin.spec.ts @@ -19,7 +19,8 @@ describe('AAVEv3 Protocol Plugin', () => { beforeAll(async () => { ctx = await createProtocolPluginContext(ChainFamilyMap.Ethereum.Mainnet) aaveV3PoolIdMock = await getAaveV3PoolIdMock() - aaveV3ProtocolPlugin = new AaveV3ProtocolPlugin({ + aaveV3ProtocolPlugin = new AaveV3ProtocolPlugin() + aaveV3ProtocolPlugin.initialize({ context: ctx, }) }) @@ -70,7 +71,7 @@ describe('AAVEv3 Protocol Plugin', () => { it('should throw an error when calling getLendingPool with chain id missing from ctx', async () => { try { - new AaveV3ProtocolPlugin({ + new AaveV3ProtocolPlugin().initialize({ context: { ...ctx, provider: { @@ -93,7 +94,7 @@ describe('AAVEv3 Protocol Plugin', () => { const wrongChainId = 2 try { - new AaveV3ProtocolPlugin({ + new AaveV3ProtocolPlugin().initialize({ context: { ...ctx, provider: { diff --git a/sdk/protocol-plugins/tests/unit/plugins/BaseProtocolPlugin.spec.ts b/sdk/protocol-plugins/tests/unit/plugins/BaseProtocolPlugin.spec.ts index 8e1321e640..b6ebcd9115 100644 --- a/sdk/protocol-plugins/tests/unit/plugins/BaseProtocolPlugin.spec.ts +++ b/sdk/protocol-plugins/tests/unit/plugins/BaseProtocolPlugin.spec.ts @@ -11,15 +11,11 @@ describe('Base Protocol Plugin', () => { let baseProtocolPlugin: BaseProtocolPlugin beforeAll(async () => { ctx = await createProtocolPluginContext(ChainFamilyMap.Ethereum.Mainnet) - baseProtocolPlugin = new MakerProtocolPlugin({ - context: ctx, - }) + baseProtocolPlugin = new MakerProtocolPlugin() }) it('should correctly return the corresponding action builder for a given simulation step', () => { - const actionBuilder = baseProtocolPlugin.getActionBuilder({ - type: SimulationSteps.PaybackWithdraw, - } as steps.PaybackWithdrawStep) + const actionBuilder = baseProtocolPlugin.getActionBuilder(SimulationSteps.PaybackWithdraw) assert(actionBuilder, 'ActionBuilder is not defined') }) }) diff --git a/sdk/protocol-plugins/tests/unit/plugins/MakerProtocolPlugin.spec.ts b/sdk/protocol-plugins/tests/unit/plugins/MakerProtocolPlugin.spec.ts index 45b9dac2fe..68846c84fc 100644 --- a/sdk/protocol-plugins/tests/unit/plugins/MakerProtocolPlugin.spec.ts +++ b/sdk/protocol-plugins/tests/unit/plugins/MakerProtocolPlugin.spec.ts @@ -19,7 +19,8 @@ describe('Maker Protocol Plugin', () => { beforeAll(async () => { ctx = await createProtocolPluginContext(ChainFamilyMap.Ethereum.Mainnet) makerPoolIdMock = await getMakerPoolIdMock() - makerProtocolPlugin = new MakerProtocolPlugin({ + makerProtocolPlugin = new MakerProtocolPlugin() + makerProtocolPlugin.initialize({ context: ctx, }) }) @@ -34,7 +35,7 @@ describe('Maker Protocol Plugin', () => { ...makerPoolIdMock, protocol: { ...makerPoolIdMock.protocol, - name: ProtocolName.AAVEv3, + name: ProtocolName.AaveV3, }, } as unknown as IMakerLendingPoolIdData @@ -68,7 +69,7 @@ describe('Maker Protocol Plugin', () => { it('should throw an error when calling getPool with chain id missing from ctx', async () => { try { - new MakerProtocolPlugin({ + new MakerProtocolPlugin().initialize({ context: { ...ctx, provider: { @@ -89,7 +90,7 @@ describe('Maker Protocol Plugin', () => { it('should throw an error when calling getPool with an unsupported chain ID', async () => { const wrongChainId = 2 try { - new MakerProtocolPlugin({ + new MakerProtocolPlugin().initialize({ context: { ...ctx, provider: { diff --git a/sdk/protocol-plugins/tests/unit/plugins/MorphoProtocolPlugin.spec.ts b/sdk/protocol-plugins/tests/unit/plugins/MorphoProtocolPlugin.spec.ts index 3788de8cb6..b6c69d50a3 100644 --- a/sdk/protocol-plugins/tests/unit/plugins/MorphoProtocolPlugin.spec.ts +++ b/sdk/protocol-plugins/tests/unit/plugins/MorphoProtocolPlugin.spec.ts @@ -16,7 +16,8 @@ describe('Protocol Plugin | Unit | Morpho', () => { let morphoProtocolPlugin: MorphoProtocolPlugin beforeAll(async () => { ctx = await createProtocolPluginContext(ChainFamilyMap.Ethereum.Mainnet) - morphoProtocolPlugin = new MorphoProtocolPlugin({ + morphoProtocolPlugin = new MorphoProtocolPlugin() + morphoProtocolPlugin.initialize({ context: ctx, }) }) @@ -64,7 +65,7 @@ describe('Protocol Plugin | Unit | Morpho', () => { it('should throw an error when calling getPool with chain id missing from ctx', async () => { try { - new MorphoProtocolPlugin({ + new MorphoProtocolPlugin().initialize({ context: { ...ctx, provider: { @@ -85,7 +86,7 @@ describe('Protocol Plugin | Unit | Morpho', () => { it('should throw an error when calling getPool with an unsupported chain ID', async () => { const wrongChainId = 2 try { - new MorphoProtocolPlugin({ + new MorphoProtocolPlugin().initialize({ context: { ...ctx, provider: { diff --git a/sdk/protocol-plugins/tests/unit/plugins/SparkProtocolPlugin.spec.ts b/sdk/protocol-plugins/tests/unit/plugins/SparkProtocolPlugin.spec.ts index d31fc864e6..ffb141304a 100644 --- a/sdk/protocol-plugins/tests/unit/plugins/SparkProtocolPlugin.spec.ts +++ b/sdk/protocol-plugins/tests/unit/plugins/SparkProtocolPlugin.spec.ts @@ -19,7 +19,8 @@ describe('Spark Protocol Plugin', () => { beforeAll(async () => { ctx = await createProtocolPluginContext(ChainFamilyMap.Ethereum.Mainnet) sparkPoolIdMock = await getSparkPoolIdMock() - sparkProtocolPlugin = new SparkProtocolPlugin({ + sparkProtocolPlugin = new SparkProtocolPlugin() + sparkProtocolPlugin.initialize({ context: ctx, }) }) @@ -70,7 +71,7 @@ describe('Spark Protocol Plugin', () => { it('should throw an error when calling getPool with chain id missing from ctx', async () => { try { - new SparkProtocolPlugin({ + new SparkProtocolPlugin().initialize({ context: { ...ctx, provider: { @@ -91,7 +92,7 @@ describe('Spark Protocol Plugin', () => { it('should throw an error when calling getPool with an unsupported chain ID', async () => { const wrongChainId = 2 try { - new SparkProtocolPlugin({ + new SparkProtocolPlugin().initialize({ context: { ...ctx, provider: { diff --git a/sdk/protocol-plugins/tests/utils/ProtocolPluginMock.ts b/sdk/protocol-plugins/tests/utils/ProtocolPluginMock.ts index ca65bf81a1..0e3b0d51e7 100644 --- a/sdk/protocol-plugins/tests/utils/ProtocolPluginMock.ts +++ b/sdk/protocol-plugins/tests/utils/ProtocolPluginMock.ts @@ -4,6 +4,7 @@ import { ActionBuilderParams, ActionBuilderUsedAction, ActionBuildersMap, + FilterStep, IActionBuilder, IProtocolPlugin, IProtocolPluginContext, @@ -84,6 +85,10 @@ export class ProtocolPluginMock implements IProtocolPlugin { } context = undefined as unknown as IProtocolPluginContext + initialize(params: { context: IProtocolPluginContext }): void { + this.context = params.context + } + isLendingPoolId(candidate: unknown): candidate is IPoolId { return true } @@ -102,14 +107,17 @@ export class ProtocolPluginMock implements IProtocolPlugin { return undefined as unknown as IPosition } - getActionBuilder(step: T): Maybe> { - const builder = this.stepBuilders[step.type] + getActionBuilder< + StepType extends SimulationSteps, + Step extends FilterStep, + >(stepType: StepType): Maybe> { + const builder = this.stepBuilders[stepType] if (!builder) { return undefined } - return new builder() as IActionBuilder + return new builder() } async getImportPositionTransaction(params: { @@ -127,6 +135,10 @@ export class EmptyProtocolPluginMock implements IProtocolPlugin { stepBuilders: Partial = {} context = undefined as unknown as IProtocolPluginContext + initialize(params: { context: IProtocolPluginContext }): void { + this.context = params.context + } + isLendingPoolId(candidate: unknown): candidate is IPoolId { return true } @@ -145,14 +157,17 @@ export class EmptyProtocolPluginMock implements IProtocolPlugin { return undefined as unknown as IPosition } - getActionBuilder(step: T): Maybe> { - const builder = this.stepBuilders[step.type] + getActionBuilder< + StepType extends SimulationSteps, + Step extends FilterStep, + >(stepType: StepType): Maybe> { + const builder = this.stepBuilders[stepType] if (!builder) { return undefined } - return new builder() as IActionBuilder + return new builder() } async getImportPositionTransaction(params: { @@ -175,6 +190,10 @@ export class NoCheckpointProtocolPluginMock implements IProtocolPlugin { } context = undefined as unknown as IProtocolPluginContext + initialize(params: { context: IProtocolPluginContext }): void { + this.context = params.context + } + isLendingPoolId(candidate: unknown): candidate is IPoolId { return true } @@ -193,14 +212,17 @@ export class NoCheckpointProtocolPluginMock implements IProtocolPlugin { return undefined as unknown as IPosition } - getActionBuilder(step: T): Maybe> { - const builder = this.stepBuilders[step.type] + getActionBuilder< + StepType extends SimulationSteps, + Step extends FilterStep, + >(stepType: StepType): Maybe> { + const builder = this.stepBuilders[stepType] if (!builder) { return undefined } - return new builder() as IActionBuilder + return new builder() } async getImportPositionTransaction(params: { diff --git a/sdk/protocol-plugins/tests/utils/ProtocolsPluginRegistryMock.ts b/sdk/protocol-plugins/tests/utils/ProtocolsPluginRegistryMock.ts index bb76e24605..4c9a5d1d07 100644 --- a/sdk/protocol-plugins/tests/utils/ProtocolsPluginRegistryMock.ts +++ b/sdk/protocol-plugins/tests/utils/ProtocolsPluginRegistryMock.ts @@ -30,9 +30,9 @@ export function createProtocolPluginsRegistry(): IProtocolPluginsRegistry { return new ProtocolPluginsRegistry({ plugins: { [ProtocolName.Maker]: ProtocolPluginMock, - [ProtocolName.AAVEv3]: ProtocolPluginMock, + [ProtocolName.AaveV3]: ProtocolPluginMock, [ProtocolName.Spark]: ProtocolPluginMock, - [ProtocolName.Morpho]: ProtocolPluginMock, + [ProtocolName.MorphoBlue]: ProtocolPluginMock, }, context: protocolPluginContext, }) diff --git a/sdk/sdk-common/src/protocols/enums/ProtocolName.ts b/sdk/sdk-common/src/protocols/enums/ProtocolName.ts index 2823fae6f2..05005f43b7 100644 --- a/sdk/sdk-common/src/protocols/enums/ProtocolName.ts +++ b/sdk/sdk-common/src/protocols/enums/ProtocolName.ts @@ -5,10 +5,10 @@ import { z } from 'zod' * @description Enumerates the names of the protocols that are supported by the SDK */ export enum ProtocolName { - AAVEv3 = 'AAVEv3', - AAVEv2 = 'AAVEv2', + AaveV3 = 'AaveV3', + AaveV2 = 'AaveV2', Spark = 'Spark', - Morpho = 'Morpho', + MorphoBlue = 'MorphoBlue', Maker = 'Maker', Ajna = 'Ajna', } diff --git a/sdk/sdk-e2e/tests/refinanceAaveV3SparkAnyPair.test.ts b/sdk/sdk-e2e/tests/refinanceAaveV3SparkAnyPair.test.ts index 53b6aa0112..40a9d85d3b 100644 --- a/sdk/sdk-e2e/tests/refinanceAaveV3SparkAnyPair.test.ts +++ b/sdk/sdk-e2e/tests/refinanceAaveV3SparkAnyPair.test.ts @@ -89,7 +89,7 @@ describe.skip('Refinance AaveV3 Spark | SDK', () => { }) assert(collateralToken, `${config.collateralTokenSymbol} not found`) - const aaveV3 = await chain.protocols.getProtocol({ name: ProtocolName.AAVEv3 }) + const aaveV3 = await chain.protocols.getProtocol({ name: ProtocolName.AaveV3 }) assert(aaveV3, 'AaveV3 protocol not found') if (!isAaveV3Protocol(aaveV3)) { diff --git a/sdk/sdk-e2e/tests/refinanceMorphoSparkAnyPair.test.ts b/sdk/sdk-e2e/tests/refinanceMorphoSparkAnyPair.test.ts index 6c5042b384..f45914dcde 100644 --- a/sdk/sdk-e2e/tests/refinanceMorphoSparkAnyPair.test.ts +++ b/sdk/sdk-e2e/tests/refinanceMorphoSparkAnyPair.test.ts @@ -89,7 +89,7 @@ describe.skip('Refinance Morpho Spark | SDK', () => { }) assert(collateralToken, `${config.collateralTokenSymbol} not found`) - const morpho = await chain.protocols.getProtocol({ name: ProtocolName.Morpho }) + const morpho = await chain.protocols.getProtocol({ name: ProtocolName.MorphoBlue }) assert(morpho, 'Maker protocol not found') if (!isMorphoProtocol(morpho)) { diff --git a/sdk/sdk-server/src/context/CreateProtocolPluginsRegistry.ts b/sdk/sdk-server/src/context/CreateProtocolPluginsRegistry.ts index cb0c95d312..8b21352e92 100644 --- a/sdk/sdk-server/src/context/CreateProtocolPluginsRegistry.ts +++ b/sdk/sdk-server/src/context/CreateProtocolPluginsRegistry.ts @@ -1,14 +1,5 @@ -import { AaveV3ProtocolPlugin } from '@summerfi/protocol-plugins/plugins/aave-v3' -import { - ProtocolPluginsRecordType, - ProtocolPluginsRegistry, -} from '@summerfi/protocol-plugins/implementation' -import { SparkProtocolPlugin } from '@summerfi/protocol-plugins/plugins/spark' -import { MakerProtocolPlugin } from '@summerfi/protocol-plugins/plugins/maker' -import { MorphoProtocolPlugin } from '@summerfi/protocol-plugins/plugins/morphoblue' - +import { ProtocolPluginsRecord, ProtocolPluginsRegistry } from '@summerfi/protocol-plugins' import { IProtocolPluginsRegistry } from '@summerfi/protocol-plugins-common' -import { ProtocolName } from '@summerfi/sdk-common/protocols' import { createPublicClient, http } from 'viem' import { mainnet } from 'viem/chains' import { ISwapManager } from '@summerfi/swap-common/interfaces' @@ -21,18 +12,6 @@ import { ITokensManager } from '@summerfi/tokens-common' import { IOracleManager } from '@summerfi/oracle-common' import { IAddressBookManager } from '@summerfi/address-book-common' -/** - * Protocol plugins record - * - * Note: add here the plugins you want to use in the SDK - */ -const ProtocolPlugins: ProtocolPluginsRecordType = { - [ProtocolName.Maker]: MakerProtocolPlugin, - [ProtocolName.Spark]: SparkProtocolPlugin, - [ProtocolName.AAVEv3]: AaveV3ProtocolPlugin, - [ProtocolName.Morpho]: MorphoProtocolPlugin, -} - /** * RPC configuration for the RPC Gateway */ @@ -83,7 +62,7 @@ export function createProtocolsPluginsRegistry(params: { }) return new ProtocolPluginsRegistry({ - plugins: ProtocolPlugins, + plugins: ProtocolPluginsRecord, context: { provider, tokensManager, diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/paybackWithdrawReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/paybackWithdrawReducer.ts index fc4d4ac80b..e0d91c4afa 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/paybackWithdrawReducer.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/paybackWithdrawReducer.ts @@ -7,12 +7,10 @@ export function paybackWithdrawReducer( step: steps.PaybackWithdrawStep, state: ISimulationState, ): ISimulationState { + const paybackAmount = getValueFromReference(step.inputs.paybackAmount) const withdrawAmount = getValueFromReference(step.inputs.withdrawAmount) - const afterPayback = addBalance(withdrawAmount, state.balances) - const afterWithdraw = subtractBalance( - getValueFromReference(step.inputs.withdrawAmount), - afterPayback, - ) + const afterPayback = subtractBalance(paybackAmount, state.balances) + const afterWithdraw = addBalance(withdrawAmount, afterPayback) return { ...state, positions: { diff --git a/sdk/simulator-service/src/strategies/StrategyIndex.ts b/sdk/simulator-service/src/strategies/StrategyIndex.ts new file mode 100644 index 0000000000..6b2369429a --- /dev/null +++ b/sdk/simulator-service/src/strategies/StrategyIndex.ts @@ -0,0 +1,12 @@ +import { refinanceLendingToLendingSamePairStrategy } from './refinanceSamePair/Strategy' +import { refinanceLendingToLendingAnyPairStrategy } from './refinanceAnyPair/Strategy' +import { refinanceLendingToLendingNoDebtStrategy } from './refinanceNoDebt/Strategy' + +/** + * List of all strategies so the strategy definition generation tool can use them + */ +export const StrategyIndex = [ + refinanceLendingToLendingSamePairStrategy, + refinanceLendingToLendingAnyPairStrategy, + refinanceLendingToLendingNoDebtStrategy, +] diff --git a/sdk/simulator-service/tsconfig.json b/sdk/simulator-service/tsconfig.json index 6e6486dd1f..bbfa557d0a 100644 --- a/sdk/simulator-service/tsconfig.json +++ b/sdk/simulator-service/tsconfig.json @@ -6,5 +6,5 @@ "baseUrl": "." }, "include": ["src/**/*.ts", "tests/**/*.ts"], - "exclude": ["node_modules"] + "exclude": ["node_modules", "dist"] } diff --git a/sdk/tools/genStrategyDefinitions/.eslintrc.cjs b/sdk/tools/genStrategyDefinitions/.eslintrc.cjs new file mode 100644 index 0000000000..8eb0f19d5c --- /dev/null +++ b/sdk/tools/genStrategyDefinitions/.eslintrc.cjs @@ -0,0 +1,7 @@ +/** @type {import("eslint").Linter.Config} */ +module.exports = { + root: true, + ignorePatterns: ['jest.config.js', 'tests'], + extends: ['@summerfi/eslint-config/library.cjs'], + parser: '@typescript-eslint/parser', +} diff --git a/sdk/tools/genStrategyDefinitions/README.md b/sdk/tools/genStrategyDefinitions/README.md new file mode 100644 index 0000000000..38ee027b64 --- /dev/null +++ b/sdk/tools/genStrategyDefinitions/README.md @@ -0,0 +1,20 @@ +## Summer.fi Tools + +# encode:makerGive + +Generates the calldata necessary to give a Maker position (CDP) to another address. This is done by +executing the calldata on a DsProxy or DPM and using the CdpManager proxy actions to delegate the +call. The parameters of the tool are: + +``` +Options: + -p, --makerProxyActions Maker Proxy Actions address + -c, --cdpManager Maker CDP Manager address + -i, --cdpId ID of the position to give + -t, --to Address to give the CDP to + -h, --help Show help +``` + +# strategy:gen + +Generates the strategy definitions for the Summer.fi protocol. The parameters of the tool are: diff --git a/sdk/tools/genStrategyDefinitions/bundle/package.json b/sdk/tools/genStrategyDefinitions/bundle/package.json new file mode 100644 index 0000000000..0327851e48 --- /dev/null +++ b/sdk/tools/genStrategyDefinitions/bundle/package.json @@ -0,0 +1,9 @@ +{ + "name": "@summer_fi/gen-strategy-definitions", + "version": "0.0.1", + "module": "dist/index.js", + "types": "dist/index.d.ts", + "packageManager": "yarn@1.22.21", + "scripts": {}, + "dependencies": {} +} diff --git a/sdk/tools/genStrategyDefinitions/jest.config.js b/sdk/tools/genStrategyDefinitions/jest.config.js new file mode 100644 index 0000000000..47ec2d384e --- /dev/null +++ b/sdk/tools/genStrategyDefinitions/jest.config.js @@ -0,0 +1,15 @@ +const { compilerOptions } = require('./tsconfig.test') +const sharedConfig = require('@summerfi/jest-config/jest.base') + +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + ...sharedConfig(compilerOptions), + collectCoverageFrom: [ + '/**/*.{ts,tsx}', + '!src/**/index.ts', + '!src/config/Config.ts', + '!src/interfaces/IOrderPlannerService.ts', + '!src/utils/**/*.{ts,tsx}', + ], + coveragePathIgnorePatterns: ['/tests/utils/', '/tests/mocks/'], +} diff --git a/sdk/tools/genStrategyDefinitions/package.json b/sdk/tools/genStrategyDefinitions/package.json new file mode 100644 index 0000000000..384cf264d9 --- /dev/null +++ b/sdk/tools/genStrategyDefinitions/package.json @@ -0,0 +1,29 @@ +{ + "name": "@summerfi/get-strategy-definitions", + "version": "0.0.1", + "scripts": { + "tsc": "tsc", + "watch": "tsc -w", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "build": "tsc -b tsconfig.build.json", + "bundle:npm": "esbuild src/index.ts --platform=node --target=es2020 --conditions= --main-fields=main --bundle --sourcemap --outfile=bundle/dist/index.js --external:crypto --external:tls --external:https --external:net --external:http --external:stream --external:zlib --external:assert --keep-names && tsc --emitDeclarationOnly --outDir bundle/dist -p tsconfig.build.json", + "strategy:gen": "pnpm bundle:npm; node ./bundle/dist/index.js" + }, + "dependencies": { + "@summerfi/order-planner-service": "workspace:*", + "@summerfi/protocol-plugins": "workspace:*", + "@summerfi/protocol-plugins-common": "workspace:*", + "@summerfi/sdk-common": "workspace:*", + "@summerfi/simulator-service": "workspace:*" + }, + "devDependencies": { + "@morpho-labs/gnosis-tx-builder": "^2.0.0", + "@summerfi/eslint-config": "workspace:*", + "@summerfi/jest-config": "workspace:*", + "@summerfi/typescript-config": "workspace:*", + "@types/yargs": "^17.0.32", + "tsx": "^4.7.2", + "yargs": "^17.7.2" + } +} diff --git a/sdk/tools/genStrategyDefinitions/src/Helpers.ts b/sdk/tools/genStrategyDefinitions/src/Helpers.ts new file mode 100644 index 0000000000..3dea8fa865 --- /dev/null +++ b/sdk/tools/genStrategyDefinitions/src/Helpers.ts @@ -0,0 +1,207 @@ +import { ActionBuildersConfig } from '@summerfi/order-planner-service/config/Config' +import { ProtocolPluginsRecord } from '@summerfi/protocol-plugins' +import { ActionBuilderUsedAction } from '@summerfi/protocol-plugins-common' +import { SimulationStrategy, StrategyStep } from '@summerfi/sdk-common/simulation' +import { + OperationDefinition, + OperationDefinitions, + StrategyDefinitions, + Transactions, +} from './Types' +import { TxBuilder } from '@morpho-labs/gnosis-tx-builder' +import { AddressValue, HexData } from '@summerfi/sdk-common' +import { encodeFunctionData, parseAbi } from 'viem' +import { BatchFile } from '@morpho-labs/gnosis-tx-builder/lib/src/types' + +const DISABLE_OPTIONALS = true + +export function generateSafeMultisendJSON( + safeAddress: AddressValue, + operationsRegistryAddress: AddressValue, + operationDefinitions: OperationDefinitions, +): BatchFile { + const transactions = generateTransactions(operationsRegistryAddress, operationDefinitions) + + return TxBuilder.batch(safeAddress, transactions) +} + +export function generateTransactions( + safeAddress: AddressValue, + operationDefinitions: OperationDefinitions, +): Transactions { + return operationDefinitions.map((operationDefinition) => { + return { + to: safeAddress, + value: '0', + data: encodeOpRegistryParameters(operationDefinition), + } + }) +} + +export function encodeOpRegistryParameters(operationDefinition: OperationDefinition): HexData { + const opRegistryAbi = parseAbi(['function addOperation((bytes32[],bool[], string))']) + + return encodeFunctionData({ + abi: opRegistryAbi, + functionName: 'addOperation', + args: [[operationDefinition.actions, operationDefinition.optional, operationDefinition.name]], + }) +} + +export function generateOperationDefinitions( + strategyName: string, + strategyDefinitions: StrategyDefinitions, +): OperationDefinitions { + return strategyDefinitions.map((strategy) => { + const paybackAction = strategy.find((action) => { + return action.name.includes('Payback') + }) + + const depositAction = strategy.find((action) => { + return action.name.includes('Deposit') + }) + + if (!paybackAction || !depositAction) { + throw new Error('Cannot find payback or deposit action') + } + + const fromProtocol = paybackAction.name.split('Payback')[0] + const toProtocol = depositAction.name.split('Deposit')[0] + + return { + actions: strategy.map((action) => action.hash), + optional: strategy.map((action) => action.optional), + name: `${strategyName}${fromProtocol}${toProtocol}`, + } + }) +} + +export function processStrategies(strategyConfigs: SimulationStrategy[]): StrategyDefinitions { + const strategyDefinitions = strategyConfigs.reduce((acc, strategy) => { + acc.push(...processStrategy(strategy)) + + return acc + }, [] as StrategyDefinitions) + + return filterDuplicateStrategies(strategyDefinitions) +} + +export function processStrategy(strategyConfig: SimulationStrategy): StrategyDefinitions { + const strategyDefinitions = strategyConfig.reduce( + (acc, stepConfig) => { + const suffixes = processStep(stepConfig) + return combinePrefixesAndSuffixes(acc, suffixes) + }, + [[]] as StrategyDefinitions, + ) + + return filterIncompatibleStrategies(strategyDefinitions) +} + +export function processActionsList( + stepConfig: StrategyStep, + actionsList: ActionBuilderUsedAction[], +): StrategyDefinitions { + return actionsList.reduce( + (acc, actionConfig) => { + const suffixes = processAction(stepConfig, actionConfig) + return combinePrefixesAndSuffixes(acc, suffixes) + }, + [[]] as StrategyDefinitions, + ) +} + +export function processStep(stepConfig: StrategyStep): StrategyDefinitions { + const stepDefinitions = processActionsList( + stepConfig, + new ActionBuildersConfig[stepConfig.step]().actions, + ) + + if (!DISABLE_OPTIONALS && stepConfig.optional) { + return [...stepDefinitions, []] + } else { + return stepDefinitions + } +} + +export function processAction( + stepConfig: StrategyStep, + actionConfig: ActionBuilderUsedAction, +): StrategyDefinitions { + if (actionConfig.action === 'DelegatedToProtocol') { + return processDelegateToProtocol(stepConfig) + } + const action = new actionConfig.action() + const definition = [ + [ + { + name: action.config.name, + hash: action.getActionHash(), + optional: + DISABLE_OPTIONALS || stepConfig.optional || actionConfig.isOptionalTags !== undefined, + }, + ], + ] + + if (!DISABLE_OPTIONALS && actionConfig.isOptionalTags !== undefined) { + definition.push([]) + } + + return definition +} + +export function processDelegateToProtocol(stepConfig: StrategyStep): StrategyDefinitions { + return Object.values(ProtocolPluginsRecord).reduce((acc, pluginClass) => { + const plugin = new pluginClass() + + const pluginBuilder = plugin.getActionBuilder(stepConfig.step) + if (!pluginBuilder) { + return acc + } + + const suffixes = processActionsList(stepConfig, pluginBuilder.actions) + acc.push(...suffixes) + return acc + }, [] as StrategyDefinitions) +} + +export function combinePrefixesAndSuffixes( + prefixes: StrategyDefinitions, + suffixes: StrategyDefinitions, +): StrategyDefinitions { + return suffixes.reduce((acc, suffix) => { + acc.push(...prefixes.map((prefix) => [...prefix, ...suffix])) + return acc + }, [] as StrategyDefinitions) +} + +export function filterIncompatibleStrategies(strategies: StrategyDefinitions): StrategyDefinitions { + return strategies.filter((strategy) => { + const strategyLowercase = strategy.map((action) => action.name.toLowerCase()) + + const setEmodeAction = strategyLowercase.find((action) => { + return action.includes('setemode') + }) + + const depositAction = strategyLowercase.find((action) => { + return action.includes('deposit') + }) + + if (setEmodeAction === undefined && depositAction !== undefined) { + const protocol = depositAction.split('deposit')[0] + + return protocol !== 'aavev3' && protocol !== 'spark' + } + + const setEmodeProtocol = setEmodeAction?.split('setemode')[0] + const depositProtocol = depositAction?.split('deposit')[0] + + return setEmodeProtocol === depositProtocol + }) +} + +export function filterDuplicateStrategies(strategies: StrategyDefinitions): StrategyDefinitions { + return strategies.filter((strategy, index) => { + return strategies.findIndex((s) => JSON.stringify(s) === JSON.stringify(strategy)) === index + }) +} diff --git a/sdk/tools/genStrategyDefinitions/src/Types.ts b/sdk/tools/genStrategyDefinitions/src/Types.ts new file mode 100644 index 0000000000..223124ec68 --- /dev/null +++ b/sdk/tools/genStrategyDefinitions/src/Types.ts @@ -0,0 +1,15 @@ +import { AddressValue, HexData } from '@summerfi/sdk-common' + +export type ActionDefinition = { name: string; hash: HexData; optional: boolean } +export type StrategyDefinition = ActionDefinition[] +export type StrategyDefinitions = StrategyDefinition[] + +export type OperationDefinition = { actions: HexData[]; optional: boolean[]; name: string } +export type OperationDefinitions = OperationDefinition[] + +export type Transaction = { + to: AddressValue + value: string + data: HexData +} +export type Transactions = Transaction[] diff --git a/sdk/tools/genStrategyDefinitions/src/index.ts b/sdk/tools/genStrategyDefinitions/src/index.ts new file mode 100644 index 0000000000..052b6bb844 --- /dev/null +++ b/sdk/tools/genStrategyDefinitions/src/index.ts @@ -0,0 +1,71 @@ +import { + generateOperationDefinitions, + generateSafeMultisendJSON, + processStrategies, +} from './Helpers' +import yargs from 'yargs' +import fs from 'fs' +import { refinanceLendingToLendingAnyPairStrategy } from '@summerfi/simulator-service/strategies' +import { AddressValue } from '@summerfi/sdk-common' + +async function main() { + const args = await yargs(process.argv.slice(2)) + .option('output', { + alias: 'o', + description: 'Output file path', + type: 'string', + }) + .option('safe', { + alias: 's', + description: 'Address of the Safe multisig', + type: 'string', + }) + .option('registry', { + alias: 'r', + description: 'Address of the Operations Registry', + type: 'string', + }) + .option('format', { + alias: 'f', + description: 'Output format (safe, tenderly)', + default: 'safe', + type: 'string', + }) + .demandOption(['output', 'safe', 'registry']) + .help() + .alias('help', 'h').argv + + const strategyDefinitions = processStrategies([refinanceLendingToLendingAnyPairStrategy]) + + const operationDefinitions = generateOperationDefinitions('Refinance', strategyDefinitions) + + const safeBatch = generateSafeMultisendJSON( + args.safe as AddressValue, + args.registry as AddressValue, + operationDefinitions, + ) + + if (args.output) { + console.log(`Writing to ${args.output}`) + + // Write to file + if (args.format === 'safe') { + fs.writeFileSync(args.output, JSON.stringify(safeBatch, null, 2)) + } else { + fs.writeFileSync(args.output, JSON.stringify(operationDefinitions, null, 2)) + } + } else { + console.log('--------------------') + console.log(JSON.stringify(strategyDefinitions, null, 2)) + console.log('--------------------') + } + + console.log(`Strategy Definitions (${operationDefinitions.length})`) +} + +main() + .catch((error) => { + console.error(error) + process.exit(1) + }) + .then(() => process.exit(0)) diff --git a/sdk/tools/genStrategyDefinitions/tsconfig.build.json b/sdk/tools/genStrategyDefinitions/tsconfig.build.json new file mode 100644 index 0000000000..b909ecaa0e --- /dev/null +++ b/sdk/tools/genStrategyDefinitions/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + // by using a separate tsconfig for build, we can set main tsconfig to + // include tests and use module paths in tests but build without tests + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "src" + }, + "include": ["src/**/*.ts"] +} diff --git a/sdk/tools/genStrategyDefinitions/tsconfig.json b/sdk/tools/genStrategyDefinitions/tsconfig.json new file mode 100644 index 0000000000..629f57d79f --- /dev/null +++ b/sdk/tools/genStrategyDefinitions/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "@summerfi/typescript-config/tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "baseUrl": ".", + "paths": { + "@summerfi/simulator-service/*": ["node_modules/@summerfi/simulator-service/src/*"], + "@summerfi/order-planner-service/*": ["node_modules/@summerfi/order-planner-service/src/*"], + "@summerfi/protocol-plugins": ["node_modules/@summerfi/protocol-plugins/src/index.ts"], + "@summerfi/protocol-plugins-common": [ + "node_modules/@summerfi/protocol-plugins-common/src/index.ts" + ], + "@summerfi/sdk-common": ["node_modules/@summerfi/sdk-common/src/index.ts"] + } + }, + "include": ["src/**/*.ts", "tests/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/sdk/tools/genStrategyDefinitions/tsconfig.test.json b/sdk/tools/genStrategyDefinitions/tsconfig.test.json new file mode 100644 index 0000000000..cad3192432 --- /dev/null +++ b/sdk/tools/genStrategyDefinitions/tsconfig.test.json @@ -0,0 +1,9 @@ +{ + "extends": "@summerfi/typescript-config/tsconfig.test.json", + "compilerOptions": { + "rootDir": "src", + "baseUrl": "." + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules"] +} From 41d579cd1aca9f4ac63e5ec53c176e372986cbf3 Mon Sep 17 00:00:00 2001 From: Halaprix Date: Mon, 27 May 2024 13:46:35 +0200 Subject: [PATCH 24/37] chore: change point accrual function timeout to 300 seconds (#305) - the default `10` seconds is not enough to process all the points and insert them to the database --- stacks/rays.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/stacks/rays.ts b/stacks/rays.ts index 90526e0b56..e7e922d71f 100644 --- a/stacks/rays.ts +++ b/stacks/rays.ts @@ -50,6 +50,7 @@ export function addRaysConfig({ stack, api, vpc, app }: SummerStackContext) { const updateRaysCronFunctionProps: FunctionProps = { handler: 'background-jobs/update-rays-cron-function/src/index.handler', runtime: 'nodejs20.x', + timeout: '300 seconds', environment: { POWERTOOLS_LOG_LEVEL: process.env.POWERTOOLS_LOG_LEVEL || 'INFO', RAYS_DB_CONNECTION_STRING: RAYS_DB_WRITE_CONNECTION_STRING, From b3c387706d19dc9841c69b692695a99b44c8edcd Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Mon, 27 May 2024 13:48:30 +0200 Subject: [PATCH 25/37] feat: accept skippable actions in order planner (#298) --- .../src/implementation/OrderPlanner.ts | 1 + .../src/utils/EncodeStrategy.ts | 12 +- .../src/utils/GenerateStrategyName.ts | 12 -- .../src/config/Config.ts | 2 + .../tests/service/OrderPlannerService.spec.ts | 5 +- .../src/actions/BaseAction.ts | 1 + .../src/actions/SkippedAction.ts | 40 ++++++ .../src/actions/Types.ts | 6 +- .../src/actions/index.ts | 13 +- .../src/context/StepBuilderContext.ts | 13 ++ .../src/interfaces/IActionBuilder.ts | 1 + .../src/interfaces/IStepBuilderContext.ts | 2 + .../AaveV3DepositBorrowActionBuilder.ts | 28 ++-- .../AaveV3PaybackWithdrawActionBuilder.ts | 87 ++++++------ .../plugins/common/actions/FlashloanAction.ts | 16 +-- .../builders/SkippedStepActionBuilder.ts | 41 ++++++ .../src/plugins/common/builders/index.ts | 1 + .../MakerPaybackWithdrawActionBuilder.ts | 31 ++-- .../MorphoDepositBorrowActionBuilder.ts | 67 ++++----- .../MorphoPaybackWithdrawActionBuilder.ts | 62 ++++---- .../SparkDepositBorrowActionBuilder.ts | 27 ++-- .../SparkPaybackWithdrawActionBuilder.ts | 85 ++++++----- .../unit/actions/FlashloanAction.spec.ts | 2 + .../AaveV3DepositBorrowActionBuilder.spec.ts | 3 +- ...AaveV3PaybackWithdrawActionBuilder.spec.ts | 6 +- .../MakerPaybackWithdrawActionBuilder.spec.ts | 5 +- .../MorphoDepositBorrowActionBuilder.spec.ts | 7 +- ...MorphoPaybackWithdrawActionBuilder.spec.ts | 6 +- .../SparkDepositBorrowActionBuilder.spec.ts | 3 +- .../SparkPaybackWithdrawActionBuilder.spec.ts | 6 +- .../tests/utils/SetupBuilderParams.ts | 4 +- .../simulations/RefinanceSimulationManager.ts | 4 +- sdk/sdk-common/src/simulation/Enums.ts | 14 +- sdk/sdk-common/src/simulation/Steps.ts | 11 ++ sdk/sdk-e2e/tests/refinance.test.ts | 6 +- .../tests/refinanceAaveV3SparkAnyPair.test.ts | 15 +- ...refinanceMakerSparkAlreadyImported.test.ts | 4 +- .../tests/refinanceMakerSparkAnyPair.test.ts | 45 +++--- .../tests/refinanceMorphoSparkAnyPair.test.ts | 4 +- .../src/handlers/getRefinanceSimulation.ts | 17 +-- .../reducer/skippedStepReducer.ts | 12 ++ .../simulator-engine/reducer/stateReducers.ts | 2 + .../simulator-engine/simulator.ts | 19 ++- .../skippedStepOutputProcessor.ts | 9 ++ .../stepProcessor/stepOutputProcessors.ts | 2 + .../utils/GetRefinanceSimulationType.ts | 20 --- .../src/strategies/StrategyIndex.ts | 10 +- .../common/RefinanceStrategyRouter.ts | 45 ------ .../src/strategies/common/index.ts | 1 - sdk/simulator-service/src/strategies/index.ts | 4 +- .../RefinanceLendingToLendingAnyPair.ts | 117 ++++++++++------ .../Strategy.ts | 0 .../index.ts | 0 .../RefinanceLendingToLendingNoDebt.ts | 132 ------------------ .../strategies/refinanceNoDebt/Strategy.ts | 30 ---- .../src/strategies/refinanceNoDebt/index.ts | 2 - .../RefinanceLendingToLendingSamePair.ts | 129 ----------------- .../strategies/refinanceSamePair/Strategy.ts | 35 ----- .../src/strategies/refinanceSamePair/index.ts | 2 - sdk/simulator-service/tests/simulator.test.ts | 68 +-------- .../src/utils/StrategyExecutorDecoding.ts | 11 +- sdk/testing-utils/src/utils/index.ts | 11 +- sdk/tools/genStrategyDefinitions/src/index.ts | 6 +- 63 files changed, 519 insertions(+), 863 deletions(-) create mode 100644 sdk/protocol-plugins-common/src/actions/SkippedAction.ts create mode 100644 sdk/protocol-plugins/src/plugins/common/builders/SkippedStepActionBuilder.ts create mode 100644 sdk/simulator-service/src/implementation/simulator-engine/reducer/skippedStepReducer.ts create mode 100644 sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/skippedStepOutputProcessor.ts delete mode 100644 sdk/simulator-service/src/implementation/utils/GetRefinanceSimulationType.ts delete mode 100644 sdk/simulator-service/src/strategies/common/RefinanceStrategyRouter.ts rename sdk/simulator-service/src/strategies/{refinanceAnyPair => refinanceLendingToLending}/RefinanceLendingToLendingAnyPair.ts (71%) rename sdk/simulator-service/src/strategies/{refinanceAnyPair => refinanceLendingToLending}/Strategy.ts (100%) rename sdk/simulator-service/src/strategies/{refinanceAnyPair => refinanceLendingToLending}/index.ts (100%) delete mode 100644 sdk/simulator-service/src/strategies/refinanceNoDebt/RefinanceLendingToLendingNoDebt.ts delete mode 100644 sdk/simulator-service/src/strategies/refinanceNoDebt/Strategy.ts delete mode 100644 sdk/simulator-service/src/strategies/refinanceNoDebt/index.ts delete mode 100644 sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts delete mode 100644 sdk/simulator-service/src/strategies/refinanceSamePair/Strategy.ts delete mode 100644 sdk/simulator-service/src/strategies/refinanceSamePair/index.ts diff --git a/sdk/order-planner-common/src/implementation/OrderPlanner.ts b/sdk/order-planner-common/src/implementation/OrderPlanner.ts index 8113c93dbf..f12f398b73 100644 --- a/sdk/order-planner-common/src/implementation/OrderPlanner.ts +++ b/sdk/order-planner-common/src/implementation/OrderPlanner.ts @@ -53,6 +53,7 @@ export class OrderPlanner implements IOrderPlanner { addressBookManager, step, protocolsRegistry, + actionBuildersMap, }) } diff --git a/sdk/order-planner-common/src/utils/EncodeStrategy.ts b/sdk/order-planner-common/src/utils/EncodeStrategy.ts index 3d1a9cd9ed..699e557359 100644 --- a/sdk/order-planner-common/src/utils/EncodeStrategy.ts +++ b/sdk/order-planner-common/src/utils/EncodeStrategy.ts @@ -3,10 +3,6 @@ import { Address, HexData, Maybe } from '@summerfi/sdk-common/common' import { IPositionsManager, TransactionInfo } from '@summerfi/sdk-common/orders' import { encodeFunctionData, parseAbi } from 'viem' -type SkippableActionCall = ActionCall & { - skipped: boolean -} - function encodeForExecutor(params: { strategyName: string; actions: ActionCall[] }): HexData { const { strategyName, actions } = params @@ -15,16 +11,10 @@ function encodeForExecutor(params: { strategyName: string; actions: ActionCall[] 'struct Call { bytes32 targetHash; bytes callData; bool skipped; }', ]) - // TODO: Hiding this here for now as we don't support skippable actions anymore in the new version - const skippableActions: SkippableActionCall[] = actions.map((action) => ({ - ...action, - skipped: false, - })) - return encodeFunctionData({ abi, functionName: 'executeOp', - args: [skippableActions, strategyName], + args: [actions, strategyName], }) } diff --git a/sdk/order-planner-common/src/utils/GenerateStrategyName.ts b/sdk/order-planner-common/src/utils/GenerateStrategyName.ts index 1006abf536..6cd3715765 100644 --- a/sdk/order-planner-common/src/utils/GenerateStrategyName.ts +++ b/sdk/order-planner-common/src/utils/GenerateStrategyName.ts @@ -1,17 +1,5 @@ import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' export function generateStrategyName(simulation: ISimulation): string { - // TODO: temporary workaround to use the right simulation name - if ( - simulation.simulationType === SimulationType.Refinance || - simulation.simulationType === SimulationType.RefinanceDifferentPair || - simulation.simulationType === SimulationType.RefinanceDifferentCollateral || - simulation.simulationType === SimulationType.RefinanceDifferentDebt || - simulation.simulationType === SimulationType.RefinanceNoDebt || - simulation.simulationType === SimulationType.RefinanceNoDebtDifferentCollateral - ) { - return `Refinance${simulation.sourcePosition?.pool.id.protocol.name}${simulation.targetPosition.pool.id.protocol.name}` - } - return `${simulation.simulationType}${simulation.sourcePosition?.pool.id.protocol.name}${simulation.targetPosition?.pool.id.protocol.name}` } diff --git a/sdk/order-planner-service/src/config/Config.ts b/sdk/order-planner-service/src/config/Config.ts index 29b8af3e55..e64920cd8d 100644 --- a/sdk/order-planner-service/src/config/Config.ts +++ b/sdk/order-planner-service/src/config/Config.ts @@ -11,6 +11,7 @@ import { ReturnFundsActionBuilder, SwapActionBuilder, OpenPositionActionBuilder, + SkippedStepActionBuilder, } from '@summerfi/protocol-plugins/plugins/common' export const ActionBuildersConfig: ActionBuildersMap = { @@ -24,4 +25,5 @@ export const ActionBuildersConfig: ActionBuildersMap = { [SimulationSteps.NewPositionEvent]: PositionCreatedActionBuilder, [SimulationSteps.Import]: ImportPositionActionBuilder, [SimulationSteps.OpenPosition]: OpenPositionActionBuilder, + [SimulationSteps.Skipped]: SkippedStepActionBuilder, } diff --git a/sdk/order-planner-service/tests/service/OrderPlannerService.spec.ts b/sdk/order-planner-service/tests/service/OrderPlannerService.spec.ts index be9a7079fc..8a9275770d 100644 --- a/sdk/order-planner-service/tests/service/OrderPlannerService.spec.ts +++ b/sdk/order-planner-service/tests/service/OrderPlannerService.spec.ts @@ -15,14 +15,13 @@ import { getRefinanceSimulation } from '../utils/RefinanceSimulation/RefinanceSi import { OrderPlannerService } from '../../src/implementation/OrderPlannerService' import { decodeActionCalldata, - SkippableActionCall, decodePositionsManagerCalldata, decodeStrategyExecutorCalldata, getErrorMessage, } from '@summerfi/testing-utils' import assert from 'assert' import { IUser } from '@summerfi/sdk-common/user' -import { IProtocolPluginsRegistry } from '@summerfi/protocol-plugins-common' +import { ActionCall, IProtocolPluginsRegistry } from '@summerfi/protocol-plugins-common' import { http, createPublicClient } from 'viem' import { MakerPaybackAction, @@ -153,7 +152,7 @@ describe('Order Planner Service', () => { expect(flashloanCall.mapping).toEqual([0, 0, 0, 0]) /* Decode flashloan sub-calls */ - const flashloanSubcalls = flashloanCall.args[0].calls as SkippableActionCall[] + const flashloanSubcalls = flashloanCall.args[0].calls as ActionCall[] // PaybackWithdraw in Maker and DepositBorrow in Spark take 2 actions each expect(flashloanSubcalls.length).toBe(6) diff --git a/sdk/protocol-plugins-common/src/actions/BaseAction.ts b/sdk/protocol-plugins-common/src/actions/BaseAction.ts index 1625697c9d..b9f8dac4c0 100644 --- a/sdk/protocol-plugins-common/src/actions/BaseAction.ts +++ b/sdk/protocol-plugins-common/src/actions/BaseAction.ts @@ -75,6 +75,7 @@ export abstract class BaseAction< name: this.config.name, targetHash, callData: calldata, + skipped: false, } as ActionCall } diff --git a/sdk/protocol-plugins-common/src/actions/SkippedAction.ts b/sdk/protocol-plugins-common/src/actions/SkippedAction.ts new file mode 100644 index 0000000000..6d589884bc --- /dev/null +++ b/sdk/protocol-plugins-common/src/actions/SkippedAction.ts @@ -0,0 +1,40 @@ +import { BaseAction } from './BaseAction' +import { InputSlotsMapping } from '../types/InputSlotsMapping' +import { ActionCall } from './Types' +import { IAction } from '../interfaces/IAction' + +export class SkippedAction extends BaseAction { + static Config = { + name: 'SkippedAction', + version: 0, + parametersAbi: ['()'], + storageInputs: [], + storageOutputs: [], + } as const + + private _skippedAction: IAction + + public constructor(skippedAction: IAction) { + super() + + this._skippedAction = skippedAction + } + + /* eslint-disable @typescript-eslint/no-unused-vars */ + public encodeCall(paramsMapping?: InputSlotsMapping): ActionCall { + return { + name: this._skippedAction.config.name, + callData: '0x', + targetHash: this._skippedAction.getActionHash(), + skipped: true, + } + } + + public get config() { + return SkippedAction.Config + } + + public getVersionedName(): string { + return this._skippedAction.getVersionedName() + } +} diff --git a/sdk/protocol-plugins-common/src/actions/Types.ts b/sdk/protocol-plugins-common/src/actions/Types.ts index c4cc1dddbb..9636f62da6 100644 --- a/sdk/protocol-plugins-common/src/actions/Types.ts +++ b/sdk/protocol-plugins-common/src/actions/Types.ts @@ -15,7 +15,7 @@ export type ActionVersion = number */ export type ActionConfig = { /** The name of the action */ - readonly name: ActionNames + readonly name: ActionNames | 'SkippedAction' /** The version of the action */ readonly version: ActionVersion /** Human-readable ABI parameters (check `viem` documentation) */ @@ -32,11 +32,13 @@ export type ActionConfig = { */ export type ActionCall = { /** Name of the action for logging */ - readonly name: ActionNames + readonly name: ActionNames | 'SkippedAction' /** The hash of the action name plus its version */ readonly targetHash: HexData /** The call data to be sent to the smart contract */ readonly callData: HexData + /** If the action was skipped */ + readonly skipped: boolean } /** diff --git a/sdk/protocol-plugins-common/src/actions/index.ts b/sdk/protocol-plugins-common/src/actions/index.ts index 44dee35d96..ab2271f948 100644 --- a/sdk/protocol-plugins-common/src/actions/index.ts +++ b/sdk/protocol-plugins-common/src/actions/index.ts @@ -1,10 +1,3 @@ -export type { - ActionConfig, - ActionCall, - ActionCallBatch, - ActionStorageName, - ActionInputStorageNames, - ActionOutputStorageNames, - ActionVersion, -} from './Types' -export { BaseAction } from './BaseAction' +export type * from './Types' +export * from './BaseAction' +export * from './SkippedAction' diff --git a/sdk/protocol-plugins-common/src/context/StepBuilderContext.ts b/sdk/protocol-plugins-common/src/context/StepBuilderContext.ts index 3ecceeb500..d7414af88e 100644 --- a/sdk/protocol-plugins-common/src/context/StepBuilderContext.ts +++ b/sdk/protocol-plugins-common/src/context/StepBuilderContext.ts @@ -7,6 +7,7 @@ import { ActionCallBatch, ActionConfig } from '../actions/Types' import { ActionCallsStack } from './ActionCallsStack' import { ExecutionStorageMapper } from './ExecutionStorageMapper' import { TransactionInfo } from '@summerfi/sdk-common/orders' +import { SkippedAction } from '../actions/SkippedAction' /** * @name StepBuilderContext @@ -33,7 +34,19 @@ export class StepBuilderContext implements IStepBuilderContext { arguments: Parameters[0] connectedInputs: Partial> connectedOutputs: Partial> + skip?: boolean }) { + // TODO: temporary solution until we remove the Operations Registry + if (params.skip) { + const skipAction = new SkippedAction(params.action) + + this._calls.addCall({ + call: skipAction.encodeCall(), + }) + + return + } + const paramsMapping = this._storage.addStorageMap({ step: params.step, action: params.action, diff --git a/sdk/protocol-plugins-common/src/interfaces/IActionBuilder.ts b/sdk/protocol-plugins-common/src/interfaces/IActionBuilder.ts index 2b31de4f5b..f05e4a8266 100644 --- a/sdk/protocol-plugins-common/src/interfaces/IActionBuilder.ts +++ b/sdk/protocol-plugins-common/src/interfaces/IActionBuilder.ts @@ -18,6 +18,7 @@ export type ActionBuilderParams = { addressBookManager: IAddressBookManager protocolsRegistry: IProtocolPluginsRegistry step: Step + actionBuildersMap: ActionBuildersMap } /** diff --git a/sdk/protocol-plugins-common/src/interfaces/IStepBuilderContext.ts b/sdk/protocol-plugins-common/src/interfaces/IStepBuilderContext.ts index afb7e84beb..9260c715d1 100644 --- a/sdk/protocol-plugins-common/src/interfaces/IStepBuilderContext.ts +++ b/sdk/protocol-plugins-common/src/interfaces/IStepBuilderContext.ts @@ -27,6 +27,7 @@ export interface IStepBuilderContext { * will read from storage * @param connectedOutputs The connected outputs to the action, this is the values that the action * will write to storage + * @param skip If true, the action will be skipped and empty calldata will be added to the TX */ addActionCall< Step extends steps.Steps, @@ -38,6 +39,7 @@ export interface IStepBuilderContext { arguments: Parameters[0] connectedInputs: Partial> connectedOutputs: Partial> + skip?: boolean }): void /** diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts index d050310b82..9182afb7d3 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts @@ -63,21 +63,19 @@ export class AaveV3DepositBorrowActionBuilder extends BaseActionBuilder { public static Config = { name: 'TakeFlashloan', @@ -26,15 +21,6 @@ export class FlashloanAction extends BaseAction { }, paramsMapping?: InputSlotsMapping, ): ActionCall { - const calls: OptionalActionCall[] = params.calls.map((call) => { - return { - name: call.name, - targetHash: call.targetHash, - callData: call.callData, - skipped: false, - } - }) - return this._encodeCall({ arguments: [ { @@ -43,7 +29,7 @@ export class FlashloanAction extends BaseAction { isProxyFlashloan: true, isDPMProxy: true, provider: params.provider, - calls: calls, + calls: params.calls, }, ], mapping: paramsMapping, diff --git a/sdk/protocol-plugins/src/plugins/common/builders/SkippedStepActionBuilder.ts b/sdk/protocol-plugins/src/plugins/common/builders/SkippedStepActionBuilder.ts new file mode 100644 index 0000000000..31eff868c3 --- /dev/null +++ b/sdk/protocol-plugins/src/plugins/common/builders/SkippedStepActionBuilder.ts @@ -0,0 +1,41 @@ +import { + ActionBuilderParams, + ActionBuilderUsedAction, + ActionConfig, + BaseAction, +} from '@summerfi/protocol-plugins-common' +import { steps } from '@summerfi/sdk-common/simulation' +import { BaseActionBuilder } from '../../../implementation/BaseActionBuilder' + +// TODO: temporary solution until we remove the Operations Registry +export class SkippedStepActionBuilder extends BaseActionBuilder { + readonly actions: ActionBuilderUsedAction[] = [] + + /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ + async build(params: ActionBuilderParams): Promise { + const { context } = params + const BuilderClass = params.actionBuildersMap[params.step.inputs.type] + if (!BuilderClass) { + return + } + + const builder = new BuilderClass() + + for (const actionConfig of builder.actions) { + if (actionConfig.action === 'DelegatedToProtocol') { + throw new Error('DelegatedToProtocol is not supported in SkippedStepActionBuilder') + } + + const action = new actionConfig.action() + + context.addActionCall({ + step: params.step, + action: action as BaseAction, + arguments: {}, + connectedInputs: {}, + connectedOutputs: {}, + skip: true, + }) + } + } +} diff --git a/sdk/protocol-plugins/src/plugins/common/builders/index.ts b/sdk/protocol-plugins/src/plugins/common/builders/index.ts index d56f468f26..c2dbc80501 100644 --- a/sdk/protocol-plugins/src/plugins/common/builders/index.ts +++ b/sdk/protocol-plugins/src/plugins/common/builders/index.ts @@ -8,3 +8,4 @@ export * from './SwapActionBuilder' export * from './PositionCreatedActionBuilder' export * from './ImportPositionActionBuilder' export * from './OpenPositionActionBuilder' +export * from './SkippedStepActionBuilder' diff --git a/sdk/protocol-plugins/src/plugins/maker/builders/MakerPaybackWithdrawActionBuilder.ts b/sdk/protocol-plugins/src/plugins/maker/builders/MakerPaybackWithdrawActionBuilder.ts index 1c2073045f..fd01e7a9fb 100644 --- a/sdk/protocol-plugins/src/plugins/maker/builders/MakerPaybackWithdrawActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/maker/builders/MakerPaybackWithdrawActionBuilder.ts @@ -30,22 +30,21 @@ export class MakerPaybackWithdrawActionBuilder extends BaseActionBuilder { name: 'SendToken', targetHash: '0x3434343434343434343434343434343456565656565656565656565656565656', callData: '0x1234567890123456789012345678901234', + skipped: false, }, { name: 'ReturnFunds', targetHash: '0x1212121212121212121212121212121278787878787878787878787878787878', callData: '0x9876543210987654321098765432109876', + skipped: false, }, ], }, diff --git a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts index 37591bff59..3a777e7eb5 100644 --- a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3DepositBorrowActionBuilder.spec.ts @@ -182,10 +182,11 @@ describe('AaveV3 Deposit Borrow Action Builder', () => { const { callsBatch } = builderParams.context.endSubContext() - expect(callsBatch.length).toEqual(2) + expect(callsBatch.length).toEqual(3) expect(callsBatch[0].name).toBe('SetApproval') expect(callsBatch[1].name).toBe('AaveV3Deposit') + expect(callsBatch[2].name).toBe('AaveV3Borrow') }) it('should add borrow but not send token when borrow target is positions manager', async () => { diff --git a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts index 8c31b47a36..1e08e65d93 100644 --- a/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/aaveV3/AaveV3PaybackWithdrawActionBuilder.spec.ts @@ -182,8 +182,10 @@ describe('AaveV3 Payback Withdraw Action Builder', () => { const { callsBatch } = builderParams.context.endSubContext() - expect(callsBatch.length).toEqual(1) + expect(callsBatch.length).toEqual(3) - expect(callsBatch[0].name).toBe('AaveV3Withdraw') + expect(callsBatch[0].name).toBe('SetApproval') + expect(callsBatch[1].name).toBe('AaveV3Payback') + expect(callsBatch[2].name).toBe('AaveV3Withdraw') }) }) diff --git a/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts index 1d7c045225..07a9f08744 100644 --- a/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/maker/MakerPaybackWithdrawActionBuilder.spec.ts @@ -187,8 +187,9 @@ describe('Maker Payback Withdraw Action Builder', () => { const { callsBatch } = builderParams.context.endSubContext() - expect(callsBatch.length).toEqual(1) + expect(callsBatch.length).toEqual(2) - expect(callsBatch[0].name).toBe('MakerWithdraw') + expect(callsBatch[0].name).toBe('MakerPayback') + expect(callsBatch[1].name).toBe('MakerWithdraw') }) }) diff --git a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts index 6d63b4a36e..3dd9eb142d 100644 --- a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoDepositBorrowActionBuilder.spec.ts @@ -190,10 +190,12 @@ describe('Morpho Deposit Borrow Action Builder', () => { const { callsBatch } = builderParams.context.endSubContext() - expect(callsBatch.length).toEqual(2) + expect(callsBatch.length).toEqual(4) expect(callsBatch[0].name).toBe('SetApproval') expect(callsBatch[1].name).toBe('MorphoBlueDeposit') + expect(callsBatch[2].name).toBe('MorphoBlueBorrow') + expect(callsBatch[3].name).toBe('SendToken') }) it('should add borrow but not send token when borrow target is positions manager', async () => { @@ -213,10 +215,11 @@ describe('Morpho Deposit Borrow Action Builder', () => { const { callsBatch } = builderParams.context.endSubContext() - expect(callsBatch.length).toEqual(3) + expect(callsBatch.length).toEqual(4) expect(callsBatch[0].name).toBe('SetApproval') expect(callsBatch[1].name).toBe('MorphoBlueDeposit') expect(callsBatch[2].name).toBe('MorphoBlueBorrow') + expect(callsBatch[3].name).toBe('SendToken') }) }) diff --git a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts index 0b71224781..f258c72097 100644 --- a/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/morpho/MorphoPaybackWithdrawActionBuilder.spec.ts @@ -187,8 +187,10 @@ describe('Morpho Payback Withdraw Action Builder', () => { const { callsBatch } = builderParams.context.endSubContext() - expect(callsBatch.length).toEqual(1) + expect(callsBatch.length).toEqual(3) - expect(callsBatch[0].name).toBe('MorphoBlueWithdraw') + expect(callsBatch[0].name).toBe('SetApproval') + expect(callsBatch[1].name).toBe('MorphoBluePayback') + expect(callsBatch[2].name).toBe('MorphoBlueWithdraw') }) }) diff --git a/sdk/protocol-plugins/tests/unit/builders/spark/SparkDepositBorrowActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/spark/SparkDepositBorrowActionBuilder.spec.ts index 6e9e5a2356..9cb115d17d 100644 --- a/sdk/protocol-plugins/tests/unit/builders/spark/SparkDepositBorrowActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/spark/SparkDepositBorrowActionBuilder.spec.ts @@ -182,10 +182,11 @@ describe('Spark Deposit Borrow Action Builder', () => { const { callsBatch } = builderParams.context.endSubContext() - expect(callsBatch.length).toEqual(2) + expect(callsBatch.length).toEqual(3) expect(callsBatch[0].name).toBe('SetApproval') expect(callsBatch[1].name).toBe('SparkDeposit') + expect(callsBatch[2].name).toBe('SparkBorrow') }) it('should add borrow but not send token when borrow target is positions manager', async () => { diff --git a/sdk/protocol-plugins/tests/unit/builders/spark/SparkPaybackWithdrawActionBuilder.spec.ts b/sdk/protocol-plugins/tests/unit/builders/spark/SparkPaybackWithdrawActionBuilder.spec.ts index 7f247571e6..8a8ffd164a 100644 --- a/sdk/protocol-plugins/tests/unit/builders/spark/SparkPaybackWithdrawActionBuilder.spec.ts +++ b/sdk/protocol-plugins/tests/unit/builders/spark/SparkPaybackWithdrawActionBuilder.spec.ts @@ -182,8 +182,10 @@ describe('Spark Payback Withdraw Action Builder', () => { const { callsBatch } = builderParams.context.endSubContext() - expect(callsBatch.length).toEqual(1) + expect(callsBatch.length).toEqual(3) - expect(callsBatch[0].name).toBe('SparkWithdraw') + expect(callsBatch[0].name).toBe('SetApproval') + expect(callsBatch[1].name).toBe('SparkPayback') + expect(callsBatch[2].name).toBe('SparkWithdraw') }) }) diff --git a/sdk/protocol-plugins/tests/utils/SetupBuilderParams.ts b/sdk/protocol-plugins/tests/utils/SetupBuilderParams.ts index 2962f2a715..b18466abdf 100644 --- a/sdk/protocol-plugins/tests/utils/SetupBuilderParams.ts +++ b/sdk/protocol-plugins/tests/utils/SetupBuilderParams.ts @@ -3,7 +3,7 @@ import { IPositionsManager } from '@summerfi/sdk-common/orders' import { Address, ChainInfo } from '@summerfi/sdk-common/common' import { SetupDeployments } from './SetupDeployments' import { IUser } from '@summerfi/sdk-common/user' -import { IProtocolPluginsRegistry } from '@summerfi/protocol-plugins-common' +import { ActionBuildersMap, IProtocolPluginsRegistry } from '@summerfi/protocol-plugins-common' import { createEmptyBuildersProtocolPluginsRegistry, createEmptyProtocolPluginsRegistry, @@ -25,6 +25,7 @@ export type SetupBuilderReturnType = { swapManager: SwapManagerMock addressBookManager: IAddressBookManager protocolsRegistry: IProtocolPluginsRegistry + actionBuildersMap: ActionBuildersMap emptyProtocolsRegistry: IProtocolPluginsRegistry emptyBuildersProtocolRegistry: IProtocolPluginsRegistry noCheckpointProtocolsRegistry: IProtocolPluginsRegistry @@ -50,6 +51,7 @@ export function setupBuilderParams(params: { chainInfo: ChainInfo }): SetupBuild swapManager: new SwapManagerMock(), addressBookManager: new AddressBookManagerMock(), protocolsRegistry: protocolsRegistry, + actionBuildersMap: {} as ActionBuildersMap, emptyProtocolsRegistry: emptyProtocolsRegistry, noCheckpointProtocolsRegistry: noCheckpointProtocolsRegistry, emptyBuildersProtocolRegistry: emptyBuildersProtocolRegistry, diff --git a/sdk/sdk-client/src/implementation/simulations/RefinanceSimulationManager.ts b/sdk/sdk-client/src/implementation/simulations/RefinanceSimulationManager.ts index a595fcd787..599f6baba5 100644 --- a/sdk/sdk-client/src/implementation/simulations/RefinanceSimulationManager.ts +++ b/sdk/sdk-client/src/implementation/simulations/RefinanceSimulationManager.ts @@ -1,5 +1,5 @@ import { IRefinanceParameters } from '@summerfi/sdk-common/orders' -import { ISimulation, RefinanceSimulationTypes } from '@summerfi/sdk-common/simulation' +import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' import { RPCClientType } from '../../rpc/SDKClient' import { IRPCClient } from '../../interfaces/IRPCClient' @@ -10,7 +10,7 @@ export class RefinanceSimulationManager extends IRPCClient { public async simulateRefinancePosition( refinanceParameters: IRefinanceParameters, - ): Promise> { + ): Promise> { return this.rpcClient.simulation.refinance.query(refinanceParameters) } } diff --git a/sdk/sdk-common/src/simulation/Enums.ts b/sdk/sdk-common/src/simulation/Enums.ts index 72e9232d8f..a81fd394e0 100644 --- a/sdk/sdk-common/src/simulation/Enums.ts +++ b/sdk/sdk-common/src/simulation/Enums.ts @@ -7,11 +7,6 @@ export enum SimulationType { Migrate = 'Migrate', CreatePosition = 'CreatePosition', Refinance = 'Refinance', - RefinanceDifferentPair = 'RefinanceDifPair', - RefinanceDifferentDebt = 'RefinanceDifDebt', - RefinanceDifferentCollateral = 'RefinanceDifCol', - RefinanceNoDebt = 'RefinanceNoDebt', - RefinanceNoDebtDifferentCollateral = 'RefNoDebtDifCol', } export enum SimulationSteps { @@ -25,6 +20,7 @@ export enum SimulationSteps { Import = 'Import', NewPositionEvent = 'NewPositionEvent', OpenPosition = 'OpenPosition', + Skipped = 'Skipped', } export enum FlashloanProvider { @@ -36,11 +32,3 @@ export enum TokenTransferTargetType { StrategyExecutor = 0, PositionsManager = 1, } - -export type RefinanceSimulationTypes = - | SimulationType.Refinance - | SimulationType.RefinanceDifferentPair - | SimulationType.RefinanceDifferentCollateral - | SimulationType.RefinanceDifferentDebt - | SimulationType.RefinanceNoDebt - | SimulationType.RefinanceNoDebtDifferentCollateral diff --git a/sdk/sdk-common/src/simulation/Steps.ts b/sdk/sdk-common/src/simulation/Steps.ts index a0092b1e62..046d268403 100644 --- a/sdk/sdk-common/src/simulation/Steps.ts +++ b/sdk/sdk-common/src/simulation/Steps.ts @@ -8,6 +8,7 @@ import { IPrice } from '../common/interfaces/IPrice' import { IPosition } from '../common/interfaces/IPosition' import { IToken } from '../common/interfaces/IToken' import { ILendingPool } from '../protocols/interfaces/ILendingPool' +import { ProtocolName } from '../protocols' export interface Step { type: T @@ -60,6 +61,15 @@ export interface PaybackWithdrawStep } > {} +export interface SkippedStep + extends Step< + SimulationSteps.Skipped, + { + type: SimulationSteps + protocol?: ProtocolName + } + > {} + export interface SwapStep extends Step< SimulationSteps.Swap, @@ -124,3 +134,4 @@ export type Steps = | NewPositionEventStep | ImportStep | OpenPosition + | SkippedStep diff --git a/sdk/sdk-e2e/tests/refinance.test.ts b/sdk/sdk-e2e/tests/refinance.test.ts index 41aa6a2611..a3b08dfedf 100644 --- a/sdk/sdk-e2e/tests/refinance.test.ts +++ b/sdk/sdk-e2e/tests/refinance.test.ts @@ -11,13 +11,13 @@ import { import { ProtocolName, isLendingPool } from '@summerfi/sdk-common/protocols' import { ProtocolClient, makeSDK, type Chain, type User } from '@summerfi/sdk-client' import { PositionsManager, IRefinanceParameters, Order } from '@summerfi/sdk-common/orders' -import { ISimulation } from '@summerfi/sdk-common/simulation' +import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' import { TransactionUtils } from './utils/TransactionUtils' import { Hex } from 'viem' import assert from 'assert' import { EmodeType } from '@summerfi/protocol-plugins/plugins/common' -import { AddressValue, CommonTokenSymbols, RefinanceSimulationTypes } from '@summerfi/sdk-common' +import { AddressValue, CommonTokenSymbols } from '@summerfi/sdk-common' import { SparkLendingPoolId, isSparkLendingPoolId, @@ -176,7 +176,7 @@ describe.skip('Refinance All | SDK', () => { assert(false, 'Spark pool type is not lending') } - const refinanceSimulation: ISimulation = + const refinanceSimulation: ISimulation = await sdk.simulator.refinance.simulateRefinancePosition({ sourcePosition: makerPosition, targetPool: sparkPool, diff --git a/sdk/sdk-e2e/tests/refinanceAaveV3SparkAnyPair.test.ts b/sdk/sdk-e2e/tests/refinanceAaveV3SparkAnyPair.test.ts index 40a9d85d3b..1cee33c628 100644 --- a/sdk/sdk-e2e/tests/refinanceAaveV3SparkAnyPair.test.ts +++ b/sdk/sdk-e2e/tests/refinanceAaveV3SparkAnyPair.test.ts @@ -4,7 +4,6 @@ import { EmodeType } from '@summerfi/protocol-plugins/plugins/common' import { AddressValue, CommonTokenSymbols, - RefinanceSimulationTypes, ISimulation, Percentage, TokenAmount, @@ -13,6 +12,7 @@ import { ChainFamilyMap, PositionType, IToken, + SimulationType, } from '@summerfi/sdk-common' import { PositionsManager, Order, RefinanceParameters } from '@summerfi/sdk-common/orders' import { @@ -37,13 +37,13 @@ jest.setTimeout(300000) /** TEST CONFIG */ const config = { SDKAPiUrl: 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sdk', - TenderlyForkUrl: 'https://virtual.mainnet.rpc.tenderly.co/cc7432cd-f037-4aa8-a05f-ae6d8cefba39', + TenderlyForkUrl: 'https://virtual.mainnet.rpc.tenderly.co/5eea57de-3dc2-4cae-b7ed-24b16b0cbde0', DPMAddress: '0x551eb8395093fde4b9eef017c93593a3c7a75138', walletAddress: '0xbEf4befb4F230F43905313077e3824d7386E09F8', collateralTokenSymbol: CommonTokenSymbols.WETH, collateralAmount: '0.0198', debtTokenSymbol: CommonTokenSymbols.DAI, - debtAmount: '26', + debtAmount: '34', sendTransactionEnabled: true, } @@ -166,7 +166,7 @@ describe.skip('Refinance AaveV3 Spark | SDK', () => { slippage: Percentage.createFrom({ value: 0.2 }), }) - const refinanceSimulation: ISimulation = + const refinanceSimulation: ISimulation = await sdk.simulator.refinance.simulateRefinancePosition(refinanceParameters) expect(refinanceSimulation).toBeDefined() @@ -181,10 +181,11 @@ describe.skip('Refinance AaveV3 Spark | SDK', () => { assert(refinanceOrder, 'Order not found') - // Send transaction - console.log('Sending transaction...') - + console.log('Order:', JSON.stringify(refinanceOrder, null, 2)) if (config.sendTransactionEnabled) { + // Send transaction + console.log('Sending transaction...') + const privateKey = process.env.DEPLOYER_PRIVATE_KEY as Hex const transactionUtils = new TransactionUtils({ rpcUrl: config.TenderlyForkUrl, diff --git a/sdk/sdk-e2e/tests/refinanceMakerSparkAlreadyImported.test.ts b/sdk/sdk-e2e/tests/refinanceMakerSparkAlreadyImported.test.ts index d9d551f404..2c265eaa7b 100644 --- a/sdk/sdk-e2e/tests/refinanceMakerSparkAlreadyImported.test.ts +++ b/sdk/sdk-e2e/tests/refinanceMakerSparkAlreadyImported.test.ts @@ -14,7 +14,7 @@ import { ProtocolName } from '@summerfi/sdk-common/protocols' import { makeSDK, type Chain, type User, ProtocolClient } from '@summerfi/sdk-client' import { CommonTokenSymbols } from '@summerfi/sdk-common/common/enums' import { PositionsManager, Order, RefinanceParameters } from '@summerfi/sdk-common/orders' -import { ISimulation, RefinanceSimulationTypes } from '@summerfi/sdk-common/simulation' +import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' import { TransactionUtils } from './utils/TransactionUtils' import { decodeActionCalldata, @@ -187,7 +187,7 @@ describe.skip('Refinance Maker Spark | SDK', () => { slippage: Percentage.createFrom({ value: 0.2 }), }) - const refinanceSimulation: ISimulation = + const refinanceSimulation: ISimulation = await sdk.simulator.refinance.simulateRefinancePosition(refinanceParameters) expect(refinanceSimulation).toBeDefined() diff --git a/sdk/sdk-e2e/tests/refinanceMakerSparkAnyPair.test.ts b/sdk/sdk-e2e/tests/refinanceMakerSparkAnyPair.test.ts index 579a6d4478..7abb09fe87 100644 --- a/sdk/sdk-e2e/tests/refinanceMakerSparkAnyPair.test.ts +++ b/sdk/sdk-e2e/tests/refinanceMakerSparkAnyPair.test.ts @@ -11,13 +11,13 @@ import { import { ProtocolName, isLendingPool } from '@summerfi/sdk-common/protocols' import { ProtocolClient, makeSDK, type Chain, type User } from '@summerfi/sdk-client' import { PositionsManager, Order, RefinanceParameters } from '@summerfi/sdk-common/orders' -import { ISimulation } from '@summerfi/sdk-common/simulation' +import { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' import { TransactionUtils } from './utils/TransactionUtils' import { Hex } from 'viem' import assert from 'assert' import { EmodeType } from '@summerfi/protocol-plugins/plugins/common' -import { AddressValue, CommonTokenSymbols, RefinanceSimulationTypes } from '@summerfi/sdk-common' +import { AddressValue, CommonTokenSymbols } from '@summerfi/sdk-common' import { SparkLendingPoolId, isSparkLendingPoolId, @@ -37,12 +37,13 @@ jest.setTimeout(300000) /** TEST CONFIG */ const config = { SDKAPiUrl: 'https://zmjmtfsocb.execute-api.us-east-1.amazonaws.com/api/sdk', - TenderlyForkUrl: 'https://virtual.mainnet.rpc.tenderly.co/4711dc9f-76a4-4f6c-9464-6f8c7369df61', - makerVaultId: '31709', - DPMAddress: '0xc1475b2735fb9130a4701ee9e2215b6305dd501b', - walletAddress: '0xbEf4befb4F230F43905313077e3824d7386E09F8', - collateralAmount: '5000.0', - debtAmount: '5000000.0', + TenderlyForkUrl: 'https://virtual.mainnet.rpc.tenderly.co/5eea57de-3dc2-4cae-b7ed-24b16b0cbde0', + makerVaultId: '31722', + DPMAddress: '0x2e0515d7A3eA0276F28c94C426c5d2D1d85FD4d5', + walletAddress: '0xDDc68f9dE415ba2fE2FD84bc62Be2d2CFF1098dA', + collateralAmount: '2.5', + debtAmount: '3501.0', + sendTransaction: true, } describe.skip('Refinance Maker Spark | SDK', () => { @@ -133,7 +134,7 @@ describe.skip('Refinance Maker Spark | SDK', () => { // Source position const makerPosition: MakerPosition = MakerPosition.createFrom({ type: PositionType.Multiply, - id: MakerPositionId.createFrom({ id: '31697', vaultId: '31697' }), + id: MakerPositionId.createFrom({ id: config.makerVaultId, vaultId: config.makerVaultId }), debtAmount: TokenAmount.createFrom({ token: DAI, amount: config.debtAmount, @@ -182,7 +183,7 @@ describe.skip('Refinance Maker Spark | SDK', () => { slippage: Percentage.createFrom({ value: 0.2 }), }) - const refinanceSimulation: ISimulation = + const refinanceSimulation: ISimulation = await sdk.simulator.refinance.simulateRefinancePosition(refinanceParameters) expect(refinanceSimulation).toBeDefined() @@ -197,19 +198,21 @@ describe.skip('Refinance Maker Spark | SDK', () => { assert(refinanceOrder, 'Order not found') - // Send transaction - console.log('Sending transaction...') + if (config.sendTransaction) { + // Send transaction + console.log('Sending transaction...') - const privateKey = process.env.DEPLOYER_PRIVATE_KEY as Hex - const transactionUtils = new TransactionUtils({ - rpcUrl: config.TenderlyForkUrl, - walletPrivateKey: privateKey, - }) + const privateKey = process.env.DEPLOYER_PRIVATE_KEY as Hex + const transactionUtils = new TransactionUtils({ + rpcUrl: config.TenderlyForkUrl, + walletPrivateKey: privateKey, + }) - const receipt = await transactionUtils.sendTransaction({ - transaction: refinanceOrder.transactions[0].transaction, - }) + const receipt = await transactionUtils.sendTransaction({ + transaction: refinanceOrder.transactions[0].transaction, + }) - console.log('Transaction sent:', receipt) + console.log('Transaction sent:', receipt) + } }) }) diff --git a/sdk/sdk-e2e/tests/refinanceMorphoSparkAnyPair.test.ts b/sdk/sdk-e2e/tests/refinanceMorphoSparkAnyPair.test.ts index f45914dcde..3dbbe93b66 100644 --- a/sdk/sdk-e2e/tests/refinanceMorphoSparkAnyPair.test.ts +++ b/sdk/sdk-e2e/tests/refinanceMorphoSparkAnyPair.test.ts @@ -4,7 +4,6 @@ import { EmodeType } from '@summerfi/protocol-plugins/plugins/common' import { AddressValue, CommonTokenSymbols, - RefinanceSimulationTypes, ISimulation, Percentage, TokenAmount, @@ -13,6 +12,7 @@ import { ChainFamilyMap, PositionType, IToken, + SimulationType, } from '@summerfi/sdk-common' import { PositionsManager, Order, RefinanceParameters } from '@summerfi/sdk-common/orders' import { @@ -164,7 +164,7 @@ describe.skip('Refinance Morpho Spark | SDK', () => { slippage: Percentage.createFrom({ value: 0.2 }), }) - const refinanceSimulation: ISimulation = + const refinanceSimulation: ISimulation = await sdk.simulator.refinance.simulateRefinancePosition(refinanceParameters) expect(refinanceSimulation).toBeDefined() diff --git a/sdk/sdk-server/src/handlers/getRefinanceSimulation.ts b/sdk/sdk-server/src/handlers/getRefinanceSimulation.ts index fac12c1ab8..1a67ec2800 100644 --- a/sdk/sdk-server/src/handlers/getRefinanceSimulation.ts +++ b/sdk/sdk-server/src/handlers/getRefinanceSimulation.ts @@ -1,22 +1,19 @@ -import type { ISimulation, RefinanceSimulationTypes } from '@summerfi/sdk-common/simulation' -import { refinanceStrategyRouter } from '@summerfi/simulator-service/strategies' +import type { ISimulation, SimulationType } from '@summerfi/sdk-common/simulation' +import { refinanceLendingToLending } from '@summerfi/simulator-service/strategies' import { publicProcedure } from '../TRPC' import { isRefinanceParameters } from '@summerfi/sdk-common/orders' import { z } from 'zod' export const getRefinanceSimulation = publicProcedure .input(z.any()) - .query(async (opts): Promise> => { + .query(async (opts): Promise> => { if (!isRefinanceParameters(opts.input)) { throw new Error('Invalid refinance parameters') } - return refinanceStrategyRouter({ - refinanceParameters: opts.input, - refinanceDependencies: { - swapManager: opts.ctx.swapManager, - oracleManager: opts.ctx.oracleManager, - protocolManager: opts.ctx.protocolManager, - }, + return refinanceLendingToLending(opts.input, { + swapManager: opts.ctx.swapManager, + oracleManager: opts.ctx.oracleManager, + protocolManager: opts.ctx.protocolManager, }) }) diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/skippedStepReducer.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/skippedStepReducer.ts new file mode 100644 index 0000000000..a8f97ddaac --- /dev/null +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/skippedStepReducer.ts @@ -0,0 +1,12 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import { ISimulationState } from '../../../interfaces/simulation' + +export function skippedStepReducer( + step: steps.SkippedStep, + state: ISimulationState, +): ISimulationState { + return { + ...state, + steps: [...state.steps, step], + } +} diff --git a/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts b/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts index daef596a5a..6baed637f0 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/reducer/stateReducers.ts @@ -11,6 +11,7 @@ import { pullTokenReducer } from './pullTokenReducer' import { importReducer } from './importReducer' import { newPositionEventReducer } from './newPositionEventReducer' import { openPositionReducer } from './openPositionReducer' +import { skippedStepReducer } from './skippedStepReducer' const stateReducers: StateReducers = { [SimulationSteps.Flashloan]: flashloanReducer, @@ -23,6 +24,7 @@ const stateReducers: StateReducers = { [SimulationSteps.Import]: importReducer, [SimulationSteps.NewPositionEvent]: newPositionEventReducer, [SimulationSteps.OpenPosition]: openPositionReducer, + [SimulationSteps.Skipped]: skippedStepReducer, } export function stateReducer(step: steps.Steps, state: ISimulationState): ISimulationState { diff --git a/sdk/simulator-service/src/implementation/simulator-engine/simulator.ts b/sdk/simulator-service/src/implementation/simulator-engine/simulator.ts index 74899968d5..e3a6900615 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/simulator.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/simulator.ts @@ -5,7 +5,7 @@ import { processStepOutput } from './stepProcessor/stepOutputProcessors' import { stateReducer } from './reducer/stateReducers' import type { SimulationStrategy } from '@summerfi/sdk-common/simulation' import { steps } from '@summerfi/sdk-common/simulation' -import { Maybe } from '@summerfi/sdk-common' +import { Maybe, ProtocolName, SimulationSteps } from '@summerfi/sdk-common' import { GetReferencedValue, NextFunction, @@ -83,24 +83,31 @@ export class Simulator, - skip?: boolean, + skipData?: { skip: boolean; type: SimulationSteps; protocol?: ProtocolName }, ): Simulator, [...AddedSteps, ProccessedStep]> { const schemaHead = head(this.schema) const schemaTail = tail(this.schema) - const nextArray = [...this.nextArray, next] - if (skip) { + if (skipData && skipData.skip) { if (schemaHead.optional === false) { throw new Error(`Step is required: ${schemaHead.step}`) } + const skippedNext = [ + ...this.nextArray, + async () => ({ + type: SimulationSteps.Skipped, + inputs: skipData, + }), + ] + return new Simulator, [...AddedSteps, ProccessedStep]>( schemaTail, this.originalSchema, this.state, // TODO: We should not use any here /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ - this.nextArray as any, + skippedNext as any, ) } @@ -108,6 +115,8 @@ export class Simulator, [...AddedSteps, ProccessedStep]>( schemaTail, this.originalSchema, diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/skippedStepOutputProcessor.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/skippedStepOutputProcessor.ts new file mode 100644 index 0000000000..5b3e859f6c --- /dev/null +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/skippedStepOutputProcessor.ts @@ -0,0 +1,9 @@ +import { steps } from '@summerfi/sdk-common/simulation' +import type { StepOutputProcessor } from '../../../interfaces/steps' + +export const skippedStepOutputProcessor: StepOutputProcessor = async (step) => { + return { + ...step, + outputs: undefined, + } +} diff --git a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts index 7f175ced45..66f3898969 100644 --- a/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts +++ b/sdk/simulator-service/src/implementation/simulator-engine/stepProcessor/stepOutputProcessors.ts @@ -14,6 +14,7 @@ import { repayFlashloanOutputProcessor } from './repayFlashloanOutputProcessor' import { importPositionProcessor } from './importPositionProcessor' import { newPositionEventProcessor } from './newPositionEvent' import { openPositionProcessor } from './openPositionProcessor' +import { skippedStepOutputProcessor } from './skippedStepOutputProcessor' const stepOutputProcessors: StepOutputProcessors = { [SimulationSteps.Flashloan]: flashloanOutputProcessor, @@ -26,6 +27,7 @@ const stepOutputProcessors: StepOutputProcessors = { [SimulationSteps.Import]: importPositionProcessor, [SimulationSteps.NewPositionEvent]: newPositionEventProcessor, [SimulationSteps.OpenPosition]: openPositionProcessor, + [SimulationSteps.Skipped]: skippedStepOutputProcessor, } export async function processStepOutput(step: StepsWithoutOutputs): Promise { diff --git a/sdk/simulator-service/src/implementation/utils/GetRefinanceSimulationType.ts b/sdk/simulator-service/src/implementation/utils/GetRefinanceSimulationType.ts deleted file mode 100644 index 1f4ba198e9..0000000000 --- a/sdk/simulator-service/src/implementation/utils/GetRefinanceSimulationType.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { RefinanceSimulationTypes, SimulationType } from '@summerfi/sdk-common/simulation' - -export function getRefinanceSimulationType( - hasCollateralSwap: boolean, - hasDebtSwap: boolean, -): RefinanceSimulationTypes { - if (hasCollateralSwap && hasDebtSwap) { - return SimulationType.RefinanceDifferentPair - } - - if (hasCollateralSwap) { - return SimulationType.RefinanceDifferentCollateral - } - - if (hasDebtSwap) { - return SimulationType.RefinanceDifferentDebt - } - - return SimulationType.Refinance -} diff --git a/sdk/simulator-service/src/strategies/StrategyIndex.ts b/sdk/simulator-service/src/strategies/StrategyIndex.ts index 6b2369429a..b020a38f1c 100644 --- a/sdk/simulator-service/src/strategies/StrategyIndex.ts +++ b/sdk/simulator-service/src/strategies/StrategyIndex.ts @@ -1,12 +1,6 @@ -import { refinanceLendingToLendingSamePairStrategy } from './refinanceSamePair/Strategy' -import { refinanceLendingToLendingAnyPairStrategy } from './refinanceAnyPair/Strategy' -import { refinanceLendingToLendingNoDebtStrategy } from './refinanceNoDebt/Strategy' +import { refinanceLendingToLending } from './refinanceLendingToLending/RefinanceLendingToLendingAnyPair' /** * List of all strategies so the strategy definition generation tool can use them */ -export const StrategyIndex = [ - refinanceLendingToLendingSamePairStrategy, - refinanceLendingToLendingAnyPairStrategy, - refinanceLendingToLendingNoDebtStrategy, -] +export const StrategyIndex = [refinanceLendingToLending] diff --git a/sdk/simulator-service/src/strategies/common/RefinanceStrategyRouter.ts b/sdk/simulator-service/src/strategies/common/RefinanceStrategyRouter.ts deleted file mode 100644 index c13bcd9d20..0000000000 --- a/sdk/simulator-service/src/strategies/common/RefinanceStrategyRouter.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { IRefinanceParameters } from '@summerfi/sdk-common/orders' -import { refinanceLendingToLendingAnyPair } from '../refinanceAnyPair/RefinanceLendingToLendingAnyPair' -import { refinanceLendingToLendingNoDebt } from '../refinanceNoDebt/RefinanceLendingToLendingNoDebt' -import { refinanceLendingToLendingSamePair } from '../refinanceSamePair/RefinanceLendingToLendingSamePair' -import { ISwapManager } from '@summerfi/swap-common/interfaces' -import { IOracleManager } from '@summerfi/oracle-common' -import { IProtocolManager } from '@summerfi/protocol-manager-common' - -function isToSamePair(parameters: IRefinanceParameters): boolean { - const { sourcePosition, targetPool } = parameters - - return ( - sourcePosition.debtAmount.token.equals(targetPool.debtToken) && - sourcePosition.collateralAmount.token.equals(targetPool.collateralToken) - ) -} - -/** - * Choses the correct refinance strategy based on the parameters - * @param refinanceParameters Parameters for the refinance simulation - * @param refinanceDependencies Dependencies for the simulation - * @returns The simulation result - */ -export function refinanceStrategyRouter(params: { - refinanceParameters: IRefinanceParameters - refinanceDependencies: { - swapManager: ISwapManager - oracleManager: IOracleManager - protocolManager: IProtocolManager - } -}) { - if (params.refinanceParameters.sourcePosition.debtAmount.amount === '0') { - return refinanceLendingToLendingNoDebt(params.refinanceParameters, params.refinanceDependencies) - } - - // TODO: in the end we should use just any pair - if (isToSamePair(params.refinanceParameters)) { - return refinanceLendingToLendingSamePair( - params.refinanceParameters, - params.refinanceDependencies, - ) - } - - return refinanceLendingToLendingAnyPair(params.refinanceParameters, params.refinanceDependencies) -} diff --git a/sdk/simulator-service/src/strategies/common/index.ts b/sdk/simulator-service/src/strategies/common/index.ts index f85330ef32..cf701220bd 100644 --- a/sdk/simulator-service/src/strategies/common/index.ts +++ b/sdk/simulator-service/src/strategies/common/index.ts @@ -1,2 +1 @@ export * from './Types' -export * from './RefinanceStrategyRouter' diff --git a/sdk/simulator-service/src/strategies/index.ts b/sdk/simulator-service/src/strategies/index.ts index 31de16f64e..c7990e6a82 100644 --- a/sdk/simulator-service/src/strategies/index.ts +++ b/sdk/simulator-service/src/strategies/index.ts @@ -1,5 +1,3 @@ -export * from './refinanceSamePair' -export * from './refinanceAnyPair' -export * from './refinanceNoDebt' +export * from './refinanceLendingToLending' export * from './common' export * from './import' diff --git a/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts b/sdk/simulator-service/src/strategies/refinanceLendingToLending/RefinanceLendingToLendingAnyPair.ts similarity index 71% rename from sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts rename to sdk/simulator-service/src/strategies/refinanceLendingToLending/RefinanceLendingToLendingAnyPair.ts index 752d6f866c..30ef7f6ab7 100644 --- a/sdk/simulator-service/src/strategies/refinanceAnyPair/RefinanceLendingToLendingAnyPair.ts +++ b/sdk/simulator-service/src/strategies/refinanceLendingToLending/RefinanceLendingToLendingAnyPair.ts @@ -1,8 +1,8 @@ import { FlashloanProvider, ISimulation, - RefinanceSimulationTypes, SimulationSteps, + SimulationType, TokenTransferTargetType, getValueFromReference, } from '@summerfi/sdk-common/simulation' @@ -13,13 +13,12 @@ import { isLendingPool } from '@summerfi/sdk-common/protocols' import { refinanceLendingToLendingAnyPairStrategy } from './Strategy' import { type IRefinanceDependencies } from '../common/Types' import { getSwapStepData } from '../../implementation/utils/GetSwapStepData' -import { getRefinanceSimulationType } from '../../implementation/utils/GetRefinanceSimulationType' import { estimateSwapFromAmount } from '../../implementation/utils/EstimateSwapFromAmount' -export async function refinanceLendingToLendingAnyPair( +export async function refinanceLendingToLending( args: IRefinanceParameters, dependencies: IRefinanceDependencies, -): Promise> { +): Promise> { // args validation if (!isLendingPool(args.sourcePosition.pool)) { throw new Error('Source pool is not a lending pool') @@ -46,27 +45,36 @@ export async function refinanceLendingToLendingAnyPair( const isCollateralSwapSkipped = targetPool.collateralToken.equals(sourcePool.collateralToken) const isDebtSwapSkipped = targetPool.debtToken.equals(sourcePool.debtToken) + const isDebtAmountZero = position.debtAmount.toBaseUnit() === '0' + + const maxDebtAmount = TokenAmount.createFrom({ + token: position.debtAmount.token, + amount: Number.MAX_SAFE_INTEGER.toString(), + }) const simulation = await simulator - .next(async () => ({ - name: 'Flashloan', - type: SimulationSteps.Flashloan, - inputs: { - amount: flashloanAmount, - provider: - flashloanAmount.token.symbol === CommonTokenSymbols.DAI - ? FlashloanProvider.Maker - : FlashloanProvider.Balancer, + .next( + async () => ({ + name: 'Flashloan', + type: SimulationSteps.Flashloan, + inputs: { + amount: flashloanAmount, + provider: + flashloanAmount.token.symbol === CommonTokenSymbols.DAI + ? FlashloanProvider.Maker + : FlashloanProvider.Balancer, + }, + }), + { + skip: isDebtAmountZero, + type: SimulationSteps.Flashloan, }, - })) + ) .next(async () => ({ name: 'PaybackWithdrawFromSourcePosition', type: SimulationSteps.PaybackWithdraw, inputs: { - paybackAmount: TokenAmount.createFrom({ - amount: Number.MAX_SAFE_INTEGER.toString(), - token: position.debtAmount.token, - }), + paybackAmount: isDebtAmountZero ? position.debtAmount : maxDebtAmount, withdrawAmount: position.collateralAmount, position: position, withdrawTargetType: TokenTransferTargetType.PositionsManager, @@ -85,7 +93,10 @@ export async function refinanceLendingToLendingAnyPair( oracleManager: dependencies.oracleManager, }), }), - isCollateralSwapSkipped, + { + skip: isCollateralSwapSkipped, + type: SimulationSteps.Swap, + }, ) .next(async () => ({ name: 'OpenTargetPosition', @@ -98,7 +109,9 @@ export async function refinanceLendingToLendingAnyPair( name: 'DepositBorrowToTargetPosition', type: SimulationSteps.DepositBorrow, inputs: { - // refactor + depositAmount: isCollateralSwapSkipped + ? position.collateralAmount + : ctx.getReference(['SwapCollateralFromSourcePosition', 'received']), borrowAmount: isDebtSwapSkipped ? position.debtAmount : await estimateSwapFromAmount({ @@ -108,9 +121,7 @@ export async function refinanceLendingToLendingAnyPair( swapManager: dependencies.swapManager, oracleManager: dependencies.oracleManager, }), - depositAmount: isCollateralSwapSkipped - ? position.collateralAmount - : ctx.getReference(['SwapCollateralFromSourcePosition', 'received']), + position: getValueFromReference(ctx.getReference(['OpenTargetPosition', 'position'])), borrowTargetType: TokenTransferTargetType.PositionsManager, }, @@ -130,30 +141,44 @@ export async function refinanceLendingToLendingAnyPair( oracleManager: dependencies.oracleManager, }), }), - isDebtSwapSkipped, + { + skip: isDebtSwapSkipped, + type: SimulationSteps.Swap, + }, ) - .next(async () => ({ - name: 'RepayFlashloan', - type: SimulationSteps.RepayFlashloan, - inputs: { - amount: flashloanAmount, + .next( + async () => ({ + name: 'RepayFlashloan', + type: SimulationSteps.RepayFlashloan, + inputs: { + amount: flashloanAmount, + }, + }), + { + skip: isDebtAmountZero, + type: SimulationSteps.RepayFlashloan, }, - })) - .next(async () => ({ - name: 'ReturnFunds', - type: SimulationSteps.ReturnFunds, - inputs: { - /* - * We swap back to the original position's debt in order to repay the flashloan. - * Therefore, the dust amount will be in the original position's debt - * */ - token: position.debtAmount.token, + ) + .next( + async () => ({ + name: 'ReturnFunds', + type: SimulationSteps.ReturnFunds, + inputs: { + /* + * We swap back to the original position's debt in order to repay the flashloan. + * Therefore, the dust amount will be in the original position's debt + * */ + token: position.debtAmount.token, + }, + }), + { + skip: isDebtAmountZero || isDebtSwapSkipped, + type: SimulationSteps.ReturnFunds, }, - })) + ) .next(async (ctx) => { - // TODO: we should have a way to get the target position more easily and realiably, - const targetPosition = Object.values(ctx.state.positions).find((p) => - p.pool.id.protocol.equals(targetPool.id.protocol), + const targetPosition = getValueFromReference( + ctx.getReference(['OpenTargetPosition', 'position']), ) if (!targetPosition) { throw new Error('Target position not found') @@ -181,10 +206,10 @@ export async function refinanceLendingToLendingAnyPair( } return { - simulationType: getRefinanceSimulationType(!isCollateralSwapSkipped, !isDebtSwapSkipped), + simulationType: SimulationType.Refinance, sourcePosition: position, - targetPosition, + targetPosition: targetPosition, swaps: simulation.swaps, steps: simulation.steps, - } satisfies ISimulation + } satisfies ISimulation } diff --git a/sdk/simulator-service/src/strategies/refinanceAnyPair/Strategy.ts b/sdk/simulator-service/src/strategies/refinanceLendingToLending/Strategy.ts similarity index 100% rename from sdk/simulator-service/src/strategies/refinanceAnyPair/Strategy.ts rename to sdk/simulator-service/src/strategies/refinanceLendingToLending/Strategy.ts diff --git a/sdk/simulator-service/src/strategies/refinanceAnyPair/index.ts b/sdk/simulator-service/src/strategies/refinanceLendingToLending/index.ts similarity index 100% rename from sdk/simulator-service/src/strategies/refinanceAnyPair/index.ts rename to sdk/simulator-service/src/strategies/refinanceLendingToLending/index.ts diff --git a/sdk/simulator-service/src/strategies/refinanceNoDebt/RefinanceLendingToLendingNoDebt.ts b/sdk/simulator-service/src/strategies/refinanceNoDebt/RefinanceLendingToLendingNoDebt.ts deleted file mode 100644 index d56c51a195..0000000000 --- a/sdk/simulator-service/src/strategies/refinanceNoDebt/RefinanceLendingToLendingNoDebt.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { - ISimulation, - SimulationSteps, - SimulationType, - TokenTransferTargetType, - getValueFromReference, -} from '@summerfi/sdk-common/simulation' -import { Simulator } from '../../implementation/simulator-engine' -import { Percentage, TokenAmount } from '@summerfi/sdk-common/common' -import { IRefinanceParameters } from '@summerfi/sdk-common/orders' -import { isLendingPool } from '@summerfi/sdk-common/protocols' -import { refinanceLendingToLendingNoDebtStrategy } from './Strategy' -import { type IRefinanceDependencies } from '../common/Types' -import { getSwapStepData } from '../../implementation/utils/GetSwapStepData' - -export async function refinanceLendingToLendingNoDebt( - args: IRefinanceParameters, - dependencies: IRefinanceDependencies, -): Promise< - ISimulation -> { - // args validation - if (!isLendingPool(args.sourcePosition.pool)) { - throw new Error('Source pool is not a lending pool') - } - if (!isLendingPool(args.targetPool)) { - throw new Error('Target pool is not a lending pool') - } - - const position = args.sourcePosition - const sourcePool = args.sourcePosition.pool - const targetPool = args.targetPool - - if (!isLendingPool(targetPool)) { - throw new Error('Target pool is not a lending pool') - } - const simulator = Simulator.create(refinanceLendingToLendingNoDebtStrategy) - - const zeroAmount = TokenAmount.createFromBaseUnit({ - token: position.debtAmount.token, - amount: '0', - }) - - const isCollateralSwapSkipped = targetPool.collateralToken.equals(sourcePool.collateralToken) - - const simulation = await simulator - .next(async () => ({ - name: 'PaybackWithdrawFromSourcePosition', - type: SimulationSteps.PaybackWithdraw, - inputs: { - paybackAmount: zeroAmount, - withdrawAmount: position.collateralAmount, - position: position, - withdrawTargetType: TokenTransferTargetType.PositionsManager, - }, - })) - .next( - async () => ({ - name: 'SwapCollateralFromSourcePosition', - type: SimulationSteps.Swap, - inputs: await getSwapStepData({ - chainInfo: position.pool.id.protocol.chainInfo, - fromAmount: position.collateralAmount, - toToken: targetPool.collateralToken, - slippage: Percentage.createFrom({ value: args.slippage.value }), - swapManager: dependencies.swapManager, - oracleManager: dependencies.oracleManager, - }), - }), - isCollateralSwapSkipped, - ) - .next(async () => ({ - name: 'OpenTargetPosition', - type: SimulationSteps.OpenPosition, - inputs: { - pool: targetPool, - }, - })) - .next(async (ctx) => ({ - name: 'DepositBorrowToTargetPosition', - type: SimulationSteps.DepositBorrow, - inputs: { - depositAmount: isCollateralSwapSkipped - ? position.collateralAmount - : ctx.getReference(['SwapCollateralFromSourcePosition', 'received']), - borrowAmount: TokenAmount.createFrom({ - amount: '0', - token: targetPool.debtToken, - }), - position: getValueFromReference(ctx.getReference(['OpenTargetPosition', 'position'])), - borrowTargetType: TokenTransferTargetType.PositionsManager, - }, - })) - .next(async (ctx) => { - const targetPosition = getValueFromReference( - ctx.getReference(['OpenTargetPosition', 'position']), - ) - if (!targetPosition) { - throw new Error('Target position not found') - } - - return { - name: 'NewPositionEvent', - type: SimulationSteps.NewPositionEvent, - inputs: { - position: targetPosition, - }, - } - }) - .run() - - const targetPositionId = getValueFromReference( - simulation.getReference(['OpenTargetPosition', 'position']), - ) - const targetPosition = Object.values(simulation.positions).find( - (p) => p.id.id === targetPositionId.id.id, - ) - - if (!targetPosition) { - throw new Error('Target position not found') - } - - return { - simulationType: isCollateralSwapSkipped - ? SimulationType.RefinanceNoDebt - : SimulationType.RefinanceNoDebtDifferentCollateral, - sourcePosition: position, - targetPosition, - swaps: Object.values(simulation.swaps), - steps: Object.values(simulation.steps), - } -} diff --git a/sdk/simulator-service/src/strategies/refinanceNoDebt/Strategy.ts b/sdk/simulator-service/src/strategies/refinanceNoDebt/Strategy.ts deleted file mode 100644 index b95a1fe56e..0000000000 --- a/sdk/simulator-service/src/strategies/refinanceNoDebt/Strategy.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { SimulationSteps } from '@summerfi/sdk-common/simulation' -import { makeStrategy } from '../../implementation/utils' - -export const refinanceLendingToLendingNoDebtStrategy = makeStrategy([ - { - name: 'PaybackWithdrawFromSourcePosition', - step: SimulationSteps.PaybackWithdraw, - optional: false, - }, - { - name: 'SwapCollateralFromSourcePosition', - step: SimulationSteps.Swap, - optional: true, - }, - { - name: 'OpenTargetPosition', - step: SimulationSteps.OpenPosition, - optional: false, - }, - { - name: 'DepositBorrowToTargetPosition', - step: SimulationSteps.DepositBorrow, - optional: false, - }, - { - name: 'NewPositionEvent', - step: SimulationSteps.NewPositionEvent, - optional: false, - }, -] as const) diff --git a/sdk/simulator-service/src/strategies/refinanceNoDebt/index.ts b/sdk/simulator-service/src/strategies/refinanceNoDebt/index.ts deleted file mode 100644 index cd0d1e4d72..0000000000 --- a/sdk/simulator-service/src/strategies/refinanceNoDebt/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './RefinanceLendingToLendingNoDebt' -export * from './Strategy' diff --git a/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts b/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts deleted file mode 100644 index 1f32eef744..0000000000 --- a/sdk/simulator-service/src/strategies/refinanceSamePair/RefinanceLendingToLendingSamePair.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { - FlashloanProvider, - ISimulation, - SimulationSteps, - SimulationType, - TokenTransferTargetType, - getValueFromReference, -} from '@summerfi/sdk-common/simulation' -import { Simulator } from '../../implementation/simulator-engine' -import { TokenAmount } from '@summerfi/sdk-common/common' -import { IRefinanceParameters } from '@summerfi/sdk-common/orders' -import { isLendingPool } from '@summerfi/sdk-common/protocols' -import { refinanceLendingToLendingSamePairStrategy } from './Strategy' -import { type IRefinanceDependencies } from '../common/Types' - -export async function refinanceLendingToLendingSamePair( - args: IRefinanceParameters, - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ - dependencies: IRefinanceDependencies, -): Promise> { - // args validation - if (!isLendingPool(args.sourcePosition.pool)) { - throw new Error('Source pool is not a lending pool') - } - if (!isLendingPool(args.targetPool)) { - throw new Error('Target pool is not a lending pool') - } - - const position = args.sourcePosition - const targetPool = args.targetPool - - if (!isLendingPool(targetPool)) { - throw new Error('Target pool is not a lending pool') - } - - const FLASHLOAN_MARGIN = 1.001 - const flashloanAmount = position.debtAmount.multiply(FLASHLOAN_MARGIN) - const simulator = Simulator.create(refinanceLendingToLendingSamePairStrategy) - - // TODO: read debt amount from chain (special step: ReadDebtAmount) - // TODO: the swap quote should also include the summer fee, in this case we need to know when we are taking the fee, - // before or after the swap, it influences actual call to oneInch api - const simulation = await simulator - .next(async () => ({ - name: 'Flashloan', - type: SimulationSteps.Flashloan, - inputs: { - amount: flashloanAmount, - provider: - flashloanAmount.token.symbol === 'DAI' - ? FlashloanProvider.Maker - : FlashloanProvider.Balancer, - }, - })) - .next(async () => ({ - name: 'PaybackWithdrawFromSourcePosition', - type: SimulationSteps.PaybackWithdraw, - inputs: { - paybackAmount: TokenAmount.createFrom({ - amount: Number.MAX_SAFE_INTEGER.toString(), - token: position.debtAmount.token, - }), - withdrawTargetType: TokenTransferTargetType.PositionsManager, - withdrawAmount: position.collateralAmount, - position: position, - }, - })) - .next(async () => ({ - name: 'OpenTargetPosition', - type: SimulationSteps.OpenPosition, - inputs: { - pool: targetPool, - }, - })) - .next(async (ctx) => ({ - name: 'DepositBorrowToTargetPosition', - type: SimulationSteps.DepositBorrow, - inputs: { - depositAmount: position.collateralAmount, - borrowAmount: position.debtAmount, // TODO figure the debt amount - position: getValueFromReference(ctx.getReference(['OpenTargetPosition', 'position'])), - borrowTargetType: TokenTransferTargetType.PositionsManager, - }, - })) - .next(async () => ({ - name: 'RepayFlashloan', - type: SimulationSteps.RepayFlashloan, - inputs: { - amount: flashloanAmount, - }, - })) - .next(async (ctx) => { - // TODO: we should have a way to get the target position more easily and realiably, - const targetPosition = Object.values(ctx.state.positions).find( - (p) => p.pool.id.protocol === targetPool.id.protocol, - ) - if (!targetPosition) { - throw new Error('Target position not found') - } - - return { - name: 'NewPositionEvent', - type: SimulationSteps.NewPositionEvent, - inputs: { - position: targetPosition, - }, - } - }) - .run() - - const targetPositionId = getValueFromReference( - simulation.getReference(['OpenTargetPosition', 'position']), - ) - const targetPosition = Object.values(simulation.positions).find( - (p) => p.id.id === targetPositionId.id.id, - ) - - if (!targetPosition) { - throw new Error('Target position not found') - } - - return { - simulationType: SimulationType.Refinance, - sourcePosition: position, - targetPosition, - swaps: Object.values(simulation.swaps), - steps: Object.values(simulation.steps), - } as ISimulation -} diff --git a/sdk/simulator-service/src/strategies/refinanceSamePair/Strategy.ts b/sdk/simulator-service/src/strategies/refinanceSamePair/Strategy.ts deleted file mode 100644 index 9645f4fb5a..0000000000 --- a/sdk/simulator-service/src/strategies/refinanceSamePair/Strategy.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { SimulationSteps } from '@summerfi/sdk-common/simulation' -import { makeStrategy } from '../../implementation/utils' - -export const refinanceLendingToLendingSamePairStrategy = makeStrategy([ - { - name: 'Flashloan', - step: SimulationSteps.Flashloan, - optional: false, - }, - { - name: 'PaybackWithdrawFromSourcePosition', - step: SimulationSteps.PaybackWithdraw, - optional: false, - }, - { - name: 'OpenTargetPosition', - step: SimulationSteps.OpenPosition, - optional: false, - }, - { - name: 'DepositBorrowToTargetPosition', - step: SimulationSteps.DepositBorrow, - optional: false, - }, - { - name: 'RepayFlashloan', - step: SimulationSteps.RepayFlashloan, - optional: false, - }, - { - name: 'NewPositionEvent', - step: SimulationSteps.NewPositionEvent, - optional: false, - }, -] as const) diff --git a/sdk/simulator-service/src/strategies/refinanceSamePair/index.ts b/sdk/simulator-service/src/strategies/refinanceSamePair/index.ts deleted file mode 100644 index df1f26236a..0000000000 --- a/sdk/simulator-service/src/strategies/refinanceSamePair/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './RefinanceLendingToLendingSamePair' -export * from './Strategy' diff --git a/sdk/simulator-service/tests/simulator.test.ts b/sdk/simulator-service/tests/simulator.test.ts index eb767a27bc..33cfb78e09 100644 --- a/sdk/simulator-service/tests/simulator.test.ts +++ b/sdk/simulator-service/tests/simulator.test.ts @@ -1,79 +1,19 @@ -import { ISimulation, SimulationSteps, steps } from '@summerfi/sdk-common/simulation' -import { - refinanceLendingToLendingAnyPair, - refinanceLendingToLendingSamePair, -} from '../src/strategies' +import { ISimulation, SimulationSteps, SimulationType } from '@summerfi/sdk-common/simulation' +import { refinanceLendingToLending } from '../src/strategies' import { Percentage } from '@summerfi/sdk-common/common' import { otherTestCollateral, otherTestDebt, testSourcePosition, - testTargetLendingPool, testTargetLendingPoolRequiredSwaps, } from './mocks/testSourcePosition' import { mockRefinanceContext, mockRefinanceContextRequiredSwaps } from './mocks/contextMock' -import assert from 'assert' -import { RefinanceSimulationTypes } from '@summerfi/sdk-common' describe('Refinance', () => { - describe('to the position with the same collateral and debt (no swaps)', () => { - let simulation: ISimulation - beforeAll(async () => { - simulation = await refinanceLendingToLendingSamePair( - { - sourcePosition: testSourcePosition, - targetPool: testTargetLendingPool, - slippage: Percentage.createFrom({ value: 1 }), - }, - mockRefinanceContext, - ) - }) - - it('should not include swap steps', async () => { - const steps = simulation.steps.filter((step) => !step.skip).map((step) => step.type) - - expect(steps).not.toContain(SimulationSteps.Swap) - }) - - it('should open position with the same collateral', async () => { - const targetPosition = simulation.targetPosition - - expect(targetPosition.collateralAmount).toEqual(testSourcePosition.collateralAmount) - }) - - it('should open position with the same debt', async () => { - const targetPosition = simulation.targetPosition - - expect(targetPosition.debtAmount).toEqual(testSourcePosition.debtAmount) - }) - - it('should open position as required target pool', async () => { - const targetPosition = simulation.targetPosition - - expect(targetPosition.pool).toEqual(testTargetLendingPool) - expect(targetPosition.id).toBeDefined() - }) - - it('should open position with id', async () => { - const targetPosition = simulation.targetPosition - - expect(targetPosition.id).toBeDefined() - }) - - it('should include a new position event step', async () => { - const newPositionStep = simulation.steps.find( - (step) => step.type === SimulationSteps.NewPositionEvent, - ) as steps.NewPositionEventStep - - assert(newPositionStep, 'New position event step not found') - expect(newPositionStep.inputs.position).toEqual(simulation.targetPosition) - }) - }) - describe('to the position with the different collateral and debt (with swaps)', () => { - let simulation: ISimulation + let simulation: ISimulation beforeAll(async () => { - simulation = await refinanceLendingToLendingAnyPair( + simulation = await refinanceLendingToLending( { sourcePosition: testSourcePosition, targetPool: testTargetLendingPoolRequiredSwaps, diff --git a/sdk/testing-utils/src/utils/StrategyExecutorDecoding.ts b/sdk/testing-utils/src/utils/StrategyExecutorDecoding.ts index 2d79e74a90..293dda7e25 100644 --- a/sdk/testing-utils/src/utils/StrategyExecutorDecoding.ts +++ b/sdk/testing-utils/src/utils/StrategyExecutorDecoding.ts @@ -2,10 +2,6 @@ import { ActionCall } from '@summerfi/protocol-plugins-common' import { HexData } from '@summerfi/sdk-common/common' import { decodeFunctionData, parseAbi } from 'viem' -export type SkippableActionCall = ActionCall & { - skipped: boolean -} - export function decodeStrategyExecutorCalldata(calldata: HexData | string): | { actionCalls: ActionCall[] @@ -26,13 +22,8 @@ export function decodeStrategyExecutorCalldata(calldata: HexData | string): return undefined } - const actionCalls: ActionCall[] = (decoded.args[0] as SkippableActionCall[]).map( - /* eslint-disable @typescript-eslint/no-unused-vars */ - ({ skipped, ...rest }) => rest, - ) - return { - actionCalls, + actionCalls: decoded.args[0] as ActionCall[], strategyName: decoded.args[1] as string, } } diff --git a/sdk/testing-utils/src/utils/index.ts b/sdk/testing-utils/src/utils/index.ts index 38ac213782..de3debca51 100644 --- a/sdk/testing-utils/src/utils/index.ts +++ b/sdk/testing-utils/src/utils/index.ts @@ -1,7 +1,4 @@ -export { decodeActionCalldata, getTargetHash } from './ActionDecoding' -export { getErrorMessage } from './ErrorMessage' -export { - type SkippableActionCall, - decodeStrategyExecutorCalldata, -} from './StrategyExecutorDecoding' -export { decodePositionsManagerCalldata } from './PositionsManagerDecoding' +export * from './ActionDecoding' +export * from './ErrorMessage' +export * from './StrategyExecutorDecoding' +export * from './PositionsManagerDecoding' diff --git a/sdk/tools/genStrategyDefinitions/src/index.ts b/sdk/tools/genStrategyDefinitions/src/index.ts index 052b6bb844..7526a5bf37 100644 --- a/sdk/tools/genStrategyDefinitions/src/index.ts +++ b/sdk/tools/genStrategyDefinitions/src/index.ts @@ -27,7 +27,7 @@ async function main() { }) .option('format', { alias: 'f', - description: 'Output format (safe, tenderly)', + description: 'Output format (safe, tenderly, debug)', default: 'safe', type: 'string', }) @@ -51,8 +51,10 @@ async function main() { // Write to file if (args.format === 'safe') { fs.writeFileSync(args.output, JSON.stringify(safeBatch, null, 2)) - } else { + } else if (args.format === 'tenderly') { fs.writeFileSync(args.output, JSON.stringify(operationDefinitions, null, 2)) + } else { + fs.writeFileSync(args.output, JSON.stringify(strategyDefinitions, null, 2)) } } else { console.log('--------------------') From 39f737017170d31a7751a98b0139936a4e9fd040 Mon Sep 17 00:00:00 2001 From: Halaprix Date: Mon, 27 May 2024 14:51:41 +0200 Subject: [PATCH 26/37] feat: add leaderboard position to user (#306) --- packages/rays-db/src/database-types.ts | 3 ++ .../src/migrations/003_leaderboard.mts | 51 +++++++++++-------- summerfi-api/get-rays-function/src/index.ts | 7 ++- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/packages/rays-db/src/database-types.ts b/packages/rays-db/src/database-types.ts index 04d20befed..4ffbe6bdeb 100644 --- a/packages/rays-db/src/database-types.ts +++ b/packages/rays-db/src/database-types.ts @@ -7,6 +7,8 @@ export type Generated = ? ColumnType : ColumnType +export type Int8 = ColumnType + export type Json = JsonValue export type JsonArray = JsonValue[] @@ -45,6 +47,7 @@ export interface EligibilityCondition { } export interface Leaderboard { + position: Int8 | null totalPoints: Numeric | null userAddress: string | null } diff --git a/packages/rays-db/src/migrations/003_leaderboard.mts b/packages/rays-db/src/migrations/003_leaderboard.mts index 4cef23a745..5f180d7a4a 100644 --- a/packages/rays-db/src/migrations/003_leaderboard.mts +++ b/packages/rays-db/src/migrations/003_leaderboard.mts @@ -2,26 +2,37 @@ import { Kysely, sql } from 'kysely' export async function up(db: Kysely) { await sql` - CREATE VIEW leaderboard AS - SELECT - ua.address AS user_address, - COALESCE(SUM(cp.total_points), 0) AS total_points - FROM - user_address ua - LEFT JOIN - ( - SELECT - COALESCE(p.user_address_id, pd.user_address_id) AS user_address_id, - SUM(pd.points) AS total_points - FROM - points_distribution pd - LEFT JOIN - position p ON pd.position_id = p.id - GROUP BY - COALESCE(p.user_address_id, pd.user_address_id) - ) AS cp ON ua.id = cp.user_address_id - GROUP BY - ua.address; + CREATE VIEW leaderboard AS + SELECT + ROW_NUMBER() OVER (ORDER BY total_points DESC) AS position, + user_address, + total_points + FROM + ( + SELECT + ua.address AS user_address, + COALESCE(SUM(cp.total_points), 0) AS total_points + FROM + user_address ua + LEFT JOIN + ( + SELECT + COALESCE(p.user_address_id, pd.user_address_id) AS user_address_id, + SUM(pd.points) AS total_points + FROM + points_distribution pd + LEFT JOIN + position p ON pd.position_id = p.id + GROUP BY + COALESCE(p.user_address_id, pd.user_address_id) + ) AS cp ON ua.id = cp.user_address_id + GROUP BY + ua.address + ) AS leaderboard + WHERE + total_points IS NOT NULL + ORDER BY + total_points DESC; `.execute(db) } diff --git a/summerfi-api/get-rays-function/src/index.ts b/summerfi-api/get-rays-function/src/index.ts index ab33729ef9..35a713384a 100644 --- a/summerfi-api/get-rays-function/src/index.ts +++ b/summerfi-api/get-rays-function/src/index.ts @@ -88,7 +88,11 @@ export const handler = async ( 'eligibilityCondition.type', ]) .execute() - + const positionInLeaderboard = await db + .selectFrom('leaderboard') + .where('userAddress', '=', address.toLowerCase()) + .select(['position']) + .execute() const points = userPoints.concat(positionsPoints) const byDueDate = groupBy( @@ -116,6 +120,7 @@ export const handler = async ( eligiblePoints, allPossiblePoints, actionRequiredPoints, + positionInLeaderboard: positionInLeaderboard[0]?.position, }, }) } From 27fc9507ead17ad11c656d0c2f66ec5673128dc3 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Tue, 28 May 2024 10:07:23 +0200 Subject: [PATCH 27/37] fix: use flashloan amount for borrowing (#308) --- .../RefinanceLendingToLendingAnyPair.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/simulator-service/src/strategies/refinanceLendingToLending/RefinanceLendingToLendingAnyPair.ts b/sdk/simulator-service/src/strategies/refinanceLendingToLending/RefinanceLendingToLendingAnyPair.ts index 30ef7f6ab7..ae8ba127d0 100644 --- a/sdk/simulator-service/src/strategies/refinanceLendingToLending/RefinanceLendingToLendingAnyPair.ts +++ b/sdk/simulator-service/src/strategies/refinanceLendingToLending/RefinanceLendingToLendingAnyPair.ts @@ -113,7 +113,7 @@ export async function refinanceLendingToLending( ? position.collateralAmount : ctx.getReference(['SwapCollateralFromSourcePosition', 'received']), borrowAmount: isDebtSwapSkipped - ? position.debtAmount + ? flashloanAmount : await estimateSwapFromAmount({ receiveAtLeast: flashloanAmount, fromToken: targetPool.debtToken, From 292d6dd540a3d12f27575280cd2c6472fb785860 Mon Sep 17 00:00:00 2001 From: Halaprix Date: Tue, 28 May 2024 14:07:58 +0200 Subject: [PATCH 28/37] fix: fx mutliple issues (#310) - add user multipliers one before processing positions ( to avoid adding duplicates) - change names - avoid skipping processing multiple users in the eligibility check ( change `return` to `continue` ) --- .../update-rays-cron-function/src/index.ts | 395 ++++++++++++------ 1 file changed, 271 insertions(+), 124 deletions(-) diff --git a/background-jobs/update-rays-cron-function/src/index.ts b/background-jobs/update-rays-cron-function/src/index.ts index caa745372b..dce0d4eecd 100644 --- a/background-jobs/update-rays-cron-function/src/index.ts +++ b/background-jobs/update-rays-cron-function/src/index.ts @@ -6,7 +6,7 @@ import { getSummerPointsSubgraphClient } from '@summerfi/summer-events-subgraph' import { ChainId } from '@summerfi/serverless-shared' import { PositionPoints, SummerPointsService } from './point-accrual' import { positionIdResolver } from './position-id-resolver' -import { Kysely } from 'kysely' +import { Kysely, Transaction } from 'kysely' const logger = new Logger({ serviceName: 'update-rays-cron-function' }) @@ -17,32 +17,57 @@ const FOURTEEN_DAYS_IN_MILLISECONDS = 14 * 24 * 60 * 60 * 1000 const SIXTY_DAYS_IN_MILLISECONDS = 60 * 24 * 60 * 60 const THIRTY_DAYS_IN_MILLISECONDS = 30 * 24 * 60 * 60 * 1000 -enum EligibilityConditionType { +enum UserMultiplier { + PROTOCOL_BOOST = 'PROTOCOL_BOOST', + SWAP = 'SWAP', +} + +enum RetroPointDistribution { + SNAPSHOT_GENERAL = 'Snapshot_General', + SNAPSHOT_DEFI = 'Snapshot_Defi', + SNAPSHOT_SUMMER = 'Snapshot_Summer', + SNAPSHOT_SUMMER_POWER = 'Snapshot_SummerPower', +} + +enum OngoingPointDistribution { + OPEN_POSITION = 'OPEN_POSITION', + MIGRATION = 'MIGRATION', + SWAP = 'SWAP', +} + +enum PositionMultiplier { + TIME_OPEN = 'TIME_OPEN', + AUTOMATION = 'AUTOMATION', + LAZY_VAULT = 'LAZY_VAULT', +} + +enum EligibilityCondition { POSITION_OPEN_TIME = 'POSITION_OPEN_TIME', POINTS_EXPIRED = 'POINTS_EXPIRED', BECOME_SUMMER_USER = 'BECOME_SUMMER_USER', } + type Eligibility = { - type: EligibilityConditionType + type: EligibilityCondition description: string metadata: Record> } -const eligibilityConditions: Record = { - [EligibilityConditionType.POSITION_OPEN_TIME]: { - type: EligibilityConditionType.POSITION_OPEN_TIME, +const eligibilityConditions: Record = { + [EligibilityCondition.POSITION_OPEN_TIME]: { + type: EligibilityCondition.POSITION_OPEN_TIME, description: 'The position must be open for at least 30 days', metadata: { minDays: 30, }, }, - [EligibilityConditionType.POINTS_EXPIRED]: { - type: EligibilityConditionType.POINTS_EXPIRED, + [EligibilityCondition.POINTS_EXPIRED]: { + type: EligibilityCondition.POINTS_EXPIRED, description: 'The points have expired', metadata: {}, }, - [EligibilityConditionType.BECOME_SUMMER_USER]: { - type: EligibilityConditionType.BECOME_SUMMER_USER, + [EligibilityCondition.BECOME_SUMMER_USER]: { + type: EligibilityCondition.BECOME_SUMMER_USER, description: 'Must use summer for at least 14 days with at least 500 USD', metadata: { minDays: 14, @@ -165,67 +190,94 @@ export const handler = async ( return } - const points = await pointAccuralService.accruePoints(startTimestamp, endTimestamp) - const sortedPoints = points.sort((a, b) => a.positionId.localeCompare(b.positionId)) + const accruedPointsFromSnapshot = await pointAccuralService.accruePoints( + startTimestamp, + endTimestamp, + ) + const sortedAccruedPointsFromSnapshot = accruedPointsFromSnapshot.sort((a, b) => + a.positionId.localeCompare(b.positionId), + ) - await checkMigrationEligibility(db, sortedPoints) - await checkOpenedPositionEligibility(db, sortedPoints) - await insertAllMissingUsers(sortedPoints, db) + await checkMigrationEligibility(db, sortedAccruedPointsFromSnapshot) + await checkOpenedPositionEligibility(db, sortedAccruedPointsFromSnapshot) + await insertAllMissingUsers(sortedAccruedPointsFromSnapshot, db) - const chunkedPoints: PositionPoints[] = createChunksOfUserPointsDistributions(sortedPoints, 30) - await db.transaction().execute(async (transaction) => { - for (let i = 0; i < chunkedPoints.length; i++) { - logger.info(`Processing: Chunk ${i} of ${chunkedPoints.length}`) - const chunk = chunkedPoints[i] - const addressesForChunk = chunk.map((c) => c.user) - const positionsForChunk = chunk.map((c) => c.positionId) + const chunkedPoints: PositionPoints[] = createChunksOfUserPointsDistributions( + sortedAccruedPointsFromSnapshot, + 30, + ) - const userAddresses = await db - .selectFrom('userAddress') - .where('address', 'in', addressesForChunk) - .selectAll() - .execute() - const positions = await db - .selectFrom('position') - .where('externalId', 'in', positionsForChunk) - .selectAll() - .execute() + // Get all unique addresses and positions from all chunks + const uniqueAddressesFromSnapshot = Array.from( + new Set(chunkedPoints.flatMap((chunk) => chunk.map((c) => c.user))), + ) + const allPositions = Array.from( + new Set(chunkedPoints.flatMap((chunk) => chunk.map((c) => c.positionId))), + ) - const usersMultipliers = await db - .selectFrom('multiplier') - .innerJoin('userAddress', 'multiplier.userAddressId', 'userAddress.id') - .where('userAddress.address', 'in', addressesForChunk) - .select([ - 'multiplier.value', - 'multiplier.type', - 'multiplier.id', - 'multiplier.userAddressId', - 'multiplier.positionId', - ]) - .execute() + // Fetch all necessary data for all chunks at once + const uniqueUserAddressesFromDatabase = await db + .selectFrom('userAddress') + .where('address', 'in', uniqueAddressesFromSnapshot) + .selectAll() + .execute() + + const positionsFromDatabase = await db + .selectFrom('position') + .where('externalId', 'in', allPositions) + .selectAll() + .execute() + + const usersMultipliersFromDatabase = await db + .selectFrom('multiplier') + .innerJoin('userAddress', 'multiplier.userAddressId', 'userAddress.id') + .where('userAddress.address', 'in', uniqueAddressesFromSnapshot) + .select([ + 'multiplier.value', + 'multiplier.type', + 'multiplier.id', + 'multiplier.userAddressId', + 'multiplier.positionId', + ]) + .execute() + const positionsMultipliersFromDatabase = await db + .selectFrom('multiplier') + .innerJoin('position', 'multiplier.positionId', 'position.id') + .where('position.externalId', 'in', allPositions) + .select([ + 'multiplier.value', + 'multiplier.type', + 'multiplier.id', + 'multiplier.userAddressId', + 'multiplier.positionId', + ]) + .execute() - const positionsMultipliers = await db - .selectFrom('multiplier') - .innerJoin('position', 'multiplier.positionId', 'position.id') - .where('position.externalId', 'in', positionsForChunk) - .select([ - 'multiplier.value', - 'multiplier.type', - 'multiplier.id', - 'multiplier.userAddressId', - 'multiplier.positionId', - ]) - .execute() + await db.transaction().execute(async (transaction) => { + await addOrUpdateUserMultipliers( + uniqueAddressesFromSnapshot, + uniqueUserAddressesFromDatabase, + accruedPointsFromSnapshot, + usersMultipliersFromDatabase, + transaction, + ) + + for (let i = 0; i < chunkedPoints.length; i++) { + const startTime = process.hrtime() + logger.info(`Processing: Chunk ${i + 1} of ${chunkedPoints.length}`) + const chunk = chunkedPoints[i] for (const record of chunk) { - const userAddress = userAddresses.find((ua) => ua.address === record.user) + const userAddress = uniqueUserAddressesFromDatabase.find( + (ua) => ua.address === record.user, + ) if (!userAddress) { throw new Error('User address not found') } const positionId = positionIdResolver(record.positionId) - let position = positions.find((p) => p.externalId === record.positionId) + let position = positionsFromDatabase.find((p) => p.externalId === record.positionId) if (!position) { position = await transaction .insertInto('position') @@ -250,7 +302,7 @@ export const handler = async ( description: 'Points for opening a position', points: record.points.openPositionsPoints, positionId: position.id, - type: 'OPEN_POSITION', + type: OngoingPointDistribution.OPEN_POSITION, }) .executeTakeFirstOrThrow() } @@ -277,7 +329,7 @@ export const handler = async ( description: 'Points for migrations', points: record.points.migrationPoints, positionId: position.id, - type: 'MIGRATION', + type: OngoingPointDistribution.MIGRATION, eligibilityConditionId: eligibilityCondition.id, }) .executeTakeFirstOrThrow() @@ -290,7 +342,7 @@ export const handler = async ( description: 'Points for swap', points: record.points.swapPoints, positionId: position.id, - type: 'SWAP', + type: OngoingPointDistribution.SWAP, }) .executeTakeFirstOrThrow() } @@ -299,62 +351,23 @@ export const handler = async ( // protocolBoostMultiplier: -> user multiplier -> type = 'PROTOCOL_BOOST' // swapMultiplier: number -> user multiplier -> type = 'SWAP' // timeOpenMultiplier: number -> position multiplier -> type = 'TIME_OPEN' - // automationProtectionMultiplier: number -> position multiplier -> type = 'AUTOMATION' + // automationProtectionMultiplier: number -> position multiplier -> type = PositionMultiplier.AUTOMATION // lazyVaultMultiplier: number -> position multiplier -> type = 'LAZY_VAULT' - const userMultipliers = usersMultipliers.filter((m) => m.userAddressId === userAddress.id) - const positionMultipliers = positionsMultipliers.filter( + const positionMultipliers = positionsMultipliersFromDatabase.filter( (m) => m.positionId === position.id, ) - let procotolBoostMultiplier = userMultipliers.find((m) => m.type === 'PROTOCOL_BOOST') - - if (!procotolBoostMultiplier) { - procotolBoostMultiplier = await transaction - .insertInto('multiplier') - .values({ - userAddressId: userAddress.id, - type: 'PROTOCOL_BOOST', - value: record.multipliers.protocolBoostMultiplier, - }) - .returningAll() - .executeTakeFirstOrThrow() - } else { - await transaction - .updateTable('multiplier') - .set('value', record.multipliers.protocolBoostMultiplier) - .where('id', '=', procotolBoostMultiplier.id) - .execute() - } - - let swapMultiplier = userMultipliers.find((m) => m.type === 'SWAP') - - if (!swapMultiplier) { - swapMultiplier = await transaction - .insertInto('multiplier') - .values({ - userAddressId: userAddress.id, - type: 'SWAP', - value: record.multipliers.swapMultiplier, - }) - .returningAll() - .executeTakeFirstOrThrow() - } else { - await transaction - .updateTable('multiplier') - .set('value', record.multipliers.swapMultiplier) - .where('id', '=', swapMultiplier.id) - .execute() - } - - let timeOpenMultiplier = positionMultipliers.find((m) => m.type === 'TIME_OPEN') + let timeOpenMultiplier = positionMultipliers.find( + (m) => m.type === PositionMultiplier.TIME_OPEN, + ) if (!timeOpenMultiplier) { timeOpenMultiplier = await transaction .insertInto('multiplier') .values({ positionId: position.id, - type: 'TIME_OPEN', + type: PositionMultiplier.TIME_OPEN, value: record.multipliers.timeOpenMultiplier, }) .returningAll() @@ -368,7 +381,7 @@ export const handler = async ( } let automationProtectionMultiplier = positionMultipliers.find( - (m) => m.type === 'AUTOMATION', + (m) => m.type === PositionMultiplier.AUTOMATION, ) if (!automationProtectionMultiplier) { @@ -376,7 +389,7 @@ export const handler = async ( .insertInto('multiplier') .values({ positionId: position.id, - type: 'AUTOMATION', + type: PositionMultiplier.AUTOMATION, value: record.multipliers.automationProtectionMultiplier, }) .returningAll() @@ -389,13 +402,15 @@ export const handler = async ( .execute() } - const lazyVaultMultiplier = positionMultipliers.find((m) => m.type === 'LAZY_VAULT') + const lazyVaultMultiplier = positionMultipliers.find( + (m) => m.type === PositionMultiplier.LAZY_VAULT, + ) if (!lazyVaultMultiplier) { await transaction .insertInto('multiplier') .values({ positionId: position.id, - type: 'LAZY_VAULT', + type: PositionMultiplier.LAZY_VAULT, value: record.multipliers.lazyVaultMultiplier, }) .execute() @@ -416,7 +431,7 @@ export const handler = async ( endTimestamp: new Date(endTimestamp * 1000), startTimestamp: new Date(startTimestamp * 1000), metadata: { - positions: points.length, + positions: accruedPointsFromSnapshot.length, }, }) .executeTakeFirstOrThrow() @@ -426,6 +441,10 @@ export const handler = async ( .set('lastTimestamp', new Date(endTimestamp * 1000)) .where('id', '=', LAST_RUN_ID) .execute() + const endTime = process.hrtime(startTime) + logger.info( + `Chunk ${i} of ${chunkedPoints.length} took ${endTime[0]}s ${endTime[1] / 1000000}ms`, + ) } }) } catch (e) { @@ -443,6 +462,117 @@ export const handler = async ( export default handler +/** + * The `addOrUpdateUserMultipliers` function is an asynchronous function that updates or inserts multipliers for users. + * + * @param addressesFromSnapshot - An array of strings, where each string is an Ethereum or Solana address. + * + * @param uniqueUserAddressesFromDatabase - An array of objects, where each object represents a user address (from DB) . Each object has the following properties: + * - `address`: A string representing the Ethereum or Solana address of the user. + * - `createdAt`: A Date object representing when the user address was created. + * - `id`: A number representing the unique ID of the user address. + * - `type`: A string that can be either 'ETH' or 'SOL', representing the type of the address. + * - `updatedAt`: A Date object representing when the user address was last updated. + * - `userId`: A number representing the unique ID of the user. + * + * @param pointDistributions - An object representing the points of a position. The structure of this object depends on the `PositionPoints` type. + * + * @param usersMultipliersFromDatabase - An array of objects, where each object represents a multiplier. Each object has the following properties: + * - `userAddressId`: A number or null, representing the unique ID of the user address associated with the multiplier. If null, the multiplier is not associated with any user address. + * - `id`: A number representing the unique ID of the multiplier. + * - `type`: A string representing the type of the multiplier. + * - `positionId`: A number or null, representing the unique ID of the position associated with the multiplier. If null, the multiplier is not associated with any position. + * - `value`: A string representing the value of the multiplier. + * + * @param transaction - A Transaction object representing a database transaction. This transaction is used to execute the database operations. + * + * The function works as follows: + * 1. It iterates over each address in the `addressesFromSnapshot` array. + * 2. For each address, it finds the corresponding user address and points distribution. + * 3. If no user address or points distribution is found, it throws an error. + * 4. It then finds the multipliers associated with the user address. + * 5. For each type of multiplier (protocol boost and swap), it checks if a multiplier already exists. + * 6. If a multiplier does not exist, it inserts a new multiplier into the 'multiplier' table with the value from the points distribution. + * 7. If a multiplier does exist, it updates the value of the multiplier in the 'multiplier' table with the value from the points distribution. + */ +async function addOrUpdateUserMultipliers( + uniqueAddressesFromSnapshot: string[], + uniqueUserAddressesFromDatabase: { + address: string + createdAt: Date + id: number + type: 'ETH' | 'SOL' + updatedAt: Date + userId: number + }[], + pointDistributionsFromSnapshot: PositionPoints, + usersMultipliersFromDatabase: { + userAddressId: number | null + id: number + type: string + positionId: number | null + value: string + }[], + transaction: Transaction, +) { + for (const user of uniqueAddressesFromSnapshot) { + const userAddress = uniqueUserAddressesFromDatabase.find((ua) => ua.address === user) + // any points distribution attached to a specific user hold the same multipliers, hence we can take the first one + const userPointsDistribution = pointDistributionsFromSnapshot.find((p) => p.user === user) + + if (!userPointsDistribution) { + throw new Error('User points distribution not found') + } + if (!userAddress) { + throw new Error('User address not found') + } + + const userMultipliers = usersMultipliersFromDatabase.filter( + (m) => m.userAddressId === userAddress.id, + ) + let procotolBoostMultiplier = userMultipliers.find( + (m) => m.type === UserMultiplier.PROTOCOL_BOOST, + ) + if (!procotolBoostMultiplier) { + procotolBoostMultiplier = await transaction + .insertInto('multiplier') + .values({ + userAddressId: userAddress.id, + type: UserMultiplier.PROTOCOL_BOOST, + value: userPointsDistribution.multipliers.protocolBoostMultiplier, + }) + .returningAll() + .executeTakeFirstOrThrow() + } else { + await transaction + .updateTable('multiplier') + .set('value', userPointsDistribution.multipliers.protocolBoostMultiplier) + .where('id', '=', procotolBoostMultiplier.id) + .execute() + } + + let swapMultiplier = userMultipliers.find((m) => m.type === UserMultiplier.SWAP) + + if (!swapMultiplier) { + swapMultiplier = await transaction + .insertInto('multiplier') + .values({ + userAddressId: userAddress.id, + type: UserMultiplier.SWAP, + value: userPointsDistribution.multipliers.swapMultiplier, + }) + .returningAll() + .executeTakeFirstOrThrow() + } else { + await transaction + .updateTable('multiplier') + .set('value', userPointsDistribution.multipliers.swapMultiplier) + .where('id', '=', swapMultiplier.id) + .execute() + } + } +} + /** * Inserts missing users into the database. * @@ -452,7 +582,7 @@ export default handler */ async function insertAllMissingUsers(sortedPoints: PositionPoints, db: Kysely) { const uniqueUsers = new Set(sortedPoints.map((p) => p.user)) - const userAddresses = await db + const uniqueUserAddressesFromDatabase = await db .selectFrom('userAddress') .where('address', 'in', Array.from(uniqueUsers)) .selectAll() @@ -460,7 +590,7 @@ async function insertAllMissingUsers(sortedPoints: PositionPoints, db: Kysely { for (const user of uniqueUsers) { - const userAddress = userAddresses.find((ua) => ua.address === user) + const userAddress = uniqueUserAddressesFromDatabase.find((ua) => ua.address === user) if (!userAddress) { const result = await transaction .insertInto('blockchainUser') @@ -516,7 +646,7 @@ function createChunksOfUserPointsDistributions(sortedPoints: PositionPoints, chu * @param positionPoints - The position points. */ async function checkMigrationEligibility(db: Kysely, positionPoints: PositionPoints) { - const existingPointDistributionsWithEligibilityCondition = await db + const existingOngoingPointDistributionsWithEligibilityCondition = await db .selectFrom('pointsDistribution') .select(['pointsDistribution.id as pointsId']) .innerJoin( @@ -526,13 +656,13 @@ async function checkMigrationEligibility(db: Kysely, positionPoints: P ) .innerJoin('position', 'position.id', 'pointsDistribution.positionId') .where('eligibilityCondition.type', '=', eligibilityConditions.POSITION_OPEN_TIME.type) - .where('pointsDistribution.type', '=', 'MIGRATION') + .where('pointsDistribution.type', '=', OngoingPointDistribution.MIGRATION) .selectAll() .execute() - if (existingPointDistributionsWithEligibilityCondition.length > 0) { + if (existingOngoingPointDistributionsWithEligibilityCondition.length > 0) { await db.transaction().execute(async (transaction) => { - for (const point of existingPointDistributionsWithEligibilityCondition) { + for (const point of existingOngoingPointDistributionsWithEligibilityCondition) { if (point.dueDate && point.dueDate < new Date()) { const positionInSnapshot = positionPoints.find((p) => p.positionId === point.externalId) if (!positionInSnapshot || positionInSnapshot.netValue <= 0) { @@ -591,6 +721,13 @@ async function checkOpenedPositionEligibility( 'pointsDistribution.eligibilityConditionId', ) .leftJoin('userAddress', 'userAddress.id', 'pointsDistribution.userAddressId') + .where((eb) => + eb('pointsDistribution.type', '=', RetroPointDistribution.SNAPSHOT_GENERAL).or( + 'pointsDistribution.type', + '=', + RetroPointDistribution.SNAPSHOT_DEFI, + ), + ) .where('eligibilityCondition.type', '=', eligibilityConditions.BECOME_SUMMER_USER.type) .selectAll() .execute() @@ -600,15 +737,18 @@ async function checkOpenedPositionEligibility( for (const user of existingUsersWithEligibilityCondition) { if (user.dueDate && user.dueDate >= new Date()) { const eligiblePositionsFromPointsAccrual = positionPoints - .filter( - (p) => - p.netValue >= 500 && - p.positionCreated * 1000 < Date.now() - FOURTEEN_DAYS_IN_MILLISECONDS, - ) .filter((p) => p.user === user.address) + .filter((p) => { + console.log('p', p, user.id) + return ( + Number(p.netValue) >= 500 && + p.positionCreated * 1000 < Date.now() - FOURTEEN_DAYS_IN_MILLISECONDS + ) + }) .sort((a, b) => a.positionCreated - b.positionCreated) + if (eligiblePositionsFromPointsAccrual.length == 0) { - return + continue } else { const oldestEligiblePosition = eligiblePositionsFromPointsAccrual[0] const becomeSummerUserMultiplier = getBecomeSummerUserMultiplier( @@ -617,9 +757,16 @@ async function checkOpenedPositionEligibility( const pointsDistributions = await transaction .selectFrom('pointsDistribution') .where('userAddressId', '=', user.id) - .where((eb) => eb('type', '=', 'Snapshot_General').or('type', '=', 'Snapshot_Defi')) + .where((eb) => + eb('type', '=', RetroPointDistribution.SNAPSHOT_GENERAL).or( + 'type', + '=', + RetroPointDistribution.SNAPSHOT_DEFI, + ), + ) .selectAll() .execute() + logger.info(`pointsDistributions for ${user.id}`, JSON.stringify(pointsDistributions)) for (const pointsDistribution of pointsDistributions) { // update points distribution await transaction From 804bbe4f4cbb7ebd0a03441ebd30d2f4a3b7ef74 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Tue, 28 May 2024 16:35:27 +0200 Subject: [PATCH 29/37] fix: oracle spot price interface (#311) --- .../implementation/oneinch/OneInchOracleProvider.ts | 11 ++++++----- .../builders/AaveV3DepositBorrowActionBuilder.ts | 2 +- .../implementation/utils/EstimateSwapFromAmount.ts | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/sdk/oracle-service/src/implementation/oneinch/OneInchOracleProvider.ts b/sdk/oracle-service/src/implementation/oneinch/OneInchOracleProvider.ts index 868a575848..2495de805b 100644 --- a/sdk/oracle-service/src/implementation/oneinch/OneInchOracleProvider.ts +++ b/sdk/oracle-service/src/implementation/oneinch/OneInchOracleProvider.ts @@ -54,12 +54,13 @@ export class OneInchOracleProvider /** @see IOracleProvider.getSpotPrice */ async getSpotPrice(params: { baseToken: IToken - quoteDenomination?: Denomination + quoteToken?: Denomination }): Promise { const authHeader = this._getOneInchSpotAuthHeader() - if (params.quoteDenomination && isToken(params.quoteDenomination)) { + + if (params.quoteToken && isToken(params.quoteToken)) { const baseTokenAddress = params.baseToken.address - const quoteTokenAddress = params.quoteDenomination.address + const quoteTokenAddress = params.quoteToken.address const quoteCurrencySymbol = FiatCurrency.USD const spotUrl = this._formatOneInchSpotUrl({ @@ -81,7 +82,7 @@ export class OneInchOracleProvider const responseData = (await response.json()) as OneInchSpotResponse const baseToken = params.baseToken - const quoteToken = params.quoteDenomination + const quoteToken = params.quoteToken const prices = Object.entries(responseData).map(([address, price]) => { const isBaseToken = baseToken.address.equals( Address.createFromEthereum({ value: address as AddressValue }), @@ -117,7 +118,7 @@ export class OneInchOracleProvider price: resultingPrice, } } else { - const quoteCurrency = params.quoteDenomination ?? FiatCurrency.USD + const quoteCurrency = params.quoteToken ?? FiatCurrency.USD const baseToken = params.baseToken const spotUrl = this._formatOneInchSpotUrl({ diff --git a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts index 9182afb7d3..f421115ac0 100644 --- a/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/aave-v3/builders/AaveV3DepositBorrowActionBuilder.ts @@ -29,7 +29,7 @@ export class AaveV3DepositBorrowActionBuilder extends BaseActionBuilder Date: Tue, 28 May 2024 17:41:31 +0200 Subject: [PATCH 30/37] fix: spark payback action wrapper (#313) Update Spark Payback action and action wrapper --- .../core-contracts/contracts/actions/spark/Payback.sol | 8 ++++++-- packages/core-contracts/contracts/core/types/Spark.sol | 1 + .../src/plugins/spark/actions/SparkPaybackAction.ts | 5 ++++- .../spark/builders/SparkPaybackWithdrawActionBuilder.ts | 3 ++- .../tests/unit/actions/spark/SparkPaybackAction.spec.ts | 2 ++ 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/core-contracts/contracts/actions/spark/Payback.sol b/packages/core-contracts/contracts/actions/spark/Payback.sol index b59d884a66..42bb37b6da 100644 --- a/packages/core-contracts/contracts/actions/spark/Payback.sol +++ b/packages/core-contracts/contracts/actions/spark/Payback.sol @@ -29,11 +29,15 @@ contract SparkPayback is Executable, UseStore { payback.amount = store().readUint(bytes32(payback.amount), paramsMap[1], address(this)); + if (payback.onBehalf == address(0)) { + payback.onBehalf = address(this); + } + IPool(registry.getRegisteredService(SPARK_LENDING_POOL)).repay( payback.asset, payback.paybackAll ? type(uint256).max : payback.amount, 2, - address(this) + payback.onBehalf ); store().write(bytes32(payback.amount)); @@ -42,4 +46,4 @@ contract SparkPayback is Executable, UseStore { function parseInputs(bytes memory _callData) public pure returns (PaybackData memory params) { return abi.decode(_callData, (PaybackData)); } -} +} \ No newline at end of file diff --git a/packages/core-contracts/contracts/core/types/Spark.sol b/packages/core-contracts/contracts/core/types/Spark.sol index 05c93767d4..3081efda6a 100644 --- a/packages/core-contracts/contracts/core/types/Spark.sol +++ b/packages/core-contracts/contracts/core/types/Spark.sol @@ -24,6 +24,7 @@ struct PaybackData { address asset; uint256 amount; bool paybackAll; + address onBehalf; } /** diff --git a/sdk/protocol-plugins/src/plugins/spark/actions/SparkPaybackAction.ts b/sdk/protocol-plugins/src/plugins/spark/actions/SparkPaybackAction.ts index 910cd68569..e263e55bb0 100644 --- a/sdk/protocol-plugins/src/plugins/spark/actions/SparkPaybackAction.ts +++ b/sdk/protocol-plugins/src/plugins/spark/actions/SparkPaybackAction.ts @@ -1,11 +1,12 @@ import { ActionCall, BaseAction, InputSlotsMapping } from '@summerfi/protocol-plugins-common' +import { IAddress } from '@summerfi/sdk-common' import { ITokenAmount } from '@summerfi/sdk-common/common' export class SparkPaybackAction extends BaseAction { public static readonly Config = { name: 'SparkPayback', version: 2, - parametersAbi: ['(address asset, uint256 amount, bool paybackAll)'], + parametersAbi: ['(address asset, uint256 amount, bool paybackAll, address onBehalf)'], storageInputs: ['asset', 'amountToPayback'], storageOutputs: ['paybackedAmount'], } as const @@ -14,6 +15,7 @@ export class SparkPaybackAction extends BaseAction): Promise { - const { context, step, addressBookManager, user } = params + const { context, step, addressBookManager, user, positionsManager } = params if (!isSparkLendingPool(step.inputs.position.pool)) { throw new Error('Invalid Spark lending pool') @@ -57,6 +57,7 @@ export class SparkPaybackWithdrawActionBuilder extends BaseActionBuilder { { paybackAmount: tokenAmount, paybackAll: true, + onBehalf: onBehalf, }, [2, 6, 7, 9], ) @@ -47,6 +48,7 @@ describe('SparkPaybackAction Action', () => { asset: tokenAmount.token.address.value, amount: BigInt(tokenAmount.toBaseUnit()), paybackAll: true, + onBehalf: onBehalf.value, }, ]) expect(actionDecodedArgs?.mapping).toEqual([2, 6, 7, 9]) From 258f6791e10e27b633dad7061e905ac091ebf7f9 Mon Sep 17 00:00:00 2001 From: Piotr Witek <739075+piotrwitek@users.noreply.github.com> Date: Wed, 29 May 2024 11:21:48 +0200 Subject: [PATCH 31/37] Bump packages and revert to new npm org (#315) --- sdk/sdk-client/bundle/package.json | 4 ++-- sdk/sdk-common/bundle/package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/sdk-client/bundle/package.json b/sdk/sdk-client/bundle/package.json index 1118207a3f..02b3b37a66 100644 --- a/sdk/sdk-client/bundle/package.json +++ b/sdk/sdk-client/bundle/package.json @@ -1,6 +1,6 @@ { - "name": "summerfi-sdk-client", - "version": "0.2.6", + "name": "@summer_fi/summerfi-sdk-client", + "version": "0.2.7", "module": "dist/index.js", "types": "dist/index.d.ts", "packageManager": "yarn@1.22.21", diff --git a/sdk/sdk-common/bundle/package.json b/sdk/sdk-common/bundle/package.json index dcfa0b7513..7b87c92b21 100644 --- a/sdk/sdk-common/bundle/package.json +++ b/sdk/sdk-common/bundle/package.json @@ -1,6 +1,6 @@ { - "name": "summerfi-sdk-common", - "version": "0.2.5", + "name": "@summer_fi/summerfi-sdk-common", + "version": "0.2.6", "module": "dist/index.js", "types": "dist/index.d.ts", "packageManager": "yarn@1.22.21", From 79cdeda9e601daebf18a2dc343b6d8524816a713 Mon Sep 17 00:00:00 2001 From: Halaprix Date: Wed, 29 May 2024 12:47:38 +0200 Subject: [PATCH 32/37] feat: add referral handling in point accrual (#316) - add new package with borrow-db type - add handling for referred users - get all users from snapshot and users that referred them - and add to db before processing points - if a user is referred - the referring user gets 5% of their points --- .env.template | 3 +- .github/workflows/deploy-production.yaml | 1 + .github/workflows/deploy-sdk-production.yaml | 1 + .github/workflows/deploy-sdk-staging.yaml | 1 + .github/workflows/deploy-staging.yaml | 1 + .../update-rays-cron-function/package.json | 1 + .../update-rays-cron-function/src/index.ts | 132 +++++-- packages/borrow-db/.env.template | 1 + packages/borrow-db/.eslintrc.cjs | 6 + packages/borrow-db/jest.config.js | 19 + packages/borrow-db/package.json | 29 ++ packages/borrow-db/src/database-types.ts | 369 ++++++++++++++++++ packages/borrow-db/src/index.ts | 28 ++ packages/borrow-db/tsconfig.build.json | 9 + packages/borrow-db/tsconfig.json | 9 + packages/borrow-db/tsconfig.test.json | 9 + pnpm-lock.yaml | 54 ++- stacks/rays.ts | 14 +- turbo.json | 3 +- 19 files changed, 635 insertions(+), 55 deletions(-) create mode 100644 packages/borrow-db/.env.template create mode 100644 packages/borrow-db/.eslintrc.cjs create mode 100644 packages/borrow-db/jest.config.js create mode 100644 packages/borrow-db/package.json create mode 100644 packages/borrow-db/src/database-types.ts create mode 100644 packages/borrow-db/src/index.ts create mode 100644 packages/borrow-db/tsconfig.build.json create mode 100644 packages/borrow-db/tsconfig.json create mode 100644 packages/borrow-db/tsconfig.test.json diff --git a/.env.template b/.env.template index d04f4f10f6..5242e9f442 100644 --- a/.env.template +++ b/.env.template @@ -7,4 +7,5 @@ SST_USER= DEBANK_API_KEY= DEBANK_API_URL= RAYS_DB_WRITE_CONNECTION_STRING=postgres://user:password@localhost:5500/rays -RAYS_DB_READ_CONNECTION_STRING=postgres://user:password@localhost:5500/rays \ No newline at end of file +RAYS_DB_READ_CONNECTION_STRING=postgres://user:password@localhost:5500/rays +BORROW_DB_READ_CONNECTION_STRING= \ No newline at end of file diff --git a/.github/workflows/deploy-production.yaml b/.github/workflows/deploy-production.yaml index 7de9bda2e3..34128ca94b 100644 --- a/.github/workflows/deploy-production.yaml +++ b/.github/workflows/deploy-production.yaml @@ -34,6 +34,7 @@ jobs: SECURITY_GROUP_ID: ${{ secrets.SECURITY_GROUP_ID }} RAYS_DB_WRITE_CONNECTION_STRING: ${{ secrets.RAYS_DB_WRITE_CONNECTION_STRING }} RAYS_DB_READ_CONNECTION_STRING: ${{ secrets.RAYS_DB_READ_CONNECTION_STRING }} + BORROW_DB_READ_CONNECTION_STRING: ${{ secrets.BORROW_DB_READ_CONNECTION_STRING }} steps: - name: Git clone the repository uses: actions/checkout@v3 diff --git a/.github/workflows/deploy-sdk-production.yaml b/.github/workflows/deploy-sdk-production.yaml index a542502d1a..b3b50fdf70 100644 --- a/.github/workflows/deploy-sdk-production.yaml +++ b/.github/workflows/deploy-sdk-production.yaml @@ -33,6 +33,7 @@ jobs: SECURITY_GROUP_ID: ${{ secrets.SECURITY_GROUP_ID }} RAYS_DB_WRITE_CONNECTION_STRING: ${{ secrets.RAYS_DB_WRITE_CONNECTION_STRING }} RAYS_DB_READ_CONNECTION_STRING: ${{ secrets.RAYS_DB_READ_CONNECTION_STRING }} + BORROW_DB_READ_CONNECTION_STRING: ${{ secrets.BORROW_DB_READ_CONNECTION_STRING }} steps: - name: Git clone the repository uses: actions/checkout@v3 diff --git a/.github/workflows/deploy-sdk-staging.yaml b/.github/workflows/deploy-sdk-staging.yaml index 4d7b2c64b4..d26fbb554f 100644 --- a/.github/workflows/deploy-sdk-staging.yaml +++ b/.github/workflows/deploy-sdk-staging.yaml @@ -33,6 +33,7 @@ jobs: SECURITY_GROUP_ID: ${{ secrets.SECURITY_GROUP_ID }} RAYS_DB_WRITE_CONNECTION_STRING: ${{ secrets.RAYS_DB_WRITE_CONNECTION_STRING }} RAYS_DB_READ_CONNECTION_STRING: ${{ secrets.RAYS_DB_READ_CONNECTION_STRING }} + BORROW_DB_READ_CONNECTION_STRING: ${{ secrets.BORROW_DB_READ_CONNECTION_STRING }} steps: - name: Git clone the repository uses: actions/checkout@v3 diff --git a/.github/workflows/deploy-staging.yaml b/.github/workflows/deploy-staging.yaml index 0d0f1af094..6e497474df 100644 --- a/.github/workflows/deploy-staging.yaml +++ b/.github/workflows/deploy-staging.yaml @@ -34,6 +34,7 @@ jobs: SECURITY_GROUP_ID: ${{ secrets.SECURITY_GROUP_ID }} RAYS_DB_WRITE_CONNECTION_STRING: ${{ secrets.RAYS_DB_WRITE_CONNECTION_STRING }} RAYS_DB_READ_CONNECTION_STRING: ${{ secrets.RAYS_DB_READ_CONNECTION_STRING }} + BORROW_DB_READ_CONNECTION_STRING: ${{ secrets.BORROW_DB_READ_CONNECTION_STRING }} steps: - name: Git clone the repository uses: actions/checkout@v3 diff --git a/background-jobs/update-rays-cron-function/package.json b/background-jobs/update-rays-cron-function/package.json index faf3fe59f9..d7a96cbc62 100644 --- a/background-jobs/update-rays-cron-function/package.json +++ b/background-jobs/update-rays-cron-function/package.json @@ -15,6 +15,7 @@ "zod": "^3.22.4", "@summerfi/summer-events-subgraph": "workspace:*", "@summerfi/rays-db": "workspace:*", + "@summerfi/borrow-db": "workspace:*", "@summerfi/serverless-shared": "workspace:*" }, "devDependencies": { diff --git a/background-jobs/update-rays-cron-function/src/index.ts b/background-jobs/update-rays-cron-function/src/index.ts index dce0d4eecd..5fc78e2802 100644 --- a/background-jobs/update-rays-cron-function/src/index.ts +++ b/background-jobs/update-rays-cron-function/src/index.ts @@ -1,6 +1,7 @@ import type { Context, EventBridgeEvent } from 'aws-lambda' import { Logger } from '@aws-lambda-powertools/logger' import { Database, getRaysDB } from '@summerfi/rays-db' +import { getBorrowDB } from '@summerfi/borrow-db' import process from 'node:process' import { getSummerPointsSubgraphClient } from '@summerfi/summer-events-subgraph' import { ChainId } from '@summerfi/serverless-shared' @@ -33,6 +34,7 @@ enum OngoingPointDistribution { OPEN_POSITION = 'OPEN_POSITION', MIGRATION = 'MIGRATION', SWAP = 'SWAP', + REFERRAL = 'REFERRAL', } enum PositionMultiplier { @@ -91,11 +93,15 @@ export const handler = async ( event: EventBridgeEvent<'Scheduled Event', never>, context: Context, ): Promise => { - const { SUBGRAPH_BASE, RAYS_DB_CONNECTION_STRING } = process.env + const { SUBGRAPH_BASE, RAYS_DB_CONNECTION_STRING, BORROW_DB_READ_CONNECTION_STRING } = process.env logger.addContext(context) logger.info('Hello World!') + if (!BORROW_DB_READ_CONNECTION_STRING) { + logger.error('BORROW_DB_READ_CONNECTION_STRING is not set') + return + } if (!SUBGRAPH_BASE) { logger.error('SUBGRAPH_BASE is not set') return @@ -111,6 +117,10 @@ export const handler = async ( logger, } const { db, services } = await getRaysDB(dbConfig) + const { db: borrowDb } = await getBorrowDB({ + connectionString: BORROW_DB_READ_CONNECTION_STRING, + logger, + }) const mainnetSubgraphClient = getSummerPointsSubgraphClient({ logger, @@ -194,31 +204,49 @@ export const handler = async ( startTimestamp, endTimestamp, ) - const sortedAccruedPointsFromSnapshot = accruedPointsFromSnapshot.sort((a, b) => - a.positionId.localeCompare(b.positionId), + + // Get all unique addresses and positions from all chunks + const allUniqueUsers: Set = new Set() + const uniqueUserAddressesFromSnapshot = Array.from( + new Set(accruedPointsFromSnapshot.map((c) => c.user)), ) - await checkMigrationEligibility(db, sortedAccruedPointsFromSnapshot) - await checkOpenedPositionEligibility(db, sortedAccruedPointsFromSnapshot) - await insertAllMissingUsers(sortedAccruedPointsFromSnapshot, db) + const allPositions = Array.from(new Set(accruedPointsFromSnapshot.map((c) => c.positionId))) - const chunkedPoints: PositionPoints[] = createChunksOfUserPointsDistributions( - sortedAccruedPointsFromSnapshot, - 30, - ) + // addresses in borrow db are stored in checsummed addresses + const usersFromReferralsTable = ( + await borrowDb + .selectFrom('user') + .where(borrowDb.fn('lower', ['user.address']), 'in', uniqueUserAddressesFromSnapshot) + .selectAll() + .execute() + ).map((u) => ({ + address: u.address.toLowerCase(), + accepted: u.accepted, + timestamp: u.timestamp, + user_that_referred_address: u.userThatReferredAddress + ? u.userThatReferredAddress.toLowerCase() + : null, + })) + + for (const user of usersFromReferralsTable) { + if (user.user_that_referred_address) { + allUniqueUsers.add(user.user_that_referred_address) + } + } + for (const user of uniqueUserAddressesFromSnapshot) { + allUniqueUsers.add(user) + } + const allUniqueUserAddresses = Array.from(allUniqueUsers) - // Get all unique addresses and positions from all chunks - const uniqueAddressesFromSnapshot = Array.from( - new Set(chunkedPoints.flatMap((chunk) => chunk.map((c) => c.user))), - ) - const allPositions = Array.from( - new Set(chunkedPoints.flatMap((chunk) => chunk.map((c) => c.positionId))), - ) + await checkMigrationEligibility(db, accruedPointsFromSnapshot) + await checkOpenedPositionEligibility(db, accruedPointsFromSnapshot) + await insertAllMissingUsers(db, allUniqueUserAddresses) // Fetch all necessary data for all chunks at once const uniqueUserAddressesFromDatabase = await db .selectFrom('userAddress') - .where('address', 'in', uniqueAddressesFromSnapshot) + .where('address', 'in', allUniqueUserAddresses) .selectAll() .execute() @@ -231,7 +259,7 @@ export const handler = async ( const usersMultipliersFromDatabase = await db .selectFrom('multiplier') .innerJoin('userAddress', 'multiplier.userAddressId', 'userAddress.id') - .where('userAddress.address', 'in', uniqueAddressesFromSnapshot) + .where('userAddress.address', 'in', allUniqueUserAddresses) .select([ 'multiplier.value', 'multiplier.type', @@ -253,9 +281,14 @@ export const handler = async ( ]) .execute() + const chunkedPoints: PositionPoints[] = createChunksOfUserPointsDistributions( + accruedPointsFromSnapshot, + 30, + ) + await db.transaction().execute(async (transaction) => { await addOrUpdateUserMultipliers( - uniqueAddressesFromSnapshot, + uniqueUserAddressesFromSnapshot, uniqueUserAddressesFromDatabase, accruedPointsFromSnapshot, usersMultipliersFromDatabase, @@ -305,6 +338,26 @@ export const handler = async ( type: OngoingPointDistribution.OPEN_POSITION, }) .executeTakeFirstOrThrow() + + const isUserReferred = usersFromReferralsTable.find((u) => u.address === record.user) + if (isUserReferred && isUserReferred.user_that_referred_address) { + const referringUser = uniqueUserAddressesFromDatabase.find( + (ua) => ua.address === isUserReferred.user_that_referred_address, + ) + if (!referringUser) { + throw new Error('Referring user not found') + } + + await transaction + .insertInto('pointsDistribution') + .values({ + description: 'Points for referred user', + points: record.points.openPositionsPoints * 0.05, + userAddressId: referringUser.id, + type: OngoingPointDistribution.REFERRAL, + }) + .executeTakeFirstOrThrow() + } } const currentDate = new Date() @@ -580,33 +633,38 @@ async function addOrUpdateUserMultipliers( * @param db - The database instance. * @returns A Promise that resolves when all missing users are inserted. */ -async function insertAllMissingUsers(sortedPoints: PositionPoints, db: Kysely) { - const uniqueUsers = new Set(sortedPoints.map((p) => p.user)) +async function insertAllMissingUsers(db: Kysely, allUniqueUsers: string[]) { const uniqueUserAddressesFromDatabase = await db .selectFrom('userAddress') - .where('address', 'in', Array.from(uniqueUsers)) + .where('address', 'in', Array.from(allUniqueUsers)) .selectAll() .execute() + const uniqueMissingUsers = allUniqueUsers.filter( + (userAddress) => !uniqueUserAddressesFromDatabase.some((ua) => ua.address === userAddress), + ) + await db.transaction().execute(async (transaction) => { - for (const user of uniqueUsers) { - const userAddress = uniqueUserAddressesFromDatabase.find((ua) => ua.address === user) - if (!userAddress) { - const result = await transaction - .insertInto('blockchainUser') - .values({ category: null }) - .returning(['id']) - .executeTakeFirstOrThrow() - await transaction - .insertInto('userAddress') - .values({ address: user, userId: result.id }) - .returningAll() - .executeTakeFirstOrThrow() - } + for (const userAddress of uniqueMissingUsers) { + await insertNewUser(transaction, userAddress) } }) } +async function insertNewUser(transaction: Transaction, userAddress: string) { + const result = await transaction + .insertInto('blockchainUser') + .values({ category: null }) + .returning(['id']) + .executeTakeFirstOrThrow() + await transaction + .insertInto('userAddress') + .values({ address: userAddress, userId: result.id }) + .returningAll() + .executeTakeFirstOrThrow() + return result +} + /** * Creates chunks of user points distributions based on a given chunk length. * diff --git a/packages/borrow-db/.env.template b/packages/borrow-db/.env.template new file mode 100644 index 0000000000..7a8ddbde11 --- /dev/null +++ b/packages/borrow-db/.env.template @@ -0,0 +1 @@ +DATABASE_URL=postgres://user:password@localhost:5500/borrowdb \ No newline at end of file diff --git a/packages/borrow-db/.eslintrc.cjs b/packages/borrow-db/.eslintrc.cjs new file mode 100644 index 0000000000..45e293e892 --- /dev/null +++ b/packages/borrow-db/.eslintrc.cjs @@ -0,0 +1,6 @@ +/** @type {import('eslint').Linter.Config} */ +module.exports = { + root: true, + extends: ['@summerfi/eslint-config/library.cjs'], + parser: '@typescript-eslint/parser', +} diff --git a/packages/borrow-db/jest.config.js b/packages/borrow-db/jest.config.js new file mode 100644 index 0000000000..4f7ca0d429 --- /dev/null +++ b/packages/borrow-db/jest.config.js @@ -0,0 +1,19 @@ +/** @type {import('ts-jest').JestConfigWithTsJest} */ +module.exports = { + preset: 'ts-jest', + roots: ['/src'], + testMatch: ['**/__tests__/**/*.+(ts|tsx|js)', '**/?(*.)+(spec|test).+(ts|tsx|js)'], + silent: true, + maxWorkers: 1, + testTimeout: 10000, + testEnvironment: 'node', + testPathIgnorePatterns: ['dist', 'node_modules'], + transform: { + '^.+\\.(ts|tsx)$': [ + 'ts-jest', + { + tsconfig: '/tsconfig.test.json', + }, + ], + }, +} diff --git a/packages/borrow-db/package.json b/packages/borrow-db/package.json new file mode 100644 index 0000000000..b05ec8d9d4 --- /dev/null +++ b/packages/borrow-db/package.json @@ -0,0 +1,29 @@ +{ + "name": "@summerfi/borrow-db", + "version": "1.0.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "test": "jest --passWithNoTests", + "build": "tsc -b -v tsconfig.build.json", + "dev": "tsc -b -w tsconfig.build.json", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "codegen": "kysely-codegen --camel-case --out-file ./src/database-types.ts" + }, + "dependencies": { + "@summerfi/abstractions": "workspace:*", + "kysely": "^0.27.3", + "kysely-postgres-js": "^2.0.0", + "pg": "^8.11.5", + "postgres": "^3.4.4" + }, + "devDependencies": { + "@summerfi/eslint-config": "workspace:*", + "@summerfi/typescript-config": "workspace:*", + "dotenv": "^16.4.5", + "eslint": "^8.57.0", + "kysely-codegen": "^0.15.0", + "tsx": "^4.9.0" + } +} diff --git a/packages/borrow-db/src/database-types.ts b/packages/borrow-db/src/database-types.ts new file mode 100644 index 0000000000..dd3f3e9296 --- /dev/null +++ b/packages/borrow-db/src/database-types.ts @@ -0,0 +1,369 @@ +import type { ColumnType } from 'kysely' + +export type AjnaRewardsPositionType = 'borrow' | 'earn' + +export type AjnaRewardsSource = 'bonus' | 'core' + +export type ArrayType = ArrayTypeImpl extends (infer U)[] ? U[] : ArrayTypeImpl + +export type ArrayTypeImpl = + T extends ColumnType ? ColumnType : T[] + +export type Generated = + T extends ColumnType + ? ColumnType + : ColumnType + +export type Json = JsonValue + +export type JsonArray = JsonValue[] + +export type JsonObject = { + [K in string]?: JsonValue +} + +export type JsonPrimitive = boolean | number | string | null + +export type JsonValue = JsonArray | JsonObject | JsonPrimitive + +export type Numeric = ColumnType + +export type Product = 'borrow' | 'earn' | 'multiply' + +export type Protocol = 'aavev2' | 'aavev3' | 'ajna' | 'maker' | 'morphoblue' | 'sparkv3' + +export type Timestamp = ColumnType + +export type VaultType = 'borrow' | 'earn' | 'multiply' + +export interface AjnaRewardsDailyClaim { + accountAddress: string + amount: string + chainId: number + dayNumber: number + id: Generated + poolAddress: string + source: AjnaRewardsSource + timestamp: Generated + type: AjnaRewardsPositionType + userAddress: string + weekNumber: number +} + +export interface AjnaRewardsMerkleTree { + chainId: number + id: Generated + source: AjnaRewardsSource + timestamp: Generated + treeRoot: string + txProcessed: Generated + weekNumber: number +} + +export interface AjnaRewardsWeeklyClaim { + amount: string + chainId: number + id: Generated + proof: string[] | null + source: AjnaRewardsSource + timestamp: Generated + userAddress: string + weekNumber: number +} + +export interface CollateralType { + collateralName: string + currentPrice: Numeric + liquidationPenalty: Generated + liquidationRatio: Numeric + marketPrice: Numeric | null + nextPrice: Numeric + rate: Numeric | null +} + +export interface Discover { + collateralType: string + createdAt: Generated + lastAction: Json + netProfit1d: Numeric | null + netProfit30d: Numeric | null + netProfit365d: Numeric | null + netProfit7d: Numeric | null + netProfitAll: Numeric | null + netProfitYtd: Numeric | null + pnl1d: Numeric + pnl30d: Numeric + pnl365d: Numeric + pnl7d: Numeric + pnlAll: Numeric + pnlYtd: Numeric + positionId: string + protocolId: string + status: Json + token: string | null + updatedAt: Timestamp + vaultCollateral: Numeric + vaultDebt: Numeric + vaultNormalizedDebt: Numeric | null + vaultType: string | null + yield30d: Numeric +} + +export interface DiscoverWithCollData { + chainId: number | null + collateralName: string | null + collateralType: string | null + createdAt: Timestamp | null + currentPrice: Numeric | null + lastAction: Json | null + liquidationPenalty: Numeric | null + liquidationRatio: Numeric | null + marketPrice: Numeric | null + netProfit1d: Numeric | null + netProfit30d: Numeric | null + netProfit365d: Numeric | null + netProfit7d: Numeric | null + netProfitAll: Numeric | null + netProfitYtd: Numeric | null + nextPrice: Numeric | null + ownerAddress: string | null + pnl1d: Numeric | null + pnl30d: Numeric | null + pnl365d: Numeric | null + pnl7d: Numeric | null + pnlAll: Numeric | null + pnlYtd: Numeric | null + positionId: string | null + protocolId: string | null + rate: Numeric | null + status: Json | null + token: string | null + type: VaultType | null + updatedAt: Timestamp | null + vaultCollateral: Numeric | null + vaultDebt: Numeric | null + vaultId: number | null + vaultNormalizedDebt: Numeric | null + vaultType: string | null + yield30d: Numeric | null +} + +export interface HighestPnl { + collateralType: string | null + collateralValue: Numeric | null + lastAction: Json | null + netProfit1d: Numeric | null + netProfit30d: Numeric | null + netProfit365d: Numeric | null + netProfit7d: Numeric | null + netProfitAll: Numeric | null + netProfitYtd: Numeric | null + pnl1d: Numeric | null + pnl30d: Numeric | null + pnl365d: Numeric | null + pnl7d: Numeric | null + pnlAll: Numeric | null + pnlYtd: Numeric | null + positionId: string | null + protocolId: string | null + token: string | null + type: VaultType | null + vaultMultiple: Numeric | null +} + +export interface HighRisk { + collateralRatio: Numeric | null + collateralType: string | null + collateralValue: Numeric | null + liquidationPrice: Numeric | null + liquidationProximity: Numeric | null + liquidationValue: Numeric | null + nextPrice: Numeric | null + positionId: string | null + protocolId: string | null + status: Json | null + token: string | null + type: VaultType | null +} + +export interface LargestDebt { + collateralType: string | null + collateralValue: Numeric | null + collRatio: Numeric | null + lastAction: Json | null + liquidationProximity: Numeric | null + positionId: string | null + protocolId: string | null + token: string | null + type: VaultType | null + vaultDebt: Numeric | null +} + +export interface MerkleTree { + endBlock: Numeric | null + snapshot: string | null + startBlock: Numeric | null + timestamp: Generated + treeRoot: string + txProcessed: Generated + weekNumber: number +} + +export interface Migrations { + executedAt: Generated + hash: string + id: number + name: string +} + +export interface MostYield { + collateralType: string | null + collateralValue: Numeric | null + lastAction: Json | null + liquidationValue: Numeric | null + netValue: Numeric | null + pnl1d: Numeric | null + pnl30d: Numeric | null + pnl365d: Numeric | null + pnl7d: Numeric | null + pnlAll: Numeric | null + pnlYtd: Numeric | null + positionId: string | null + protocolId: string | null + token: string | null + type: VaultType | null + yield30d: Numeric | null +} + +export interface ProductHubItems { + automationFeatures: string[] | null + depositToken: string | null + earnStrategy: 'erc_4626' | 'liquidity_provision' | 'other' | 'yield_loop' | null + earnStrategyDescription: string | null + fee: string | null + hasRewards: Generated + id: string + label: string + liquidity: string | null + managementType: 'active' | 'passive' | null + maxLtv: string | null + maxMultiply: string | null + multiplyStrategy: string | null + multiplyStrategyType: 'long' | 'short' | null + network: + | 'arbitrum' + | 'arbitrum_goerli' + | 'base' + | 'base_goerli' + | 'ethereum' + | 'ethereum_goerli' + | 'optimism' + | 'optimism_goerli' + | 'polygon' + | 'polygon_mumbai' + primaryToken: string + primaryTokenAddress: Generated + primaryTokenGroup: string | null + product: ArrayType | null + protocol: Protocol + reverseTokens: boolean | null + secondaryToken: string + secondaryTokenAddress: Generated + secondaryTokenGroup: string | null + tooltips: Json | null + updatedAt: Timestamp + weeklyNetApy: string | null +} + +export interface Tokens { + address: string + chainId: number + name: string + precision: number + source: string | null + symbol: string +} + +export interface TosApproval { + address: string + chainId: Generated + docVersion: string + id: Generated + message: Generated + signature: Generated + signDate: Timestamp +} + +export interface User { + accepted: boolean + address: string + timestamp: Generated + userThatReferredAddress: string | null +} + +export interface UsersWhoFollowVaults { + protocol: Protocol + userAddress: string + vaultChainId: number + vaultId: number +} + +export interface Vault { + chainId: number | null + ownerAddress: string + protocol: Generated + tokenPair: Generated + type: VaultType + vaultId: number +} + +export interface VaultChangeLog { + chainId: number + createdAt: Generated + id: Generated + newVaultType: VaultType | null + oldVaultType: VaultType | null + ownerAddress: string + protocol: string + tokenPair: string + vaultId: number +} + +export interface WalletRisk { + address: string + isRisky: boolean + lastCheck: Timestamp +} + +export interface WeeklyClaim { + amount: string + id: Generated + proof: string[] | null + timestamp: Generated + userAddress: string + weekNumber: number +} + +export interface DB { + ajnaRewardsDailyClaim: AjnaRewardsDailyClaim + ajnaRewardsMerkleTree: AjnaRewardsMerkleTree + ajnaRewardsWeeklyClaim: AjnaRewardsWeeklyClaim + collateralType: CollateralType + discover: Discover + discoverWithCollData: DiscoverWithCollData + highestPnl: HighestPnl + highRisk: HighRisk + largestDebt: LargestDebt + merkleTree: MerkleTree + migrations: Migrations + mostYield: MostYield + productHubItems: ProductHubItems + tokens: Tokens + tosApproval: TosApproval + user: User + usersWhoFollowVaults: UsersWhoFollowVaults + vault: Vault + vaultChangeLog: VaultChangeLog + walletRisk: WalletRisk + weeklyClaim: WeeklyClaim +} diff --git a/packages/borrow-db/src/index.ts b/packages/borrow-db/src/index.ts new file mode 100644 index 0000000000..23faab38d6 --- /dev/null +++ b/packages/borrow-db/src/index.ts @@ -0,0 +1,28 @@ +import { CamelCasePlugin, Kysely } from 'kysely' +import { PostgresJSDialect } from 'kysely-postgres-js' +import postgres from 'postgres' +import { Logger } from '@summerfi/abstractions' +import { DB } from './database-types' + +export interface PgBorrowDbConfig { + connectionString: string + logger: Logger +} + +export interface BorrowDB { + db: Kysely +} + +export const getBorrowDB = async (config: PgBorrowDbConfig): Promise => { + const pg = postgres(config.connectionString) + const db = new Kysely({ + dialect: new PostgresJSDialect({ + postgres: pg, + }), + plugins: [new CamelCasePlugin()], + }) + + return { + db, + } +} diff --git a/packages/borrow-db/tsconfig.build.json b/packages/borrow-db/tsconfig.build.json new file mode 100644 index 0000000000..9db652c4f2 --- /dev/null +++ b/packages/borrow-db/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "@summerfi/typescript-config/tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "include": ["src/**/*.ts", "src/**/*.mts"], + "exclude": ["node_modules", "**/*.spec.ts", "src/scripts/**/*"] +} diff --git a/packages/borrow-db/tsconfig.json b/packages/borrow-db/tsconfig.json new file mode 100644 index 0000000000..edcffca18e --- /dev/null +++ b/packages/borrow-db/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@summerfi/typescript-config/tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "include": ["src/**/*.ts", "src/**/*.mts"], + "exclude": ["node_modules", "**/*.spec.ts"] +} diff --git a/packages/borrow-db/tsconfig.test.json b/packages/borrow-db/tsconfig.test.json new file mode 100644 index 0000000000..c7ba960834 --- /dev/null +++ b/packages/borrow-db/tsconfig.test.json @@ -0,0 +1,9 @@ +{ + "extends": "@summerfi/typescript-config/tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ebd199f1ff..0e2289ac72 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -117,6 +117,9 @@ importers: '@aws-lambda-powertools/tracer': specifier: ^2.0.2 version: 2.0.4 + '@summerfi/borrow-db': + specifier: workspace:* + version: link:../../packages/borrow-db '@summerfi/rays-db': specifier: workspace:* version: link:../../packages/rays-db @@ -294,6 +297,43 @@ importers: specifier: ^8.57.0 version: 8.57.0 + packages/borrow-db: + dependencies: + '@summerfi/abstractions': + specifier: workspace:* + version: link:../abstractions + kysely: + specifier: ^0.27.3 + version: 0.27.3 + kysely-postgres-js: + specifier: ^2.0.0 + version: 2.0.0(kysely@0.27.3)(postgres@3.4.4) + pg: + specifier: ^8.11.5 + version: 8.11.5 + postgres: + specifier: ^3.4.4 + version: 3.4.4 + devDependencies: + '@summerfi/eslint-config': + specifier: workspace:* + version: link:../eslint-config + '@summerfi/typescript-config': + specifier: workspace:* + version: link:../typescript-config + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + eslint: + specifier: ^8.57.0 + version: 8.57.0 + kysely-codegen: + specifier: ^0.15.0 + version: 0.15.0(kysely@0.27.3)(pg@8.11.5) + tsx: + specifier: ^4.9.0 + version: 4.9.3 + packages/common: devDependencies: '@summerfi/eslint-config': @@ -15609,17 +15649,14 @@ packages: /pg-cloudflare@1.1.1: resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} requiresBuild: true - dev: true optional: true /pg-connection-string@2.6.4: resolution: {integrity: sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==} - dev: true /pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} - dev: true /pg-numeric@1.0.2: resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==} @@ -15632,11 +15669,9 @@ packages: pg: '>=8.0' dependencies: pg: 8.11.5 - dev: true /pg-protocol@1.6.1: resolution: {integrity: sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==} - dev: true /pg-types@2.2.0: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} @@ -15647,7 +15682,6 @@ packages: postgres-bytea: 1.0.0 postgres-date: 1.0.7 postgres-interval: 1.2.0 - dev: true /pg-types@4.0.2: resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==} @@ -15678,13 +15712,11 @@ packages: pgpass: 1.0.5 optionalDependencies: pg-cloudflare: 1.1.1 - dev: true /pgpass@1.0.5: resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} dependencies: split2: 4.2.0 - dev: true /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -15760,7 +15792,6 @@ packages: /postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} - dev: true /postgres-array@3.0.2: resolution: {integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==} @@ -15770,7 +15801,6 @@ packages: /postgres-bytea@1.0.0: resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} engines: {node: '>=0.10.0'} - dev: true /postgres-bytea@3.0.0: resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==} @@ -15782,7 +15812,6 @@ packages: /postgres-date@1.0.7: resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} engines: {node: '>=0.10.0'} - dev: true /postgres-date@2.1.0: resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==} @@ -15794,7 +15823,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: xtend: 4.0.2 - dev: true /postgres-interval@3.0.0: resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==} @@ -16862,7 +16890,6 @@ packages: /split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} - dev: true /sponge-case@1.0.1: resolution: {integrity: sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA==} @@ -18280,7 +18307,6 @@ packages: /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} - dev: true /y18n@4.0.3: resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} diff --git a/stacks/rays.ts b/stacks/rays.ts index e7e922d71f..67431ad344 100644 --- a/stacks/rays.ts +++ b/stacks/rays.ts @@ -3,8 +3,16 @@ import { Cron, Function, FunctionProps } from 'sst/constructs' import * as process from 'node:process' export function addRaysConfig({ stack, api, vpc, app }: SummerStackContext) { - const { RAYS_DB_WRITE_CONNECTION_STRING, RAYS_DB_READ_CONNECTION_STRING, SUBGRAPH_BASE } = - process.env + const { + RAYS_DB_WRITE_CONNECTION_STRING, + RAYS_DB_READ_CONNECTION_STRING, + SUBGRAPH_BASE, + BORROW_DB_READ_CONNECTION_STRING, + } = process.env + + if (!BORROW_DB_READ_CONNECTION_STRING) { + throw new Error('BORROW_DB_READ_CONNECTION_STRING is not set') + } if (!RAYS_DB_WRITE_CONNECTION_STRING) { throw new Error('RAYS_DB_WRITE_CONNECTION_STRING is not set') } @@ -22,6 +30,7 @@ export function addRaysConfig({ stack, api, vpc, app }: SummerStackContext) { environment: { POWERTOOLS_LOG_LEVEL: process.env.POWERTOOLS_LOG_LEVEL || 'INFO', RAYS_DB_CONNECTION_STRING: RAYS_DB_READ_CONNECTION_STRING, + BORROW_DB_READ_CONNECTION_STRING: BORROW_DB_READ_CONNECTION_STRING, }, ...(vpc && { vpc: vpc.vpc, @@ -54,6 +63,7 @@ export function addRaysConfig({ stack, api, vpc, app }: SummerStackContext) { environment: { POWERTOOLS_LOG_LEVEL: process.env.POWERTOOLS_LOG_LEVEL || 'INFO', RAYS_DB_CONNECTION_STRING: RAYS_DB_WRITE_CONNECTION_STRING, + BORROW_DB_READ_CONNECTION_STRING: BORROW_DB_READ_CONNECTION_STRING, SUBGRAPH_BASE, }, ...(vpc && { diff --git a/turbo.json b/turbo.json index 06711d0611..d58e1b69aa 100644 --- a/turbo.json +++ b/turbo.json @@ -44,7 +44,8 @@ "RAYS_DB_CONNECTION_STRING", "IS_LOCAL", "RAYS_DB_WRITE_CONNECTION_STRING", - "RAYS_DB_READ_CONNECTION_STRING" + "RAYS_DB_READ_CONNECTION_STRING", + "BORROW_DB_READ_CONNECTION_STRING" ], "pipeline": { "dev": { From 35eefa907327d076ad63b6d11a86bcb483ba5510 Mon Sep 17 00:00:00 2001 From: Halaprix Date: Wed, 29 May 2024 14:22:04 +0200 Subject: [PATCH 33/37] chore: add manual deploy (#317) --- .github/workflows/deploy-staging.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy-staging.yaml b/.github/workflows/deploy-staging.yaml index 6e497474df..52e22978e0 100644 --- a/.github/workflows/deploy-staging.yaml +++ b/.github/workflows/deploy-staging.yaml @@ -4,6 +4,7 @@ on: push: branches: - dev + workflow_dispatch: permissions: id-token: write # This is required for requesting the JWT contents: read # This is required for actions/checkout From f62724e50aa32885523e3496912516c5be91d2dd Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Thu, 30 May 2024 19:50:32 +0200 Subject: [PATCH 34/37] fix: add missing tokens (#318) --- .../implementation/static/StaticTokensList.ts | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/sdk/tokens-service/src/implementation/static/StaticTokensList.ts b/sdk/tokens-service/src/implementation/static/StaticTokensList.ts index 13fc60c9cd..afdc128e84 100644 --- a/sdk/tokens-service/src/implementation/static/StaticTokensList.ts +++ b/sdk/tokens-service/src/implementation/static/StaticTokensList.ts @@ -12,6 +12,56 @@ export const StaticTokensData: TokenListData = { logoURI: 'https://summer.fi/static/img/logos/logo_dark.svg', keywords: ['Summer.fi', 'MakerDAO'], tokens: [ + { + name: 'Renzo Restaked ETH', + address: '0xbf5495Efe5DB9ce00f80364C8B423567e58d2110', + symbol: 'ezETH', + decimals: 18, + chainId: 1, + logoURI: + 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xbf5495Efe5DB9ce00f80364C8B423567e58d2110/logo.png', + }, + { + name: 'Staked ETH', + address: '0xf1C9acDc66974dFB6dEcB12aA385b9cD01190E38', + symbol: 'osETH', + decimals: 18, + chainId: 1, + logoURI: '', + }, + { + name: 'Wrapped eETH', + address: '0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee', + symbol: 'weETH', + decimals: 18, + chainId: 1, + logoURI: '', + }, + { + name: 'USDe', + address: '0x4c9EDD5852cd905f086C759E8383e09bff1E68B3', + symbol: 'USDe', + decimals: 18, + chainId: 1, + logoURI: '', + }, + { + name: 'Staked USDe', + address: '0x9D39A5DE30e57443BfF2A8307A4256c8797A3497', + symbol: 'sUSDe', + decimals: 18, + chainId: 1, + logoURI: '', + }, + { + name: 'USDA', + address: '0x0000206329b97DB379d5E1Bf586BbDB969C63274', + symbol: 'USDA', + decimals: 18, + chainId: 1, + logoURI: + 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x0000206329b97DB379d5E1Bf586BbDB969C63274/logo.png', + }, { name: 'Dai Stablecoin', address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', @@ -132,6 +182,14 @@ export const StaticTokensData: TokenListData = { decimals: 18, logoURI: 'https://tokens.1inch.io/0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0.png', }, + { + address: '0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0', + chainId: 1, + name: 'Wrapped Staked ETH', + symbol: 'WSTETH', + decimals: 18, + logoURI: 'https://tokens.1inch.io/0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0.png', + }, { address: '0xEB4C2781e4ebA804CE9a9803C67d0893436bB27D', chainId: 1, From e7d53f0066108df301e7396598b1386a950bb120 Mon Sep 17 00:00:00 2001 From: Roberto Cano <3525807+robercano@users.noreply.github.com> Date: Fri, 31 May 2024 11:15:02 +0200 Subject: [PATCH 35/37] fix: skip send action with correct flags (#319) --- .../morphoblue/builders/MorphoDepositBorrowActionBuilder.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoDepositBorrowActionBuilder.ts b/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoDepositBorrowActionBuilder.ts index 72e4f122dd..61bc30c11f 100644 --- a/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoDepositBorrowActionBuilder.ts +++ b/sdk/protocol-plugins/src/plugins/morphoblue/builders/MorphoDepositBorrowActionBuilder.ts @@ -77,8 +77,8 @@ export class MorphoDepositBorrowActionBuilder extends BaseActionBuilder Date: Mon, 3 Jun 2024 11:50:04 +0200 Subject: [PATCH 36/37] chore: bump dma-library to `0.6.6` in setup trigger (#320) --- pnpm-lock.yaml | 8 ++++---- summerfi-api/setup-trigger-function/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0e2289ac72..dff6889a78 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2144,8 +2144,8 @@ importers: specifier: 1.6.5-morpho.6 version: 1.6.5-morpho.6 '@oasisdex/dma-library': - specifier: 0.6.4-automation.22 - version: 0.6.4-automation.22 + specifier: 0.6.6-automation + version: 0.6.6-automation '@summerfi/abis': specifier: workspace:* version: link:../../packages/abis @@ -7557,8 +7557,8 @@ packages: - utf-8-validate dev: false - /@oasisdex/dma-library@0.6.4-automation.22: - resolution: {integrity: sha512-V3fFKUptoAJeBPaV2cQI8ZJw4ONmyB0zVtFEQe/MBXKGpGBFl455zDf+U4C2TPwM3u9RImXZ6JpcESEVMdA+Bw==} + /@oasisdex/dma-library@0.6.6-automation: + resolution: {integrity: sha512-2wqvmw8Z/v09LEDMNXWdzo2zjKspp7ikv9P0GUYUOHGfXp3h5WiKH1KcWtChc0hzkJpg+KU1CaX+oF3T3CUsNA==} dependencies: bignumber.js: 9.0.1 ethers: 5.6.2 diff --git a/summerfi-api/setup-trigger-function/package.json b/summerfi-api/setup-trigger-function/package.json index 44ef7356a0..921bc9ef18 100644 --- a/summerfi-api/setup-trigger-function/package.json +++ b/summerfi-api/setup-trigger-function/package.json @@ -14,7 +14,7 @@ "@aws-lambda-powertools/metrics": "^2.0.4", "@aws-lambda-powertools/tracer": "^2.0.4", "@oasisdex/automation": "1.6.5-morpho.6", - "@oasisdex/dma-library": "0.6.4-automation.22", + "@oasisdex/dma-library": "0.6.6-automation", "@summerfi/abis": "workspace:*", "@summerfi/prices-subgraph": "workspace:*", "@summerfi/serverless-shared": "workspace:*", From e6f5e359f5fbb40cf836e331042e647f3819fb0b Mon Sep 17 00:00:00 2001 From: Piotr Witek <739075+piotrwitek@users.noreply.github.com> Date: Mon, 3 Jun 2024 13:55:08 +0200 Subject: [PATCH 37/37] Bump packages and revert to new npm org (#321) This pull request includes the following changes: - Release new SDK private packages to the npm. --- sdk/sdk-client/bundle/package.json | 2 +- sdk/sdk-common/bundle/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/sdk-client/bundle/package.json b/sdk/sdk-client/bundle/package.json index 02b3b37a66..9d456e50bc 100644 --- a/sdk/sdk-client/bundle/package.json +++ b/sdk/sdk-client/bundle/package.json @@ -1,6 +1,6 @@ { "name": "@summer_fi/summerfi-sdk-client", - "version": "0.2.7", + "version": "0.2.8", "module": "dist/index.js", "types": "dist/index.d.ts", "packageManager": "yarn@1.22.21", diff --git a/sdk/sdk-common/bundle/package.json b/sdk/sdk-common/bundle/package.json index 7b87c92b21..c7cf1f74af 100644 --- a/sdk/sdk-common/bundle/package.json +++ b/sdk/sdk-common/bundle/package.json @@ -1,6 +1,6 @@ { "name": "@summer_fi/summerfi-sdk-common", - "version": "0.2.6", + "version": "0.2.7", "module": "dist/index.js", "types": "dist/index.d.ts", "packageManager": "yarn@1.22.21",