Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const files = {
...defaults.types,
},
['modules/subgraphs/balancer-subgraph/generated/balancer-subgraph-types.ts']: {
schema: config.MAINNET.subgraphs.balancer,
schema: config.SONIC.subgraphs.balancer,
documents: 'modules/subgraphs/balancer-subgraph/balancer-subgraph-queries.graphql',
...defaults.types,
},
Expand Down
18 changes: 10 additions & 8 deletions modules/actions/pool/v2/sync-swaps.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Chain } from '@prisma/client';
import { Chain, PrismaPoolToken } from '@prisma/client';
import { prisma } from '../../../../prisma/prisma-client';
import { V2SubgraphClient } from '../../../subgraphs/balancer-subgraph';
import _ from 'lodash';
Expand Down Expand Up @@ -29,24 +29,25 @@ export async function syncSwaps(
},
select: {
id: true,
typeData: true, // contains the quote token address
typeData: true, // contains the quote token address'
tokens: true,
},
})) as { id: string; typeData: { quoteToken: string } }[];
})) as { id: string; typeData: { quoteToken: string }; tokens: PrismaPoolToken[] }[];

// Get events
console.time('BalancerSwaps');
const swaps = await subgraphClient.getSwapsFromBlock(lastSyncedBlock);
console.timeEnd('BalancerSwaps');

console.time('swapV2Transformer');
const dbSwaps = swaps.map((swap) => swapV2Transformer(swap, chain, fxPools));
const dbSwaps = swaps.map((swap) => swapV2Transformer(swap, chain));
console.timeEnd('swapV2Transformer');

// TODO: parse batchSwaps, if needed

// Enrich with USD values
console.time('swapsUsd');
const dbEntries = await swapsUsd(dbSwaps, chain);
const dbEntries = await swapsUsd(dbSwaps, chain, fxPools);
console.timeEnd('swapsUsd');

console.time('prismaPoolEvent.createMany');
Expand Down Expand Up @@ -76,17 +77,18 @@ export async function reloadSwapsForPool(
select: {
id: true,
typeData: true, // contains the quote token address
tokens: true,
},
})) as { id: string; typeData: { quoteToken: string } }[];
})) as { id: string; typeData: { quoteToken: string }; tokens: PrismaPoolToken[] }[];

// Get events
const swaps = await subgraphClient.getAllSwapsForPool(poolId);

const dbSwaps = swaps.map((swap) => swapV2Transformer(swap, chain, fxPools));
const dbSwaps = swaps.map((swap) => swapV2Transformer(swap, chain));

// Enrich with USD values
console.time('swapsUsd');
const dbEntries = await swapsUsd(dbSwaps, chain);
const dbEntries = await swapsUsd(dbSwaps, chain, fxPools);
console.timeEnd('swapsUsd');

await eventRepo.upsertEvents(dbEntries);
Expand Down
2 changes: 1 addition & 1 deletion modules/pool/subgraph-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ const subgraphMapper = (
swapEnabled: pool.swapEnabled,
totalShares: pool.totalShares,
totalSharesNum: parseFloat(pool.totalShares),
totalLiquidity: Math.max(parseFloat(pool.totalLiquidity), 0),
totalLiquidity: 0,
};

const typeData: ReturnType<(typeof typeDataMapper)[keyof typeof typeDataMapper]> | {} = Object.keys(
Expand Down
34 changes: 31 additions & 3 deletions modules/sources/enrichers/swaps-usd.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _ from 'lodash';
import { daysAgo, roundToHour, roundToMidnight } from '../../common/time';
import { Chain } from '@prisma/client';
import { Chain, PrismaPoolToken } from '@prisma/client';
import { prisma } from '../../../prisma/prisma-client';
import { SwapEvent } from '../../../prisma/prisma-types';

Expand All @@ -11,7 +11,11 @@ import { SwapEvent } from '../../../prisma/prisma-types';
* @param chain
* @returns
*/
export async function swapsUsd(swaps: SwapEvent[], chain: Chain): Promise<SwapEvent[]> {
export async function swapsUsd(
swaps: SwapEvent[],
chain: Chain,
fxPools: { id: string; typeData: { quoteToken: string }; tokens: PrismaPoolToken[] }[] = [],
): Promise<SwapEvent[]> {
// Enrich with USD values
// Group swaps based on timestamp, hourly and daily buckets
const groupedSwaps = _.groupBy(swaps, (swap) => {
Expand Down Expand Up @@ -40,9 +44,33 @@ export async function swapsUsd(swaps: SwapEvent[], chain: Chain): Promise<SwapEv
const tokenOut = tokenPrices.find((price) => price.tokenAddress === swap.payload.tokenOut.address);
const feeToken = tokenPrices.find((price) => price.tokenAddress === swap.payload.fee.address);
const surplusToken = tokenPrices.find((price) => price.tokenAddress === swap.payload.surplus?.address);
const feeValueUSD = parseFloat(swap.payload.fee.amount) * (feeToken?.price || 0);
let feeValueUSD = parseFloat(swap.payload.fee.amount) * (feeToken?.price || 0);
const dynamicFeeValueUSD = parseFloat(swap.payload.dynamicFee?.amount || '0') * (feeToken?.price || 0);

const fxPool = fxPools.find((pool) => pool.id === swap.poolId);
if (fxPool) {
const quoteTokenAddress = fxPool.typeData.quoteToken;
const baseTokenAddress =
swap.payload.tokenIn.address === quoteTokenAddress
? swap.payload.tokenOut.address
: swap.payload.tokenIn.address;
let isTokenInBase = swap.payload.tokenOut.address === quoteTokenAddress;
let baseRate = fxPool.tokens.find((t) => t.address === baseTokenAddress)?.latestFxPrice;
let quoteRate = fxPool.tokens.find((t) => t.address === quoteTokenAddress)?.latestFxPrice;

if (baseRate && quoteRate) {
if (isTokenInBase) {
feeValueUSD +=
parseFloat(swap.payload.tokenIn.amount) * baseRate -
parseFloat(swap.payload.tokenOut.amount) * quoteRate;
} else {
feeValueUSD +=
parseFloat(swap.payload.tokenIn.amount) * quoteRate -
parseFloat(swap.payload.tokenOut.amount) * baseRate;
}
}
}

const payload = {
fee: {
...swap.payload.fee,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2835,7 +2835,6 @@ export type _Meta_ = {
* 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 */
Expand Down
50 changes: 4 additions & 46 deletions modules/sources/transformers/swap-v2-transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,52 +10,10 @@ import { SwapEvent } from '../../../prisma/prisma-types';
* @param chain
* @returns
*/
export function swapV2Transformer(
swap: BalancerSwapFragment,
chain: Chain,
fxPools: { id: string; typeData: { quoteToken: string } }[] = [],
): SwapEvent {
export function swapV2Transformer(swap: BalancerSwapFragment, chain: Chain): SwapEvent {
// Avoiding scientific notation
const feeFloat = parseFloat(swap.tokenAmountIn) * parseFloat(swap.poolId.swapFee ?? 0);
let fee = feeFloat < 1e6 ? feeFloat.toFixed(18).replace(/0+$/, '').replace(/\.$/, '') : String(feeFloat);
let feeFloatUSD = parseFloat(swap.valueUSD) * parseFloat(swap.poolId.swapFee ?? 0);
let feeUSD =
feeFloatUSD < 1e6 ? feeFloatUSD.toFixed(18).replace(/0+$/, '').replace(/\.$/, '') : String(feeFloatUSD);

// FX pools have a different fee calculation
// Replica of the subgraph logic:
// https://github.com/balancer/balancer-subgraph-v2/blob/60453224453bd07a0a3a22a8ad6cc26e65fd809f/src/mappings/vault.ts#L551-L564
if (swap.poolId.poolType === 'FX') {
// Find the pool that has the quote token
const fxPool = fxPools.find((pool) => pool.id === swap.poolId.id);
if (fxPool && [swap.tokenOut, swap.tokenIn].includes(fxPool.typeData.quoteToken)) {
const quoteTokenAddress = fxPool.typeData.quoteToken;
const baseTokenAddress = swap.tokenIn === quoteTokenAddress ? swap.tokenOut : swap.tokenIn;
let isTokenInBase = swap.tokenOut === quoteTokenAddress;
let baseToken = swap.poolId.tokens?.find(({ token }) => token.address == baseTokenAddress);
let quoteToken = swap.poolId.tokens?.find(({ token }) => token.address == quoteTokenAddress);
let baseRate = baseToken != null ? baseToken.token.latestFXPrice : null;
let quoteRate = quoteToken != null ? quoteToken.token.latestFXPrice : null;

if (baseRate && quoteRate) {
if (isTokenInBase) {
feeFloatUSD +=
parseFloat(swap.tokenAmountIn) * parseFloat(baseRate) -
parseFloat(swap.tokenAmountOut) * parseFloat(quoteRate);
// Need to set the fee in the tokenIn price, because it's later recalculated based on the DB prices
fee = String(feeFloatUSD / parseFloat(baseRate)); // fee / tokenIn price
} else {
feeFloatUSD +=
parseFloat(swap.tokenAmountIn) * parseFloat(quoteRate) -
parseFloat(swap.tokenAmountOut) * parseFloat(baseRate);
// Need to set the fee in the tokenIn price, because it's later recalculated based on the DB prices
fee = String(feeFloatUSD / parseFloat(quoteRate)); // fee / tokenIn price
}
}

feeUSD = String(feeFloatUSD);
}
}

return {
id: swap.id, // tx + logIndex
Expand All @@ -64,16 +22,16 @@ export function swapV2Transformer(
poolId: swap.poolId.id,
chain: chain,
protocolVersion: 2,
userAddress: swap.userAddress.id,
userAddress: typeof swap.userAddress === 'string' ? swap.userAddress : swap.userAddress.id,
blockNumber: Number(swap.block ?? 0), // FANTOM is missing block
blockTimestamp: Number(swap.timestamp),
logIndex: Number(swap.id.substring(66)),
valueUSD: Number(swap.valueUSD),
valueUSD: 0,
payload: {
fee: {
address: swap.tokenIn,
amount: fee,
valueUSD: feeUSD,
valueUSD: '0', // to be filled later
},
tokenIn: {
address: swap.tokenIn,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ fragment BalancerPool on Pool {
symbol
name
swapFee
totalWeight
totalSwapVolume
totalSwapFee
totalLiquidity
totalShares
swapsCount
holdersCount
Expand Down Expand Up @@ -129,41 +125,6 @@ query BalancerPool($id: ID!, $block: Block_height) {
}
}

query BalancerPoolSnapshots(
$skip: Int
$first: Int
$orderBy: PoolSnapshot_orderBy
$orderDirection: OrderDirection
$where: PoolSnapshot_filter
$block: Block_height
) {
poolSnapshots(
skip: $skip
first: $first
orderBy: $orderBy
orderDirection: $orderDirection
where: $where
block: $block
) {
...BalancerPoolSnapshot
}
}

fragment BalancerPoolSnapshot on PoolSnapshot {
id
pool {
id
}
amounts
totalShares
swapVolume
swapFees
timestamp
liquidity
swapsCount
holdersCount
}

query BalancerJoinExits(
$skip: Int
$first: Int
Expand Down Expand Up @@ -196,7 +157,6 @@ fragment BalancerJoinExit on JoinExit {
id
tokensList
}
valueUSD
}

query BalancerSwaps(
Expand Down Expand Up @@ -239,12 +199,9 @@ fragment BalancerSwap on Swap {
}
}
}
userAddress {
id
}
userAddress
timestamp
tx
valueUSD
block
}

Expand All @@ -254,11 +211,6 @@ query BalancerGetPoolsWithActiveUpdates($timestamp: BigInt!) {
id
}
}
gradualWeightUpdates(where: { endTimestamp_gte: $timestamp }) {
poolId {
id
}
}
}

query BalancerGetMeta {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,10 @@ export class BalancerSubgraphService {
}

public async getPoolsWithActiveUpdates(timestamp: number): Promise<string[]> {
const { ampUpdates, gradualWeightUpdates } = await this.sdk.BalancerGetPoolsWithActiveUpdates({
const { ampUpdates } = await this.sdk.BalancerGetPoolsWithActiveUpdates({
timestamp: `${timestamp}`,
});

return [...ampUpdates, ...gradualWeightUpdates].map((item) => item.poolId.id);
return ampUpdates.map((item) => item.poolId.id);
}
}
Loading