goosefx-amm-sdk
Version:
SDK for the GooseFx AMM
2 lines • 4.8 kB
JavaScript
import D from"bn.js";import l from"bn.js";import d from"decimal.js-light";import R from"bn.js";var B=new R(0);function h(w,e){if(e.isZero())throw Error("divisor is zero");return w.mod(e)}function b(w,e){if(e.isZero())throw Error("rhs is zero");let t=w.div(e);return t.isZero()?[t,e]:w.sub(t.mul(e)).isZero()?[t,e]:[t.add(new R(1)),e]}function F(w,e){return w.gt(e)?w.sub(e):new R(0)}var Z=new l(100),v=new l(1e6),I=100,W=new l(3600),y=new l(1e5),z=new l(3e5),f=class{static calculateDynamicFee(e,t,n,r,i,o,s){let a=this.calculateDynamicFeeRate(t,n,r,i,o,s),[c,p]=b(e.mul(a),v);return c}static calculatePreDynamicFee(e,t,n,r,i,o,s){let a=this.calculateDynamicFeeRate(t,n,r,i,o,s);if(a.isZero())return e;let c=v.sub(a);if(c.isZero())throw new Error("Fee rate equals denominator, causing division by zero");return e.mul(v).add(c).sub(new l(1)).div(c)}static calculateDynamicFeeRate(e,t,n,r,i,o){switch(n){case"volatility":return this.calculateVolatileFee(e,t,r,i,o)}}static calculateVolatileFee(e,t,n,r,i){let{minPrice:o,maxPrice:s,twapPrice:a}=this.getPriceRange(t,e,W);if(o.eqn(0)||s.eqn(0)||a.eqn(0)||a.eqn(1))return n;let c=new d(s.toString()).ln(),p=new d(o.toString()).ln(),m=new d(a.toString()).ln(),u=c.sub(p),N=m.abs();if(N.eq(0))return n;let g=u.div(N),T=r.eqn(0)?z:r,q=new d(T.toString()).mul(g),k=new d(n.toString()).add(q),x=new l(k.lessThan(new d(y.toString()))?k.toString():y.toString());if(i){let A=F(x,Z);return n.gt(A)?n:A}else return x}static getPriceRange(e,t,n){let r=new l(1).ushln(128).subn(1),i=new l(0),o=e.observations.map((m,u)=>({observation:m,idx:u})).filter(({observation:m})=>{m.blockTimestamp.eqn(0)&&!m.cumulativeToken0PriceX32.eqn(0)&&!m.cumulativeToken1PriceX32.eqn(0)&&t.sub(m.blockTimestamp)<=n}).map(({observation:m,idx:u})=>({index:u,observation:m}));if(o.length<2)return{minPrice:new l(0),maxPrice:new l(0),twapPrice:new l(0)};o.sort((m,u)=>u.observation.blockTimestamp.cmp(m.observation.blockTimestamp));let s=o[0],a=o[o.length-1],c=F(s.observation.blockTimestamp,a.observation.blockTimestamp);if(c.eqn(0))return{minPrice:new l(0),maxPrice:new l(0),twapPrice:new l(0)};let p=s.observation.cumulativeToken0PriceX32.sub(a.observation.cumulativeToken0PriceX32).div(c);for(let m of o){let u;if(m.index==0?u=e.observations[I-1]:u=e.observations[m.index-1],u.blockTimestamp.eqn(0))continue;if(u.blockTimestamp>m.observation.blockTimestamp)break;let N=m.observation,g=F(N.blockTimestamp,u.blockTimestamp);if(g.eqn(0))continue;let T=N.cumulativeToken0PriceX32.sub(u.cumulativeToken0PriceX32).div(g);r=l.min(r,T),i=l.max(i,T)}return{minPrice:r,maxPrice:i,twapPrice:p}}static calculatePreFeeAmount(e,t,n,r,i,o,s){let a=this.calculateDynamicFeeRate(e,n,r,i,o,s);if(a.eqn(0))return t;{let c=t.mul(v),p=v.sub(a);return c.add(p).subn(1).div(p)}}};import E from"bn.js";var S=class{static swapWithoutFees(e,t,n){let r=t.mul(n),i=t.add(e),[o,s]=b(r,i),a=s.sub(t),c=n.sub(o);if(c.isZero())throw Error("destinationAmountSwapped is zero");return{sourceAmountSwapped:a,destinationAmountSwapped:c}}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 r=t.mul(e),i=n.sub(e);if(i.isZero())throw new Error("denominator is zero");let[o]=b(r,i);return{sourceAmountSwapped:o,destinationAmountSwapped:e}}static lpTokensToTradingTokens(e,t,n,r,i){let o=e.mul(n).div(t),s=e.mul(r).div(t);if(i===0)return{tokenAmount0:o,tokenAmount1:s};if(i===1)return h(e.mul(n),t).gt(B)&&o.gt(B)&&(o=o.add(new E(1))),h(e.mul(r),t).gt(B)&&s.gt(B)&&(s=s.add(new E(1))),{tokenAmount0:o,tokenAmount1:s};throw Error("roundDirection value error")}};var C=(t=>(t[t.Floor=0]="Floor",t[t.Ceiling=1]="Ceiling",t))(C||{}),_=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,r,i,o,s=!1){let a=f.calculateDynamicFee(e,new D(new Date().getTime()/1e3),i,"volatility",r,o,s),c=e.sub(a),{sourceAmountSwapped:p,destinationAmountSwapped:m}=S.swapWithoutFees(c,t,n),u=p.add(a);return{newSwapSourceAmount:t.add(u),newSwapDestinationAmount:n.sub(m),sourceAmountSwapped:u,destinationAmountSwapped:m,tradeFee:a}}static swapBaseOut(e,t,n,r,i,o,s=!1){if(e.isZero())throw new Error("destinationAmount is zero");if(e.gt(n))throw new Error("destinationAmount exceeds available destination reserve");let{sourceAmountSwapped:a,destinationAmountSwapped:c}=S.swapWithoutFeesBaseOut(e,t,n),p=f.calculatePreDynamicFee(a,new D(new Date().getTime()/1e3),i,"volatility",r,o,s);return{newSwapSourceAmount:t.add(p),newSwapDestinationAmount:n.sub(c),sourceAmountSwapped:p,destinationAmountSwapped:c,tradeFee:p.sub(a)}}};export{_ as CurveCalculator,C as RoundDirection};
//# sourceMappingURL=calculator.mjs.map