UNPKG

@deliquifiedlabs/uniswapx-sdk

Version:

SDK for the UniswapX protocol

385 lines 16 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CosignedV2DutchOrder = exports.UnsignedV2DutchOrder = void 0; const permit2_sdk_1 = require("@uniswap/permit2-sdk"); const ethers_1 = require("ethers"); const utils_1 = require("../utils"); const dutchDecay_1 = require("../utils/dutchDecay"); const validation_1 = require("./validation"); const COSIGNER_DATA_TUPLE_ABI = "tuple(uint256,uint256,address,uint256,uint256,uint256[])"; const V2_DUTCH_ORDER_TYPES = { V2DutchOrder: [ { name: "info", type: "OrderInfo" }, { name: "cosigner", type: "address" }, { name: "baseInputToken", type: "address" }, { name: "baseInputStartAmount", type: "uint256" }, { name: "baseInputEndAmount", type: "uint256" }, { name: "baseOutputs", type: "DutchOutput[]" }, ], OrderInfo: [ { name: "reactor", type: "address" }, { name: "swapper", type: "address" }, { name: "nonce", type: "uint256" }, { name: "deadline", type: "uint256" }, { name: "additionalValidationContract", type: "address" }, { name: "additionalValidationData", type: "bytes" }, ], DutchOutput: [ { name: "token", type: "address" }, { name: "startAmount", type: "uint256" }, { name: "endAmount", type: "uint256" }, { name: "recipient", type: "address" }, ], }; const V2_DUTCH_ORDER_ABI = [ "tuple(" + [ "tuple(address,address,uint256,uint256,address,bytes)", "address", "tuple(address,uint256,uint256)", "tuple(address,uint256,uint256,address)[]", COSIGNER_DATA_TUPLE_ABI, "bytes", // cosignature ].join(",") + ")", ]; class UnsignedV2DutchOrder { constructor(info, chainId, _permit2Address) { this.info = info; this.chainId = chainId; this.permit2Address = (0, utils_1.getPermit2)(chainId, _permit2Address); } static fromJSON(json, chainId, _permit2Address) { return new UnsignedV2DutchOrder(Object.assign(Object.assign({}, json), { nonce: ethers_1.BigNumber.from(json.nonce), input: { token: json.input.token, startAmount: ethers_1.BigNumber.from(json.input.startAmount), endAmount: ethers_1.BigNumber.from(json.input.endAmount), }, outputs: json.outputs.map((output) => ({ token: output.token, startAmount: ethers_1.BigNumber.from(output.startAmount), endAmount: ethers_1.BigNumber.from(output.endAmount), recipient: output.recipient, })) }), chainId, _permit2Address); } static parse(encoded, chainId, permit2) { return new UnsignedV2DutchOrder(parseSerializedOrder(encoded), chainId, permit2); } /** * @inheritdoc order */ toJSON() { return { chainId: this.chainId, permit2Address: this.permit2Address, reactor: this.info.reactor, swapper: this.info.swapper, nonce: this.info.nonce.toString(), deadline: this.info.deadline, additionalValidationContract: this.info.additionalValidationContract, additionalValidationData: this.info.additionalValidationData, input: { token: this.info.input.token, startAmount: this.info.input.startAmount.toString(), endAmount: this.info.input.endAmount.toString(), }, outputs: this.info.outputs.map((output) => ({ token: output.token, startAmount: output.startAmount.toString(), endAmount: output.endAmount.toString(), recipient: output.recipient, })), cosigner: this.info.cosigner, }; } /** * @inheritdoc order */ serialize() { const abiCoder = new ethers_1.ethers.utils.AbiCoder(); return abiCoder.encode(V2_DUTCH_ORDER_ABI, [ [ [ this.info.reactor, this.info.swapper, this.info.nonce, this.info.deadline, this.info.additionalValidationContract, this.info.additionalValidationData, ], this.info.cosigner, [ this.info.input.token, this.info.input.startAmount, this.info.input.endAmount, ], this.info.outputs.map((output) => [ output.token, output.startAmount, output.endAmount, output.recipient, ]), // use empty default for cosignerData and cosignature [0, 0, ethers_1.ethers.constants.AddressZero, 0, 0, [0]], "0x", ], ]); } /** * @inheritdoc Order */ getSigner(signature) { return ethers_1.ethers.utils.computeAddress(ethers_1.ethers.utils.recoverPublicKey(permit2_sdk_1.SignatureTransfer.hash(this.toPermit(), this.permit2Address, this.chainId, this.witness()), signature)); } /** * @inheritdoc Order */ permitData() { return permit2_sdk_1.SignatureTransfer.getPermitData(this.toPermit(), this.permit2Address, this.chainId, this.witness()); } /** * @inheritdoc Order */ hash() { return ethers_1.ethers.utils._TypedDataEncoder .from(V2_DUTCH_ORDER_TYPES) .hash(this.witnessInfo()); } /** * Returns the resolved order with the given options * @return The resolved order */ // eslint-disable-next-line @typescript-eslint/no-unused-vars resolve(_options) { // no cosigner data so no resolution possible throw new Error("Method not implemented"); } /** * Returns the parsed validation * @return The parsed validation data for the order */ get validation() { return (0, validation_1.parseValidation)(this.info); } toPermit() { return { permitted: { token: this.info.input.token, amount: this.info.input.endAmount, }, spender: this.info.reactor, nonce: this.info.nonce, deadline: this.info.deadline, }; } witnessInfo() { return { info: { reactor: this.info.reactor, swapper: this.info.swapper, nonce: this.info.nonce, deadline: this.info.deadline, additionalValidationContract: this.info.additionalValidationContract, additionalValidationData: this.info.additionalValidationData, }, cosigner: this.info.cosigner, baseInputToken: this.info.input.token, baseInputStartAmount: this.info.input.startAmount, baseInputEndAmount: this.info.input.endAmount, baseOutputs: this.info.outputs, }; } witness() { return { witness: this.witnessInfo(), witnessTypeName: "V2DutchOrder", witnessType: V2_DUTCH_ORDER_TYPES, }; } /** * Full order hash that should be signed over by the cosigner */ cosignatureHash(cosignerData) { const abiCoder = new ethers_1.ethers.utils.AbiCoder(); return ethers_1.ethers.utils.solidityKeccak256(["bytes32", "bytes"], [ this.hash(), abiCoder.encode([COSIGNER_DATA_TUPLE_ABI], [ [ cosignerData.decayStartTime, cosignerData.decayEndTime, cosignerData.exclusiveFiller, cosignerData.exclusivityOverrideBps, cosignerData.inputOverride, cosignerData.outputOverrides, ], ]), ]); } } exports.UnsignedV2DutchOrder = UnsignedV2DutchOrder; class CosignedV2DutchOrder extends UnsignedV2DutchOrder { // build a cosigned order from an unsigned order plus cosigner data static fromUnsignedOrder(order, cosignerData, cosignature) { return new CosignedV2DutchOrder(Object.assign(Object.assign({}, order.info), { cosignerData, cosignature }), order.chainId, order.permit2Address); } // build a cosigned order from json static fromJSON(json, chainId, _permit2Address) { return new CosignedV2DutchOrder(Object.assign(Object.assign({}, json), { nonce: ethers_1.BigNumber.from(json.nonce), input: { token: json.input.token, startAmount: ethers_1.BigNumber.from(json.input.startAmount), endAmount: ethers_1.BigNumber.from(json.input.endAmount), }, outputs: json.outputs.map((output) => ({ token: output.token, startAmount: ethers_1.BigNumber.from(output.startAmount), endAmount: ethers_1.BigNumber.from(output.endAmount), recipient: output.recipient, })), cosignerData: { decayStartTime: json.cosignerData.decayStartTime, decayEndTime: json.cosignerData.decayEndTime, exclusiveFiller: json.cosignerData.exclusiveFiller, exclusivityOverrideBps: ethers_1.BigNumber.from(json.cosignerData.exclusivityOverrideBps), inputOverride: ethers_1.BigNumber.from(json.cosignerData.inputOverride), outputOverrides: json.cosignerData.outputOverrides.map(ethers_1.BigNumber.from), }, cosignature: json.cosignature }), chainId, _permit2Address); } // build a cosigned order from serialized static parse(encoded, chainId, permit2) { return new CosignedV2DutchOrder(parseSerializedOrder(encoded), chainId, permit2); } constructor(info, chainId, _permit2Address) { super(info, chainId, _permit2Address); this.info = info; this.chainId = chainId; } /** * @inheritdoc order */ toJSON() { return Object.assign(Object.assign({}, super.toJSON()), { cosignerData: { decayStartTime: this.info.cosignerData.decayStartTime, decayEndTime: this.info.cosignerData.decayEndTime, exclusiveFiller: this.info.cosignerData.exclusiveFiller, exclusivityOverrideBps: this.info.cosignerData.exclusivityOverrideBps.toNumber(), inputOverride: this.info.cosignerData.inputOverride.toString(), outputOverrides: this.info.cosignerData.outputOverrides.map((o) => o.toString()), }, cosignature: this.info.cosignature }); } /** * @inheritdoc Order */ resolve(options) { return { input: { token: this.info.input.token, amount: (0, dutchDecay_1.getDecayedAmount)({ decayStartTime: this.info.cosignerData.decayStartTime, decayEndTime: this.info.cosignerData.decayEndTime, startAmount: originalIfZero(this.info.cosignerData.inputOverride, this.info.input.startAmount), endAmount: this.info.input.endAmount, }, options.timestamp), }, outputs: this.info.outputs.map((output, idx) => { return { token: output.token, amount: (0, dutchDecay_1.getDecayedAmount)({ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion decayStartTime: this.info.cosignerData.decayStartTime, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion decayEndTime: this.info.cosignerData.decayEndTime, startAmount: originalIfZero( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.info.cosignerData.outputOverrides[idx], output.startAmount), endAmount: output.endAmount, }, options.timestamp), }; }), }; } /** * @inheritdoc order */ serialize() { const abiCoder = new ethers_1.ethers.utils.AbiCoder(); return abiCoder.encode(V2_DUTCH_ORDER_ABI, [ [ [ this.info.reactor, this.info.swapper, this.info.nonce, this.info.deadline, this.info.additionalValidationContract, this.info.additionalValidationData, ], this.info.cosigner, [ this.info.input.token, this.info.input.startAmount, this.info.input.endAmount, ], this.info.outputs.map((output) => [ output.token, output.startAmount, output.endAmount, output.recipient, ]), [ this.info.cosignerData.decayStartTime, this.info.cosignerData.decayEndTime, this.info.cosignerData.exclusiveFiller, this.info.cosignerData.exclusivityOverrideBps, this.info.cosignerData.inputOverride.toString(), this.info.cosignerData.outputOverrides.map((o) => o.toString()), ], this.info.cosignature, ], ]); } /** * recovers co-signer address from cosignature and full order hash * @returns The address which co-signed the order */ recoverCosigner() { return ethers_1.ethers.utils.verifyMessage(this.cosignatureHash(this.info.cosignerData), this.info.cosignature); } } exports.CosignedV2DutchOrder = CosignedV2DutchOrder; function originalIfZero(value, original) { return value.isZero() ? original : value; } function parseSerializedOrder(serialized) { const abiCoder = new ethers_1.ethers.utils.AbiCoder(); const decoded = abiCoder.decode(V2_DUTCH_ORDER_ABI, serialized); const [[[reactor, swapper, nonce, deadline, additionalValidationContract, additionalValidationData,], cosigner, [inputToken, inputStartAmount, inputEndAmount], outputs, [decayStartTime, decayEndTime, exclusiveFiller, exclusivityOverrideBps, inputOverride, outputOverrides,], cosignature,],] = decoded; return { reactor, swapper, nonce, deadline: deadline.toNumber(), additionalValidationContract, additionalValidationData, cosigner, input: { token: inputToken, startAmount: inputStartAmount, endAmount: inputEndAmount, }, outputs: outputs.map(([token, startAmount, endAmount, recipient]) => { return { token, startAmount, endAmount, recipient, }; }), cosignerData: { decayStartTime: decayStartTime.toNumber(), decayEndTime: decayEndTime.toNumber(), exclusiveFiller, exclusivityOverrideBps, inputOverride, outputOverrides, }, cosignature, }; } //# sourceMappingURL=V2DutchOrder.js.map