diff --git a/lib/config/ChainConfigManager.ts b/lib/config/ChainConfigManager.ts index 8ed13559..2d8cbe39 100644 --- a/lib/config/ChainConfigManager.ts +++ b/lib/config/ChainConfigManager.ts @@ -53,7 +53,7 @@ export abstract class ChainConfigManager { // 25 blocks from now // to cover time to sign, run secondary auction, and some blocks for decay deadlineBufferSecs: 300, - priceBufferBps: 10, + priceBufferBps: 15, }, }, alarmEnabled: true, diff --git a/lib/entities/quote/DutchV2Quote.ts b/lib/entities/quote/DutchV2Quote.ts index 2f03edbd..98ba959e 100644 --- a/lib/entities/quote/DutchV2Quote.ts +++ b/lib/entities/quote/DutchV2Quote.ts @@ -18,7 +18,7 @@ import { timestampInMstoSeconds } from '../../util/time'; import { DutchQuote, getPortionAdjustedOutputs } from './DutchQuote'; export const DEFAULT_LABS_COSIGNER = ethers.constants.AddressZero; -export const V2_OUTPUT_AMOUNT_BUFFER_BPS = 10; +export const DEFAULT_V2_OUTPUT_AMOUNT_BUFFER_BPS = 10; // JSON format of a DutchV2Quote, to be returned by the API export type DutchV2QuoteDataJSON = SharedOrderQuoteDataJSON & { @@ -35,6 +35,7 @@ export class DutchV2Quote extends DutchQuote implements IQuote { public readonly defaultDeadlineBufferInSecs: number = DEFAULT_V2_DEADLINE_BUFFER_SECS; public toJSON(): DutchV2QuoteDataJSON { + const quoteConfig = ChainConfigManager.getQuoteConfig(this.chainId, this.request.routingType); return { orderInfo: this.toOrder().toJSON(), encodedOrder: this.toOrder().serialize(), @@ -48,7 +49,12 @@ export class DutchV2Quote extends DutchQuote implements IQuote { // this is FE requirement ...(frontendAndUraEnablePortion(this.request.info.sendPortionEnabled) && { portionBips: this.portion?.bips ?? 0, - portionAmount: applyBufferToPortion(this.portionAmountOutStart, this.request.info.type).toString() ?? '0', + portionAmount: + applyBufferToPortion( + this.portionAmountOutStart, + this.request.info.type, + quoteConfig.priceBufferBps ?? DEFAULT_V2_OUTPUT_AMOUNT_BUFFER_BPS + ).toString() ?? '0', portionRecipient: this.portion?.recipient, }), }; @@ -110,6 +116,7 @@ export class DutchV2Quote extends DutchQuote implements IQuote { } public toLog(): LogJSON { + const quoteConfig = ChainConfigManager.getQuoteConfig(this.chainId, this.request.routingType); return { tokenInChainId: this.chainId, tokenOutChainId: this.chainId, @@ -135,8 +142,16 @@ export class DutchV2Quote extends DutchQuote implements IQuote { createdAtMs: this.createdAtMs, portionBips: this.portion?.bips, portionRecipient: this.portion?.recipient, - portionAmountOutStart: applyBufferToPortion(this.portionAmountOutStart, this.request.info.type).toString(), - portionAmountOutEnd: applyBufferToPortion(this.portionAmountOutEnd, this.request.info.type).toString(), + portionAmountOutStart: applyBufferToPortion( + this.portionAmountOutStart, + this.request.info.type, + quoteConfig.priceBufferBps ?? DEFAULT_V2_OUTPUT_AMOUNT_BUFFER_BPS + ).toString(), + portionAmountOutEnd: applyBufferToPortion( + this.portionAmountOutEnd, + this.request.info.type, + quoteConfig.priceBufferBps ?? DEFAULT_V2_OUTPUT_AMOUNT_BUFFER_BPS + ).toString(), }; } @@ -181,9 +196,9 @@ export function addBufferToV2InputOutput( * if exact_input, apply buffer to both user and portion outputs * if exact_output, do nothing since the buffer is applied to user input */ -export function applyBufferToPortion(portionAmount: BigNumber, type: TradeType): BigNumber { +export function applyBufferToPortion(portionAmount: BigNumber, type: TradeType, bps: number): BigNumber { if (type === TradeType.EXACT_INPUT) { - return portionAmount.mul(BPS - V2_OUTPUT_AMOUNT_BUFFER_BPS).div(BPS); + return portionAmount.mul(BPS - bps).div(BPS); } else { return portionAmount; } diff --git a/test/unit/entities/DutchV2Quote.test.ts b/test/unit/entities/DutchV2Quote.test.ts index 7e3f6a37..d03a9748 100644 --- a/test/unit/entities/DutchV2Quote.test.ts +++ b/test/unit/entities/DutchV2Quote.test.ts @@ -3,8 +3,9 @@ import Logger from 'bunyan'; import { it } from '@jest/globals'; import { TradeType } from '@uniswap/sdk-core'; import { BigNumber } from 'ethers'; -import { BPS } from '../../../lib/constants'; -import { DEFAULT_LABS_COSIGNER, DutchQuote, V2_OUTPUT_AMOUNT_BUFFER_BPS } from '../../../lib/entities'; +import { ChainConfigManager } from '../../../lib/config/ChainConfigManager'; +import { BPS, RoutingType } from '../../../lib/constants'; +import { DEFAULT_LABS_COSIGNER, DutchQuote } from '../../../lib/entities'; import { PortionType } from '../../../lib/fetchers/PortionFetcher'; import { AMOUNT, ETH_IN, SWAPPER, TOKEN_IN } from '../../constants'; import { createDutchV2QuoteWithRequestOverrides } from '../../utils/fixtures'; @@ -17,6 +18,8 @@ describe('DutchV2Quote', () => { const logger = Logger.createLogger({ name: 'test' }); logger.level(Logger.FATAL); + const quoteConfig = ChainConfigManager.getQuoteConfig(1, RoutingType.DUTCH_V2); + describe('toOrder', () => { it('should have proper json form', () => { const v2Quote = createDutchV2QuoteWithRequestOverrides( @@ -34,7 +37,7 @@ describe('DutchV2Quote', () => { expect(orderJson.outputs.length).toEqual(1); expect(orderJson.outputs[0].startAmount).toEqual( BigNumber.from(AMOUNT) // Default starting amount out in createDutchV2QuoteWithRequestOverrides - .mul(BPS - 10) + .mul(BPS - quoteConfig.priceBufferBps!) .div(BPS) .toString() ); @@ -58,13 +61,13 @@ describe('DutchV2Quote', () => { expect(orderJson.outputs[0].startAmount).toEqual( v2Quote.amountOutGasAndPortionAdjusted - .mul(BPS - V2_OUTPUT_AMOUNT_BUFFER_BPS) + .mul(BPS - quoteConfig.priceBufferBps!) .div(BPS) .toString() ); expect(orderJson.outputs[1].startAmount).toEqual( v2Quote.portionAmountOutStart - .mul(BPS - V2_OUTPUT_AMOUNT_BUFFER_BPS) + .mul(BPS - quoteConfig.priceBufferBps!) .div(BPS) .toString() ); @@ -90,7 +93,7 @@ describe('DutchV2Quote', () => { expect(orderJson.input.startAmount).toEqual( v2Quote.amountInGasAndPortionAdjusted - .mul(BPS + V2_OUTPUT_AMOUNT_BUFFER_BPS) + .mul(BPS + quoteConfig.priceBufferBps!) .div(BPS) .toString() );