@mento-protocol/mento-sdk 3.2.7-beta.0 → 3.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/dist/cache/routes.d.ts +0 -13
- package/dist/cache/routes.js +0 -14649
- package/dist/cache/tokens.d.ts +0 -68
- package/dist/cache/tokens.js +0 -488
- package/dist/core/abis/activePool.d.ts +0 -2
- package/dist/core/abis/activePool.js +0 -14
- package/dist/core/abis/addressesRegistry.d.ts +0 -2
- package/dist/core/abis/addressesRegistry.js +0 -26
- package/dist/core/abis/bipoolmanager.d.ts +0 -34
- package/dist/core/abis/bipoolmanager.js +0 -72
- package/dist/core/abis/borrowerOperations.d.ts +0 -9
- package/dist/core/abis/borrowerOperations.js +0 -89
- package/dist/core/abis/breakerbox.d.ts +0 -13
- package/dist/core/abis/breakerbox.js +0 -8
- package/dist/core/abis/broker.d.ts +0 -2
- package/dist/core/abis/broker.js +0 -9
- package/dist/core/abis/erc20.d.ts +0 -9
- package/dist/core/abis/erc20.js +0 -21
- package/dist/core/abis/fpmm.d.ts +0 -270
- package/dist/core/abis/fpmm.js +0 -49
- package/dist/core/abis/fpmmFactory.d.ts +0 -85
- package/dist/core/abis/fpmmFactory.js +0 -26
- package/dist/core/abis/hintHelpers.d.ts +0 -2
- package/dist/core/abis/hintHelpers.js +0 -14
- package/dist/core/abis/index.d.ts +0 -22
- package/dist/core/abis/index.js +0 -38
- package/dist/core/abis/liquidityStrategy.d.ts +0 -132
- package/dist/core/abis/liquidityStrategy.js +0 -10
- package/dist/core/abis/multiTroveGetter.d.ts +0 -8
- package/dist/core/abis/multiTroveGetter.js +0 -15
- package/dist/core/abis/priceFeed.d.ts +0 -7
- package/dist/core/abis/priceFeed.js +0 -16
- package/dist/core/abis/pricingmodule.d.ts +0 -2
- package/dist/core/abis/pricingmodule.js +0 -6
- package/dist/core/abis/reserve.d.ts +0 -3
- package/dist/core/abis/reserve.js +0 -18
- package/dist/core/abis/router.d.ts +0 -521
- package/dist/core/abis/router.js +0 -45
- package/dist/core/abis/sortedTroves.d.ts +0 -2
- package/dist/core/abis/sortedTroves.js +0 -15
- package/dist/core/abis/systemParams.d.ts +0 -2
- package/dist/core/abis/systemParams.js +0 -14
- package/dist/core/abis/troveManager.d.ts +0 -2
- package/dist/core/abis/troveManager.js +0 -27
- package/dist/core/abis/troveNFT.d.ts +0 -2
- package/dist/core/abis/troveNFT.js +0 -9
- package/dist/core/abis/virtualPool.d.ts +0 -50
- package/dist/core/abis/virtualPool.js +0 -11
- package/dist/core/abis/virtualPoolFactory.d.ts +0 -59
- package/dist/core/abis/virtualPoolFactory.js +0 -17
- package/dist/core/constants/addresses.d.ts +0 -18
- package/dist/core/constants/addresses.js +0 -113
- package/dist/core/constants/borrowConstants.d.ts +0 -10
- package/dist/core/constants/borrowConstants.js +0 -16
- package/dist/core/constants/borrowRegistries.d.ts +0 -7
- package/dist/core/constants/borrowRegistries.js +0 -34
- package/dist/core/constants/chainId.d.ts +0 -7
- package/dist/core/constants/chainId.js +0 -11
- package/dist/core/constants/contractNames.d.ts +0 -21
- package/dist/core/constants/contractNames.js +0 -24
- package/dist/core/constants/index.d.ts +0 -6
- package/dist/core/constants/index.js +0 -22
- package/dist/core/errors/base.d.ts +0 -8
- package/dist/core/errors/base.js +0 -17
- package/dist/core/errors/index.d.ts +0 -4
- package/dist/core/errors/index.js +0 -20
- package/dist/core/errors/oracle.d.ts +0 -9
- package/dist/core/errors/oracle.js +0 -15
- package/dist/core/errors/router.d.ts +0 -14
- package/dist/core/errors/router.js +0 -24
- package/dist/core/types/borrow.d.ts +0 -87
- package/dist/core/types/borrow.js +0 -3
- package/dist/core/types/contractAddresses.d.ts +0 -42
- package/dist/core/types/contractAddresses.js +0 -3
- package/dist/core/types/index.d.ts +0 -10
- package/dist/core/types/index.js +0 -26
- package/dist/core/types/liquidity.d.ts +0 -194
- package/dist/core/types/liquidity.js +0 -3
- package/dist/core/types/pool.d.ts +0 -208
- package/dist/core/types/pool.js +0 -14
- package/dist/core/types/provider.d.ts +0 -45
- package/dist/core/types/provider.js +0 -3
- package/dist/core/types/route.d.ts +0 -62
- package/dist/core/types/route.js +0 -3
- package/dist/core/types/token.d.ts +0 -21
- package/dist/core/types/token.js +0 -3
- package/dist/core/types/tradingLimits.d.ts +0 -91
- package/dist/core/types/tradingLimits.js +0 -3
- package/dist/core/types/tradingMode.d.ts +0 -24
- package/dist/core/types/tradingMode.js +0 -31
- package/dist/core/types/transaction.d.ts +0 -45
- package/dist/core/types/transaction.js +0 -3
- package/dist/esm/cache/routes.js +0 -14644
- package/dist/esm/cache/tokens.js +0 -480
- package/dist/esm/core/abis/activePool.js +0 -10
- package/dist/esm/core/abis/addressesRegistry.js +0 -22
- package/dist/esm/core/abis/bipoolmanager.js +0 -68
- package/dist/esm/core/abis/borrowerOperations.js +0 -85
- package/dist/esm/core/abis/breakerbox.js +0 -4
- package/dist/esm/core/abis/broker.js +0 -5
- package/dist/esm/core/abis/erc20.js +0 -17
- package/dist/esm/core/abis/fpmm.js +0 -45
- package/dist/esm/core/abis/fpmmFactory.js +0 -22
- package/dist/esm/core/abis/hintHelpers.js +0 -10
- package/dist/esm/core/abis/index.js +0 -21
- package/dist/esm/core/abis/liquidityStrategy.js +0 -6
- package/dist/esm/core/abis/multiTroveGetter.js +0 -11
- package/dist/esm/core/abis/priceFeed.js +0 -12
- package/dist/esm/core/abis/pricingmodule.js +0 -2
- package/dist/esm/core/abis/reserve.js +0 -14
- package/dist/esm/core/abis/router.js +0 -41
- package/dist/esm/core/abis/sortedTroves.js +0 -11
- package/dist/esm/core/abis/systemParams.js +0 -10
- package/dist/esm/core/abis/troveManager.js +0 -23
- package/dist/esm/core/abis/troveNFT.js +0 -5
- package/dist/esm/core/abis/virtualPool.js +0 -7
- package/dist/esm/core/abis/virtualPoolFactory.js +0 -13
- package/dist/esm/core/constants/addresses.js +0 -107
- package/dist/esm/core/constants/borrowConstants.js +0 -12
- package/dist/esm/core/constants/borrowRegistries.js +0 -29
- package/dist/esm/core/constants/chainId.js +0 -7
- package/dist/esm/core/constants/contractNames.js +0 -20
- package/dist/esm/core/constants/index.js +0 -5
- package/dist/esm/core/errors/base.js +0 -12
- package/dist/esm/core/errors/index.js +0 -3
- package/dist/esm/core/errors/oracle.js +0 -10
- package/dist/esm/core/errors/router.js +0 -18
- package/dist/esm/core/types/borrow.js +0 -1
- package/dist/esm/core/types/contractAddresses.js +0 -1
- package/dist/esm/core/types/index.js +0 -9
- package/dist/esm/core/types/liquidity.js +0 -1
- package/dist/esm/core/types/pool.js +0 -10
- package/dist/esm/core/types/provider.js +0 -1
- package/dist/esm/core/types/route.js +0 -1
- package/dist/esm/core/types/token.js +0 -1
- package/dist/esm/core/types/tradingLimits.js +0 -1
- package/dist/esm/core/types/tradingMode.js +0 -26
- package/dist/esm/core/types/transaction.js +0 -1
- package/dist/esm/index.js +0 -139
- package/dist/esm/package.json +0 -1
- package/dist/esm/services/borrow/BorrowService.js +0 -455
- package/dist/esm/services/borrow/borrowHelpers.js +0 -3
- package/dist/esm/services/borrow/borrowMath.js +0 -127
- package/dist/esm/services/borrow/index.js +0 -3
- package/dist/esm/services/borrow/internal/borrowApprovalService.js +0 -48
- package/dist/esm/services/borrow/internal/borrowContextStore.js +0 -35
- package/dist/esm/services/borrow/internal/borrowErc20.js +0 -38
- package/dist/esm/services/borrow/internal/borrowHints.js +0 -27
- package/dist/esm/services/borrow/internal/borrowPositionParser.js +0 -82
- package/dist/esm/services/borrow/internal/borrowReadService.js +0 -271
- package/dist/esm/services/borrow/internal/borrowRegistryReader.js +0 -108
- package/dist/esm/services/borrow/internal/borrowTransactionService.js +0 -271
- package/dist/esm/services/borrow/internal/borrowTypes.js +0 -1
- package/dist/esm/services/borrow/internal/borrowValidation.js +0 -89
- package/dist/esm/services/index.js +0 -8
- package/dist/esm/services/liquidity/LiquidityService.js +0 -163
- package/dist/esm/services/liquidity/basicLiquidity.js +0 -162
- package/dist/esm/services/liquidity/index.js +0 -1
- package/dist/esm/services/liquidity/liquidityHelpers.js +0 -95
- package/dist/esm/services/liquidity/rebalance.js +0 -59
- package/dist/esm/services/liquidity/zapHelpers.js +0 -181
- package/dist/esm/services/liquidity/zapIn.js +0 -131
- package/dist/esm/services/liquidity/zapOut.js +0 -248
- package/dist/esm/services/pools/PoolService.js +0 -204
- package/dist/esm/services/pools/index.js +0 -1
- package/dist/esm/services/pools/poolDetails.js +0 -209
- package/dist/esm/services/pools/poolDiscovery.js +0 -112
- package/dist/esm/services/pools/rebalancePreview.js +0 -181
- package/dist/esm/services/quotes/QuoteService.js +0 -85
- package/dist/esm/services/quotes/index.js +0 -1
- package/dist/esm/services/routes/RouteService.js +0 -268
- package/dist/esm/services/routes/index.js +0 -1
- package/dist/esm/services/swap/SwapService.js +0 -247
- package/dist/esm/services/swap/index.js +0 -1
- package/dist/esm/services/tokens/index.js +0 -1
- package/dist/esm/services/tokens/tokenService.js +0 -285
- package/dist/esm/services/trading/TradingLimitsService.js +0 -154
- package/dist/esm/services/trading/TradingService.js +0 -222
- package/dist/esm/services/trading/index.js +0 -2
- package/dist/esm/utils/chainConfig.js +0 -118
- package/dist/esm/utils/costUtils.js +0 -56
- package/dist/esm/utils/deadline.js +0 -22
- package/dist/esm/utils/index.js +0 -9
- package/dist/esm/utils/multicall.js +0 -47
- package/dist/esm/utils/pathEncoder.js +0 -69
- package/dist/esm/utils/rateFeed.js +0 -23
- package/dist/esm/utils/retry.js +0 -24
- package/dist/esm/utils/routeUtils.js +0 -361
- package/dist/esm/utils/routes.js +0 -2
- package/dist/esm/utils/sortUtils.js +0 -33
- package/dist/esm/utils/tokens.js +0 -2
- package/dist/esm/utils/tradingLimits.js +0 -163
- package/dist/esm/utils/validation.js +0 -30
- package/dist/index.d.ts +0 -101
- package/dist/index.js +0 -158
- package/dist/services/borrow/BorrowService.d.ts +0 -381
- package/dist/services/borrow/BorrowService.js +0 -460
- package/dist/services/borrow/borrowHelpers.d.ts +0 -4
- package/dist/services/borrow/borrowHelpers.js +0 -13
- package/dist/services/borrow/borrowMath.d.ts +0 -21
- package/dist/services/borrow/borrowMath.js +0 -137
- package/dist/services/borrow/index.d.ts +0 -4
- package/dist/services/borrow/index.js +0 -20
- package/dist/services/borrow/internal/borrowApprovalService.d.ts +0 -14
- package/dist/services/borrow/internal/borrowApprovalService.js +0 -53
- package/dist/services/borrow/internal/borrowContextStore.d.ts +0 -11
- package/dist/services/borrow/internal/borrowContextStore.js +0 -40
- package/dist/services/borrow/internal/borrowErc20.d.ts +0 -5
- package/dist/services/borrow/internal/borrowErc20.js +0 -43
- package/dist/services/borrow/internal/borrowHints.d.ts +0 -7
- package/dist/services/borrow/internal/borrowHints.js +0 -31
- package/dist/services/borrow/internal/borrowPositionParser.d.ts +0 -4
- package/dist/services/borrow/internal/borrowPositionParser.js +0 -87
- package/dist/services/borrow/internal/borrowReadService.d.ts +0 -31
- package/dist/services/borrow/internal/borrowReadService.js +0 -276
- package/dist/services/borrow/internal/borrowRegistryReader.d.ts +0 -5
- package/dist/services/borrow/internal/borrowRegistryReader.js +0 -113
- package/dist/services/borrow/internal/borrowTransactionService.d.ts +0 -23
- package/dist/services/borrow/internal/borrowTransactionService.js +0 -276
- package/dist/services/borrow/internal/borrowTypes.d.ts +0 -15
- package/dist/services/borrow/internal/borrowTypes.js +0 -3
- package/dist/services/borrow/internal/borrowValidation.d.ts +0 -14
- package/dist/services/borrow/internal/borrowValidation.js +0 -104
- package/dist/services/index.d.ts +0 -9
- package/dist/services/index.js +0 -25
- package/dist/services/liquidity/LiquidityService.d.ts +0 -139
- package/dist/services/liquidity/LiquidityService.js +0 -168
- package/dist/services/liquidity/basicLiquidity.d.ts +0 -11
- package/dist/services/liquidity/basicLiquidity.js +0 -172
- package/dist/services/liquidity/index.d.ts +0 -2
- package/dist/services/liquidity/index.js +0 -18
- package/dist/services/liquidity/liquidityHelpers.d.ts +0 -19
- package/dist/services/liquidity/liquidityHelpers.js +0 -104
- package/dist/services/liquidity/rebalance.d.ts +0 -6
- package/dist/services/liquidity/rebalance.js +0 -64
- package/dist/services/liquidity/zapHelpers.d.ts +0 -100
- package/dist/services/liquidity/zapHelpers.js +0 -192
- package/dist/services/liquidity/zapIn.d.ts +0 -18
- package/dist/services/liquidity/zapIn.js +0 -138
- package/dist/services/liquidity/zapOut.d.ts +0 -9
- package/dist/services/liquidity/zapOut.js +0 -255
- package/dist/services/pools/PoolService.d.ts +0 -69
- package/dist/services/pools/PoolService.js +0 -209
- package/dist/services/pools/index.d.ts +0 -2
- package/dist/services/pools/index.js +0 -18
- package/dist/services/pools/poolDetails.d.ts +0 -13
- package/dist/services/pools/poolDetails.js +0 -216
- package/dist/services/pools/poolDiscovery.d.ts +0 -12
- package/dist/services/pools/poolDiscovery.js +0 -117
- package/dist/services/pools/rebalancePreview.d.ts +0 -5
- package/dist/services/pools/rebalancePreview.js +0 -186
- package/dist/services/quotes/QuoteService.d.ts +0 -51
- package/dist/services/quotes/QuoteService.js +0 -91
- package/dist/services/quotes/index.d.ts +0 -2
- package/dist/services/quotes/index.js +0 -18
- package/dist/services/routes/RouteService.d.ts +0 -117
- package/dist/services/routes/RouteService.js +0 -306
- package/dist/services/routes/index.d.ts +0 -2
- package/dist/services/routes/index.js +0 -18
- package/dist/services/swap/SwapService.d.ts +0 -198
- package/dist/services/swap/SwapService.js +0 -252
- package/dist/services/swap/index.d.ts +0 -2
- package/dist/services/swap/index.js +0 -18
- package/dist/services/tokens/index.d.ts +0 -2
- package/dist/services/tokens/index.js +0 -18
- package/dist/services/tokens/tokenService.d.ts +0 -55
- package/dist/services/tokens/tokenService.js +0 -290
- package/dist/services/trading/TradingLimitsService.d.ts +0 -38
- package/dist/services/trading/TradingLimitsService.js +0 -159
- package/dist/services/trading/TradingService.d.ts +0 -115
- package/dist/services/trading/TradingService.js +0 -227
- package/dist/services/trading/index.d.ts +0 -3
- package/dist/services/trading/index.js +0 -19
- package/dist/utils/chainConfig.d.ts +0 -16
- package/dist/utils/chainConfig.js +0 -123
- package/dist/utils/costUtils.d.ts +0 -12
- package/dist/utils/costUtils.js +0 -60
- package/dist/utils/deadline.d.ts +0 -21
- package/dist/utils/deadline.js +0 -26
- package/dist/utils/index.d.ts +0 -10
- package/dist/utils/index.js +0 -26
- package/dist/utils/multicall.d.ts +0 -30
- package/dist/utils/multicall.js +0 -52
- package/dist/utils/pathEncoder.d.ts +0 -34
- package/dist/utils/pathEncoder.js +0 -73
- package/dist/utils/rateFeed.d.ts +0 -18
- package/dist/utils/rateFeed.js +0 -27
- package/dist/utils/retry.d.ts +0 -12
- package/dist/utils/retry.js +0 -28
- package/dist/utils/routeUtils.d.ts +0 -295
- package/dist/utils/routeUtils.js +0 -371
- package/dist/utils/routes.d.ts +0 -3
- package/dist/utils/routes.js +0 -8
- package/dist/utils/sortUtils.d.ts +0 -24
- package/dist/utils/sortUtils.js +0 -39
- package/dist/utils/tokens.d.ts +0 -2
- package/dist/utils/tokens.js +0 -13
- package/dist/utils/tradingLimits.d.ts +0 -41
- package/dist/utils/tradingLimits.js +0 -171
- package/dist/utils/validation.d.ts +0 -19
- package/dist/utils/validation.js +0 -34
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { encodeFunctionData } from 'viem';
|
|
2
|
-
import { ROUTER_ABI, ERC20_ABI } from '../../core/abis';
|
|
3
|
-
import { getContractAddress } from '../../core/constants';
|
|
4
|
-
import { validateAddress } from '../../utils/validation';
|
|
5
|
-
import { buildApprovalParams, getAllowance, calculateMinAmount, getPoolInfo, validatePoolTokens } from './liquidityHelpers';
|
|
6
|
-
function encodeAddLiquidityCall(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin, recipient, deadline) {
|
|
7
|
-
return encodeFunctionData({
|
|
8
|
-
abi: ROUTER_ABI,
|
|
9
|
-
functionName: 'addLiquidity',
|
|
10
|
-
args: [tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin, recipient, deadline],
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
function encodeRemoveLiquidityCall(token0, token1, liquidity, amount0Min, amount1Min, recipient, deadline) {
|
|
14
|
-
return encodeFunctionData({
|
|
15
|
-
abi: ROUTER_ABI,
|
|
16
|
-
functionName: 'removeLiquidity',
|
|
17
|
-
args: [token0, token1, liquidity, amount0Min, amount1Min, recipient, deadline],
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
export async function buildAddLiquidityTransactionInternal(publicClient, chainId, poolService, poolAddress, tokenA, amountA, tokenB, amountB, recipient, owner, options) {
|
|
21
|
-
const addLiquidity = await buildAddLiquidityParamsInternal(publicClient, chainId, poolService, poolAddress, tokenA, amountA, tokenB, amountB, recipient, options);
|
|
22
|
-
validateAddress(owner, 'owner');
|
|
23
|
-
const ownerAddr = owner;
|
|
24
|
-
const tokenAAddr = addLiquidity.tokenA;
|
|
25
|
-
const tokenBAddr = addLiquidity.tokenB;
|
|
26
|
-
const [allowanceA, allowanceB] = await Promise.all([
|
|
27
|
-
getAllowance(publicClient, tokenAAddr, ownerAddr, chainId),
|
|
28
|
-
getAllowance(publicClient, tokenBAddr, ownerAddr, chainId),
|
|
29
|
-
]);
|
|
30
|
-
const approvalA = allowanceA < amountA
|
|
31
|
-
? { token: addLiquidity.tokenA, amount: amountA, params: buildApprovalParams(chainId, tokenAAddr, amountA) }
|
|
32
|
-
: null;
|
|
33
|
-
const approvalB = allowanceB < amountB
|
|
34
|
-
? { token: addLiquidity.tokenB, amount: amountB, params: buildApprovalParams(chainId, tokenBAddr, amountB) }
|
|
35
|
-
: null;
|
|
36
|
-
return { approvalA, approvalB, addLiquidity };
|
|
37
|
-
}
|
|
38
|
-
export async function buildAddLiquidityParamsInternal(publicClient, chainId, poolService, poolAddress, tokenA, amountA, tokenB, amountB, recipient, options) {
|
|
39
|
-
validateAddress(poolAddress, 'poolAddress');
|
|
40
|
-
validateAddress(tokenA, 'tokenA');
|
|
41
|
-
validateAddress(tokenB, 'tokenB');
|
|
42
|
-
validateAddress(recipient, 'recipient');
|
|
43
|
-
const { token0, token1, factoryAddr } = await getPoolInfo(poolService, poolAddress);
|
|
44
|
-
validatePoolTokens(token0, token1, tokenA, tokenB);
|
|
45
|
-
const quote = await quoteAddLiquidityInternal(publicClient, chainId, poolService, poolAddress, tokenA, amountA, tokenB, amountB);
|
|
46
|
-
const amountAMin = calculateMinAmount(quote.amountA, options.slippageTolerance);
|
|
47
|
-
const amountBMin = calculateMinAmount(quote.amountB, options.slippageTolerance);
|
|
48
|
-
const routerAddress = getContractAddress(chainId, 'Router');
|
|
49
|
-
const data = encodeAddLiquidityCall(tokenA, tokenB, amountA, amountB, amountAMin, amountBMin, recipient, options.deadline);
|
|
50
|
-
return {
|
|
51
|
-
params: {
|
|
52
|
-
to: routerAddress,
|
|
53
|
-
data,
|
|
54
|
-
value: '0',
|
|
55
|
-
},
|
|
56
|
-
poolAddress,
|
|
57
|
-
token0,
|
|
58
|
-
token1,
|
|
59
|
-
tokenA,
|
|
60
|
-
tokenB,
|
|
61
|
-
amountADesired: amountA,
|
|
62
|
-
amountBDesired: amountB,
|
|
63
|
-
amountAMin,
|
|
64
|
-
amountBMin,
|
|
65
|
-
estimatedMinLiquidity: quote.liquidity,
|
|
66
|
-
deadline: options.deadline,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
export async function quoteAddLiquidityInternal(publicClient, chainId, poolService, poolAddress, tokenA, amountA, tokenB, amountB) {
|
|
70
|
-
validateAddress(poolAddress, 'poolAddress');
|
|
71
|
-
validateAddress(tokenA, 'tokenA');
|
|
72
|
-
validateAddress(tokenB, 'tokenB');
|
|
73
|
-
const { token0, token1, factoryAddr } = await getPoolInfo(poolService, poolAddress);
|
|
74
|
-
validatePoolTokens(token0, token1, tokenA, tokenB);
|
|
75
|
-
const routerAddress = getContractAddress(chainId, 'Router');
|
|
76
|
-
const [resultAmountA, resultAmountB, liquidity] = (await publicClient.readContract({
|
|
77
|
-
address: routerAddress,
|
|
78
|
-
abi: ROUTER_ABI,
|
|
79
|
-
functionName: 'quoteAddLiquidity',
|
|
80
|
-
args: [tokenA, tokenB, factoryAddr, amountA, amountB],
|
|
81
|
-
}));
|
|
82
|
-
return { amountA: resultAmountA, amountB: resultAmountB, liquidity };
|
|
83
|
-
}
|
|
84
|
-
export async function buildRemoveLiquidityTransactionInternal(publicClient, chainId, poolService, poolAddress, liquidity, recipient, owner, options) {
|
|
85
|
-
validateAddress(owner, 'owner');
|
|
86
|
-
// Build remove liquidity params
|
|
87
|
-
const removeLiquidity = await buildRemoveLiquidityParamsInternal(publicClient, chainId, poolService, poolAddress, liquidity, recipient, options);
|
|
88
|
-
const poolAddr = poolAddress; // Pool address IS the LP token
|
|
89
|
-
const ownerAddr = owner;
|
|
90
|
-
const currentAllowance = await getAllowance(publicClient, poolAddr, ownerAddr, chainId);
|
|
91
|
-
const approval = currentAllowance < liquidity
|
|
92
|
-
? { token: poolAddress, amount: liquidity, params: buildApprovalParams(chainId, poolAddr, liquidity) }
|
|
93
|
-
: null;
|
|
94
|
-
return { approval, removeLiquidity };
|
|
95
|
-
}
|
|
96
|
-
export async function buildRemoveLiquidityParamsInternal(publicClient, chainId, poolService, poolAddress, liquidity, recipient, options) {
|
|
97
|
-
validateAddress(poolAddress, 'poolAddress');
|
|
98
|
-
validateAddress(recipient, 'recipient');
|
|
99
|
-
const { token0, token1 } = await getPoolInfo(poolService, poolAddress);
|
|
100
|
-
const quote = await quoteRemoveLiquidityInternal(publicClient, chainId, poolService, poolAddress, liquidity);
|
|
101
|
-
const amount0Min = calculateMinAmount(quote.amount0, options.slippageTolerance);
|
|
102
|
-
const amount1Min = calculateMinAmount(quote.amount1, options.slippageTolerance);
|
|
103
|
-
const routerAddress = getContractAddress(chainId, 'Router');
|
|
104
|
-
const data = encodeRemoveLiquidityCall(token0, token1, liquidity, amount0Min, amount1Min, recipient, options.deadline);
|
|
105
|
-
return {
|
|
106
|
-
params: {
|
|
107
|
-
to: routerAddress,
|
|
108
|
-
data,
|
|
109
|
-
value: '0',
|
|
110
|
-
},
|
|
111
|
-
poolAddress,
|
|
112
|
-
token0,
|
|
113
|
-
token1,
|
|
114
|
-
liquidity,
|
|
115
|
-
amount0Min,
|
|
116
|
-
amount1Min,
|
|
117
|
-
expectedAmount0: quote.amount0,
|
|
118
|
-
expectedAmount1: quote.amount1,
|
|
119
|
-
deadline: options.deadline,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
export async function quoteRemoveLiquidityInternal(publicClient, chainId, poolService, poolAddress, liquidity) {
|
|
123
|
-
validateAddress(poolAddress, 'poolAddress');
|
|
124
|
-
const { token0, token1, factoryAddr } = await getPoolInfo(poolService, poolAddress);
|
|
125
|
-
const routerAddress = getContractAddress(chainId, 'Router');
|
|
126
|
-
const [amount0, amount1] = (await publicClient.readContract({
|
|
127
|
-
address: routerAddress,
|
|
128
|
-
abi: ROUTER_ABI,
|
|
129
|
-
functionName: 'quoteRemoveLiquidity',
|
|
130
|
-
args: [token0, token1, factoryAddr, liquidity],
|
|
131
|
-
}));
|
|
132
|
-
return { amount0, amount1 };
|
|
133
|
-
}
|
|
134
|
-
export async function getLPTokenBalanceInternal(publicClient, poolService, poolAddress, owner) {
|
|
135
|
-
validateAddress(poolAddress, 'poolAddress');
|
|
136
|
-
validateAddress(owner, 'owner');
|
|
137
|
-
const { token0, token1 } = await getPoolInfo(poolService, poolAddress);
|
|
138
|
-
// Pool address IS the LP token address (FPMM pools are ERC20)
|
|
139
|
-
const [balance, totalSupply] = await Promise.all([
|
|
140
|
-
publicClient.readContract({
|
|
141
|
-
address: poolAddress,
|
|
142
|
-
abi: ERC20_ABI,
|
|
143
|
-
functionName: 'balanceOf',
|
|
144
|
-
args: [owner],
|
|
145
|
-
}),
|
|
146
|
-
publicClient.readContract({
|
|
147
|
-
address: poolAddress,
|
|
148
|
-
abi: ERC20_ABI,
|
|
149
|
-
functionName: 'totalSupply',
|
|
150
|
-
args: [],
|
|
151
|
-
}),
|
|
152
|
-
]);
|
|
153
|
-
const sharePercent = totalSupply > 0n ? Number((balance * 10000n) / totalSupply) / 100 : 0;
|
|
154
|
-
return {
|
|
155
|
-
poolAddress,
|
|
156
|
-
balance,
|
|
157
|
-
token0,
|
|
158
|
-
token1,
|
|
159
|
-
totalSupply,
|
|
160
|
-
sharePercent,
|
|
161
|
-
};
|
|
162
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './LiquidityService';
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { encodeFunctionData } from 'viem';
|
|
2
|
-
import { PoolType } from '../../core/types';
|
|
3
|
-
import { ERC20_ABI, FPMM_ABI } from '../../core/abis';
|
|
4
|
-
import { getContractAddress } from '../../core/constants';
|
|
5
|
-
import { validateAddress } from '../../utils/validation';
|
|
6
|
-
import { multicall } from '../../utils/multicall';
|
|
7
|
-
function getApprovalSpender(chainId, spender) {
|
|
8
|
-
return spender ?? getContractAddress(chainId, 'Router');
|
|
9
|
-
}
|
|
10
|
-
export function buildApprovalParams(chainId, token, amount, spender) {
|
|
11
|
-
const approvalSpender = getApprovalSpender(chainId, spender);
|
|
12
|
-
const data = encodeFunctionData({
|
|
13
|
-
abi: ERC20_ABI,
|
|
14
|
-
functionName: 'approve',
|
|
15
|
-
args: [approvalSpender, amount],
|
|
16
|
-
});
|
|
17
|
-
return { to: token, data, value: '0' };
|
|
18
|
-
}
|
|
19
|
-
export async function getAllowance(publicClient, token, owner, chainId, spender) {
|
|
20
|
-
const approvalSpender = getApprovalSpender(chainId, spender);
|
|
21
|
-
return (await publicClient.readContract({
|
|
22
|
-
address: token,
|
|
23
|
-
abi: ERC20_ABI,
|
|
24
|
-
functionName: 'allowance',
|
|
25
|
-
args: [owner, approvalSpender],
|
|
26
|
-
}));
|
|
27
|
-
}
|
|
28
|
-
export function calculateMinAmount(amount, slippageTolerance) {
|
|
29
|
-
if (slippageTolerance < 0) {
|
|
30
|
-
throw new Error('Slippage tolerance cannot be negative');
|
|
31
|
-
}
|
|
32
|
-
if (slippageTolerance > 100) {
|
|
33
|
-
throw new Error('Slippage tolerance cannot exceed 100%');
|
|
34
|
-
}
|
|
35
|
-
const basisPoints = BigInt(Math.floor(slippageTolerance * 100));
|
|
36
|
-
const slippageMultiplier = 10000n - basisPoints;
|
|
37
|
-
return (amount * slippageMultiplier) / 10000n;
|
|
38
|
-
}
|
|
39
|
-
export async function getPoolInfo(poolService, poolAddress) {
|
|
40
|
-
validateAddress(poolAddress, 'poolAddress');
|
|
41
|
-
const pools = await poolService.getPools();
|
|
42
|
-
const pool = pools.find((p) => p.poolAddr.toLowerCase() === poolAddress.toLowerCase());
|
|
43
|
-
if (!pool) {
|
|
44
|
-
throw new Error(`Pool not found: ${poolAddress}. Ensure the address is a valid FPMM pool.`);
|
|
45
|
-
}
|
|
46
|
-
if (pool.poolType !== PoolType.FPMM) {
|
|
47
|
-
throw new Error(`Pool ${poolAddress} is type ${pool.poolType}. Only FPMM pools support liquidity provision.`);
|
|
48
|
-
}
|
|
49
|
-
return {
|
|
50
|
-
token0: pool.token0,
|
|
51
|
-
token1: pool.token1,
|
|
52
|
-
factoryAddr: pool.factoryAddr,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
export function validatePoolTokens(poolToken0, poolToken1, tokenA, tokenB) {
|
|
56
|
-
const tokenALower = tokenA.toLowerCase();
|
|
57
|
-
const tokenBLower = tokenB.toLowerCase();
|
|
58
|
-
const token0Lower = poolToken0.toLowerCase();
|
|
59
|
-
const token1Lower = poolToken1.toLowerCase();
|
|
60
|
-
// Ensure both tokens belong to pool
|
|
61
|
-
const aInPool = tokenALower === token0Lower || tokenALower === token1Lower;
|
|
62
|
-
const bInPool = tokenBLower === token0Lower || tokenBLower === token1Lower;
|
|
63
|
-
if (!aInPool || !bInPool) {
|
|
64
|
-
throw new Error(`Tokens don't match pool. Pool has ${poolToken0} and ${poolToken1}, but received ${tokenA} and ${tokenB}`);
|
|
65
|
-
}
|
|
66
|
-
// Ensure tokens are different
|
|
67
|
-
if (tokenALower === tokenBLower) {
|
|
68
|
-
throw new Error('tokenA and tokenB must be different');
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
export async function getPoolSnapshot(publicClient, poolAddress) {
|
|
72
|
-
const results = await multicall(publicClient, [
|
|
73
|
-
{
|
|
74
|
-
address: poolAddress,
|
|
75
|
-
abi: FPMM_ABI,
|
|
76
|
-
functionName: 'getReserves',
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
address: poolAddress,
|
|
80
|
-
abi: ERC20_ABI,
|
|
81
|
-
functionName: 'totalSupply',
|
|
82
|
-
args: [],
|
|
83
|
-
},
|
|
84
|
-
]);
|
|
85
|
-
if (results[0].status === 'failure' || results[1].status === 'failure') {
|
|
86
|
-
throw new Error(`Failed to fetch pool snapshot for ${poolAddress}`);
|
|
87
|
-
}
|
|
88
|
-
const [reserve0, reserve1, blockTimestampLast] = results[0].result;
|
|
89
|
-
return {
|
|
90
|
-
reserve0,
|
|
91
|
-
reserve1,
|
|
92
|
-
blockTimestampLast,
|
|
93
|
-
totalSupply: results[1].result,
|
|
94
|
-
};
|
|
95
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { encodeFunctionData } from 'viem';
|
|
2
|
-
import { LIQUIDITY_STRATEGY_ABI } from '../../core/abis';
|
|
3
|
-
import { validateAddress } from '../../utils/validation';
|
|
4
|
-
import { buildApprovalParams, getAllowance } from './liquidityHelpers';
|
|
5
|
-
function getRebalanceUnavailableError(poolAddress) {
|
|
6
|
-
return new Error(`Pool ${poolAddress} is not currently rebalanceable or does not have a supported liquidity strategy.`);
|
|
7
|
-
}
|
|
8
|
-
function assertRebalanceActionAmounts(poolAddress, amountRequired, amountTransferred) {
|
|
9
|
-
if (amountRequired <= 0n || amountTransferred <= 0n) {
|
|
10
|
-
throw new Error(`Rebalance action for pool ${poolAddress} has zero amounts and cannot be executed.`);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
export async function buildRebalanceParamsInternal(publicClient, chainId, poolService, poolAddress) {
|
|
14
|
-
validateAddress(poolAddress, 'poolAddress');
|
|
15
|
-
const preview = await poolService.getPoolRebalancePreview(poolAddress);
|
|
16
|
-
if (!preview) {
|
|
17
|
-
throw getRebalanceUnavailableError(poolAddress);
|
|
18
|
-
}
|
|
19
|
-
assertRebalanceActionAmounts(poolAddress, preview.amountRequired.amount, preview.amountTransferred.amount);
|
|
20
|
-
const data = encodeFunctionData({
|
|
21
|
-
abi: LIQUIDITY_STRATEGY_ABI,
|
|
22
|
-
functionName: 'rebalance',
|
|
23
|
-
args: [poolAddress],
|
|
24
|
-
});
|
|
25
|
-
return {
|
|
26
|
-
params: {
|
|
27
|
-
to: preview.strategyAddress,
|
|
28
|
-
data,
|
|
29
|
-
value: '0',
|
|
30
|
-
},
|
|
31
|
-
poolAddress,
|
|
32
|
-
strategyAddress: preview.strategyAddress,
|
|
33
|
-
inputToken: preview.inputToken,
|
|
34
|
-
outputToken: preview.outputToken,
|
|
35
|
-
amountRequired: preview.amountRequired.amount,
|
|
36
|
-
expectedAmountTransferred: preview.amountTransferred.amount,
|
|
37
|
-
expectedProtocolIncentive: preview.protocolIncentive.amount,
|
|
38
|
-
expectedLiquiditySourceIncentive: preview.liquiditySourceIncentive.amount,
|
|
39
|
-
approvalToken: preview.approvalToken,
|
|
40
|
-
approvalSpender: preview.approvalSpender,
|
|
41
|
-
approvalAmount: preview.approvalAmount,
|
|
42
|
-
direction: preview.direction,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
export async function buildRebalanceTransactionInternal(publicClient, chainId, poolService, poolAddress, owner) {
|
|
46
|
-
validateAddress(owner, 'owner');
|
|
47
|
-
const rebalance = await buildRebalanceParamsInternal(publicClient, chainId, poolService, poolAddress);
|
|
48
|
-
const approvalToken = rebalance.approvalToken;
|
|
49
|
-
const approvalSpender = rebalance.approvalSpender;
|
|
50
|
-
const currentAllowance = await getAllowance(publicClient, approvalToken, owner, chainId, approvalSpender);
|
|
51
|
-
const approval = currentAllowance < rebalance.approvalAmount
|
|
52
|
-
? {
|
|
53
|
-
token: rebalance.approvalToken,
|
|
54
|
-
amount: rebalance.approvalAmount,
|
|
55
|
-
params: buildApprovalParams(chainId, approvalToken, rebalance.approvalAmount, approvalSpender),
|
|
56
|
-
}
|
|
57
|
-
: null;
|
|
58
|
-
return { approval, rebalance };
|
|
59
|
-
}
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { encodeFunctionData } from 'viem';
|
|
2
|
-
import { ROUTER_ABI } from '../../core/abis';
|
|
3
|
-
import { encodeRoutePath } from '../../utils/pathEncoder';
|
|
4
|
-
// ========== ENCODING FUNCTIONS ==========
|
|
5
|
-
/**
|
|
6
|
-
* Encodes the zapIn function call for the Router contract
|
|
7
|
-
*/
|
|
8
|
-
export function encodeZapInCall(tokenIn, amountInA, amountInB, zapParams, routesA, routesB, recipient) {
|
|
9
|
-
return encodeFunctionData({
|
|
10
|
-
abi: ROUTER_ABI,
|
|
11
|
-
functionName: 'zapIn',
|
|
12
|
-
args: [tokenIn, amountInA, amountInB, zapParams, routesA, routesB, recipient],
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Encodes the zapOut function call for the Router contract
|
|
17
|
-
*/
|
|
18
|
-
export function encodeZapOutCall(tokenOut, liquidity, zapParams, routesA, routesB) {
|
|
19
|
-
return encodeFunctionData({
|
|
20
|
-
abi: ROUTER_ABI,
|
|
21
|
-
functionName: 'zapOut',
|
|
22
|
-
args: [tokenOut, liquidity, zapParams, routesA, routesB],
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
// ========== ROUTING FUNCTIONS ==========
|
|
26
|
-
/**
|
|
27
|
-
* Finds routes for zap in operations (from tokenIn to both pool tokens)
|
|
28
|
-
*
|
|
29
|
-
* @param routeService - Route service for finding swap paths
|
|
30
|
-
* @param tokenIn - Input token address
|
|
31
|
-
* @param token0 - Pool's token0 address
|
|
32
|
-
* @param token1 - Pool's token1 address
|
|
33
|
-
* @returns Routes from tokenIn to token0 and token1
|
|
34
|
-
*/
|
|
35
|
-
export async function findZapInRoutes(routeService, tokenIn, token0, token1) {
|
|
36
|
-
const [routeA, routeB] = await Promise.all([
|
|
37
|
-
tokenIn.toLowerCase() !== token0.toLowerCase()
|
|
38
|
-
? routeService.findRoute(tokenIn, token0)
|
|
39
|
-
: Promise.resolve(null),
|
|
40
|
-
tokenIn.toLowerCase() !== token1.toLowerCase()
|
|
41
|
-
? routeService.findRoute(tokenIn, token1)
|
|
42
|
-
: Promise.resolve(null),
|
|
43
|
-
]);
|
|
44
|
-
const routesA = routeA ? encodeRoutePath(routeA.path, tokenIn, token0) : [];
|
|
45
|
-
const routesB = routeB ? encodeRoutePath(routeB.path, tokenIn, token1) : [];
|
|
46
|
-
return { routesA, routesB };
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Finds routes for zap out operations (from both pool tokens to tokenOut)
|
|
50
|
-
*
|
|
51
|
-
* @param routeService - Route service for finding swap paths
|
|
52
|
-
* @param token0 - Pool's token0 address
|
|
53
|
-
* @param token1 - Pool's token1 address
|
|
54
|
-
* @param tokenOut - Output token address
|
|
55
|
-
* @returns Routes from token0 and token1 to tokenOut
|
|
56
|
-
*/
|
|
57
|
-
export async function findZapOutRoutes(routeService, token0, token1, tokenOut) {
|
|
58
|
-
const [routeA, routeB] = await Promise.all([
|
|
59
|
-
token0.toLowerCase() !== tokenOut.toLowerCase()
|
|
60
|
-
? routeService.findRoute(token0, tokenOut)
|
|
61
|
-
: Promise.resolve(null),
|
|
62
|
-
token1.toLowerCase() !== tokenOut.toLowerCase()
|
|
63
|
-
? routeService.findRoute(token1, tokenOut)
|
|
64
|
-
: Promise.resolve(null),
|
|
65
|
-
]);
|
|
66
|
-
const routesA = routeA ? encodeRoutePath(routeA.path, token0, tokenOut) : [];
|
|
67
|
-
const routesB = routeB ? encodeRoutePath(routeB.path, token1, tokenOut) : [];
|
|
68
|
-
return { routesA, routesB };
|
|
69
|
-
}
|
|
70
|
-
// ========== CALCULATION FUNCTIONS ==========
|
|
71
|
-
/**
|
|
72
|
-
* Splits an amount into two parts based on a ratio
|
|
73
|
-
*
|
|
74
|
-
* @param amountIn - Total input amount
|
|
75
|
-
* @param splitRatio - Ratio for splitting (0-1, e.g., 0.5 for 50/50)
|
|
76
|
-
* @returns Split amounts for each part
|
|
77
|
-
*/
|
|
78
|
-
export function splitAmount(amountIn, splitRatio) {
|
|
79
|
-
if (splitRatio < 0 || splitRatio > 1) {
|
|
80
|
-
throw new Error('Split ratio must be between 0 and 1');
|
|
81
|
-
}
|
|
82
|
-
const amountA = (amountIn * BigInt(Math.floor(splitRatio * 10000))) / 10000n;
|
|
83
|
-
const amountB = amountIn - amountA;
|
|
84
|
-
return { amountA, amountB };
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Off-chain mirror of Router.sol's quoteAddLiquidity / _quoteZapLiquidity logic.
|
|
88
|
-
*
|
|
89
|
-
* Given desired amounts and pool reserves, returns the (amountA, amountB) the
|
|
90
|
-
* router will actually deposit when adding liquidity. Used to predict the exact
|
|
91
|
-
* `amountAMin` / `amountBMin` the contract will check against post-swap reserves.
|
|
92
|
-
*
|
|
93
|
-
* @param amountADesired - Desired amount of tokenA
|
|
94
|
-
* @param amountBDesired - Desired amount of tokenB
|
|
95
|
-
* @param reserveA - Reserve of tokenA at the moment liquidity is added
|
|
96
|
-
* @param reserveB - Reserve of tokenB at the moment liquidity is added
|
|
97
|
-
*/
|
|
98
|
-
export function quoteAddLiquidityFromReserves(amountADesired, amountBDesired, reserveA, reserveB) {
|
|
99
|
-
if (reserveA === 0n && reserveB === 0n) {
|
|
100
|
-
return { amountA: amountADesired, amountB: amountBDesired };
|
|
101
|
-
}
|
|
102
|
-
if (reserveA === 0n || reserveB === 0n) {
|
|
103
|
-
// Mirrors Router.sol's InsufficientLiquidity revert. Caller can fall back.
|
|
104
|
-
return { amountA: 0n, amountB: 0n };
|
|
105
|
-
}
|
|
106
|
-
const amountBOptimal = (amountADesired * reserveB) / reserveA;
|
|
107
|
-
if (amountBOptimal <= amountBDesired) {
|
|
108
|
-
return { amountA: amountADesired, amountB: amountBOptimal };
|
|
109
|
-
}
|
|
110
|
-
const amountAOptimal = (amountBDesired * reserveA) / reserveB;
|
|
111
|
-
return { amountA: amountAOptimal, amountB: amountBDesired };
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Computes the net delta a single-hop zap swap applies to a target pool's
|
|
115
|
-
* reserves. Returns `{delta0, delta1}` to add to the pool's pre-swap reserves
|
|
116
|
-
* to obtain the reserves the router will see when it runs `_quoteZapLiquidity`.
|
|
117
|
-
*
|
|
118
|
-
* Only single-hop routes whose factory matches the target pool's factory and
|
|
119
|
-
* whose `(from, to)` are `(token0, token1)` (in either direction) are
|
|
120
|
-
* considered. Multi-hop routes and routes through other pools have no effect
|
|
121
|
-
* on the target pool's reserves and return `{0, 0}`.
|
|
122
|
-
*
|
|
123
|
-
* Note: Multi-hop routes that traverse the target pool as an intermediate hop
|
|
124
|
-
* are intentionally not handled here — they are uncommon for single-sided zaps
|
|
125
|
-
* and would require per-hop amounts from `getAmountsOut`.
|
|
126
|
-
*/
|
|
127
|
-
export function computeTargetPoolImpact(routes, amountIn, amountOut, token0, token1, factoryAddr) {
|
|
128
|
-
if (routes.length !== 1) {
|
|
129
|
-
return { delta0: 0n, delta1: 0n };
|
|
130
|
-
}
|
|
131
|
-
const route = routes[0];
|
|
132
|
-
if (route.factory.toLowerCase() !== factoryAddr.toLowerCase()) {
|
|
133
|
-
return { delta0: 0n, delta1: 0n };
|
|
134
|
-
}
|
|
135
|
-
const fromLower = route.from.toLowerCase();
|
|
136
|
-
const toLower = route.to.toLowerCase();
|
|
137
|
-
const t0 = token0.toLowerCase();
|
|
138
|
-
const t1 = token1.toLowerCase();
|
|
139
|
-
if (fromLower === t0 && toLower === t1) {
|
|
140
|
-
return { delta0: amountIn, delta1: -amountOut };
|
|
141
|
-
}
|
|
142
|
-
if (fromLower === t1 && toLower === t0) {
|
|
143
|
-
return { delta0: -amountOut, delta1: amountIn };
|
|
144
|
-
}
|
|
145
|
-
return { delta0: 0n, delta1: 0n };
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Estimates minimum LP tokens from zap in amounts.
|
|
149
|
-
*
|
|
150
|
-
* This is a conservative lower-bound estimate. The inputs are slippage-adjusted
|
|
151
|
-
* minimums, not expected amounts. Actual LP tokens minted on-chain may be higher
|
|
152
|
-
* because the router uses balanceOf(address(this)) after swaps, which can exceed
|
|
153
|
-
* the pre-calculated minimums.
|
|
154
|
-
*
|
|
155
|
-
* @param amountOutA - Minimum amount of token0 after swap (slippage-adjusted)
|
|
156
|
-
* @param amountOutB - Minimum amount of token1 after swap (slippage-adjusted)
|
|
157
|
-
* @param reserve0 - Current reserve of token0 in pool
|
|
158
|
-
* @param reserve1 - Current reserve of token1 in pool
|
|
159
|
-
* @param totalSupply - Total LP token supply
|
|
160
|
-
* @returns Conservative estimate of minimum LP tokens to be minted
|
|
161
|
-
*/
|
|
162
|
-
export function estimateLiquidityFromZapIn(amountOutA, amountOutB, reserve0, reserve1, totalSupply) {
|
|
163
|
-
if (totalSupply === 0n) {
|
|
164
|
-
// First liquidity provision - use geometric mean with BigInt sqrt
|
|
165
|
-
// to avoid precision loss from Number() conversion on 18-decimal values
|
|
166
|
-
const product = amountOutA * amountOutB;
|
|
167
|
-
if (product === 0n)
|
|
168
|
-
return 0n;
|
|
169
|
-
let x = product;
|
|
170
|
-
let y = (x + 1n) / 2n;
|
|
171
|
-
while (y < x) {
|
|
172
|
-
x = y;
|
|
173
|
-
y = (x + product / x) / 2n;
|
|
174
|
-
}
|
|
175
|
-
return x;
|
|
176
|
-
}
|
|
177
|
-
// Existing pool - calculate based on smaller ratio
|
|
178
|
-
const liquidityA = (amountOutA * totalSupply) / reserve0;
|
|
179
|
-
const liquidityB = (amountOutB * totalSupply) / reserve1;
|
|
180
|
-
return liquidityA < liquidityB ? liquidityA : liquidityB;
|
|
181
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { ROUTER_ABI } from '../../core/abis';
|
|
2
|
-
import { getContractAddress } from '../../core/constants';
|
|
3
|
-
import { validateAddress } from '../../utils/validation';
|
|
4
|
-
import { buildApprovalParams, getAllowance, calculateMinAmount, getPoolInfo, getPoolSnapshot } from './liquidityHelpers';
|
|
5
|
-
import { encodeZapInCall, findZapInRoutes, splitAmount, estimateLiquidityFromZapIn, quoteAddLiquidityFromReserves, computeTargetPoolImpact, } from './zapHelpers';
|
|
6
|
-
// ========== ZAP IN OPERATIONS ==========
|
|
7
|
-
/**
|
|
8
|
-
* Builds a complete zap in transaction including approval if needed
|
|
9
|
-
*/
|
|
10
|
-
export async function buildZapInTransactionInternal(publicClient, chainId, poolService, routeService, poolAddress, tokenIn, amountIn, amountInSplit, recipient, owner, options) {
|
|
11
|
-
const prepared = await prepareZapInInternal(publicClient, chainId, poolService, routeService, poolAddress, tokenIn, amountIn, amountInSplit, recipient, owner, options);
|
|
12
|
-
return {
|
|
13
|
-
approval: prepared.approval ?? null,
|
|
14
|
-
zapIn: prepared.details,
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Builds zap in transaction parameters without checking approval
|
|
19
|
-
*/
|
|
20
|
-
export async function buildZapInParamsInternal(publicClient, chainId, poolService, routeService, poolAddress, tokenIn, amountIn, amountInSplit, recipient, options) {
|
|
21
|
-
const prepared = await prepareZapInInternal(publicClient, chainId, poolService, routeService, poolAddress, tokenIn, amountIn, amountInSplit, recipient, undefined, options);
|
|
22
|
-
return prepared.details;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Quotes a zap in operation (read-only)
|
|
26
|
-
*/
|
|
27
|
-
export async function quoteZapInInternal(publicClient, chainId, poolService, routeService, poolAddress, tokenIn, amountIn, amountInSplit, options) {
|
|
28
|
-
const prepared = await prepareZapInInternal(publicClient, chainId, poolService, routeService, poolAddress, tokenIn, amountIn, amountInSplit, tokenIn, undefined, options);
|
|
29
|
-
return prepared.quote;
|
|
30
|
-
}
|
|
31
|
-
export async function prepareZapInInternal(publicClient, chainId, poolService, routeService, poolAddress, tokenIn, amountIn, amountInSplit, recipient, owner, options) {
|
|
32
|
-
if (owner) {
|
|
33
|
-
validateAddress(owner, 'owner');
|
|
34
|
-
}
|
|
35
|
-
const [context, currentAllowance] = await Promise.all([
|
|
36
|
-
prepareZapInContextInternal(publicClient, chainId, poolService, routeService, poolAddress, tokenIn, amountIn, amountInSplit, recipient, options),
|
|
37
|
-
owner ? getAllowance(publicClient, tokenIn, owner, chainId) : Promise.resolve(null),
|
|
38
|
-
]);
|
|
39
|
-
const approval = owner && currentAllowance !== null && currentAllowance < amountIn
|
|
40
|
-
? { token: tokenIn, amount: amountIn, params: buildApprovalParams(chainId, tokenIn, amountIn) }
|
|
41
|
-
: owner
|
|
42
|
-
? null
|
|
43
|
-
: undefined;
|
|
44
|
-
return {
|
|
45
|
-
routesA: context.routesA,
|
|
46
|
-
routesB: context.routesB,
|
|
47
|
-
quote: context.quote,
|
|
48
|
-
approval,
|
|
49
|
-
details: context.details,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
async function prepareZapInContextInternal(publicClient, chainId, poolService, routeService, poolAddress, tokenIn, amountIn, amountInSplit, recipient, options) {
|
|
53
|
-
validateAddress(poolAddress, 'poolAddress');
|
|
54
|
-
validateAddress(tokenIn, 'tokenIn');
|
|
55
|
-
validateAddress(recipient, 'recipient');
|
|
56
|
-
const { token0, token1, factoryAddr } = await getPoolInfo(poolService, poolAddress);
|
|
57
|
-
const { amountA: amountInA, amountB: amountInB } = splitAmount(amountIn, amountInSplit);
|
|
58
|
-
const [{ routesA, routesB }, poolSnapshot] = await Promise.all([
|
|
59
|
-
findZapInRoutes(routeService, tokenIn, token0, token1),
|
|
60
|
-
getPoolSnapshot(publicClient, poolAddress),
|
|
61
|
-
]);
|
|
62
|
-
const routerAddress = getContractAddress(chainId, 'Router');
|
|
63
|
-
const [amountOutMinA, amountOutMinB, amountAMin, amountBMin] = (await publicClient.readContract({
|
|
64
|
-
address: routerAddress,
|
|
65
|
-
abi: ROUTER_ABI,
|
|
66
|
-
functionName: 'generateZapInParams',
|
|
67
|
-
args: [token0, token1, factoryAddr, amountInA, amountInB, routesA, routesB],
|
|
68
|
-
}));
|
|
69
|
-
// Re-quote amountAMin / amountBMin against POST-swap reserves.
|
|
70
|
-
//
|
|
71
|
-
// `generateZapInParams` calls `quoteAddLiquidity` with the pool's *current*
|
|
72
|
-
// reserves, but on-chain `_quoteZapLiquidity` runs *after* the zap's internal
|
|
73
|
-
// swap, which moves the same pool when tokenIn is one of the pool tokens.
|
|
74
|
-
// Applying user slippage on top of a pre-swap minimum makes the contract
|
|
75
|
-
// reject any non-trivial amount because the deterministic price impact of
|
|
76
|
-
// the swap alone exceeds the slippage budget. Predict the post-swap reserves
|
|
77
|
-
// and re-derive the minimums so that user slippage only covers real drift
|
|
78
|
-
// between quote-time and execution.
|
|
79
|
-
const impactA = computeTargetPoolImpact(routesA, amountInA, amountOutMinA, token0, token1, factoryAddr);
|
|
80
|
-
const impactB = computeTargetPoolImpact(routesB, amountInB, amountOutMinB, token0, token1, factoryAddr);
|
|
81
|
-
const projectedReserveA = poolSnapshot.reserve0 + impactA.delta0 + impactB.delta0;
|
|
82
|
-
const projectedReserveB = poolSnapshot.reserve1 + impactA.delta1 + impactB.delta1;
|
|
83
|
-
const useReserveA = projectedReserveA > 0n ? projectedReserveA : poolSnapshot.reserve0;
|
|
84
|
-
const useReserveB = projectedReserveB > 0n ? projectedReserveB : poolSnapshot.reserve1;
|
|
85
|
-
const projected = quoteAddLiquidityFromReserves(amountOutMinA, amountOutMinB, useReserveA, useReserveB);
|
|
86
|
-
const baselineAmountAMin = projected.amountA > 0n ? projected.amountA : amountAMin;
|
|
87
|
-
const baselineAmountBMin = projected.amountB > 0n ? projected.amountB : amountBMin;
|
|
88
|
-
const finalAmountAMin = calculateMinAmount(baselineAmountAMin, options.slippageTolerance);
|
|
89
|
-
const finalAmountBMin = calculateMinAmount(baselineAmountBMin, options.slippageTolerance);
|
|
90
|
-
const finalAmountOutMinA = calculateMinAmount(amountOutMinA, options.slippageTolerance);
|
|
91
|
-
const finalAmountOutMinB = calculateMinAmount(amountOutMinB, options.slippageTolerance);
|
|
92
|
-
const expectedLiquidity = estimateLiquidityFromZapIn(finalAmountOutMinA, finalAmountOutMinB, poolSnapshot.reserve0, poolSnapshot.reserve1, poolSnapshot.totalSupply);
|
|
93
|
-
const quote = {
|
|
94
|
-
amountOutFromA: finalAmountOutMinA,
|
|
95
|
-
amountOutFromB: finalAmountOutMinB,
|
|
96
|
-
amountAMin: finalAmountAMin,
|
|
97
|
-
amountBMin: finalAmountBMin,
|
|
98
|
-
estimatedMinLiquidity: expectedLiquidity,
|
|
99
|
-
};
|
|
100
|
-
const zapParams = {
|
|
101
|
-
tokenA: token0,
|
|
102
|
-
tokenB: token1,
|
|
103
|
-
factory: factoryAddr,
|
|
104
|
-
amountAMin: finalAmountAMin,
|
|
105
|
-
amountBMin: finalAmountBMin,
|
|
106
|
-
amountOutMinA: finalAmountOutMinA,
|
|
107
|
-
amountOutMinB: finalAmountOutMinB,
|
|
108
|
-
};
|
|
109
|
-
const data = encodeZapInCall(tokenIn, amountInA, amountInB, zapParams, routesA, routesB, recipient);
|
|
110
|
-
return {
|
|
111
|
-
routesA,
|
|
112
|
-
routesB,
|
|
113
|
-
quote,
|
|
114
|
-
details: {
|
|
115
|
-
params: {
|
|
116
|
-
to: routerAddress,
|
|
117
|
-
data,
|
|
118
|
-
value: '0',
|
|
119
|
-
},
|
|
120
|
-
poolAddress,
|
|
121
|
-
tokenIn,
|
|
122
|
-
amountIn,
|
|
123
|
-
amountInA,
|
|
124
|
-
amountInB,
|
|
125
|
-
routesA,
|
|
126
|
-
routesB,
|
|
127
|
-
zapParams,
|
|
128
|
-
estimatedMinLiquidity: expectedLiquidity,
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
}
|