# KyberSwap Onchain Limit Order [ID] *Stand Alone Version* --- General implement view ![](https://i.imgur.com/Sp1q68C.png) ## I.RouterTokenHelper ### unwrapWeth() Unwrap all ETH balance and send to the recipient #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `minAmount` | `uint256` | min amount to receive | | `recipient` | `address` | recipient address | ### transferAllTokens() Transfer all tokens from the contract to the recipient #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `token` | `address` | token address | | `minAmount` | `uint256` | min amount of token | | `recipient` | `address` | recipient address | ### refundEth() Send all ETH balance of this contract to the sender ### _transferTokens() Transfer tokenAmount amount of token from the sender to the recipient #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `token` | `address` | token address | | `sender` | `address` | sender address | | `recipient` | `address` | recipient address | | `tokenAmount` | `uint256` | token amount to send | ### factory() Get Factory contract address ### WETH() Get Wrap ETH token address ### receive() Receive native token ## II.Multicall ### multicall() #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `data` | `bytes[]` | encode data for functions call | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `results` | `bytes[]` | result of tx | ## III.Router ### `CreateOrderParams` Struct to keep parameters of create order function | Field | Type | Explanation | | -------- | -------- | -------- | | `tokenIn` | `address` | token input use to create order | | `tokenOut` | `address` | token output to get in create order | | `amountIn` | `uint256` | amount of token input | | `tickDistance` | `int24` | tick distance of pool | | `tick` | `int24` | create order at tick number | ### `ExactInputParams` Struct to keep parameters of Swap Exact Input function | Field | Type | Explanation | | -------- | -------- | -------- | | `tokenIn` | `address` | token input use to create order | | `tokenOut` | `address` | token output to get in create order | | `amount` | `uint256` | amount of token input | | `minAmountOut` | `uint256` | min amount out user want to get | | `tickDistance` | `int24` | tick distance of pool | ### `ExactOutputParams` Struct to keep parameters of Swap Exact Output function | Field | Type | Explanation | | -------- | -------- | -------- | | `tokenIn` | `address` | token input use to create order | | `tokenOut` | `address` | token output to get in create order | | `amount` | `uint256` | maximum amount of token input user can pay | | `amountOut` | `uint256` | amount of token output user want to get | | `tickDistance` | `int24` | tick distance of pool | ### createOrder() Call to Order Manager to create limit order for sender. If order use native token then help to wrap and transfer token directly to pool contract. Get pool address and order ID back after finish tx. Money flow ![](https://i.imgur.com/Ix556tj.png) #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `CreateOrderParams` | `struct` | input order params | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `pool` | `address` | pool of the order | | `orderId` | `uint256` | nftId-orderId | ### cancelOrder() Cancel user order by their order id (nft). If the order are filled then claim funds from pool. Also make that order `isCancel = true`. User can't use orders which already cancel or full-filled. User also need to sign struct DelegateMessage to get permission from OrderManager when cancel the order (prove that you are owner and Router can call to Order Manager to cancel the orderId). #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `d` | `OrderManager.DelegateMessage` | struct delegate message | | `sig` | `bytes` | data with sign by permit of user | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `amountOut` | `uint256` | Amount of tokenOut user receive | ### claim() Claim user order by their order id (nft). If the order are filled then claim funds from pool. If full-filled then `usedAmount = inputAmount` and if user call claim again then revert. User also need to sign struct DelegateMessage to get permission from OrderManager when claim the order (prove that you are owner and Router can call to Order Manager to claim the orderId). #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `d` | `OrderManager.DelegateMessage` | struct delegate message | | `sig` | `bytes` | data with sign by permit of user || #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `amountOut` | `uint256` | Amount of tokenOut user receive | ### swapExactTokenIn() Call to pool contract to swap. User will need to determined `minAmountOut` when swap. Contract will do swap by market order and calculate amountOut. If `amountOut < minAmountOut` it will revert. | Field | Type | Explanation | | -------- | -------- | -------- | | `ExactInputParams` | `struct` | input swapExactTokenIn params | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `amountOut` | `uint256` | Amount of tokenOut user receive | ### swapExactTokenOut() Call to pool contract to swap. User will need to determined `amount` which represents for maximum inputAmount they can use to swap and `amountOut` for how much they want to get. If `poolBalance < amountOut` then revert. Contract will do swap by market order and calculate exact amountShouldUse user will pay. If `amountShouldUse > amount` then revert. | Field | Type | Explanation | | -------- | -------- | -------- | | `ExactOutputParams` | `struct` | input swapExactTokenOut params | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `amountIn` | `uint256` | Amount of tokenIn user need to pay | ### orderManager() Get Order Manager contract address ## IV.Order Manager ### `CreateOrderData` Struct to keep parameters of create order function | Field | Type | Explanation | | -------- | -------- | -------- | | `owner` | `address` | owner of the order | | `pool` | `address` | pool pair address | | `amount` | `uint256` | amount of order | | `tick` | `int24` | tick number of order | | `isSell` | `bool` | order is sell or not | ### `Order` Struct to store data of an order | Field | Type | Explanation | | -------- | -------- | -------- | | `tick` | `int24` | tick number of order | | `isSell` | `bool` | order is sell or not | | `isCancel` | `bool` |order is cancel or not | | `owner` | `address` | owner of order | | `liquidityIndex` | `uint256` | liquidity Index of order. Read technical document for more information. | | `inputAmount` | `uint256` | input amount token of order | | `usedAmount` | `uint256` | amount token input which was used | | `turn` | `uint256` | turn of order. Read technical document for more information. | ### `PoolInfo` Struct to store data (pair token) of a pool | Field | Type | Explanation | | -------- | -------- | -------- | | `token0` | `address` | token 0 of pool | | `token1` | `address` | token 1 of pool | ### `DelegateMessage` Struct to store data (pair token) of a pool | Field | Type | Explanation | | -------- | -------- | -------- | | `nonce` | `uint256` | nonce of permit user, increase each time delegate message called | | `deadline` | `uint256` | deadline valid of message | | `data` | `bytes` | encode function with selector | ### createAndUnlockPoolIfNecessary() Create pool if not existed. Return pool address if already created. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `token0` | `address` | token 0 of pool | | `token1` | `address` | token 1 of pool | | `tickDistance` | `int24` | tick distance of pool | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `pool` | `uint256` | pool contract address | ### create() Create limit order. Return orderId (NFT id) of that order. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `CreateOrderData` | `struct` | input createOrderData params | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `orderId` | `uint256` | nftId-orderId | ### cancel() Cancel user limit order. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tokenId` | `uint256` | nftId-orderId | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `filledAmount` | `uint256` | amount tokenIn which was filled | | `amountTokenIn` | `uint256` | amount tokenInput of order | | `amountTokenOut` | `uint256` | amount tokenOutput of order| ### delegateCancel() Delegate call cancel for user limit order. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `d` | `DelegateMessage` | struct delegate message | | `sig` | `bytes` | data with sign by permit of user | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `orderId` | `uint256` | order id(nft) | | `filledAmount` | `uint256` | amount tokenIn which was filled | | `amountTokenIn` | `uint256` | amount tokenInput of order | | `amountTokenOut` | `uint256` | amount tokenOutput of order| ### claim() Claim user limit order if it filled. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tokenId` | `uint256` | nftId-orderId | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `filledAmount` | `uint256` | amount tokenIn which was filled | | `amountTokenOut` | `uint256` | amount tokenOutput of order| ### delegateClaim() Delegate call claim for user limit order. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `d` | `DelegateMessage` | struct delegate message | | `sig` | `bytes` | data with sign by permit of user | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `orderId` | `uint256` | order id(nft) | | `filledAmount` | `uint256` | amount tokenIn which was filled | | `amountTokenOut` | `uint256` | amount tokenOutput of order| ### calculateCancelAmounts() Canculate amount can get in cancel #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `orderId` | `uint256` | order id(nft) | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `o` | `Order` | Order struct | | `filledAmount` | `uint256` | amount tokenIn which was filled | | `amountTokenIn` | `uint256` | amount token in| ### orders() Get user order data by their order Id ( NFT id). #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tokenId` | `uint256` | nftId-orderId | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `o` | `Order` | order struct data | | `p` | `PoolInfo` | pool info struct data | ### poolsInfo() Get poll data (token0,token1) by pool address. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | | `address` | address of pool | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | | `PoolInfo` | pool info struct data | ### _getTickData() Get Tick order data in pool. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tick`| `int24` | tick number| | `p`| `IPool` | pool address| #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tickData` | `TickData` | tick struct data | ### _doTransfer() Helper transfer function. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `token` | `address` | token to send | | `amount` | `uint256` | amount of token | | `sender` | `address` | who send token | | `recipient` | `address` | who receive token | ### _fullfilled() check whether order is fullfilled #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `orderTurn` | `uint256` | turn of order | | `orderAmount` | `uint256` | amount input of order | | `orderLiquidityIndex` | `uint256` | liq index of order | | `poolTickTurn` | `uint256` | turn tick of pool | | `filledLiquidity` | `uint256` | liq was filled | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | | `bool` | check order is filled or not | ### _priceFromTick() Calculate price from tick #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tick` | `int24` | tick number | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `p`| `uint256` | price was display at P * 2^96 | ### _buyOrder() Create buy limit order. User will need to transfer token to Pool before by using Router or Third-party. Also mint new order id (NFT) for user. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `pool` | `IPool` | pool pair address | | `poolCurrentTick` | `int24` | current tick of pool | | `params` | `CreateOrderData` | | | `tickData` | `TickData` | | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tokenId`| `uint256` | | ### _sellOrder() Create sell limit order. User will need to transfer token to Pool before by using Router or Third-party. Also mint new order id (NFT) for user. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `pool` | `IPool` | pool pair address| | `poolCurrentTick` | `int24` | current tick of pool| | `params` | `CreateOrderData` | | | `tickData` | `TickData` | | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tokenId`| `uint256` | | ### _upperTickOrOddTickTurn() Check if order tick is above pool's current tick OR same tick with tick is in sell turn. Please read Technical docs for more infomation about turn. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `orderTick` | `int24` | | | `poolTick` | `int24` | | | `poolTickTurn` | `uint256` | | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | | `bool` | | ### _mintOrder() Mint an order, the order owner must have awared of receiving ERC721 token #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `params` | `CreateOrderData` | | | `tickData` | `TickData` | | | `usedAmount` | `uint256` | | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `id`| `uint256` | | ## V.Factory ### `Parameters` Struct to store factory data. | Field | Type | Explanation | | -------- | -------- | -------- | | `factory` | `address` | factory contract address| | `token0` | `address` | token0 of pool | | `token1` | `uint256` | token1 of pool | | `tickDistance` | `int24` | tickDistance of pool | | `orderManager` | `address` | order manager contract address | ### createPool() ### updateTickDistance() Only configMaster can call this function to update a tick to be enabled or not. ### setOrderManager() Only configMaster can call this function to save Order Manager contract address. Pool can get OrderManager address from here. ### updateConfigMaster() Only configMaster can call this function to update a new configMaster address. ### configMaster() Get config master address of Factory contract. In initial step, who deploy Factory contract will be it's configMaster. ## VI.Pool ### add() Add an amount of token to a tick ( tick.liquidity ), init this tick (add it to linked list - use to swap later) if it not initialized yet. If tick > currentTick (sell) pool will get amountIn by tracking token0's balance. If tick < currentTick (buy) pool will get amountIn by tracking token1's balance. Update pool's reserve0 or reserve1 base on sell or buy. Only Order Manager can call this function. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tick` | `int24` | tick to add | ### remove() Remove an amount of token0 and token1 (filled or cancelled or both base on tick and turn). For amountFill will calculate with tick's price ( 1.0001^tick ) and transfer to recipient. For amountCancel will transfer to recipient. Update tick's cancelled amount or reset tick and increase turn (by 1 if fully filled, 2 if cancelled) if no liquidity left (tick.liquidity == tick.filled + tick.cancelled) Update pool's reserve0 or reserve1 base on amountCancelled. Only Order Manager can call this function. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tick` | `int24` | tick to remove | | `amountFill` | `uint256` | amount of filled liquidity, could be 0 if order is not filled | | `amountCancel` | `uint256` | amount of cancel liquidity, could be 0 if order is fully filled | | `turn` | `uint256` | the turn of tick when order is add liquidity | | `recipient` | `address` | address of recipient | ### swap() Swap an amount of token for the other token at specific tick. Pool will loops throw ticks to fill order, start from currentTick to tick. If tick < currentTick (sell) then pool will find buyTicks ( tick < buyTicks < currentTick ) to fill until amount is 0 or passed tick. If tick > currentTick (buy) then pool will find sellTicks ( currentTick > sellTicks > tick ) orders to fill until amount is 0 or passed tick. Along the way, pool will update tick's state ( liquidity, filled, turn ) base on how tick liquidity is filled (fully filled or partial filled) Update pool's reserve0 and reserve1. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tick` | `int24` | tick to swap | | `recipient` | `address` | address of recipient | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `amountIn` | `uint256` | | | `amountOut` | `uint256` | | ### getAmountIn() Get how much amountIn user need to get exact `amoutOut`, revert if pool not have enough liquidity #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `amountOut` | `uint256` | amountOut token user want to get| | `isSell` | `bool` | if true then tokenIn = token0, else tokenIn = token1 | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `amountIn` | `uint256` | amount tokenIn user need to pay | ### getAmountOut() Get how much amountOut user need to get exact `amoutIn`, revert if pool not have enough liquidity #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `amountIn` | `uint256` | amountIn token user need to pay| | `isSell` | `bool` | if true then tokenIn = token0, else tokenIn = token1 | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `amountOut` | `uint256` | amount tokenOut user can get | ### _poolBalToken0() Get balance token 0 of pool #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | | `uint256` | token0's balance of pool | ### _poolBalToken1() Get balance token 1 of pool #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | | `uint256` | token1's balance of pool | ## VII.Pool Tick State ### _add() Add an amount of token to a tick, init tick if it's not initialized yet. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tick` | `int24` | tick number | | `amount` | `uint256` | amount to add| ### _remove() Remove amountFill, amountCancel of token0 and token1, update tick's data and return amount0Out, amount1Out. #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tick` | `int24` | tick number| | `amountFill` | `uint256` | amount was filled| | `amountCancel` | `uint256` | amount was canceled | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | `amountOut0` | `uint256` | amountOut of token0| | `amountOut1` | `uint256` | amountOut of token1 | ## VIII.Pool Storage ### `TickData` | Field | Type | Explanation | | -------- | -------- | -------- | | `liquidity` | `uint256` | total liquidity which was add at a tick number | | `filledLiquidity` | `uint256` | total liquidity which was filled at a tick | | `cancelledLiquidity` | `uint256` | total liquidity which was cancelled at a tick | | `turn` | `uint256` | turn at tick | ### factory() Get Factory contract address. ### token0() Get token0 of pool. ### token1() Get token1 of pool. ### tickDistance() Get tick distance config of pool. ### ticks() Get tick data by tick number #### Inputs | Field | Type | Explanation | | -------- | -------- | -------- | | `tick` | `int24` | | #### Outputs | Field | Type | Explanation | | -------- | -------- | -------- | | | `TickData` | | ### currentTick() Get current tick of pool. ### reserve0() Get reserve token 0 of pool. ### reserve1() Get reserve token 1 of pool. ### orderManager() Get Order Manager contract address.