Skip to content

Commit efe2d0f

Browse files
authored
Option to use minimum amounts from swap as position minAmounts (Uniswap#19)
* Use minimum amounts from swap as a potential legitimate position
1 parent 9bba925 commit efe2d0f

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

src/approveAndCall.ts

+20-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Position,
1010
toHex,
1111
} from '@uniswap/v3-sdk'
12+
import JSBI from 'jsbi'
1213

1314
// condensed version of v3-sdk AddLiquidityOptions containing only necessary swap + add attributes
1415
export type CondensedAddLiquidityOptions = Omit<MintSpecificOptions, 'createPool'> | IncreaseSpecificOptions
@@ -60,13 +61,30 @@ export abstract class ApproveAndCall {
6061
return ApproveAndCall.INTERFACE.encodeFunctionData('callPositionManager', [encodedMulticall])
6162
}
6263
}
63-
64+
/**
65+
* Encode adding liquidity to a position in the nft manager contract
66+
* @param position Forcasted position with expected amount out from swap
67+
* @param minimalPosition Forcasted position with custom minimal token amounts
68+
* @param addLiquidityOptions Options for adding liquidity
69+
* @param slippageTolerance Defines maximum slippage
70+
*/
6471
public static encodeAddLiquidity(
6572
position: Position,
73+
minimalPosition: Position,
6674
addLiquidityOptions: CondensedAddLiquidityOptions,
6775
slippageTolerance: Percent
6876
): string {
69-
const { amount0: amount0Min, amount1: amount1Min } = position.mintAmountsWithSlippage(slippageTolerance)
77+
let { amount0: amount0Min, amount1: amount1Min } = position.mintAmountsWithSlippage(slippageTolerance)
78+
79+
// position.mintAmountsWithSlippage() can create amounts not dependenable in scenarios
80+
// such as range orders. Allow the option to provide a position with custom minimum amounts
81+
// for these scenarios
82+
if (JSBI.lessThan(minimalPosition.amount0.quotient, amount0Min)) {
83+
amount0Min = minimalPosition.amount0.quotient
84+
}
85+
if (JSBI.lessThan(minimalPosition.amount1.quotient, amount1Min)) {
86+
amount1Min = minimalPosition.amount1.quotient
87+
}
7088

7189
if (isMint(addLiquidityOptions)) {
7290
return ApproveAndCall.INTERFACE.encodeFunctionData('mint', [

src/swapRouter.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ export abstract class SwapRouter {
392392
sampleTrade,
393393
totalAmountIn: totalAmountSwapped,
394394
quoteAmountOut,
395+
minimumAmountOut,
395396
} = SwapRouter.encodeSwaps(trades, options, true)
396397

397398
// encode output token permit if necessary
@@ -429,8 +430,21 @@ export abstract class SwapRouter {
429430
if (tokenOutApprovalType !== ApprovalTypes.NOT_REQUIRED)
430431
calldatas.push(ApproveAndCall.encodeApprove(tokenOut, tokenOutApprovalType))
431432

433+
// represents a position with token amounts resulting from a swap with maximum slippage
434+
// hence the minimal amount out possible.
435+
const minimalPosition = Position.fromAmounts({
436+
pool: position.pool,
437+
tickLower: position.tickLower,
438+
tickUpper: position.tickUpper,
439+
amount0: zeroForOne ? position.amount0.quotient.toString() : minimumAmountOut.quotient.toString(),
440+
amount1: zeroForOne ? minimumAmountOut.quotient.toString() : position.amount1.quotient.toString(),
441+
useFullPrecision: false,
442+
})
443+
432444
// encode NFTManager add liquidity
433-
calldatas.push(ApproveAndCall.encodeAddLiquidity(position, addLiquidityOptions, options.slippageTolerance))
445+
calldatas.push(
446+
ApproveAndCall.encodeAddLiquidity(position, minimalPosition, addLiquidityOptions, options.slippageTolerance)
447+
)
434448

435449
// sweep remaining tokens
436450
inputIsNative

0 commit comments

Comments
 (0)