import {uint32max, uint64max} from "@/misc.js"; import {decodeIEE754, encodeIEE754} from "@/blockchain/common.js"; export const MAX_FRACTION = 65535; export const NO_CHAIN = uint64max; export const NO_OCO = uint64max; export const DISTANT_PAST = 0 export const DISTANT_FUTURE = uint32max // struct SwapOrder { // address tokenIn; // address tokenOut; // Route route; // uint256 amount; // uint256 minFillAmount; // if a tranche has less than this amount available to fill, it is considered completed // bool amountIsInput; // bool outputDirectlyToOwner; // uint64 chainOrder; // use NO_CHAIN for no chaining. chainOrder index must be < than this order's index for safety (written first) and chainOrder state must be Template // Tranche[] tranches; // } // struct Route { // Exchange exchange; // uint24 fee; // } export function newOrder(tokenIn, tokenOut, exchange, fee, amount, amountIsInput, tranches, minAmount=null, outputToOwner = false, chainOrder = NO_CHAIN) { if (!tranches) tranches = [newTranche({marketOrder: true})] // todo this is just a swap: issue warning? if( minAmount === null ) minAmount = BigInt(amount) / 100n // default to min trade size of 1% return [tokenIn, tokenOut, [exchange, fee], amount, minAmount, amountIsInput, outputToOwner, chainOrder, tranches] } // struct Tranche { // uint16 fraction; // // bool startTimeIsRelative; // bool endTimeIsRelative; // bool minIsBarrier; // bool maxIsBarrier; // bool marketOrder; // if true, both min and max lines are ignored, and minIntercept is treated as a maximum slippage value (use positive numbers) // bool _reserved5; // bool _reserved6; // bool _reserved7; // uint8 _reserved8; // uint32 _reserved16; // // uint32 startTime; // use DISTANT_PAST to disable // uint32 endTime; // use DISTANT_FUTURE to disable // // // if intercept and slope are both 0 the line is disabled // float minIntercept; // if marketOrder==true, this is the (positive) max slippage amount // float minSlope; // float maxIntercept; // float maxSlope; // } export function newTranche({ fraction = MAX_FRACTION, marketOrder = false, startTimeIsRelative = false, startTime = DISTANT_PAST, endTimeIsRelative = false, endTime = DISTANT_FUTURE, minIsBarrier = false, minIntercept = 0, minSlope = 0, maxIsBarrier = false, maxIntercept = 0, maxSlope = 0, } = {}) { if( minIntercept === 0 && minSlope === 0 && maxIntercept === 0 && maxSlope === 0 ) marketOrder = true if( marketOrder ) minIntercept = encodeIEE754(minIntercept) // this is the slippage field for market orders else { minIntercept = encodeIEE754(minIntercept) minSlope = encodeIEE754(minSlope) maxIntercept = encodeIEE754(maxIntercept) maxSlope = encodeIEE754(maxSlope) } return { fraction: Math.min(MAX_FRACTION, Math.round(fraction)), marketOrder, startTimeIsRelative, startTime, endTimeIsRelative, endTime, minIsBarrier, minIntercept, minSlope, maxIsBarrier, maxIntercept, maxSlope, _reserved5: false, _reserved6: false, _reserved7: false, _reserved8: 0, _reserved16: 0, } } export const Exchange = { UniswapV2: 0, UniswapV3: 1, } export const OrderState = { Unknown: -1, Signing: 0, Underfunded: 1, Open: 2, Canceled: 3, Expired: 4, Filled: 5, } export function orderIsOpen(order) { return isOpen(order.state) } export function isOpen(state) { return state < 3 } export function parseOrderStatus(status) { let [ order, state, start, ocoGroup, filledIn, filledOut, trancheFilledIn, trancheFilledOut, ] = status order = parseOrder(order) filledIn = BigInt(filledIn) filledOut = BigInt(filledOut) trancheFilledIn = trancheFilledIn.map((f)=>BigInt(f)) trancheFilledOut = trancheFilledOut.map((f)=>BigInt(f)) return { order, state, start, ocoGroup, filledIn, filledOut, trancheFilledIn, trancheFilledOut, } } export function parseOrder(order) { let [ tokenIn, tokenOut, route, amount, minFillAmount, amountIsInput, outputDirectlyToOwner, chainOrder, tranches, ] = order route = parseRoute(route) amount = BigInt(amount) minFillAmount = BigInt(minFillAmount) tranches = tranches.map(parseTranche) return { tokenIn, tokenOut, route, amount, minFillAmount, amountIsInput, outputDirectlyToOwner, chainOrder, tranches } } export function parseRoute(route) { let [exchange, fee] = route return {exchange, fee} // todo enum? } export function parseTranche(tranche) { let [ fraction, startTimeIsRelative, endTimeIsRelative, minIsBarrier, maxIsBarrier, marketOrder, _reserved5, _reserved6, _reserved7, _reserved8, _reserved16, startTime, endTime, minIntercept, minSlope, maxIntercept, maxSlope, ] = tranche minIntercept = decodeIEE754(minIntercept) minSlope = decodeIEE754(minSlope) maxIntercept = decodeIEE754(maxIntercept) maxSlope = decodeIEE754(maxSlope) return { fraction, startTimeIsRelative, endTimeIsRelative, minIsBarrier, maxIsBarrier, marketOrder, startTime, endTime, minIntercept, minSlope, maxIntercept, maxSlope, } }