diff --git a/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.test.ts b/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.test.ts index 3f6898ab..b778b1b1 100644 --- a/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.test.ts +++ b/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.test.ts @@ -865,6 +865,34 @@ describe("V3DutchOrderBuilder", () => { const maxout = V3DutchOrderBuilder.getMaxAmountOut(startAmount, relativeAmounts); expect(maxout).toEqual(startAmount); }); + + it("Test minAmountOut", () => { + const startAmount = OUTPUT_START_AMOUNT; + const relativeAmounts = [BigInt(0), BigInt(3), BigInt(-2), BigInt(-4), BigInt(-3)]; + const minout = V3DutchOrderBuilder.getMinAmountOut(startAmount, relativeAmounts); + expect(minout).toEqual(startAmount.sub(3)); + }); + + it("Test minAmountOut with empty curve", () => { + const startAmount = OUTPUT_START_AMOUNT; + const relativeAmounts : bigint[] = []; + const minout = V3DutchOrderBuilder.getMinAmountOut(startAmount, relativeAmounts); + expect(minout).toEqual(startAmount); + }); + + it("Test minAmountOut with negative relativeAmounts", () => { + const startAmount = OUTPUT_START_AMOUNT; + const relativeAmounts = [BigInt(-1), BigInt(-2), BigInt(-3)]; + const minout = V3DutchOrderBuilder.getMinAmountOut(startAmount, relativeAmounts); + expect(minout).toEqual(startAmount); + }); + + it("Test minAmountOut with entirely positive relativeAmounts", () => { + const startAmount = OUTPUT_START_AMOUNT; + const relativeAmounts = [BigInt(1), BigInt(2), BigInt(3)]; + const minout = V3DutchOrderBuilder.getMinAmountOut(startAmount, relativeAmounts); + expect(minout).toEqual(startAmount.sub(3)); + }); }); describe("fromOrder", () => { diff --git a/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.ts b/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.ts index d6f67691..e407b930 100644 --- a/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.ts +++ b/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.ts @@ -319,7 +319,7 @@ export class V3DutchOrderBuilder extends OrderBuilder { ); } - // A helper function for users of the class to easily the value to pass to maxAmount in an input + // A helper function for users of the class to easily find the value to pass to maxAmount in an input static getMaxAmountOut( startAmount: BigNumber, relativeAmounts: bigint[] @@ -338,4 +338,24 @@ export class V3DutchOrderBuilder extends OrderBuilder { const maxOut = startAmount.sub(minRelativeAmount.toString()); return maxOut; } + + // A helper function for users of the class find the lowest possible output amount + static getMinAmountOut( + startAmount: BigNumber, + relativeAmounts: bigint[] + ): BigNumber { + if (relativeAmounts.length == 0) { + return startAmount; + } + + // Find the maximum of the relative amounts + const maxRelativeAmount = relativeAmounts.reduce( + (max, amount) => (amount > max ? amount : max), + BigInt(0) + ); + + // Minimum is the start - the max of the relative amounts + const minOut = startAmount.sub(maxRelativeAmount.toString()); + return minOut; + } }