Skip to content

Commit

Permalink
Merge pull request #599 from beethovenxfi/refactor/sor-service
Browse files Browse the repository at this point in the history
Refactor/sor service
  • Loading branch information
franzns authored Dec 20, 2023
2 parents 6510405 + 27ca9aa commit 2fa7fe5
Show file tree
Hide file tree
Showing 14 changed files with 162 additions and 332 deletions.
39 changes: 0 additions & 39 deletions modules/balancer/balancer.gql

This file was deleted.

23 changes: 0 additions & 23 deletions modules/balancer/balancer.resolvers.ts

This file was deleted.

45 changes: 0 additions & 45 deletions modules/beethoven/balancer-sdk.resolvers.ts

This file was deleted.

File renamed without changes.
11 changes: 5 additions & 6 deletions modules/sor/constants.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { TokenAmount } from '@balancer/sdk';
import { GqlCowSwapApiResponse, GqlSorSwapType } from '../../schema';

export const EMPTY_COWSWAP_RESPONSE = (assetIn: string, assetOut: string, amount: TokenAmount): GqlCowSwapApiResponse => {
export const EMPTY_COWSWAP_RESPONSE = (
assetIn: string,
assetOut: string,
amount: TokenAmount,
): GqlCowSwapApiResponse => {
return {
marketSp: '0',
returnAmount: '0',
returnAmountConsideringFees: '0',
returnAmountFromSwaps: '0',
swapAmount: amount.amount.toString(),
swapAmountForSwaps: '0',
swaps: [],
tokenAddresses: [],
tokenIn: assetIn,
Expand Down Expand Up @@ -352,4 +352,3 @@ export const poolsToIgnore = [
'0xbfd65c6160cfd638a85c645e6e6d8acac5dac935000000000000000000000004',
'0xe274c9deb6ed34cfe4130f8d0a8a948dea5bb28600000000000000000000000d',
];

45 changes: 24 additions & 21 deletions modules/beethoven/balancer-sdk.gql → modules/sor/sor.gql
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,37 @@ extend type Query {
swapAmount: BigDecimal! #expected in human readable form
swapOptions: GqlSorSwapOptionsInput!
): GqlSorGetSwapsResponse!
sorGetCowSwaps(
chain: GqlChain!
tokenIn: String!
tokenOut: String!
swapType: GqlSorSwapType!
swapAmount: BigDecimal! #expected in raw amount
): GqlCowSwapApiResponse!
sorGetBatchSwapForTokensIn(
tokensIn: [GqlTokenAmountHumanReadable!]!
tokenOut: String!
swapOptions: GqlSorSwapOptionsInput!
): GqlSorGetBatchSwapForTokensInResponse!
}

type GqlCowSwapApiResponse {
tokenAddresses: [String!]!
swaps: [GqlSwap!]!
swapAmount: String!
returnAmount: String!
tokenIn: String!
tokenOut: String!
}

type GqlSwap {
poolId: String!
assetInIndex: Int!
assetOutIndex: Int!
amount: String!
userData: String!
}

enum GqlSorSwapType {
EXACT_IN
EXACT_OUT
Expand Down Expand Up @@ -109,24 +133,3 @@ type GqlSorGetBatchSwapForTokensInResponse {
swaps: [GqlSorSwap!]!
assets: [String!]!
}

type GqlCowSwapApiResponse {
tokenAddresses: [String!]!
swaps: [GqlSwap!]!
swapAmount: String!
swapAmountForSwaps: String!
returnAmount: String!
returnAmountFromSwaps: String!
returnAmountConsideringFees: String!
tokenIn: String!
tokenOut: String!
marketSp: String!
}

type GqlSwap {
poolId: String!
assetInIndex: Int!
assetOutIndex: Int!
amount: String!
userData: String!
}
31 changes: 31 additions & 0 deletions modules/sor/sor.resolvers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Resolvers } from '../../schema';
import { balancerSorService } from './sorV1Beets/balancer-sor.service';
import { tokenService } from '../token/token.service';
import { sorService } from './sor.service';
import { getTokenAmountHuman } from './utils';
import { headerChain } from '../context/header-chain';

const balancerSdkResolvers: Resolvers = {
Query: {
sorGetSwaps: async (parent, args, context) => {
const currentChain = headerChain();
if (!args.chain && currentChain) {
args.chain = currentChain;
} else if (!args.chain) {
throw new Error('sorGetSwaps error: Provide "chain" param');
}

return sorService.getSorSwaps(args);
},
sorGetBatchSwapForTokensIn: async (parent, args, context) => {
const tokens = await tokenService.getTokens();

return balancerSorService.getBatchSwapForTokensIn({ ...args, tokens });
},
sorGetCowSwaps: async (parent, args, context) => {
return sorService.getCowSwaps(args);
},
},
};

export default balancerSdkResolvers;
74 changes: 47 additions & 27 deletions modules/sor/sor.service.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,81 @@
import { GqlCowSwapApiResponse, GqlSorSwapType, GqlSorGetSwapsResponse, GqlSorSwapOptionsInput } from '../../schema';
import { sorV1BalancerService } from './sorV1Balancer/sorV1Balancer.service';
import {
GqlCowSwapApiResponse,
GqlSorSwapType,
GqlSorGetSwapsResponse,
QuerySorGetSwapsArgs,
QuerySorGetCowSwapsArgs,
} from '../../schema';
import { sorV1BeetsService } from './sorV1Beets/sorV1Beets.service';
import { sorV2Service } from './sorV2/sorV2.service';
import { GetSwapsInput, SwapResult, SwapService } from './types';
import { GetSwapsInput, SwapResult } from './types';
import { EMPTY_COWSWAP_RESPONSE } from './constants';
import { publishMetric } from '../metrics/sor.metric';
import { Chain } from '@prisma/client';
import { parseUnits, formatUnits } from '@ethersproject/units';
import { tokenService } from '../token/token.service';
import { getTokenAmountHuman, getTokenAmountRaw } from './utils';

export class SorService {
async getCowSwaps(input: GetSwapsInput): Promise<GqlCowSwapApiResponse> {
const swap = await this.getSwap({ ...input, swapOptions: {} });
const emptyResponse = EMPTY_COWSWAP_RESPONSE(input.tokenIn, input.tokenOut, input.swapAmount);
async getCowSwaps(args: QuerySorGetCowSwapsArgs): Promise<GqlCowSwapApiResponse> {
console.log('getCowSwaps args', JSON.stringify(args));
const amountToken = args.swapType === 'EXACT_IN' ? args.tokenIn : args.tokenOut;
// Use TokenAmount to help follow scaling requirements in later logic
// args.swapAmount is RawScale, e.g. 1USDC should be passed as 1000000
const amount = await getTokenAmountRaw(amountToken, args.swapAmount, args.chain!);

const swap = await sorV2Service.getSwapResult({
chain: args.chain!,
swapAmount: amount,
swapType: args.swapType,
tokenIn: args.tokenIn.toLowerCase(),
tokenOut: args.tokenOut.toLowerCase(),
swapOptions: {},
});
const emptyResponse = EMPTY_COWSWAP_RESPONSE(args.tokenIn, args.tokenOut, amount);

if (!swap) return emptyResponse;

try {
// Updates with latest onchain data before returning
return await swap.getCowSwapResponse(input.chain, true);
return await swap.getCowSwapResponse(true);
} catch (err) {
console.log(`Error Retrieving QuerySwap`, err);
return emptyResponse;
}
}

async getBeetsSwaps(input: GetSwapsInput): Promise<GqlSorGetSwapsResponse> {
console.log('getBeetsSwaps input', JSON.stringify(input));
const swap = await this.getSwap(input, sorV1BeetsService);
const emptyResponse = sorV1BeetsService.zeroResponse(
input.swapType,
input.tokenIn,
input.tokenOut,
input.swapAmount,
);
async getSorSwaps(args: QuerySorGetSwapsArgs): Promise<GqlSorGetSwapsResponse> {
console.log('getSorSwaps args', JSON.stringify(args));
const tokenIn = args.tokenIn.toLowerCase();
const tokenOut = args.tokenOut.toLowerCase();
const amountToken = args.swapType === 'EXACT_IN' ? tokenIn : tokenOut;
// Use TokenAmount to help follow scaling requirements in later logic
// args.swapAmount is HumanScale
const amount = await getTokenAmountHuman(amountToken, args.swapAmount, args.chain!);

const swap = await this.getComparingSwap({
chain: args.chain!,
swapAmount: amount,
swapOptions: args.swapOptions,
swapType: args.swapType,
tokenIn: tokenIn,
tokenOut: tokenOut,
});
const emptyResponse = sorV1BeetsService.zeroResponse(args.swapType, args.tokenIn, args.tokenOut, amount);

if (!swap) return emptyResponse;

try {
// Updates with latest onchain data before returning
return swap.getBeetsSwapResponse(true);
return swap.getSorSwapResponse(true);
} catch (err) {
console.log(`Error Retrieving QuerySwap`, err);
return emptyResponse;
}
}

private async getSwap(input: GetSwapsInput, v1Service: SwapService = sorV1BalancerService) {
private async getComparingSwap(input: GetSwapsInput) {
const v1Start = +new Date();
const swapV1 = await v1Service.getSwapResult(input);
const swapV1 = await sorV1BeetsService.getSwapResult(input);
const v1Time = +new Date() - v1Start;

const v2Start = +new Date();
Expand Down Expand Up @@ -122,9 +149,6 @@ export class SorService {
v1Time: number,
v2Time: number,
) {
// await publishMetric(chain, `SOR_VALID_V1`, v1.isValid ? 1 : 0);
// await publishMetric(chain, `SOR_VALID_V2`, v2.isValid ? 1 : 0);

if (!version) return;

let v1ResultAmount = v1.inputAmount;
Expand Down Expand Up @@ -154,10 +178,6 @@ export class SorService {
let diff = bn(diffN.toFixed(decimals), decimals);
let bestResultAmount = version === 'V1' ? v1ResultAmount : v2ResultAmount;

// await publishMetric(chain, `SOR_TIME_V1`, v1Time);
// await publishMetric(chain, `SOR_TIME_V2`, v2Time);
// await publishMetric(chain, `SOR_V2_PERFORMACE`, v2Perf);

console.log(
[
'SOR_RESULT',
Expand Down
Loading

0 comments on commit 2fa7fe5

Please sign in to comment.