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 7f59dcf..e5c314a 100755 Binary files a/sdk/bun.lockb and b/sdk/bun.lockb differ diff --git a/sdk/packages/instaswap-core/src/constants.ts b/sdk/packages/instaswap-core/src/constants.ts index 614f7ec..4617717 100644 --- a/sdk/packages/instaswap-core/src/constants.ts +++ b/sdk/packages/instaswap-core/src/constants.ts @@ -1,3 +1,5 @@ +export const MAX_SQRT_RATIO = 6277100250585753475930931601400621808602321654880405518632n; +export const MIN_SQRT_RATIO = 18446748437148339061n; /** * The default factory enabled fee amounts, denominated in hundredths of bips. @@ -7,14 +9,26 @@ export enum FeeAmount { LOW = 500, MEDIUM = 3000, HIGH = 10000 - } - - /** - * The default factory tick spacings by fee amount. - */ - export const TICK_SPACINGS: { [amount in FeeAmount]: number } = { +} + +/** +* The default factory tick spacings by fee amount. +*/ +export const TICK_SPACINGS: { [amount in FeeAmount]: number } = { [FeeAmount.LOWEST]: 200, [FeeAmount.LOW]: 1000, [FeeAmount.MEDIUM]: 5096, [FeeAmount.HIGH]: 10000 - } \ No newline at end of file +} + +export enum SwapType { + AVNU = 'AVNU', + SIMPLE_SWAPPER = 'SIMPLE_SWAPPER' +} + +export enum SwapDirection { + ERC1155_TO_ERC20, + ERC20_TO_ERC1155, +} + + diff --git a/sdk/packages/instaswap-core/src/tickMath.ts b/sdk/packages/instaswap-core/src/tickMath.ts index 003b292..4e6afaa 100644 --- a/sdk/packages/instaswap-core/src/tickMath.ts +++ b/sdk/packages/instaswap-core/src/tickMath.ts @@ -1,5 +1,5 @@ import { Decimal } from 'decimal.js-light'; -import JSBI from 'jsbi'; +// import JSBI from 'jsbi'; export abstract class TickMath { diff --git a/sdk/packages/instaswap-core/src/wrap.ts b/sdk/packages/instaswap-core/src/wrap.ts index bb98562..8680b72 100644 --- a/sdk/packages/instaswap-core/src/wrap.ts +++ b/sdk/packages/instaswap-core/src/wrap.ts @@ -1,417 +1,392 @@ -import { Contract, uint256, CallData, RawArgs, Call, num, cairo, BigNumberish, Provider } from 'starknet' +import {BigNumberish, cairo, Call, CallData, constants, Contract, num, Provider} from 'starknet' import ERC1155 from "./abi/erc1155-abi.json"; import WERC20 from "./abi/werc20-abi.json"; import ERC20 from "./abi/erc20-abi.json"; import EkuboPosition from "./abi/ekubo-position-abi.json"; import EkuboCore from "./abi/ekubo-core-abi.json"; -import { FeeAmount } from './constants'; -import { TickMath } from './tickMath'; -import { Decimal } from 'decimal.js-light'; +import {FeeAmount, MAX_SQRT_RATIO, MIN_SQRT_RATIO, SwapDirection} from './constants'; +import {TickMath} from './tickMath'; +import {Decimal} from 'decimal.js-light'; + + +type Config = { + erc1155Address: string; + werc20Address:string; + erc20Address:string; + ekuboPositionAddress:string; + ekuboCoreAddress:string; + provider?:Provider; +}; + + +type LiquidityParams = { + erc1155Amount: BigNumberish; + erc20Amount: BigNumberish; + fee: FeeAmount; + lowerPrice: number; + upperPrice: number; +} + + +type AVNUSwapParams = SwapParams & { + erc1155AmountIn: BigNumberish; + aggregatorAddress: string; +} + +type SimpleSwapParams = SwapParams & { + simpleSwapperAddress: string; + amountIn: BigNumberish; +} + + +type SwapParams = { + minERC20AmountOut: BigNumberish; + userAddress: string; + fee: FeeAmount; + slippage: number; +} + -const MAX_SQRT_RATIO = 6277100250585753475930931601400621808602321654880405518632n; -const MIN_SQRT_RATIO = 18446748437148339061n; export class Wrap { + public static ERC1155Contract: Contract; public static WERC20Contract: Contract; public static ERC20Contract: Contract; public static EkuboPosition: Contract; public static EkuboCoreContract: Contract; + public static SortedTokens:Contract[]; + public static ERC1155ApproveCall:Call; + public static CancelERC1155ApproveCall:Call; - - constructor(ERC1155Address: string, WERC20Address: string, ERC20Address: string, EkuboPositionAddress: string, EkuboCoreAddress: string, provider: Provider) { - Wrap.ERC1155Contract = new Contract(ERC1155, ERC1155Address, provider); - Wrap.WERC20Contract = new Contract(WERC20, WERC20Address, provider); - Wrap.ERC20Contract = new Contract(ERC20, ERC20Address, provider); - Wrap.EkuboPosition = new Contract(EkuboPosition, EkuboPositionAddress, provider); - Wrap.EkuboCoreContract = new Contract(EkuboCore, EkuboCoreAddress, provider); - } + constructor(config:Config) { + //default provider + const provider = config.provider ? config.provider : new Provider({ sequencer: { network: constants.NetworkName.SN_GOERLI } }); + Wrap.ERC1155Contract = new Contract(ERC1155, config.erc1155Address, provider); + Wrap.WERC20Contract = new Contract(WERC20, config.werc20Address, provider); + Wrap.ERC20Contract = new Contract(ERC20, config.erc20Address, provider); + Wrap.EkuboPosition = new Contract(EkuboPosition, config.ekuboPositionAddress, provider); + Wrap.EkuboCoreContract = new Contract(EkuboCore, config.ekuboCoreAddress, provider); + Wrap.SortedTokens = [Wrap.ERC20Contract, Wrap.WERC20Contract].sort((a, b) => 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); + } + + + }