UNPKG

goosefx-amm-sdk

Version:

SDK for the GooseFx AMM

2 lines 7.41 kB
"use strict";var J=Object.create;var E=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var ee=Object.getPrototypeOf,te=Object.prototype.hasOwnProperty;var ne=(u,e)=>{for(var t in e)E(u,t,{get:e[t],enumerable:!0})},V=(u,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of $(e))!te.call(u,o)&&o!==t&&E(u,o,{get:()=>e[o],enumerable:!(n=K(e,o))||n.enumerable});return u};var D=(u,e,t)=>(t=u!=null?J(ee(u)):{},V(e||!u||!u.__esModule?E(t,"default",{value:u,enumerable:!0}):t,u)),ie=u=>V(E({},"__esModule",{value:!0}),u);var me={};ne(me,{OracleBasedCurveCalculator:()=>A});module.exports=ie(me);var y=D(require("bn.js"));var w=D(require("bn.js")),v=D(require("decimal.js-light"));var C=D(require("bn.js")),k=new C.default(0);function _(u,e){if(e.isZero())throw Error("divisor is zero");return u.mod(e)}function f(u,e){if(e.isZero())throw Error("rhs is zero");let t=u.div(e);return t.isZero()?[t,e]:u.sub(t.mul(e)).isZero()?[t,e]:[t.add(new C.default(1)),e]}function b(u,e){return u.gt(e)?u.sub(e):new C.default(0)}var re=new w.default(100),d=new w.default(1e6),oe=100,ae=new w.default(3600),Y=new w.default(1e5),ce=new w.default(3e5),P=class{static calculateDynamicFee(e,t,n,o,a,r,i){let c=this.calculateDynamicFeeRate(t,n,o,a,r,i),[s,l]=f(e.mul(c),d);return s}static calculatePreDynamicFee(e,t,n,o,a,r,i){let c=this.calculateDynamicFeeRate(t,n,o,a,r,i);if(c.isZero())return e;let s=d.sub(c);if(s.isZero())throw new Error("Fee rate equals denominator, causing division by zero");return e.mul(d).add(s).sub(new w.default(1)).div(s)}static calculateDynamicFeeRate(e,t,n,o,a,r){switch(n){case"volatility":return this.calculateVolatileFee(e,t,o,a,r)}}static calculateVolatileFee(e,t,n,o,a){let{minPrice:r,maxPrice:i,twapPrice:c}=this.getPriceRange(t,e,ae);if(r.eqn(0)||i.eqn(0)||c.eqn(0)||c.eqn(1))return n;let s=new v.default(i.toString()).ln(),l=new v.default(r.toString()).ln(),m=new v.default(c.toString()).ln(),p=s.sub(l),F=m.abs();if(F.eq(0))return n;let g=p.div(F),B=o.eqn(0)?ce:o,I=new v.default(B.toString()).mul(g),N=new v.default(n.toString()).add(I),R=new w.default(N.lessThan(new v.default(Y.toString()))?N.toString():Y.toString());if(a){let O=b(R,re);return n.gt(O)?n:O}else return R}static getPriceRange(e,t,n){let o=new w.default(1).ushln(128).subn(1),a=new w.default(0),r=e.observations.map((m,p)=>({observation:m,idx:p})).filter(({observation:m})=>{m.blockTimestamp.eqn(0)&&!m.cumulativeToken0PriceX32.eqn(0)&&!m.cumulativeToken1PriceX32.eqn(0)&&t.sub(m.blockTimestamp)<=n}).map(({observation:m,idx:p})=>({index:p,observation:m}));if(r.length<2)return{minPrice:new w.default(0),maxPrice:new w.default(0),twapPrice:new w.default(0)};r.sort((m,p)=>p.observation.blockTimestamp.cmp(m.observation.blockTimestamp));let i=r[0],c=r[r.length-1],s=b(i.observation.blockTimestamp,c.observation.blockTimestamp);if(s.eqn(0))return{minPrice:new w.default(0),maxPrice:new w.default(0),twapPrice:new w.default(0)};let l=i.observation.cumulativeToken0PriceX32.sub(c.observation.cumulativeToken0PriceX32).div(s);for(let m of r){let p;if(m.index==0?p=e.observations[oe-1]:p=e.observations[m.index-1],p.blockTimestamp.eqn(0))continue;if(p.blockTimestamp>m.observation.blockTimestamp)break;let F=m.observation,g=b(F.blockTimestamp,p.blockTimestamp);if(g.eqn(0))continue;let B=F.cumulativeToken0PriceX32.sub(p.cumulativeToken0PriceX32).div(g);o=w.default.min(o,B),a=w.default.max(a,B)}return{minPrice:o,maxPrice:a,twapPrice:l}}static calculatePreFeeAmount(e,t,n,o,a,r,i){let c=this.calculateDynamicFeeRate(e,n,o,a,r,i);if(c.eqn(0))return t;{let s=t.mul(d),l=d.sub(c);return s.add(l).subn(1).div(l)}}};var Z=D(require("bn.js"));var q=D(require("bn.js"));var T=class{static validate_supply(e,t){if(e.isZero())throw Error("tokenAmount0 is zero");if(t.isZero())throw Error("tokenAmount1 is zero")}static swapBaseIn(e,t,n,o,a,r,i=!1){let c=P.calculateDynamicFee(e,new q.default(new Date().getTime()/1e3),a,"volatility",o,r,i),s=e.sub(c),{sourceAmountSwapped:l,destinationAmountSwapped:m}=S.swapWithoutFees(s,t,n),p=l.add(c);return{newSwapSourceAmount:t.add(p),newSwapDestinationAmount:n.sub(m),sourceAmountSwapped:p,destinationAmountSwapped:m,tradeFee:c}}static swapBaseOut(e,t,n,o,a,r,i=!1){if(e.isZero())throw new Error("destinationAmount is zero");if(e.gt(n))throw new Error("destinationAmount exceeds available destination reserve");let{sourceAmountSwapped:c,destinationAmountSwapped:s}=S.swapWithoutFeesBaseOut(e,t,n),l=P.calculatePreDynamicFee(c,new q.default(new Date().getTime()/1e3),a,"volatility",o,r,i);return{newSwapSourceAmount:t.add(l),newSwapDestinationAmount:n.sub(s),sourceAmountSwapped:l,destinationAmountSwapped:s,tradeFee:l.sub(c)}}};var S=class{static swapWithoutFees(e,t,n){let o=t.mul(n),a=t.add(e),[r,i]=f(o,a),c=i.sub(t),s=n.sub(r);if(s.isZero())throw Error("destinationAmountSwapped is zero");return{sourceAmountSwapped:c,destinationAmountSwapped:s}}static swapWithoutFeesBaseOut(e,t,n){if(e.isZero())throw new Error("destinationAmount is zero");if(e.gt(n))throw new Error("destinationAmount exceeds available destination reserve");let o=t.mul(e),a=n.sub(e);if(a.isZero())throw new Error("denominator is zero");let[r]=f(o,a);return{sourceAmountSwapped:r,destinationAmountSwapped:e}}static lpTokensToTradingTokens(e,t,n,o,a){let r=e.mul(n).div(t),i=e.mul(o).div(t);if(a===0)return{tokenAmount0:r,tokenAmount1:i};if(a===1)return _(e.mul(n),t).gt(k)&&r.gt(k)&&(r=r.add(new Z.default(1))),_(e.mul(o),t).gt(k)&&i.gt(k)&&(i=i.add(new Z.default(1))),{tokenAmount0:r,tokenAmount1:i};throw Error("roundDirection value error")}};var x=new y.default(Math.pow(10,9)),se=x.mul(x),A=class{static validate_supply(e,t){return T.validate_supply(e,t)}static swap(e,t,n,o,a,r,i,c=!1){let s=t?n:o,l=t?o:n,m=i.oraclePriceUpdatedAt,p=new y.default(new Date().getTime()/1e3);if(b(p,m).gtn(i.maxOraclePriceUpdateTimeDiff)||p.lt(m)||m.eqn(0)||i.oraclePriceToken0ByToken1.eqn(0))return T.swapBaseIn(e,s,l,a,r,i.volatilityFactor,c);let g=l.mul(x).div(s),B=t?se.div(i.oraclePriceToken0ByToken1):i.oraclePriceToken0ByToken1;if(A.getSpotPriceAndOraclePriceRateDifference(B,g).gtn(i.acceptablePriceDifference))return T.swapBaseIn(e,s,l,a,r,i.volatilityFactor,c);let N=A.getAmountToBeSwappedAtOraclePrice(e,s,l,B,i),R=e.sub(N);if(N.eqn(0))return T.swapBaseIn(e,s,l,a,r,i.volatilityFactor,c);let O=P.calculateDynamicFeeRate(p,r,"volatility",a,i.volatilityFactor,c),Q=O.gten(i.minTradeRateAtOraclePrice)?O:new y.default(i.minTradeRateAtOraclePrice),L=f(N.mul(Q),d)[0],j=N.sub(L),W=A.getExecutionOraclePrice(B,new y.default(i.pricePremiumForSwapAtOraclePrice)).mul(j).div(x),G=s.add(N),H=l.sub(W),z=f(R.mul(O),d)[0],U=b(R,z),X=new y.default(0);U.isZero()||(X=S.swapWithoutFees(U,G,H).destinationAmountSwapped);let M=W.add(X);return{newSwapSourceAmount:s.add(e),newSwapDestinationAmount:l.sub(M),sourceAmountSwapped:e,destinationAmountSwapped:M,tradeFee:z.add(L)}}static getAmountToBeSwappedAtOraclePrice(e,t,n,o,a){let r=t.muln(a.maxAmountSwappableAtOraclePrice).div(d),i=d.subn(a.acceptablePriceDifference),c=o.mul(i).div(d),s=c.mul(t).sub(n.mul(x)).abs(),l=o.add(c),m=s.div(l),p=m.gt(r)?r:m;return p.gt(e)?e:p}static getSpotPriceAndOraclePriceRateDifference(e,t){return t.sub(e).abs().mul(d).div(e)}static getExecutionOraclePrice(e,t){let n=e.mul(t).div(d);return e.add(n)}};0&&(module.exports={OracleBasedCurveCalculator}); //# sourceMappingURL=oracleCalculator.js.map