UNPKG

@paraswap/sdk

Version:
140 lines (120 loc) 3.45 kB
import { MarkOptional } from 'ts-essentials'; import { Domain, ZERO_ADDRESS } from '../../common/orders/buildOrderData'; import { DeltaAuctionOrder } from './types'; import { composeDeltaOrderPermit } from './composePermit'; import { DeltaPrice } from '../getDeltaPrice'; // Order(address owner,address beneficiary,address srcToken,address destToken,uint256 srcAmount,uint256 destAmount,uint256 deadline,uint256 nonce,bytes permit)"; const Order = [ { name: 'owner', type: 'address' }, { name: 'beneficiary', type: 'address' }, { name: 'srcToken', type: 'address' }, { name: 'destToken', type: 'address' }, { name: 'srcAmount', type: 'uint256' }, { name: 'destAmount', type: 'uint256' }, { name: 'expectedDestAmount', type: 'uint256' }, { name: 'deadline', type: 'uint256' }, { name: 'nonce', type: 'uint256' }, { name: 'partnerAndFee', type: 'uint256' }, { name: 'permit', type: 'bytes' }, ]; export type SignableDeltaOrderData = { types: { Order: typeof Order; }; domain: Domain; data: DeltaAuctionOrder; }; type SignDeltaOrderInput = { orderInput: DeltaAuctionOrder; paraswapDeltaAddress: string; chainId: number; }; function produceDeltaOrderTypedData({ orderInput, chainId, paraswapDeltaAddress, }: SignDeltaOrderInput): SignableDeltaOrderData { const typedData = { types: { Order }, domain: { name: 'Portikus', version: '2.0.0', chainId, verifyingContract: paraswapDeltaAddress, }, data: orderInput, }; return typedData; } export type DeltaOrderDataInput = MarkOptional< Omit<DeltaAuctionOrder, 'partnerAndFee'>, 'beneficiary' | 'deadline' | 'nonce' | 'permit' > & Pick<DeltaPrice, 'partnerFee'>; export type BuildDeltaOrderDataInput = DeltaOrderDataInput & { partnerAddress: string; paraswapDeltaAddress: string; takeSurplus: boolean; chainId: number; }; // default deadline = 1 hour from now (may be changed later) export const DELTA_DEFAULT_EXPIRY = 60 * 60; // seconds export function buildDeltaSignableOrderData({ owner, beneficiary = owner, srcToken, destToken, srcAmount, destAmount, expectedDestAmount, deadline = Math.floor(Date.now() / 1000 + DELTA_DEFAULT_EXPIRY), nonce = Date.now().toString(10), // random enough to not cause collisions permit = '0x', partnerAddress, partnerFee, takeSurplus, chainId, paraswapDeltaAddress, }: BuildDeltaOrderDataInput): SignableDeltaOrderData { const orderInput: DeltaAuctionOrder = { owner, beneficiary, srcToken, destToken, srcAmount, destAmount, expectedDestAmount, deadline, nonce, permit: composeDeltaOrderPermit({ permit, nonce }), partnerAndFee: producePartnerAndFee({ partnerFee, partnerAddress, takeSurplus, }), }; return produceDeltaOrderTypedData({ orderInput, chainId, paraswapDeltaAddress, }); } type ProducePartnerAndFeeInput = { partnerFee: number; partnerAddress: string; takeSurplus: boolean; }; // fee and address are encoded together function producePartnerAndFee({ partnerFee, partnerAddress, takeSurplus, }: ProducePartnerAndFeeInput): string { if (partnerAddress === ZERO_ADDRESS) return '0'; const partnerFeeBps = BigInt((partnerFee * 100).toFixed(0)); const partnerAndFee = (BigInt(partnerAddress) << BigInt(96)) | partnerFeeBps | (BigInt(takeSurplus) << BigInt(8)); return partnerAndFee.toString(10); }