Skip to content

Commit

Permalink
refactor: turn HardquoteResponse into base class for V2 & V3
Browse files Browse the repository at this point in the history
  • Loading branch information
alanhwu committed Nov 5, 2024
1 parent 831ba96 commit e861717
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 45 deletions.
44 changes: 4 additions & 40 deletions lib/entities/HardQuoteResponse.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { CosignedV2DutchOrder } from '@uniswap/uniswapx-sdk';
import { BigNumber } from 'ethers';
import { CosignedV2DutchOrder, CosignedV3DutchOrder } from '@uniswap/uniswapx-sdk';
import { v4 as uuidv4 } from 'uuid';

import { HardQuoteRequest } from '.';
import { HardQuoteResponseData } from '../handlers/hard-quote/schema';
import { currentTimestampInMs, timestampInMstoSeconds } from '../util/time';

// data class for hard quote response helpers and conversions
export class HardQuoteResponse {
export abstract class HardQuoteResponse<T extends CosignedV2DutchOrder | CosignedV3DutchOrder> {
public createdAt: string;

constructor(
public request: HardQuoteRequest,
public order: CosignedV2DutchOrder,
public order: T,
public createdAtMs = currentTimestampInMs()
) {
this.createdAt = timestampInMstoSeconds(parseInt(this.createdAtMs));
Expand All @@ -29,23 +28,7 @@ export class HardQuoteResponse {
};
}

public toLog() {
return {
quoteId: this.quoteId,
requestId: this.requestId,
tokenInChainId: this.chainId,
tokenOutChainId: this.chainId,
tokenIn: this.tokenIn,
amountIn: this.amountIn.toString(),
tokenOut: this.tokenOut,
amountOut: this.amountOut.toString(),
swapper: this.swapper,
filler: this.filler,
orderHash: this.order.hash(),
createdAt: this.createdAt,
createdAtMs: this.createdAtMs,
};
}
public abstract toLog(): any;

public get quoteId(): string {
return this.request.quoteId ?? uuidv4();
Expand All @@ -67,25 +50,6 @@ export class HardQuoteResponse {
return this.request.tokenIn;
}

public get amountOut(): BigNumber {
const resolved = this.order.resolve({
timestamp: this.order.info.cosignerData.decayStartTime,
});
let amount = BigNumber.from(0);
for (const output of resolved.outputs) {
amount = amount.add(output.amount);
}

return amount;
}

public get amountIn(): BigNumber {
const resolved = this.order.resolve({
timestamp: this.order.info.cosignerData.decayStartTime,
});
return resolved.input.amount;
}

public get tokenOut(): string {
return this.request.tokenOut;
}
Expand Down
42 changes: 42 additions & 0 deletions lib/entities/V2HardQuoteResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { BigNumber } from "ethers";
import { HardQuoteResponse } from "./HardQuoteResponse";
import { CosignedV2DutchOrder } from "@uniswap/uniswapx-sdk";

export class V2HardQuoteResponse extends HardQuoteResponse<CosignedV2DutchOrder> {
public toLog() {
return {
quoteId: this.quoteId,
requestId: this.requestId,
tokenInChainId: this.chainId,
tokenOutChainId: this.chainId,
tokenIn: this.tokenIn,
amountIn: this.amountIn.toString(),
tokenOut: this.tokenOut,
amountOut: this.amountOut.toString(),
swapper: this.swapper,
filler: this.filler,
orderHash: this.order.hash(),
createdAt: this.createdAt,
createdAtMs: this.createdAtMs,
};
}

public get amountOut(): BigNumber {
const resolved = this.order.resolve({
timestamp: this.order.info.cosignerData.decayStartTime,
});
let amount = BigNumber.from(0);
for (const output of resolved.outputs) {
amount = amount.add(output.amount);
}

return amount;
}

public get amountIn(): BigNumber {
const resolved = this.order.resolve({
timestamp: this.order.info.cosignerData.decayStartTime,
});
return resolved.input.amount;
}
}
48 changes: 48 additions & 0 deletions lib/entities/V3HardQuoteResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { CosignedV3DutchOrder } from "@uniswap/uniswapx-sdk";
import { HardQuoteResponse } from "./HardQuoteResponse";

export class V3HardQuoteResponse extends HardQuoteResponse<CosignedV3DutchOrder> {
public toLog() {
return {
quoteId: this.quoteId,
requestId: this.requestId,
tokenInChainId: this.chainId,
tokenOutChainId: this.chainId,
tokenIn: this.tokenIn,
input: this.input,
tokenOut: this.tokenOut,
outputs: this.outputs,
swapper: this.swapper,
filler: this.filler,
orderHash: this.order.hash(),
createdAt: this.createdAt,
createdAtMs: this.createdAtMs,
};
}

get input() {
const input = this.order.info.input;
const relativeAmounts = input.curve.relativeAmounts.map((amount) => amount.toString());

return {
...input,
curve: {
...input.curve,
relativeAmounts,
},
}
}

get outputs() {
const processedOutputs = this.order.info.outputs.map((output) => {
return {
...output,
curve: {
...output.curve,
relativeAmounts: output.curve.relativeAmounts.map((amount) => amount.toString()),
}
}
});
return processedOutputs;
}
}
5 changes: 3 additions & 2 deletions lib/handlers/hard-quote/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { BigNumber, ethers } from 'ethers';
import Joi from 'joi';

import { POST_ORDER_ERROR_REASON } from '../../constants';
import { HardQuoteRequest, HardQuoteResponse, Metric, QuoteResponse } from '../../entities';
import { HardQuoteRequest, Metric, QuoteResponse } from '../../entities';
import { checkDefined } from '../../preconditions/preconditions';
import { ChainId } from '../../util/chains';
import { NoQuotesAvailable, OrderPostError, UnknownOrderCosignerError } from '../../util/errors';
Expand All @@ -22,6 +22,7 @@ import {
HardQuoteResponseData,
HardQuoteResponseDataJoi,
} from './schema';
import { V2HardQuoteResponse } from '../../entities/V2HardQuoteResponse';

const DEFAULT_EXCLUSIVITY_OVERRIDE_BPS = BigNumber.from(100); // non-exclusive fillers must override price by this much
const RESPONSE_LOG_TYPE = 'HardResponse';
Expand Down Expand Up @@ -113,7 +114,7 @@ export class QuoteHandler extends APIGLambdaHandler<
if (response.statusCode == 200 || response.statusCode == 201) {
metric.putMetric(Metric.QUOTE_200, 1, MetricLoggerUnit.Count);
metric.putMetric(Metric.QUOTE_LATENCY, Date.now() - start, MetricLoggerUnit.Milliseconds);
const hardResponse = new HardQuoteResponse(request, cosignedOrder);
const hardResponse = new V2HardQuoteResponse(request, cosignedOrder);
if (!bestQuote) {
// The RFQ responses are logged in getBestQuote()
// we log the Open Orders here
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
"@uniswap/signer": "0.0.3-beta.4",
"@uniswap/smart-order-router": "^3.3.0",
"@uniswap/token-lists": "^1.0.0-beta.31",
"@uniswap/uniswapx-sdk": "2.1.0-beta.4",
"@uniswap/uniswapx-sdk": "2.1.0-beta.20",
"@uniswap/v3-sdk": "^3.9.0",
"aws-cdk-lib": "2.85.0",
"aws-embedded-metrics": "^4.1.0",
Expand Down
5 changes: 3 additions & 2 deletions test/entities/HardQuoteResponse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import {
import { ethers, Wallet } from 'ethers';
import { parseEther } from 'ethers/lib/utils';

import { HardQuoteRequest, HardQuoteResponse } from '../../lib/entities';
import { HardQuoteRequest } from '../../lib/entities';
import { HardQuoteRequestBody } from '../../lib/handlers/hard-quote';
import { getOrder } from '../handlers/hard-quote/handler.test';
import { V2HardQuoteResponse } from '../../lib/entities/V2HardQuoteResponse';

const QUOTE_ID = 'a83f397c-8ef4-4801-a9b7-6e79155049f6';
const REQUEST_ID = 'a83f397c-8ef4-4801-a9b7-6e79155049f7';
Expand Down Expand Up @@ -51,7 +52,7 @@ describe('HardQuoteResponse', () => {
cosignerData,
ethers.utils.joinSignature(cosignature)
);
return new HardQuoteResponse(new HardQuoteRequest(await getRequest(unsigned)), order);
return new V2HardQuoteResponse(new HardQuoteRequest(await getRequest(unsigned)), order);
};

it('toResponseJSON', async () => {
Expand Down

0 comments on commit e861717

Please sign in to comment.