From 71071b2a98d48fae87e0c0e54a18fa4cf104a86a Mon Sep 17 00:00:00 2001 From: huyao Date: Tue, 10 Oct 2023 14:46:07 +0800 Subject: [PATCH] sdk-refactor refactor wrap.ts code. Move duplicate code to standalone function. --- examples/interface/.eslintrc.json | 5 +- examples/interface/.gitignore | 1 + examples/interface/package.json | 2 +- .../interface/src/components/ButtonClick.tsx | 110 +++- sdk/bun.lockb | Bin 133918 -> 134301 bytes sdk/packages/instaswap-core/src/constants.ts | 28 +- sdk/packages/instaswap-core/src/tickMath.ts | 2 +- sdk/packages/instaswap-core/src/wrap.ts | 619 +++++++++--------- 8 files changed, 411 insertions(+), 356 deletions(-) diff --git a/examples/interface/.eslintrc.json b/examples/interface/.eslintrc.json index 7b49ed5..9b8544e 100644 --- a/examples/interface/.eslintrc.json +++ b/examples/interface/.eslintrc.json @@ -13,5 +13,8 @@ }, "plugins": ["react", "@typescript-eslint"], "root": true, - "rules": {} + "rules": { + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": ["off"] + } } diff --git a/examples/interface/.gitignore b/examples/interface/.gitignore index a547bf3..289e710 100644 --- a/examples/interface/.gitignore +++ b/examples/interface/.gitignore @@ -10,6 +10,7 @@ lerna-debug.log* node_modules dist dist-ssr +.vite *.local # Editor directories and files diff --git a/examples/interface/package.json b/examples/interface/package.json index 3963dee..863c0ff 100644 --- a/examples/interface/package.json +++ b/examples/interface/package.json @@ -12,7 +12,7 @@ "@starknet-react/core": "^1.0.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "@bibliothecadao/instaswap-core": "link:instaswap/packages/instaswap-core" + "@bibliothecadao/instaswap-core": "link:@bibliothecadao/instaswap-core" }, "devDependencies": { "@types/react": "^18.0.27", diff --git a/examples/interface/src/components/ButtonClick.tsx b/examples/interface/src/components/ButtonClick.tsx index 5adf71c..907ccd4 100644 --- a/examples/interface/src/components/ButtonClick.tsx +++ b/examples/interface/src/components/ButtonClick.tsx @@ -2,7 +2,7 @@ import { useAccount, useConnectors } from '@starknet-react/core' import { useCallback, useMemo, useState, useEffect } from 'react' import { Contract, uint256, CallData, RawArgs, Call, num } from 'starknet' import { Wrap } from '@bibliothecadao/instaswap-core' -import { FeeAmount } from '@bibliothecadao/instaswap-core' +import { FeeAmount,SwapDirection } from '@bibliothecadao/instaswap-core' import { Provider, constants, cairo } from "starknet" @@ -27,17 +27,22 @@ const ButtonClick = () => { const simple_swapper = useMemo(() => "0x064f7ed2dc5070133ae8ccdf85f01e82507facbe5cdde456e1418e3901dc51a0", []) const provider = new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } }); - let wrap = new Wrap( - erc1155_address, - werc20_address, - eth_address, - ekubo_position_address, - ekubo_core_address, - provider - ) + + const config = { + erc1155Address: erc1155_address, + werc20Address:werc20_address, + erc20Address:eth_address, + ekuboPositionAddress:ekubo_position_address, + ekuboCoreAddress:ekubo_core_address, + provider:provider + } + + + const wrap = new Wrap(config); + const getERC1155Balance = useCallback(async () => { if (!address) return; - let b = await Wrap.getERC1155Balance(address, 1); + const b = await Wrap.getERC1155Balance(address, 1); setBalance(b.toString()); }, [address, erc1155_address]); @@ -56,33 +61,78 @@ const ButtonClick = () => { }, [getERC1155Balance]); const handleAddLiquidity = useCallback(() => { - if (!account) return; - const realERC1155Amount = erc1155Amount; - const realERC20Amount = ethAmount * (10 **18); - account?.execute(wrap.addLiquidity(realERC1155Amount, realERC20Amount, FeeAmount.LOWEST, lowerBound, upperBound)) + + if (!account) return; + + const params = { + erc1155Amount: erc1155Amount, + erc20Amount: ethAmount * (10 **18), + fee: FeeAmount.LOWEST, + lowerPrice: lowerBound, + upperPrice:upperBound, + }; + + //add liquidity + account?.execute(wrap.addLiquidity(params)); + + // const realERC1155Amount = erc1155Amount; + // const realERC20Amount = ethAmount * (10 **18); + // account?.execute(wrap.addLiquidity(realERC1155Amount, realERC20Amount, FeeAmount.LOWEST, lowerBound, upperBound)) }, [account, lowerBound, upperBound, ethAmount, erc1155Amount]) const handleSwapFromERC1155ToERC20ByAVNU = useCallback(() => { if (!account) return; - const realERC1155Amount = erc1155AmountForSwap; - account?.execute(wrap.swapFromERC1155ToERC20ByAVNU(realERC1155Amount, 1313331313, avnu_address, account.address, FeeAmount.LOWEST, 0.99, currentPrice)) + + const params = { + erc1155AmountIn: erc1155AmountForSwap, + minERC20AmountOut: 1313331313, + aggregatorAddress: avnu_address, + userAddress: account.address, + fee: FeeAmount.LOWEST, + slippage: 0.99, + currentPrice: currentPrice, + } + + account?.execute(wrap.swapFromERC1155ToERC20ByAVNU(params)); + // + // const realERC1155Amount = erc1155AmountForSwap; + // account?.execute(wrap.swapFromERC1155ToERC20ByAVNU(realERC1155Amount, 1313331313, avnu_address, account.address, FeeAmount.LOWEST, 0.99, currentPrice)) }, [account, erc1155AmountForSwap, currentPrice, avnu_address]) const handleSwapFromERC1155ToERC20BySimpleSwap = useCallback(() => { if (!account) return; - const realERC1155Amount = erc1155AmountForSwap; - account?.execute(wrap.swapFromERC1155ToERC20BySimpleSwapper(realERC1155Amount, 1313331313, simple_swapper, account.address, FeeAmount.LOWEST, 0.99, currentPrice)) + + const params = { + amountIn: erc1155AmountForSwap, + minERC20AmountOut: 1313331313, + simpleSwapperAddress: simple_swapper, + userAddress: account.address, + fee: FeeAmount.LOWEST, + slippage: 0.99, + } + account?.execute(wrap.swapBySimple(SwapDirection.ERC1155_TO_ERC20,params)) + // const realERC1155Amount = erc1155AmountForSwap; + // account?.execute(wrap.swapFromERC1155ToERC20BySimpleSwapper(realERC1155Amount, 1313331313, simple_swapper, account.address, FeeAmount.LOWEST, 0.99, currentPrice)) }, [account, erc1155AmountForSwap, currentPrice, avnu_address]) const handleSwapFromERC20ToERC1155BySimpleSwap = useCallback(() => { if (!account) return; - debugger; - const realERC1155Amount = erc20AmountForSwap * (10 **18); - account?.execute(wrap.swapFromERC20ToERC1155BySimpleSwapper(realERC1155Amount, 1313331313, simple_swapper, account.address, FeeAmount.LOWEST, 0.99, currentPrice)) + // debugger; + const params = { + amountIn: erc20AmountForSwap * (10 **18), + minERC20AmountOut: 1313331313, + simpleSwapperAddress: simple_swapper, + userAddress: account.address, + fee: FeeAmount.LOWEST, + slippage: 0.99, + } + account?.execute(wrap.swapBySimple(SwapDirection.ERC20_TO_ERC1155,params)); + // const realERC1155Amount = erc20AmountForSwap * (10 **18); + // account?.execute(wrap.swapFromERC20ToERC1155BySimpleSwapper(realERC1155Amount, 1313331313, simple_swapper, account.address, FeeAmount.LOWEST, 0.99, currentPrice)) }, [account, erc20AmountForSwap, currentPrice, avnu_address]) const mayInitializePool = useCallback(() => { - let initialize_tick = { + const initialize_tick = { mag: 0n, sign: false } @@ -148,8 +198,20 @@ const ButtonClick = () => {
+ + {/*
*/} + {/*

Swap From ERC1155 to ERC20 By AVNU

*/} + {/*
*/} + {/*
*/} + {/* */} + {/* setERC1155AmountForSwap(parseFloat(e.target.value))} />*/} + {/*
*/} + {/*
*/} + {/* */} + {/*
*/} +
-

Swap From ERC1155 to ERC20

+

Swap From ERC1155 to ERC20 By SimpleSwapper

@@ -159,7 +221,7 @@ const ButtonClick = () => {
-

Swap From ERC20 to ERC1155

+

Swap From ERC20 to ERC1155 By SimpleSwapper

diff --git a/sdk/bun.lockb b/sdk/bun.lockb index 7f59dcfd11f8ce93660ed9184bf8181370f74d9f..e5c314a41fb8b2127eb9fe38b6decb923343c681 100755 GIT binary patch delta 27311 zcmeI5d3;S*+xO2p9C8dr2_iuRH6{`yClPYQSdOu1s4*f4iG)N6A~6r8=xV#EnyaX4 z(N;xEtE#O|bgrsa?~ZEf+;W$`-)j$~y}9q_eV^y^dH#5NK7Qv~zcpXiy4JAw+1b|K zAGBsw(DJAzb&GzB>Uq;wZ3cb$bJs1Ee0z>Gn>+QDG6#lyzNhb;QB~)^P_csBC7&KE zQtCE)@K$9K>&xqM6@?S5gB+JTGDBjY0F~j}R;+4Nc!k^*Ao(%z6C`nRDU0_n?Q)eP z{sCLIL)L(|M3zU6B3~8c0AwX(dTv^3X6mT)w9Jgj(#nJ~E|)aE3n}?8AuA%gm9^>( zrX0Mm=o=y=VN!Z(T3%#Eu2UdB$cn#+l!h|X?@X5-p0M+$jZMuQ5C4HyZX$hbYHsA{ z%+xV&lP(RH!zR*jBwwOn9hhM$s#ggOE}n zEh92x!su*QIeISqZCaHIb2C$O$I_8k;9{|(m_s_e8(ABfK50_+q{#HCFJf~kx4}*~ z6)3!p2KQ3B8W|l+{MB@~kuKwRAFWFVbCD6q19k^SPD)Kn&vm&TrxNMV&q%RQ*I+CE z6A0oQSp)VO9spvzb zl*>)ex-)%}%QYDHmiYYC%*>43JXd+RIORp`FXg{OO8UmSmL<}s=A@_Pxm*WoV@Jtw zj11w(Xt#c~R8(O`eJgr5(V}2%LyOl!(xsw1NSFG@WM+>{&CGQr!KFX*ZgIKzS2UI{ ziWc=mO8$VIzd5`fd_0LVg5z?THh948OqUNil%} zvStiHih)j0v2zX#+oz(;i7RQl0FudK{i63q8Ads6B&&xL{g+^7?OWQNqmXH zLy#D?=n6zEbsX7{Nm2AQt%->*#96K}z-PHecU$IUOiIne%U9lH$Q==BH+5y3%uVCS_!$x>6^N$w{4*o8GB| z)p}X-iHD8Om@q1Ga*nHNN2~rITQbG7(=ebt)eBuYk$IEojmud+H7+V1HXX?{F4}@F z6_8UqTWU^9&&|%fGu_pwiQq*QS7A;+ayILMLhH^5+kA_+1dJZWaeB6|H z+`e0_gpEXqOSb7|HTXWpmVzsY7g@f$<*H+lQo$aiSgr~VAeNg$>oPvS@Fn&9BVcuC zD)ExKPGZi#w1tzRMu2Je~>Oc$(fX$m6Mn2%Dl~Nudrx*X8PnwWSC-i zplv^ES!jxs2Ggger=^lUy1%u4W=}}Z%g9Q1WwBbPMUI|u2l3KyPHNuR$nojNDuq;z1)*o-vUxiWI8*)`tf+H|`$xOb*l1wv_9eEPP5mJK@~#pX4TRgqb# znW_I=jKE9n*cw)hIliW~I(Vn!}2e?v1qN zAf${!z~*V$lhPx{<+|G0eD-L|nD@}q^~9&;R+OvEc64Zn97C&0F( zl+g#f#0S~Lqg73x_Y@2lDk`OC)$w`bJT4c@T2YY6@?hOzZnMGzIw8dGEnUXtiZ}Dq zh_@}QrI}yqngU}jE-EXfJUw=Czo4rV>%a`!8%_ti@BEF-d`-ru)vX)_>t zbPm$fLX*5RgRD+?^sG>ydRAWy^}EY?b(^pxcfhNsg(Z0kuvtfaIW$o{uP=uAz2Z}y ztcF8<-cB&-Vrf%}88GQo89gi5=h*{Gkdp3%^14l(B(*^2*YT^Py10(tTb40oVZaum zO%7~;$5Fy!YKu+?_p7gTez@Ngh6nle#%ImGA9gUQg*PJ~bG)(H*#>L;Dw!0(A>-ec*AMDJQcVhhtU z>O-B-(C_tEvwBooYEjd5F>%FqTv^i)rC655x|YNAfn6Kq#W25VkPLnC7QcE;Cp5y4 ztgX@)rB!X8r!y>07lb8x=iBivJuA%Tc@buo^;Tl;OAA5bXx@IX_As~UMjDnZEqKon z5;rQX4>t696IdU_l1iAGtc#oYy^j$mCD8>N{Hhb0`aLacxm=yi@{0+{xR@n8AHv#6 zyeF6yCt&JOp!1vgz0bhKu4en*@?n%W8BXEp154KX2eb_$AZ9R4>1oWC+fk};H>#sA zHBa)6s&m!r7^$@|)MY*r`I%6xnc6hm8HBeB?`xUl z+0@A88lv~dB)b0~A|}b5(pXPxmE>93*yS1}@t)raVU|{jYN}3X?N^WJ{MLSVv!;4q zYo>WqYjr7Qt}d_Wgjm0~Q8SmT3w^L0Ckuvyv`X|mN+?xdj%ll!OG};yQDd-~@++Zq z33*pWS|<0HPV_cROm5ch4vNy#d`ap7UF`FF-7Or?K~Z;73*9C@NzKyv@qYD=E{99(*ZLqz!8o*2C^A<45ShJ{nKRG;dEHhxbJj6OxTYm?|XL?~NA z?v}0er8Y^P^{rg4S!Pl_#%Zp;Os36*(#*J^SabTfNmS!>LR-J*19*yAJStA_Yn$X* zg&xWJa%9^epJg#~0=P%`^t5(K-nB%^TyyDzwS3->VYa6=^LcKL7vI?**0wZ(&U%0K zwm}5=hbqajKJSkN#dDONRm10wPS9=qN#5}Z*7@IBR#wBLdfbUgcic`hcLZ-$CV)&q znvV2&d&8t^7N7<`?|raN7Q>s4>x=FE-a3gmj9C}c-#ZO<)!)1?!EPh1j5&H^sa7U3 zi#F3|7fj|FHRIBkbbbfFcThX0ZCR`DgGp=V)b<{SF=XsROaX5Lx__&gCetPp7OnS3 zCVC$vWGOG29fMhI$dXmgk1o2PZlbq?gv`>jn$c$%8O31qYcEWC$#RCqzrk*Yv9w3{ zylEteKJ=L_=_#904$bScOG`Nx)Q0gozl-1d9x>Li(MNar4*F7;BzLb4x=q(4@8S+t z|IJ0y`!>uTU}~z<(dv)2)eW&3J)n0Fz@+D-k@Ibsl*5OEecm99g_jDWcWq#zJN*gw zdGcT*%<20sq1(&}eoJTFrnx_ebwhidZrLGw|vhbLTzL_ z@mwZkE#Y0dIZNm)LgsSsdC3WR>r%bcRL<0W3XGwWk)fvtVKSmviB|rAS&MRyfXmg- zT!7aRGS_y`cZ52bEw{#Tt*z@`LSj4owyV$cCd}%+x2Iz(v3_ru?Q6k4b-zyN>-WAu zoRlnWTK#vJrOOcZsDQZ%93Yfp9#)$5*3)iF^5k7om6OZ1*4Lw~=e;8Let&E0wYJokVbTlyt+vm5876*8 z8kUM3V9gDz!n~dgv(^;xlpQd!m|Lq+@j(!ABD0vg$?f`5jU;dS?UuG>rH9_vVbTX{ z?YeT6$+$TILF znJ}5*R?7!qWR{U8XZ1U*b;4TPGGRfz9C6$3>Sy^ zz26RYnviNDhFF7Vne8?hGh7<;g?9jBQ3{EB^2j%(A46TA7iS39ub$Nidnotc)D(7sEKo;I)S(L_Dic zsL#zd+a@i^yC}`lpNU$Z|;%Fy5C)4w7!&{0y;q7J@hrn4xSACXdyiCJhy5cn5albDHi zd`VfFxXE^WNhuB8X~&C{j!y+*j_E+sX8`$JldY_T0wN{DOiAS!Ep; z-R4_~E|I}tHIQc40Qr=ZQu|sn){>&eMj-K53$8H2%QqgW8 zACY3%y}%0&0x9qUkWWcj9sZ#iYsqSa&jQJR&X(tq@+m2$y&vS(wFG{VR6Zib(fCC(qVRdNm-8gTkQCfQlc91C9*MJVymV|sV7n* zZ7DsBu{pBP%-G6~C@H02oE6@A*JEBZT>z|y!&G$|6KALuEv%P;ZL!OC|2DoClQI+A~`ns$5$Qu5Wd%?prH`%HJcKr3Elv_Z$=ytcA4{4dZM1xg`P2^vWe!C ztc~JnyTtXRBo*@|HSMz{LCfKg|IM?RWz!g`k&j4G?Z0q1lkC?$yh-_ZAo4$-&B*ol z;fzDt--k2Y#XO|_eK-?KScf#3Lw_I6u6IcL`*8NBLz?Uoe;>{;!rzB8jNtnFaP~iP zI5RJ>uXiXD8%w-QyQ_yYy=q3Tes)G%-99)-_bCY06$=8Ylpa)&qJw5u)cau`?VXvT z_rkJf22@#H3>#ZmQP(aED6h^aOwl!qD(W|2<#k9=ihc!FP!v!V^%2`oXdm1ymzl3>&)`{T2sQ6P>Xb{qDL+zqz=( zYNkW(LchDv@2-G~)JI@bm!RL0fNG)hm!RKL^n=CdCQH!|wsdJgwbI973-3n1y8|j# zFS;B3mZ2ZarxTW;A8gICfJ)G(VJnxT-|~P;)T@@G-wO1DwbR{JpdW05Ti(?|#M) z7SJL0qaUo`{($PKkHDrH=w}2}Z=G+T-%9j@_0>&Qq91JO%7E&pkHZ$OLcdi3H9#*~ zg?jNr7XRJrR4d@3O zuR}JVAFN->%Aw+a1V6LphK=m%T6DWG!oaoEC#(C?uD4^u39 z2>mvrA8d+F*o=O#HJbw}U!R7pd>H*64)D0hs)x~U3;Mwdbhj<&2ivhFpbGUx*w(G+ zw>7};>)W=X-!}By7Ep8apl#^)2>QY1Y40QG2g`aSz!N#eu(8|GZ+k#3(iz*)?@{!F z-K9ewML$@!gKtyk?rzuo8uTcf+}MnBk&-2t^uUxaOa z0{xx{s117C6X^FO`aKy?oAjV3(eEkrgKgH{r&83zI+gD&y7(!y+k~bK14rQ!H4GV2b+2v{f?Wv-*NQ&2>oDHbd!(J54Q9pbN7QSJb`{E z%-!z<`hARkuo^nyWAuZq`Pkh3U@K3e-$`@#JBfaupdYNZ?)C}#!FGIN?tZYXpQ7KV z=I-|?`kg|*Q|9h>3jIDqKUhQU{S5tJS)ZA^A8hPD(C;7S?)MM$`yBmX&2-4;DXO`i z$akbZ!grLe_eF~Ae0)dixA>0HO}sxcz`xd>+pl4UP6J>u&N6$O`-QlC#<3GP?XXf!AbK_%1RI9t>p5bp! zPOP+a{@Q|C>giLXzVGYJ&3h{AnKlo9H}VhHwswCU@1FT-{af-6Ep)ZiL(kRJwa=Nm z=Q-?i9{a!oI^=vm9Uoko$5cyKPNKCcE}ou8)Fok6Q_60=&GNe5&yq}_Q76L1Ltp1YSpnG2mVv1+6PyWObz~;$<&6Yj^!89 zXX{&!GnXhBTR{fm^INPZ+OH;L2YV_ze>#%g#Ju%hbT!ej1DSXPwBE(4YObDmv8sN0 zM)LotecA_yib}!b?7u`vOST?+mb=>g5FXj$Us`J)T+_6a^QQxEbhd`{U%Kw7a3k41 zxSmH=f56mXG9@U!l$CKjimE=|E>9rOZu0eqECe z$eBqRkw*~ZK^^HpceAj$JGiFVaREDy(~fH?Vfpm1<8CIrjIeZ|ryW<7@N)B4cmneD z1^>+7s(ncL^tR*VksWDRI@QOHt4>%NmbkulTn)nV#E^7U9>(CG{JGTCd&~XoIQivQ z@=3in%hMWWM(IAE%s$4YZtAv*Vm`S$CU?sA8iTs4Mo~KnO4(W<6odi!rFS6^_gD<> z0!zSBxA9naRp%B_QhxdT1^FxZ4O|2rK_|dT!L`S2{Lo!BZCI5a1cRDDes6sOJPG6% z@n)boh%}Np)hnNo%0)q85;5&TGUxz0fzBX6tvx_5AV0*{0TF~71Nmk5K5##fpQD$7 zfyAE$7r;L7Jm>;sRAdyy2cwb6K>SPm2?sZR<@%;joV6|p2Ms|82nF(&S8^|R6c`Q0 zf($SYj0c%O9CRYc1>%@_;7%YAKGE!>^o+IiW_EZFyNhT{(Hz1Qs9+_DQ zR)Gh=YVaVKLp{?$5s;@A)>C#nSVEdiy5(RBm~4T3CJJ3W$=nO{27SS8pg)jj z-`vR3;2R2^1Lwg7@E!OKOd?M%kZY4g@C9HVcpe-CF93P)WHsp@AYTQ)6TS?tfInPD zTrX9puq^R&;PPb7<3Jw$XaZ!y$AFeVR*dyvE!YaSfwsh_kZ&Lu1O|Yrpc)7UUND(F z3&}el$WuA;z|36Yb|U3@r2A#9+fLw7Fqi^&fENj$1oOza1GyX200wDOh?6x^mc%U3 z6)wx9EQ_)l<%4OU3uzmW%aHQ;h6W|mXOK1>Jgjh!&1BLbo(LzQfbcHjM6T>ZfY02) zvI<3*tE0GsxP`cfxQXm6vV+Kc^B_xuQh;{NdAJKH-k1sMkf$~nL0Hypd$Tiz)M1t- zy#e8W0@(v3u@rH)i>{IoE|EZnQZk8aO9M55Y!FgF);U?^s{pPw%qKhKu|R3G5|DMe z0;mYe+hMM7%r)5IvZmJn(q?@SF1BWRnUCel!W#xcK`l@l$O2vuL;y*Xc_>Rj#%ke+#734})*OARrwd3Z&y)U&Y(yx7|TE&;!u%LNiluNG~8}md2ch z`V$TZ(wJ1%7u*IafB`@{D0#*7DR$T~zjQ>(h^53jl5YqI2hwq|W{8ZxWVizi2BPg3 z;4|SjK+_cn7=e*iU+WRR4y*;n@_wp8p(Z3szo4`gO<#z&^29JU5 zK*~DhdJ>khTfr8v4HQ1Y*P~zucpNkbQh{jtA~*!s^KkSUNxlid;mTIC&0Th{$e)KSPF^xPXVdybMOx!=`z8`fZ^Z^;FOVg z34aNsjzK`;q^_^P*Pt#40aD*z%QmBZ*BLue8oM1hm4_4l9()Hbfb(D!kVb|A>5McK z0MfuYAe!C*q>gYPjY}R$mknb*@>d`}_7f-!=S#Gef-*io16h$IJPk|)Qs5UmEaN9} z7r}2p;+;5&za2P3A$48`zXKW8*MQTpD}>2ccy+^fDNY$cfq^7eLrP`qfn$;Wgu_7; zuq$wR$kzfcV=tE34BiE$iSLRmX({oEK0s!HSR_WqzXAangEf@};VuUv052hBhb^|VyRl|ia{p(qqfoLq|tgi9Mf z8=aBTnNCRQU`J#JkPO-bxdYJ#NPBXJqAify9PL0CForTRi~+)8(Y=ES@Y%D`l!kGK zs@G2ta1u~{W#VzZlakM(!83{u15qFP7Av=+~h!(>t7wmF;I zSDCh&l$Hrmu~E^k#m2ciR7mLkWT2X&>1W5hvGC?I5oCyoijHE0)*1B%t1+S5$WV?9 z>lzj{Z#FM|BpE0k)r#3?Y#OYZHc-P_N426t^MX>U>ROT3>u~Ukh00B=id49Eb#LX_G+<~>JOvpFgk0Nrm|8- z*u7L{Y8B!RE@gz@r)nCH4O6wMUZ-Z`#4wc@>%21W@r>>7ylvZ!_1Tz8HmY-8lkEisl!!m%TOV4&YSqoj=E#O$+pjTB6B>|FbK}O`X0@W zc{1~S+FDW=97*Y4+IVxgsu}9M)$b1V;E683uFD~Z45-skh}+5NyvA?9J7*hA%dR|# zj6SQXT}JN_Sk>%UwQ&4JYPSZbcEo4(pZ7)-lR3`He92ft<}l~we{T(Z!i1Nnr#j2(| zvb?cmq-v@1jORwGkT~b^6Q& zQ$19+(Rmaa*%gI4FSL5J$GL%hYrMAaTERJnKZBvMjHp%`pN)cTF)HR@Fz4le$LjQ& zdr#f-$F7z7vk$8S##>nwd&MY7M_7Yk>`Z4s-ZoxKrymjJ?;p*0Y%oGbGakE*o};PW zdHLbA6Ll-Uo)(!;^)kY79KnoPWN_bB#dvTu=G|o+mHf_|{_fted%)#_qXW$R=3Mx} zC^bg4igjLoIC5fxcJ0eoiZ?SP$N>MVGf7LVNv>Sut!b);F?);(Q}-F`s3z2Tnd5*F zXaBggJoOh*n-vR(f801XMuo&WFG(ytux0-@$~F)GX-(wT$n^s#;ga&v`-F>`EysGkP}mOP8#Hx5m$1 zs`~v!IEeFNv%!x)Q~c&LAAWHyU;XOF^Vtl6HMH*5)s0?DuP#Pm&f6J})&42XwaF_( zVb|ZIx>0$YY8fgofaDsX=>Ez@$*qPy)>#(o*r*sxxW^be4wViX>sG7kr7`w&V+9e8 zHqLris-|&j94-D}TpWiF{AsDYs=9jDDAcNzsk~h<>=fr0S#@>5_t@_EcD3kRYis>! z5n@~!&kA+pwdA}J!%S9|@ntz5!5~<(+j+6%<%yC1=7Uqwa+3JFzV2G;6!Y3L{JMIj^>>-lM{WCl5@2 zCNX!@lLnmy(@Jr4`FDM? zON1T|H}9ks=|+XA1J3vQ%`{KE>}ywyzImt;QqRcDV=gDvGmmgZ=li7G{Y{n3es)G? z+^~AadUC`Tl7m&LXvd<}C!X&&@#AYbc9Md!MNxfyM-F%Fb>v#gDdQZC#FdFK506F1 z(tlci&$mDRel0^JDV)2DLf=_AvhCJ;OEfz$!e~30j?E+o*Cs{#7q6-_dkNTqG zWi`bea>x;Tf*ir*aE(6j;<@E!$67|==3KdR?5sjc_ox0i^~sP^vWDXtEm=rR7Yd2{ zj-qtFsP&AcD}R`=`;)5~Vx9Mx4x0AR{-1+CdF*ORLUetj!kuiBN%f5@Q&o*pae?|q zdm=)ecdyp^E$iI2K*Zu}MRpr8`IJb=FqYn_I;-i%J9nx9q0T#78yu2Cx1Wd%ydy3lp!RMu51qE76;F|k#nomJ)` zb%nV7O^hC5i`$zRqw`hEIOlz`Bf6!Pk61L|BYMQH0+<4x*_yHSqltFNui|Nf~DPxzmmNm(umq7t}{`A>rtYj@PPX_)f@+hNDQi|Vz$ z)*{DbF|kdW8*8Uw^&1=2-0nloF(Zq~!s)6TDj&L^=GJ7an2iea~Iuu<;l$rX3&Eo{#QF^8)|{7RyL+JR}Yr{)k{T2Td_uVf%4c^`G1Qo8xzeM_Ft>_ zzn`~kj4T=dwbuTmTj|JXO37i`*}HFKv6y(*M@B&*N0kg?S0O9@A>%cKvoqP-sIzZc z2V#5QH%1q!*6M<>x`+wxyo9(#rJ#{@S3L18gUMLSdOyHt9OKaDbR^7qi*WXktoFOd zO-UiAT%WM6Iu{3Vv)F)k8hvM7>&Krv;I@uyHJy%}oyFBeqXZ*jw(8;bwlQ*MGfCyO z#W&$HGs+BI-EPU|3AAHh*If7HE92_)fa?lzqI%|m#d**0mYm=dzuZ)yuDNNewno%E zb_(a+uBA@z%De$GMzwswEjy=W@khmhWj_H&qMg_(IIk`CSv2;cGTy`Jaz1kbM&ZF?##`JmARW{k!33b;I{m``V_b~HxMSEDT>Ig8BI>2x*1Xt_Xz{l$+$$8@$f#&_S__~?>E z^MoJ6mPze@zSc61Ex-q+8fO;J#Y$a_@P*jfd7<*0o#{uLCiE`0?c`&R?_%^{$no8I zwesp!uhyEFwYR*P!@OIt#n`YAclyhr*FJp5-C#Lkayai`K2sq)r2OoLEveD=BKxA# zzSeQK>1ISPx#s4|I&c~X7NLiI&a}?F|I!C5rxP9Kyv=#jd#^P9arfITL9BmFm-Z7pNW&!TGlt^Q&BQ!22E zIGWzz+D0zzLycWaxWY8wBh3svwEF$G<`?gHgdW)!0ke%imQdlJPqkOC)~+7QXDwx2 zvip0Naa5RfePQ>vrK6L*F4wNb z%M!bcZN+)7b>Bu&^`ClRaESCcAu5h}Wggfa->w1$X!F8jVn$FAe|1@b^N{W@qBf;m4rOP?eI_jng=JTt9X-jE*`puKGI+}E?O zRYUt3SMH%_|MpISb-6soSxds4mw%sF@QyliXmfjOl+61>*3HMiUi|&(s?XiFpRtxZ zlwmi%@8jGyxax@9puKu4GxWxH5$qd8mK&OPhGK7g(SDtqp>FFotKD6*^;RrVG7aLK zHDf5GqToZ9qggn(fy6a2Fv^=W0|3PsymI71{dtk`^$eH>AKY6 zj~e$<6-$#izJ2TGx+58O;|12)^jS7)aSi|S%4?U!vQ<}}DdE9W8QG4gH&lJX$RjO9pjqk?X zctCF(X!Lr3%fcHE?2W9@(q-O@tzL)AT<1SkIP=W|5AxyfoEC1Z zvTZISY&E7dZ}x^5eO7ZcvJ^|ILMT)1Fl~PGO0ST1SI7wqk*ix{d}5jOmCl z=Z*N)uS9fy?(ui-rVaZ}D_hpibsTpCX~q?5jCJ0rua=d4D(u3N1ais&9HTjJ-5;Cp z_7}hP*-%orI1-P_F#_wcxAU6*0ndy&n)yfR7tEsOkmeYLlEL}!2bTY`dHufHrDj*Y zddL5;@x*#|YeVC>$gTJZmXq>WD152x;eVCj|4)f(F^d05r^U#O2`!wzbLn_3F>PG# W)1Pfr+eRBzK2Y_Z-tKkhs{aF6Wj4M5 delta 30639 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 f*BW)jrt8 a.address.localeCompare(b.address)); - // public deposit = async (amount: bigint) => { - // // TODO: implement - // } + Wrap.ERC1155ApproveCall = { + contractAddress: Wrap.ERC1155Contract.address, + entrypoint: "setApprovalForAll", + calldata: CallData.compile({ + operator: Wrap.WERC20Contract.address, + approved: num.toCairoBool(true) + }) + }; - // public withdraw = async (amount: bigint) => { - // // - // } - public static closestTick(tick: number): bigint { - let t = 200n; - let tick2 = BigInt(tick); - let closestTick = tick2 - (tick2 % t); - return closestTick; + Wrap.CancelERC1155ApproveCall = { + contractAddress: Wrap.ERC1155Contract.address, + entrypoint: "setApprovalForAll", + calldata: CallData.compile({ + operator: Wrap.WERC20Contract.address, + approved: num.toCairoBool(false) + }) + }; - + Decimal.set({ precision: 78 }); } - public addLiquidity(erc1155Amount: BigNumberish, erc20Amount: BigNumberish, fee: FeeAmount, lowerPrice: number, upperPrice: number): Call[] { - - // sort tokens - // TODO check length - const sortedTokens: Contract[] = [Wrap.ERC20Contract, Wrap.WERC20Contract].sort((a, b) => a.address.localeCompare(b.address)); + private static createDepositCall(contract:string,amount:BigNumberish):Call{ + return { + contractAddress: contract, + entrypoint: "deposit", + calldata: CallData.compile({ + amount: cairo.uint256(amount) + }) + } + } - const approveForAll: Call = { - contractAddress: Wrap.ERC1155Contract.address, - entrypoint: "setApprovalForAll", + private static createTransferCall(contract:string,recipient:string,amount:BigNumberish):Call{ + return { + contractAddress: contract, + entrypoint: "transfer", calldata: CallData.compile({ - operator: Wrap.WERC20Contract.address, - approved: num.toCairoBool(true) + recipient: recipient, + amount: cairo.uint256(amount) // wrap token has 18 decimals }) } + } - // wrap token - const depositToWERC20: Call = { - contractAddress: Wrap.WERC20Contract.address, - entrypoint: "deposit", + + private static createClearCall(contract:string,token:string):Call{ + return { + contractAddress: contract, + entrypoint: "clear", calldata: CallData.compile({ - amount: cairo.uint256(erc1155Amount) + token: token }) } + } - // transfer werc20 - const transferWERC20: Call = { + private static createWERC20ApproveCall(spender:string,amount:BigNumberish):Call{ + return { contractAddress: Wrap.WERC20Contract.address, - entrypoint: "transfer", + entrypoint: "approve", calldata: CallData.compile({ - recipient: Wrap.EkuboPosition.address, - amount: cairo.uint256(BigInt(erc1155Amount) * (BigInt(10) ** BigInt(18))) // wrap token has 18 decimals + spender: spender, + amount: cairo.uint256(amount) }) } - // transfer erc20 - const transferERC20: Call = { - contractAddress: Wrap.ERC20Contract.address, - entrypoint: "transfer", + } + + + + public mayInitializePool(fee: FeeAmount, initial_tick: { mag: BigNumberish, sign: boolean }): Call[] { + + const mayInitializePool: Call = { + contractAddress: Wrap.EkuboCoreContract.address, + entrypoint: "maybe_initialize_pool", calldata: CallData.compile({ - recipient: Wrap.EkuboPosition.address, - amount: cairo.uint256(BigInt(erc20Amount)) + pool_key: { + token0: Wrap.SortedTokens[0].address, + token1: Wrap.SortedTokens[1].address, + fee: Wrap.getFeeX128(fee), + tick_spacing: 200, + extension: 0, + }, + initial_tick }) } - Decimal.set({ precision: 78 }); - let lowerSqrtRatioX128 = new Decimal(lowerPrice).sqrt().mul(new Decimal(2).pow(128)).toFixed(0); - let upperSqrtRatioX128 = new Decimal(upperPrice).sqrt().mul(new Decimal(2).pow(128)).toFixed(0); + + return [mayInitializePool]; + } + + public addLiquidity(params:LiquidityParams): Call[] { + + const lowerSqrtRatioX128 = new Decimal(params.lowerPrice).sqrt().mul(new Decimal(2).pow(128)).toFixed(0); + const upperSqrtRatioX128 = new Decimal(params.upperPrice).sqrt().mul(new Decimal(2).pow(128)).toFixed(0); const lowerTick = TickMath.getTickAtSqrtRatio(BigInt(lowerSqrtRatioX128)); const upperTick = TickMath.getTickAtSqrtRatio(BigInt(upperSqrtRatioX128)); + if (lowerTick > upperTick) { throw new Error("lowerTick should be less than upperTick"); } - let absLowerTick = Math.abs(lowerTick); - let signLowerTick = lowerTick < 0 ? true : false; - let absUpperTick = Math.abs(upperTick); - let signUpperTick = upperTick < 0 ? true : false; - let tick = 50000000n; - let tmp = { - pool_key: { - token0: sortedTokens[0].address, - token1: sortedTokens[1].address, - fee: Wrap.getFeeX128(fee), - tick_spacing: 200, - extension: 0, - }, - bounds: { - lower: { - mag: tick, - sign: signLowerTick, - }, - upper: { - mag: tick, - sign: signUpperTick, - } - }, - min_liquidity: 2000, - }; - // mint_and_deposit + + /** + * create needed contract calls + * mint_and_deposit + */ const mintAndDeposit: Call = { contractAddress: Wrap.EkuboPosition.address, entrypoint: "mint_and_deposit", - calldata: CallData.compile(tmp) - } - // clear werc20 - const clearWERC20: Call = { - contractAddress: Wrap.EkuboPosition.address, - entrypoint: "clear", - calldata: CallData.compile({ - token: Wrap.WERC20Contract.address - }) - } - // clear erc20 - const clearERC20: Call = { - contractAddress: Wrap.EkuboPosition.address, - entrypoint: "clear", - calldata: CallData.compile({ - token: Wrap.ERC20Contract.address - }) - } - // cancel approval - const cancelApproval: Call = { - contractAddress: Wrap.ERC1155Contract.address, - entrypoint: "setApprovalForAll", - calldata: CallData.compile({ - operator: Wrap.WERC20Contract.address, - approved: num.toCairoBool(false) - }) + calldata: CallData.compile( + { + pool_key: { + token0: Wrap.SortedTokens[0].address, + token1: Wrap.SortedTokens[1].address, + fee: Wrap.getFeeX128(params.fee), + tick_spacing: 200, + extension: 0, + }, + bounds: { + lower: { + mag: 50000000n, + sign: lowerTick < 0, + }, + upper: { + mag: 50000000n, + sign: upperTick < 0, + } + }, + min_liquidity: 2000, + } + ) } - return [approveForAll, depositToWERC20, transferWERC20, transferERC20, mintAndDeposit, clearWERC20, clearERC20, cancelApproval]; + + return [ + Wrap.ERC1155ApproveCall, + Wrap.createDepositCall(Wrap.WERC20Contract.address,params.erc1155Amount), + Wrap.createTransferCall(Wrap.WERC20Contract.address,Wrap.EkuboPosition.address, + BigInt(params.erc1155Amount) * (BigInt(10) ** BigInt(18))), + Wrap.createTransferCall(Wrap.ERC20Contract.address,Wrap.EkuboPosition.address,BigInt(params.erc20Amount)), + mintAndDeposit, + Wrap.createClearCall(Wrap.EkuboPosition.address,Wrap.WERC20Contract.address), + Wrap.createClearCall(Wrap.EkuboPosition.address,Wrap.ERC20Contract.address), + Wrap.CancelERC1155ApproveCall + ]; } - public withdraw(id: number) { - // sort tokens - // TODO check length - const sortedTokens: Contract[] = [Wrap.ERC20Contract, Wrap.WERC20Contract].sort((a, b) => a.address.localeCompare(b.address)); + public withdraw(id: number):Call[]{ + return []; + } + public swapBySimple(direction:SwapDirection,params:SimpleSwapParams){ + if (direction == SwapDirection.ERC1155_TO_ERC20){ + return this.swapFromERC1155ToERC20BySimpleSwapper(params); + } + return this.swapFromERC20ToERC1155BySimpleSwapper(params); } - public swapFromERC1155ToERC20ByAVNU(erc1155AmountIn: BigNumberish, minERC20AmountOut: BigNumberish, aggregatorAddress: string, userAddress: string, fee: FeeAmount, slippage: number, currentPrice: number) { - // sort tokens - // TODO check length - const sortedTokens: Contract[] = [Wrap.ERC20Contract, Wrap.WERC20Contract].sort((a, b) => a.address.localeCompare(b.address)); - if (slippage < 0 || slippage > 1) { + + public swapFromERC1155ToERC20ByAVNU(params:AVNUSwapParams):Call[] { + + if (params.slippage < 0 || params.slippage > 1) { throw new Error("slippage should be between 0 and 1"); } - const werc20AmountIn = BigInt(erc1155AmountIn.toString()) * BigInt(10 ** 18); - Decimal.set({ precision: 78 }); - let sqrtRatioLimitX128 = (Wrap.ERC20Contract.address < Wrap.WERC20Contract.address) ? new Decimal(currentPrice / 300).sqrt().mul(new Decimal(2).pow(128)).toFixed(0) : new Decimal(currentPrice * 300).sqrt().mul(new Decimal(2).pow(128)).toFixed(0); - - const approveForAll: Call = { - contractAddress: Wrap.ERC1155Contract.address, - entrypoint: "setApprovalForAll", - calldata: CallData.compile({ - operator: Wrap.WERC20Contract.address, - approved: num.toCairoBool(true) - }) - } - // wrap token - const depositToWERC20: Call = { - contractAddress: Wrap.WERC20Contract.address, - entrypoint: "deposit", - calldata: CallData.compile({ - amount: cairo.uint256(erc1155AmountIn) - }) - } - // approve WERC20 - const approveWERC20: Call = { - contractAddress: Wrap.WERC20Contract.address, - entrypoint: "approve", - calldata: CallData.compile({ - spender: aggregatorAddress, - amount: cairo.uint256(werc20AmountIn) - }) - } - let tmp = { - token_from_address: Wrap.WERC20Contract.address, - token_from_amount: cairo.uint256(werc20AmountIn), - token_to_address: Wrap.ERC20Contract.address, - token_to_amount: cairo.uint256(minERC20AmountOut), // this is useless in avnu contract - token_to_min_amount: cairo.uint256(minERC20AmountOut), - beneficiary: userAddress, - integrator_fee_amount_bps: 0, - integrator_fee_recipient: 0, - routes: [ - { - token_from: Wrap.WERC20Contract.address, - token_to: Wrap.ERC20Contract.address, - exchange_address: Wrap.EkuboCoreContract.address, - percent: 100, - additional_swap_params: [ - sortedTokens[0].address, - sortedTokens[1].address, - Wrap.getFeeX128(fee), //fee for determin the pool_key - 200, // tick_spacing for determin the pool_key - 0, // extension for determin the pool_key - 363034526046013994104916607590000000000000000000001n //sqrt_ratio_limit - ], - } - ] - }; - // swap + + + const werc20AmountIn = BigInt(params.erc1155AmountIn.toString()) * BigInt(10 ** 18); + + /** + * swap + */ const multiRouteSwap: Call = { - contractAddress: aggregatorAddress, + contractAddress: params.aggregatorAddress, entrypoint: "multi_route_swap", - calldata: CallData.compile(tmp) + calldata: CallData.compile({ + token_from_address: Wrap.WERC20Contract.address, + token_from_amount: cairo.uint256(werc20AmountIn), + token_to_address: Wrap.ERC20Contract.address, + token_to_amount: cairo.uint256(params.minERC20AmountOut), // this is useless in avnu contract + token_to_min_amount: cairo.uint256(params.minERC20AmountOut), + beneficiary: params.userAddress, + integrator_fee_amount_bps: 0, + integrator_fee_recipient: 0, + routes: [ + { + token_from: Wrap.WERC20Contract.address, + token_to: Wrap.ERC20Contract.address, + exchange_address: Wrap.EkuboCoreContract.address, + percent: 100, + additional_swap_params: [ + Wrap.SortedTokens[0].address, + Wrap.SortedTokens[1].address, + Wrap.getFeeX128(params.fee), //fee for determin the pool_key + 200, // tick_spacing for determin the pool_key + 0, // extension for determin the pool_key + 363034526046013994104916607590000000000000000000001n//sqrt_ratio_limit + ], + } + ] + }) } - return [approveForAll, depositToWERC20, approveWERC20, multiRouteSwap]; + return [ + Wrap.ERC1155ApproveCall, + Wrap.createDepositCall(Wrap.WERC20Contract.address,params.erc1155AmountIn), + Wrap.createWERC20ApproveCall(params.aggregatorAddress,werc20AmountIn), + multiRouteSwap + ]; } - public swapFromERC1155ToERC20BySimpleSwapper(erc1155AmountIn: BigNumberish, minERC20AmountOut: BigNumberish, simpleSwapperAddress: string, userAddress: string, fee: FeeAmount, slippage: number, currentPrice: number) { - // sort tokens - // TODO check length - const sortedTokens: Contract[] = [Wrap.ERC20Contract, Wrap.WERC20Contract].sort((a, b) => a.address.localeCompare(b.address)); - if (slippage < 0 || slippage > 1) { + public swapFromERC1155ToERC20BySimpleSwapper(params:SimpleSwapParams):Call[] { + + if (params.slippage < 0 || params.slippage > 1) { throw new Error("slippage should be between 0 and 1"); } - const werc20AmountIn = BigInt(erc1155AmountIn.toString()) * BigInt(10 ** 18); - Decimal.set({ precision: 78 }); - let sqrtRatioLimitX128 = (Wrap.ERC20Contract.address < Wrap.WERC20Contract.address) ? new Decimal(currentPrice / 300).sqrt().mul(new Decimal(2).pow(128)).toFixed(0) : new Decimal(currentPrice * 300).sqrt().mul(new Decimal(2).pow(128)).toFixed(0); - - const approveForAll: Call = { - contractAddress: Wrap.ERC1155Contract.address, - entrypoint: "setApprovalForAll", - calldata: CallData.compile({ - operator: Wrap.WERC20Contract.address, - approved: num.toCairoBool(true) - }) - } - // wrap token - const depositToWERC20: Call = { - contractAddress: Wrap.WERC20Contract.address, - entrypoint: "deposit", - calldata: CallData.compile({ - amount: cairo.uint256(erc1155AmountIn) - }) - } - // transfer werc20 - const transferWERC20: Call = { - contractAddress: Wrap.WERC20Contract.address, - entrypoint: "transfer", - calldata: CallData.compile({ - recipient: simpleSwapperAddress, - amount: cairo.uint256(BigInt(erc1155AmountIn) * (BigInt(10 ** 18))) // wrap token has 18 decimals - }) - } - let isToken1 = !(Wrap.ERC20Contract.address > Wrap.WERC20Contract.address) ? true : false; - let sqrt_ratio_limit = !(Wrap.ERC20Contract.address > Wrap.WERC20Contract.address) ? MAX_SQRT_RATIO : MIN_SQRT_RATIO; - let tmp = { - pool_key: { - token0: sortedTokens[0].address, - token1: sortedTokens[1].address, - fee: Wrap.getFeeX128(fee), - tick_spacing: 200, - extension: 0, - }, - swap_params: { - amount: { - mag: werc20AmountIn, - sign: false - }, - is_token1: isToken1, - sqrt_ratio_limit: cairo.uint256(sqrt_ratio_limit), - skip_ahead: 4294967295, - }, - recipient: userAddress, - calculated_amount_threshold: 0, - }; + + const werc20AmountIn = BigInt(params.amountIn.toString()) * BigInt(10 ** 18); + + + const sqrt_ratio_limit = !(Wrap.ERC20Contract.address > Wrap.WERC20Contract.address) ? MAX_SQRT_RATIO : MIN_SQRT_RATIO; + // swap const simpleSwap: Call = { - contractAddress: simpleSwapperAddress, + contractAddress: params.simpleSwapperAddress, entrypoint: "swap", - calldata: CallData.compile(tmp) - } - const clearToken0: Call = { - contractAddress: simpleSwapperAddress, - entrypoint: "clear", calldata: CallData.compile({ - token: sortedTokens[0].address - }) - } - const clearToken1: Call = { - contractAddress: simpleSwapperAddress, - entrypoint: "clear", - calldata: CallData.compile({ - token: sortedTokens[1].address + pool_key: { + token0: Wrap.SortedTokens[0].address, + token1: Wrap.SortedTokens[1].address, + fee: Wrap.getFeeX128(params.fee), + tick_spacing: 200, + extension: 0, + }, + swap_params: { + amount: { + mag: werc20AmountIn, + sign: false + }, + is_token1: !(Wrap.ERC20Contract.address > Wrap.WERC20Contract.address), + sqrt_ratio_limit: cairo.uint256(sqrt_ratio_limit), + skip_ahead: 4294967295, + }, + recipient: params.userAddress, + calculated_amount_threshold: 0, }) } - return [approveForAll, depositToWERC20, transferWERC20, simpleSwap, clearToken0, clearToken1]; + + return [ + Wrap.ERC1155ApproveCall, + Wrap.createDepositCall(Wrap.WERC20Contract.address,params.amountIn), + Wrap.createTransferCall(Wrap.WERC20Contract.address,params.simpleSwapperAddress, + BigInt(params.amountIn) * (BigInt(10 ** 18))), + simpleSwap, + Wrap.createClearCall(params.simpleSwapperAddress,Wrap.SortedTokens[0].address), + Wrap.createClearCall(params.simpleSwapperAddress,Wrap.SortedTokens[1].address), + ]; } - public swapFromERC20ToERC1155BySimpleSwapper(erc20AmountIn: BigNumberish, minERC1155AmountOut: BigNumberish, simpleSwapperAddress: string, userAddress: string, fee: FeeAmount, slippage: number, currentPrice: number) { - // sort tokens - // TODO check length - const sortedTokens: Contract[] = [Wrap.ERC20Contract, Wrap.WERC20Contract].sort((a, b) => a.address.localeCompare(b.address)); - if (slippage < 0 || slippage > 1) { + public swapFromERC20ToERC1155BySimpleSwapper(params:SimpleSwapParams):Call[] { + if (params.slippage < 0 || params.slippage > 1) { throw new Error("slippage should be between 0 and 1"); } - - // transfer werc20 - const transferERC20: Call = { - contractAddress: Wrap.ERC20Contract.address, - entrypoint: "transfer", - calldata: CallData.compile({ - recipient: simpleSwapperAddress, - amount: cairo.uint256(erc20AmountIn) - }) - } - let isToken1 = (Wrap.ERC20Contract.address > Wrap.WERC20Contract.address) ? true : false; - let sqrt_ratio_limit = (Wrap.ERC20Contract.address > Wrap.WERC20Contract.address) ? MAX_SQRT_RATIO : MIN_SQRT_RATIO; - let tmp = { - pool_key: { - token0: sortedTokens[0].address, - token1: sortedTokens[1].address, - fee: Wrap.getFeeX128(fee), - tick_spacing: 200, - extension: 0, - }, - swap_params: { - amount: { - mag: erc20AmountIn, - sign: false - }, - is_token1: isToken1, - sqrt_ratio_limit: cairo.uint256(sqrt_ratio_limit), - skip_ahead: 4294967295, - }, - recipient: userAddress, - calculated_amount_threshold: 0, - }; + + // let isToken1 = (Wrap.ERC20Contract.address > Wrap.WERC20Contract.address); + const sqrt_ratio_limit = (Wrap.ERC20Contract.address > Wrap.WERC20Contract.address) ? MAX_SQRT_RATIO : MIN_SQRT_RATIO; // swap const simpleSwap: Call = { - contractAddress: simpleSwapperAddress, + contractAddress: params.simpleSwapperAddress, entrypoint: "swap", - calldata: CallData.compile(tmp) - } - const clearToken0: Call = { - contractAddress: simpleSwapperAddress, - entrypoint: "clear", - calldata: CallData.compile({ - token: sortedTokens[0].address - }) - } - const clearToken1: Call = { - contractAddress: simpleSwapperAddress, - entrypoint: "clear", - calldata: CallData.compile({ - token: sortedTokens[1].address - }) - } - return [transferERC20, simpleSwap, clearToken0, clearToken1]; - } - - public mayInitializePool(fee: FeeAmount, initial_tick: { mag: BigNumberish, sign: boolean }): Call[] { - // sort tokens - // TODO check length - const sortedTokens: Contract[] = [Wrap.ERC20Contract, Wrap.WERC20Contract].sort((a, b) => a.address.localeCompare(b.address)); - - const mayInitializePool: Call = { - contractAddress: Wrap.EkuboCoreContract.address, - entrypoint: "maybe_initialize_pool", calldata: CallData.compile({ pool_key: { - token0: sortedTokens[0].address, - token1: sortedTokens[1].address, - fee: Wrap.getFeeX128(fee), + token0: Wrap.SortedTokens[0].address, + token1: Wrap.SortedTokens[1].address, + fee: Wrap.getFeeX128(params.fee), tick_spacing: 200, extension: 0, }, - initial_tick + swap_params: { + amount: { + mag: params.amountIn, + sign: false + }, + is_token1: Wrap.ERC20Contract.address > Wrap.WERC20Contract.address, + sqrt_ratio_limit: cairo.uint256(sqrt_ratio_limit), + skip_ahead: 4294967295, + }, + recipient: params.userAddress, + calculated_amount_threshold: 0, }) - } - return [mayInitializePool]; + }; + + + return [ + Wrap.createTransferCall(Wrap.ERC20Contract.address,params.simpleSwapperAddress,params.amountIn), + simpleSwap, + Wrap.createClearCall(params.simpleSwapperAddress,Wrap.SortedTokens[0].address), + Wrap.createClearCall(params.simpleSwapperAddress,Wrap.SortedTokens[1].address), + ]; } + + public static getFeeX128(fee: FeeAmount): bigint { - let feeX128 = BigInt(fee) * (2n ** 128n) / (10n ** 6n); - return feeX128; + return BigInt(fee) * (2n ** 128n) / (10n ** 6n); } public static getERC1155Balance = async (address: string, tokenId: BigNumberish): Promise => { const tokenIdCairo = cairo.uint256(tokenId); - const balance = await Wrap.ERC1155Contract.balance_of(address, tokenIdCairo); - return balance + return await Wrap.ERC1155Contract.balance_of(address, tokenIdCairo) } + public static closestTick(tick: number): bigint { + let t = 200n; + let tick2 = BigInt(tick); + return tick2 - (tick2 % t); + } + + + }