UNPKG

@deliquifiedlabs/uniswapx-sdk

Version:

SDK for the UniswapX protocol

534 lines 23.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const ethers_1 = require("ethers"); const order_1 = require("../order"); const validation_1 = require("../order/validation"); const V2DutchOrderBuilder_1 = require("./V2DutchOrderBuilder"); const INPUT_TOKEN = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"; const OUTPUT_TOKEN = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"; const INPUT_START_AMOUNT = ethers_1.BigNumber.from("1000000"); const OUTPUT_START_AMOUNT = ethers_1.BigNumber.from("1000000000000000000"); describe("V2DutchOrderBuilder", () => { let builder; beforeEach(() => { builder = new V2DutchOrderBuilder_1.V2DutchOrderBuilder(1, ethers_1.constants.AddressZero); }); it("builds a valid order", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; const order = builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT.mul(90).div(100), recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(99).div(100)) .outputOverrides([OUTPUT_START_AMOUNT]) .build(); expect(order.info.cosignerData.decayStartTime).toEqual(deadline - 100); expect(order.info.outputs.length).toEqual(1); }); it("Builds a valid order with validation", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; const fillerAddress = "0x1111111111111111111111111111111111111111"; const additionalValidationContract = "0x2222222222222222222222222222222222222222"; const timestamp = Math.floor(Date.now() / 1000) + 100; const validationInfo = (0, validation_1.encodeExclusiveFillerData)(fillerAddress, timestamp, 1, additionalValidationContract); const order = builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT.mul(90).div(100), recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .validation(validationInfo) .build(); expect(order.info.cosignerData.decayStartTime).toEqual(deadline - 100); expect(order.info.outputs.length).toEqual(1); expect(order.validation).toEqual({ type: validation_1.ValidationType.ExclusiveFiller, data: { filler: fillerAddress, lastExclusiveTimestamp: timestamp, }, }); }); it("Regenerates builder from order json", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; const fillerAddress = "0x1111111111111111111111111111111111111111"; const additionalValidationContract = "0x2222222222222222222222222222222222222222"; const timestamp = Math.floor(Date.now() / 1000) + 100; const validationInfo = (0, validation_1.encodeExclusiveFillerData)(fillerAddress, timestamp, 1, additionalValidationContract); const order = builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT.mul(90).div(100), recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .validation(validationInfo) .build(); const json = order.toJSON(); const regenerated = V2DutchOrderBuilder_1.V2DutchOrderBuilder.fromOrder(order_1.CosignedV2DutchOrder.fromJSON(json, 1)).build(); expect(regenerated.toJSON()).toMatchObject(order.toJSON()); }); it("Regenerates builder allows modification", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; const fillerAddress = "0x1111111111111111111111111111111111111111"; const additionalValidationContract = "0x2222222222222222222222222222222222222222"; const timestamp = Math.floor(Date.now() / 1000) + 100; const validationInfo = (0, validation_1.encodeExclusiveFillerData)(fillerAddress, timestamp, 1, additionalValidationContract); const order = builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT.mul(90).div(100), recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .validation(validationInfo) .build(); const regenerated = V2DutchOrderBuilder_1.V2DutchOrderBuilder.fromOrder(order) .decayStartTime(order.info.cosignerData.decayStartTime + 1) .build(); expect(regenerated.info.cosignerData.decayStartTime).toEqual(order.info.cosignerData.decayStartTime + 1); }); it("builds a valid order with multiple outputs", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; const order = builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT.mul(90).div(100), recipient: ethers_1.constants.AddressZero, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT.mul(10).div(100), endAmount: OUTPUT_START_AMOUNT.mul(9).div(100), recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .build(); expect(order.info.cosignerData.decayStartTime).toEqual(deadline - 100); expect(order.info.outputs.length).toEqual(2); }); it("cosigner not set", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; expect(() => builder .cosignature("0x") .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT, recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .build()).toThrow("Invariant failed: cosigner not set"); }); it("swapper not set", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; expect(() => builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline - 100) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT, recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .build()).toThrow("Invariant failed: swapper not set"); }); it("neither deadline or decayEndTime is set", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; expect(() => builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .decayStartTime(deadline - 100) .nonce(ethers_1.BigNumber.from(100)) .swapper(ethers_1.constants.AddressZero) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT, recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .build()).toThrow("Invariant failed: deadline not set"); }); it("nonce not set", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; expect(() => builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT, recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .build()).toThrow("Invariant failed: nonce not set"); }); it("inputOverride larger than input", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; expect(() => builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .nonce(ethers_1.BigNumber.from(1)) .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT, recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(102).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .build()).toThrow("Invariant failed: inputOverride not set or larger than original input"); }); it("outputOverride smaller than output", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; expect(() => builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .nonce(ethers_1.BigNumber.from(1)) .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT, recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(98).div(100)]) .build()).toThrow("Invariant failed: outputOverride must be larger than or equal to original output"); }); it("decayEndTime defaults to deadline", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; const order = builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .deadline(deadline) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT.mul(90).div(100), recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .build(); expect(order.info.cosignerData.decayEndTime).toEqual(deadline); expect(order.info.outputs.length).toEqual(1); }); it("deadline defaults to decayEndTime", () => { const decayEndTime = Math.floor(Date.now() / 1000) + 1000; const order = builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .decayEndTime(decayEndTime) .decayStartTime(decayEndTime - 100) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT.mul(90).div(100), recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .build(); expect(order.info.deadline).toEqual(decayEndTime); expect(order.info.outputs.length).toEqual(1); }); it("startAmount <= endAmount", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; expect(() => builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT.add(100), recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .build()).toThrow("startAmount must be greater than endAmount: 100"); }); it("deadline already passed", () => { const deadline = 1234; expect(() => builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT, recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(89).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .build()).toThrow("Invariant failed: Deadline must be in the future: 1234"); }); it("Start time after deadline", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; expect(() => builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .deadline(deadline) .decayEndTime(deadline) .decayStartTime(deadline + 100) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT, recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .build()).toThrow(`Invariant failed: decayStartTime must be before or same as deadline: ${deadline + 100}`); }); it("decayEndTime after deadline", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; expect(() => builder .cosigner(ethers_1.constants.AddressZero) .cosignature("0x") .deadline(deadline) .decayEndTime(deadline + 100) .decayStartTime(deadline - 100) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT, recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .outputOverrides([OUTPUT_START_AMOUNT.mul(102).div(100)]) .build()).toThrow(`Invariant failed: decayEndTime must be before or same as deadline: ${deadline + 100}`); }); it("Does not throw before an order has not been finished building", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; expect(() => builder.deadline(deadline).decayStartTime(deadline + 1)).not.toThrowError(); }); it("Unknown chainId", () => { const chainId = 99999999; expect(() => new V2DutchOrderBuilder_1.V2DutchOrderBuilder(chainId)).toThrow(`Missing configuration for reactor: ${chainId}`); }); describe("partial order tests", () => { it("builds an unsigned partial order with default cosignerData values", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; const order = builder .cosigner(ethers_1.constants.AddressZero) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .deadline(deadline) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT.mul(90).div(100), recipient: ethers_1.constants.AddressZero, }) .buildPartial(); expect(order.info.outputs.length).toEqual(1); }); it("builds an unsigned partial order with incomplete cosignerData values", () => { const deadline = Math.floor(Date.now() / 1000) + 1000; const order = builder .cosigner(ethers_1.constants.AddressZero) .swapper(ethers_1.constants.AddressZero) .nonce(ethers_1.BigNumber.from(100)) .deadline(deadline) .decayStartTime(1) .input({ token: INPUT_TOKEN, startAmount: INPUT_START_AMOUNT, endAmount: INPUT_START_AMOUNT, }) .output({ token: OUTPUT_TOKEN, startAmount: OUTPUT_START_AMOUNT, endAmount: OUTPUT_START_AMOUNT.mul(90).div(100), recipient: ethers_1.constants.AddressZero, }) .inputOverride(INPUT_START_AMOUNT.mul(98).div(100)) .buildPartial(); expect(order.info.outputs.length).toEqual(1); }); }); }); //# sourceMappingURL=V2DutchOrderBuilder.test.js.map