@bancor/carbon-sdk
Version:
The SDK is a READ-ONLY tool, intended to facilitate working with Carbon contracts. It's a convenient wrapper around our matching algorithm, allowing programs and users get a ready to use transaction data that will allow them to manage strategies and fulfi
2 lines (1 loc) • 4.9 kB
JavaScript
import{Decimal as e,tenPow as r,formatUnits as t,parseUnits as n}from"../../utils/numerics/index.js";import{Logger as i}from"../../common/logger/index.js";import{encodeOrders as o,decodeOrder as l,calculateRequiredLiquidity as a}from"../../utils/encoders/index.js";import{encodedStrategyBNToStr as u}from"../../utils/serializers/index.js";const c=new i("utils.ts");function d(t,n,i){return new e(t.toString()).times(r(n,i)).toFixed()}function g(t,n,i){return 0==+t.toString()?"0":new e(1).div(t.toString()).times(r(i,n)).toFixed()}const s=e=>{const[r,t]=o([e.order0,e.order1]);return{token0:e.token0,token1:e.token1,order0:r,order1:t}},w=e=>({id:e.id,token0:e.token0,token1:e.token1,order0:l(e.order0),order1:l(e.order1),encoded:e});async function b(e,r){c.debug("parseStrategy called",arguments);const{id:n,token0:i,token1:o,order0:l,order1:a,encoded:s}=e,w=await r.fetchDecimals(i),b=await r.fetchDecimals(o),f=d(a.lowestRate,w,b),m=d(a.marginalRate,w,b),y=d(a.highestRate,w,b),P=g(l.highestRate,b,w),h=g(l.marginalRate,b,w),p=g(l.lowestRate,b,w),v=t(l.liquidity,w),k=t(a.liquidity,b),S=n.toString(),B=u(s);return c.debug("parseStrategy info:",{id:S,token0:i,token1:o,order0:l,order1:a,decimals0:w,decimals1:b,baseToken:i,quoteToken:o,buyPriceLow:f,buyPriceMarginal:m,buyPriceHigh:y,buyBudget:k,sellPriceLow:P,sellPriceMarginal:h,sellPriceHigh:p,sellBudget:v,encoded:B}),{id:S,baseToken:i,quoteToken:o,buyPriceLow:f,buyPriceMarginal:m,buyPriceHigh:y,buyBudget:k,sellPriceLow:P,sellPriceMarginal:h,sellPriceHigh:p,sellBudget:v,encoded:B}}function f(r,t,n,i,o,l,a,u,d,g,s,w){if(c.debug("buildStrategyObject called",arguments),new e(o).isNegative()||new e(l).isNegative()||new e(a).isNegative()||new e(d).isNegative()||new e(g).isNegative()||new e(s).isNegative())throw new Error("prices cannot be negative");if(new e(o).gt(l)||new e(o).gt(a)||new e(l).gt(a)||new e(d).gt(g)||new e(d).gt(s)||new e(g).gt(s))throw new Error("low/marginal price must be lower than or equal to marginal/high price");if(new e(u).isNegative()||new e(w).isNegative())throw new Error("budgets cannot be negative");const{order0:b,order1:f}=P(n,i,o,l,a,u,d,g,s,w);return c.debug("buildStrategyObject info:",{token0:r,token1:t,order0:b,order1:f}),{token0:r,token1:t,order0:b,order1:f}}function m(e,r,t,i,o,l){c.debug("createFromBuyOrder called",arguments);const a=n(l,r),u=d(t,r,e),g=d(i,r,e),s=d(o,r,e),w={liquidity:a.toString(),lowestRate:u,highestRate:s,marginalRate:g};return c.debug("createFromBuyOrder info:",{order:w}),w}function y(e,r,t,i,o,l){c.debug("createFromSellOrder called",arguments);const a=n(l,e),u=g(o,r,e),d=g(i,r,e),s=g(t,r,e),w={liquidity:a.toString(),lowestRate:u,highestRate:s,marginalRate:d};return c.debug("createFromSellOrder info:",{order:w}),w}function P(e,r,t,n,i,o,l,a,u,d){c.debug("createOrders called",arguments);const g=y(e,r,l,a,u,d),s=m(e,r,t,n,i,o);return c.debug("createOrders info:",{order0:g,order1:s}),{order0:g,order1:s}}const h=1e6;function p(r,t){return new e(r.toString()).mul(h).div(h-t).ceil()}function v(r,t){return new e(r.toString()).mul(h-t).div(h).floor()}function k(e,r,t){return t.lte(e)?e:t.gte(r)?r:t}function S(r,t,n,i){c.debug("calculateOverlappingPrices called",arguments);const o=new e(i).div(100).plus(1),l=new e(t).div(o),a=new e(r).mul(o),u=k(new e(r),l,new e(n).div(o.sqrt())),d=k(a,new e(t),new e(n).mul(o.sqrt())),g={buyPriceHigh:l.toString(),buyPriceMarginal:u.toString(),sellPriceLow:a.toString(),sellPriceMarginal:d.toString(),buyPriceLow:r,sellPriceHigh:t,marketPrice:n};return c.debug("calculateOverlappingPrices info:",{prices:g}),g}function B(r,n,i,o,l,u,d){if(c.debug("calculateOverlappingSellBudget called",arguments),"0"===d)return"0";const{buyPriceHigh:g,sellPriceLow:s,sellPriceMarginal:w,buyPriceMarginal:b}=S(i,o,l,u);if(new e(w).gte(o))return"0";if(new e(b).lte(i))throw new Error("calculateOverlappingSellBudget called with zero buy range and non zero buy budget");const f=m(r,n,i,b,g,d),P=y(r,n,s,w,o,"0"),h=a(f,P),p=t(h,r);return c.debug("calculateOverlappingSellBudget info:",{sellBudget:p}),p}function O(r,n,i,o,l,u,d){if(c.debug("calculateOverlappingBuyBudget called",arguments),"0"===d)return"0";const{sellPriceLow:g,buyPriceHigh:s,sellPriceMarginal:w,buyPriceMarginal:b}=S(i,o,l,u);if(new e(b).lte(i))return"0";if(new e(w).gte(o))throw new Error("calculateOverlappingBuyBudget called with zero sell range and non zero sell budget");const f=m(r,n,i,b,s,"0"),P=y(r,n,g,w,o,d),h=a(P,f),p=t(h,n);return c.debug("calculateOverlappingBuyBudget info:",{buyBudget:p}),p}export{h as PPM_RESOLUTION,p as addFee,f as buildStrategyObject,O as calculateOverlappingBuyBudget,S as calculateOverlappingPrices,B as calculateOverlappingSellBudget,m as createFromBuyOrder,y as createFromSellOrder,P as createOrders,w as decodeStrategy,s as encodeStrategy,k as enforcePriceRange,g as normalizeInvertedRate,d as normalizeRate,b as parseStrategy,v as subtractFee};