UNPKG

@catalabs/catalyst-sdk

Version:
477 lines 26.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.sendAsset = sendAsset; exports.receiveAsset = receiveAsset; exports.getImmediatePrice = getImmediatePrice; exports.depositMixed = depositMixed; exports.withdrawEqual = withdrawEqual; exports.solvWithdrawEqual = solvWithdrawEqual; exports.withdrawMixed = withdrawMixed; exports.estimateImbalanceLossDeposit = estimateImbalanceLossDeposit; exports.estimateImbalanceLossWithdraw = estimateImbalanceLossWithdraw; exports.findOptimalLiquiditySwaps = findOptimalLiquiditySwaps; exports.findOptimalDepositValues = findOptimalDepositValues; exports.balancedWithdrawalMacro = balancedWithdrawalMacro; exports.findOptimalWithdrawLiquiditySwaps = findOptimalWithdrawLiquiditySwaps; exports.distributeVaultTokenValue = distributeVaultTokenValue; exports.computeEstimatedOutGivenPercentageWithdrawal = computeEstimatedOutGivenPercentageWithdrawal; exports.findMeExpectedWithdrawnUnits = findMeExpectedWithdrawnUnits; const liquidity_amplified_functions_1 = require("./amplified/liquidity.amplified.functions"); const math_amplified_functions_1 = require("./amplified/math.amplified.functions"); const math_amplified_integrals_1 = require("./amplified/math.amplified.integrals"); const math_lib_1 = require("./math.lib"); const math_utils_1 = require("./math.utils"); const liquidity_volatile_functions_1 = require("./volatile/liquidity.volatile.functions"); const math_volatile_functions_1 = require("./volatile/math.volatile.functions"); const math_volatile_integrals_1 = require("./volatile/math.volatile.integrals"); function sendAsset(fromBalance, input, fromWeight, amp) { if (fromBalance === 0n) { return 0n; } if (amp === math_lib_1.WAD) { return (0, math_volatile_functions_1.sendAssetVol)(fromBalance, input, fromWeight); } else if (amp < math_lib_1.WAD) { return (0, math_amplified_functions_1.sendAssetAmp)(fromBalance, input, fromWeight, amp); } else { throw new Error('Amplification outside range [0, 1]'); } } function receiveAsset(toBalance, input, toWeight, amp) { if (toBalance === 0n) { return 0n; } if (amp === math_lib_1.WAD) { return (0, math_volatile_functions_1.receiveAssetVol)(toBalance, input, toWeight); } else if (amp < math_lib_1.WAD) { return (0, math_amplified_functions_1.receiveAssetAmp)(toBalance, input, toWeight, amp); } else { throw new Error('Amplification outside range [0, 1]'); } } function getImmediatePrice(balanceFrom, balanceTo, weightFrom, weightTo, amplification, escrowTo = 0n) { const adjustedBalance = balanceTo - escrowTo; if (amplification === math_lib_1.WAD) { return (adjustedBalance * weightFrom * math_lib_1.WAD) / (balanceFrom * weightTo); } else { let num = adjustedBalance * weightTo; num = (0, math_lib_1.powWad)(num, amplification); let denom = balanceFrom * weightFrom; denom = (0, math_lib_1.powWad)(denom, amplification); return (num * weightFrom * math_lib_1.WAD) / (denom * weightTo); } } function depositMixed(vault, depositAmounts) { if (depositAmounts.length !== vault.balances.length) { throw new Error('Different length between tokenAmounts and PoolBalance'); } if (depositAmounts.length !== vault.weights.length) { throw new Error('Different length between tokenAmounts and tokenWeights'); } let U = 0n; for (let i = 0; i < depositAmounts.length; i++) { U += vault.amplification === math_lib_1.WAD ? (0, math_volatile_integrals_1.calcPriceCurveAreaVol)(depositAmounts[i], vault.balances[i], vault.weights[i]) : (0, math_amplified_integrals_1.calcPriceCurveAreaAmp)(depositAmounts[i], vault.balances[i], vault.weights[i], math_lib_1.WAD - vault.amplification); } U = (U * (math_lib_1.WAD - vault.vaultFee)) / math_lib_1.WAD; let vaultTokens; if (vault.amplification === math_lib_1.WAD) { let wsum = 0n; for (const weight of vault.weights) { wsum = wsum + weight; } vaultTokens = (0, math_volatile_integrals_1.calcUnitsToVaultTokensVol)(U, vault.totalSupply, wsum); } else { vaultTokens = (0, math_amplified_integrals_1.calcUnitsToVaultTokensAmp)(U, vault.totalSupply, vault.balances, vault.weights, vault.unitTracker, vault.amplification); } return vaultTokens; } function withdrawEqual(vault, vaultTokens) { if (vault.amplification === math_lib_1.WAD) { return (0, math_volatile_functions_1.withdrawEqualVol)(vaultTokens, vault.totalSupply, vault.escrowedVaultTokens, vault.weights, vault.balances, vault.escrowedTokens); } else { return (0, math_amplified_functions_1.withdrawEqualAmp)(vaultTokens, vault.totalSupply, vault.escrowedVaultTokens, vault.weights, vault.balances, vault.escrowedTokens, vault.amplification, vault.unitTracker); } } function solvWithdrawEqual(vault, referenceTokenWithdraw, referenceTokenIndex) { if (vault.amplification === math_lib_1.WAD) { return (0, math_volatile_functions_1.solvWithdrawEqualVol)(referenceTokenWithdraw, referenceTokenIndex, vault.totalSupply, vault.escrowedVaultTokens, vault.weights, vault.balances, vault.escrowedTokens); } else { return (0, math_amplified_functions_1.solvWithdrawEqualAmp)(referenceTokenWithdraw, referenceTokenIndex, vault.totalSupply, vault.escrowedVaultTokens, vault.weights, vault.balances, vault.escrowedTokens, vault.amplification, vault.unitTracker); } } function withdrawMixed(vault, vaultTokens, withdrawRatio) { if (vault.amplification === math_lib_1.WAD) { return (0, math_volatile_functions_1.withdrawMixedVol)(vaultTokens, (0, math_utils_1.weightedToProgressRatio)(withdrawRatio), vault.totalSupply, vault.escrowedVaultTokens, vault.weights, vault.balances, vault.escrowedTokens); } else { return (0, math_amplified_functions_1.withdrawMixedAmp)(vaultTokens, (0, math_utils_1.weightedToProgressRatio)(withdrawRatio), vault.totalSupply, vault.escrowedVaultTokens, vault.weights, vault.balances, vault.escrowedTokens, vault.amplification, vault.unitTracker); } } function estimateImbalanceLossDeposit(vaults, userDeposits) { const referenceAssetBalance = vaults[0].balances[0]; const referenceAssetWeight = vaults[0].weights[0]; let vaultTokenEquivValue = 0n; let depositedTokenValue = 0n; for (let vaultIndex = 0; vaultIndex < vaults.length; ++vaultIndex) { const vault = vaults[vaultIndex]; const userDeposit = userDeposits[vaultIndex]; const vaultTokens = depositMixed(vault, userDeposit); const vaultCopy = { ...vault }; vaultCopy.balances = vault.balances.map((pb, i) => pb + userDeposit[i]); vaultCopy.totalSupply = vault.totalSupply + vaultTokens; const vaultTokenEquiv = withdrawEqual(vaultCopy, vaultTokens); for (let assetIndex = 0; assetIndex < vault.balances.length; ++assetIndex) { const price = getImmediatePrice(referenceAssetBalance, vault.balances[assetIndex], referenceAssetWeight, vault.weights[assetIndex], vault.amplification); depositedTokenValue = depositedTokenValue + (price * userDeposit[assetIndex]) / math_lib_1.WAD; vaultTokenEquivValue = vaultTokenEquivValue + (price * vaultTokenEquiv[assetIndex]) / math_lib_1.WAD; } } return (vaultTokenEquivValue * math_lib_1.WAD) / depositedTokenValue; } function estimateImbalanceLossWithdraw(vaults, vaultTokens, withdrawRatios) { const referenceAssetBalance = vaults[0].balances[0]; const referenceAssetWeight = vaults[0].weights[0]; let tokensMixedValue = 0n; let tokensEqualValue = 0n; for (let vaultIndex = 0; vaultIndex < vaults.length; ++vaultIndex) { const vault = vaults[vaultIndex]; const withdrawRatio = withdrawRatios[vaultIndex]; const vaultToken = vaultTokens[vaultIndex]; const tokensEqual = withdrawEqual(vault, vaultToken); const tokensMixed = withdrawMixed(vault, vaultToken, withdrawRatio); for (let assetIndex = 0; assetIndex < vault.balances.length; ++assetIndex) { const price = getImmediatePrice(referenceAssetBalance, vault.balances[assetIndex], referenceAssetWeight, vault.weights[assetIndex], vault.amplification); tokensEqualValue = tokensEqualValue + (price * tokensEqual[assetIndex]) / math_lib_1.WAD; tokensMixedValue = tokensMixedValue + (price * tokensMixed[assetIndex]) / math_lib_1.WAD; } } return (tokensMixedValue * math_lib_1.WAD) / tokensEqualValue; } function findOptimalLiquiditySwaps(vaults, userDeposit) { const boughtUnits = vaults[0].amplification === math_lib_1.WAD ? (0, liquidity_volatile_functions_1.assetsToUnitsVolatile)(vaults, userDeposit, true) : (0, liquidity_amplified_functions_1.assetsToUnitsAmplified)(vaults, userDeposit, true); const unitSwaps = vaults[0].amplification === math_lib_1.WAD ? (0, liquidity_volatile_functions_1.findOptimalSwapsVolatile)(vaults, boughtUnits, boughtUnits.map(() => 0n)) : (0, liquidity_amplified_functions_1.findOptimalSwapsAmplified)(vaults, boughtUnits, boughtUnits.map(() => 0n)); const expectedVaultTokens = []; const vaultsPostDeposit = vaults.map((v, vi) => { const vaultCopy = { ...v }; const vaultTokens = depositMixed(vaultCopy, userDeposit[vi]); expectedVaultTokens.push(vaultTokens); vaultCopy.totalSupply = vaultCopy.totalSupply + vaultTokens; vaultCopy.balances = vaultCopy.balances.map((b, bi) => b + userDeposit[vi][bi]); return vaultCopy; }); const vaultsPostDepositCopy = vaultsPostDeposit.map((e) => { return { ...e }; }); const rawVaultTokenSwaps = unitSwaps.map((swap) => { const U = swap.units; const fromVault = vaultsPostDeposit[swap.from]; const toVault = vaultsPostDeposit[swap.to]; const vaultTokensSent = fromVault.amplification === math_lib_1.WAD ? (0, math_volatile_integrals_1.calcUnitsForVaultTokensVol)(U, fromVault.totalSupply, (0, math_utils_1.bigNumberSum)(fromVault.weights)) : (0, math_amplified_integrals_1.calcUnitsForVaultTokensAmp)(U, fromVault.totalSupply, fromVault.balances, fromVault.weights, fromVault.unitTracker, fromVault.amplification); const vaultTokensReceived = fromVault.amplification === math_lib_1.WAD ? (0, math_volatile_integrals_1.calcUnitsToVaultTokensVol)(U, toVault.totalSupply, (0, math_utils_1.bigNumberSum)(toVault.weights)) : (0, math_amplified_integrals_1.calcUnitsToVaultTokensAmp)(U, toVault.totalSupply, toVault.balances, toVault.weights, toVault.unitTracker, toVault.amplification); expectedVaultTokens[swap.from] = expectedVaultTokens[swap.from] - vaultTokensSent; expectedVaultTokens[swap.to] = expectedVaultTokens[swap.to] + vaultTokensReceived; fromVault.totalSupply = fromVault.totalSupply - vaultTokensSent; toVault.totalSupply = toVault.totalSupply + vaultTokensReceived; if (fromVault.amplification !== math_lib_1.WAD) { fromVault.unitTracker = fromVault.unitTracker + U; } if (toVault.amplification !== math_lib_1.WAD) { toVault.unitTracker = toVault.unitTracker - U; } return { ...swap, vaultTokensSent, vaultTokensReceived }; }); const postBalance = []; for (let i = 0; i < expectedVaultTokens.length; ++i) { postBalance.push(withdrawEqual(vaultsPostDeposit[i], expectedVaultTokens[i])); } const deltaTokens = []; for (let i = 0; i < expectedVaultTokens.length; ++i) { const deltaWithinVault = []; for (let j = 0; j < userDeposit[i].length; ++j) { deltaWithinVault.push(postBalance[i][j] - userDeposit[i][j]); } deltaTokens.push(deltaWithinVault); } const negativeDeltaTokens = deltaTokens.map((vaultDeltaTokens) => vaultDeltaTokens.map((dt) => (dt < 0n ? dt * -1n : 0n))); const unitsSwappedInput = vaults[0].amplification === math_lib_1.WAD ? (0, liquidity_volatile_functions_1.assetsToUnitsVolatile)(vaults, negativeDeltaTokens, false) : (0, liquidity_amplified_functions_1.assetsToUnitsAmplified)(vaults, negativeDeltaTokens, false); const withdrawalRatiosInput = unitsSwappedInput.map((unitsBought) => { let vaultBoughtUnitSum = 0n; const withdrawRatios = []; for (const assetBought of unitsBought) { vaultBoughtUnitSum = vaultBoughtUnitSum + assetBought; if (vaultBoughtUnitSum === 0n) { withdrawRatios.push(0n); } else { withdrawRatios.push((assetBought * math_lib_1.WAD) / vaultBoughtUnitSum); } } return withdrawRatios; }); const vaultTokenSwapsWithInputs = rawVaultTokenSwaps.map((swap) => { const fromVaultPostDeposit = vaultsPostDepositCopy[swap.from]; const equivalentInput = withdrawMixed(fromVaultPostDeposit, swap.vaultTokensSent, withdrawalRatiosInput[swap.from]); return { ...swap, equivalentInput }; }); const positiveDeltaTokens = deltaTokens.map((vaultDeltaTokens) => vaultDeltaTokens.map((dt) => (dt > 0n ? dt : 0n))); const unitsSwappedOutput = vaults[0].amplification === math_lib_1.WAD ? (0, liquidity_volatile_functions_1.assetsForUnitsVolatile)(vaults, positiveDeltaTokens) : (0, liquidity_amplified_functions_1.assetsForUnitsAmplified)(vaults, positiveDeltaTokens); const withdrawalRatiosOutput = unitsSwappedOutput.map((unitsBought) => { let vaultBoughtUnitSum = 0n; const withdrawRatios = []; for (const assetBought of unitsBought) { vaultBoughtUnitSum = vaultBoughtUnitSum + assetBought; if (vaultBoughtUnitSum === 0n) { withdrawRatios.push(0n); } else { withdrawRatios.push((assetBought * math_lib_1.WAD) / vaultBoughtUnitSum); } } return withdrawRatios; }); const vaultTokenSwaps = vaultTokenSwapsWithInputs.map((swap) => { const toVaultPostDeposit = vaultsPostDeposit[swap.to]; const equivalentOutput = (0, math_utils_1.bigNumberSum)(withdrawalRatiosOutput[swap.to]) === 0n ? withdrawalRatiosOutput.map((_) => 0n) : withdrawMixed(toVaultPostDeposit, swap.vaultTokensReceived, withdrawalRatiosOutput[swap.to]); return { ...swap, equivalentOutput }; }); return { vaultTokenSwaps, expectedVaultTokens, vaultsPostDeposit, postBalance, }; } function findOptimalDepositValues(vaults, userBalances, userInputs) { const ratios = []; let reference = undefined; for (const vault of vaults) { const vaultRatios = []; let i = 0; for (const token_balance of vault.balances) { let localReference; const assetWeight = vault.weights[i]; if (vault.amplification === math_lib_1.WAD) { if (reference === undefined) { reference = token_balance; localReference = reference; } else { localReference = token_balance; } } else { if (reference === undefined) { reference = (0, math_lib_1.powWad)(token_balance * vault.weights[i], vault.amplification) / assetWeight; localReference = reference; } else { localReference = (0, math_lib_1.powWad)(token_balance * vault.weights[i], vault.amplification) / assetWeight; } } vaultRatios.push((localReference * math_lib_1.WAD) / reference); ++i; } ratios.push(vaultRatios); } const ratioedUserBalances = userBalances.flatMap((uB, i) => uB.map((b, j) => (b * math_lib_1.WAD) / ratios[i][j])); const ratioedUserInputs = userInputs.flatMap((uI, i) => uI.map((I, j) => (I * math_lib_1.WAD) / ratios[i][j])); let smallestUserBalance = ratioedUserBalances[0]; let smallestUserBalanceIndex = 0; for (let i = 1; i < ratioedUserBalances.length; ++i) { const userBalanceCompare = ratioedUserBalances[i]; if (userBalanceCompare === 0n) { continue; } if (userBalanceCompare < smallestUserBalance) { smallestUserBalance = userBalanceCompare; smallestUserBalanceIndex = i; } } let largestUserInput = ratioedUserInputs[0]; for (let i = 1; i < ratioedUserInputs.length; ++i) { const userInputCompare = ratioedUserInputs[i]; if (userInputCompare > largestUserInput) { largestUserInput = userInputCompare; } } const referenceBalance = smallestUserBalance > largestUserInput ? largestUserInput : smallestUserBalance; const searchForSubIndex = (relevantIndex) => { let n = relevantIndex; let i = 0; for (; i < userInputs.length; ++i) { const subElementLength = userInputs[i].length; if (n >= subElementLength) { n = n - subElementLength; continue; } if (n < subElementLength) { break; } } return [i, n]; }; const restrictingBalanceIndex = smallestUserBalance > largestUserInput ? [-1, -1] : searchForSubIndex(smallestUserBalanceIndex); const ignoreIndexes = ratioedUserBalances.map((v) => v === 0n); const newUserInputs = []; for (let i = 0; i < ratios.length; ++i) { const vaultRatios = ratios[i]; const newUserVaultInput = []; for (let j = 0; j < vaultRatios.length; ++j) { const ratio = vaultRatios[j]; if (ignoreIndexes[i][j]) { newUserVaultInput.push(0n); } else { newUserVaultInput.push((referenceBalance * ratio) / math_lib_1.WAD); } } newUserInputs.push(newUserVaultInput); } return { newUserInputs, restrictingBalanceIndex }; } function balancedWithdrawalMacro(vaults, userVaultTokens, userInput) { const numTargetPoolTokens = solvWithdrawEqual(vaults[userInput.vaultIndex], userInput.value, userInput.tokenIndex); const vaultTokenPercentage = (numTargetPoolTokens * math_lib_1.WAD) / userVaultTokens[userInput.vaultIndex]; const vaultTokensToWithdraw = userVaultTokens.map((v) => (v * vaultTokenPercentage) / math_lib_1.WAD); const newUserInputs = vaults.map((vault, index) => withdrawEqual(vault, vaultTokensToWithdraw[index])); return { newUserInputs, vaultTokensToWithdraw, }; } function findOptimalWithdrawLiquiditySwaps(vaults, userVaultTokens, userWithdrawals) { const boughtUnits = vaults[0].amplification === math_lib_1.WAD ? (0, liquidity_volatile_functions_1.assetsForUnitsVolatile)(vaults, userWithdrawals) : (0, liquidity_amplified_functions_1.assetsForUnitsAmplified)(vaults, userWithdrawals); const holdingUnits = vaults[0].amplification === math_lib_1.WAD ? (0, liquidity_volatile_functions_1.poolTokensToUnitsVolatile)(vaults, userVaultTokens) : (0, liquidity_amplified_functions_1.poolTokensToUnitsAmplified)(vaults, userVaultTokens); const unitSwaps = vaults[0].amplification === math_lib_1.WAD ? (0, liquidity_volatile_functions_1.findOptimalWithdrawalsVolatile)(vaults, boughtUnits .flatMap((unitArray) => (0, math_utils_1.bigNumberSum)(unitArray)) .map((U) => U * -1n), holdingUnits) : (0, liquidity_amplified_functions_1.findOptimalWithdrawalsAmplified)(vaults, boughtUnits .flatMap((unitArray) => (0, math_utils_1.bigNumberSum)(unitArray)) .map((U) => U * -1n), holdingUnits); const vaultTokenSwaps = unitSwaps.map((swap) => { const U = swap.units; const fromVault = vaults[swap.from]; const vaultTokens = fromVault.amplification === math_lib_1.WAD ? (0, math_volatile_integrals_1.calcUnitsForVaultTokensVol)(U, fromVault.totalSupply, (0, math_utils_1.bigNumberSum)(fromVault.weights)) : (0, math_amplified_integrals_1.calcUnitsForVaultTokensAmp)(U, fromVault.totalSupply, fromVault.balances, fromVault.weights, fromVault.unitTracker, fromVault.amplification); const userVaultToken = userVaultTokens[swap.from]; return { ...swap, vaultTokens: vaultTokens < userVaultToken ? vaultTokens : vaultTokens, }; }); return { vaultTokenSwaps, boughtUnits }; } function distributeVaultTokenValue(vaults, userVaultTokens, withdrawalWeights) { const holdingUnits = vaults[0].amplification === math_lib_1.WAD ? (0, liquidity_volatile_functions_1.poolTokensToUnitsVolatile)(vaults, userVaultTokens) : (0, liquidity_amplified_functions_1.poolTokensToUnitsAmplified)(vaults, userVaultTokens); const totalHoldingUnits = (0, math_utils_1.bigNumberSum)(holdingUnits); const assetWeightTotal = (0, math_utils_1.bigNumberSum)(withdrawalWeights.flatMap((vaultWithdrawalWeights) => vaultWithdrawalWeights.map((v) => v))); const withdrawableTokens = []; for (let vaultIndex = 0; vaultIndex < vaults.length; ++vaultIndex) { const vault = vaults[vaultIndex]; const vaultWithdrawalWeights = withdrawalWeights[vaultIndex]; const withdrawableTokensForVault = []; for (let assetIndex = 0; assetIndex < vaultWithdrawalWeights.length; ++assetIndex) { const weightedWithdrawalAsset = vaultWithdrawalWeights[assetIndex]; const unitForAsset = (weightedWithdrawalAsset * totalHoldingUnits) / assetWeightTotal; const assetBalance = vault.balances[assetIndex]; const assetWeight = vault.weights[assetIndex]; const amplification = vault.amplification; withdrawableTokensForVault.push(amplification === math_lib_1.WAD ? (0, math_volatile_functions_1.receiveAssetVol)(assetBalance, unitForAsset, assetWeight) : (0, math_amplified_functions_1.receiveAssetAmp)(assetBalance, unitForAsset, assetWeight, amplification)); } withdrawableTokens.push(withdrawableTokensForVault); } return withdrawableTokens; } function computeEstimatedOutGivenPercentageWithdrawal(vaults, userPoolTokens, percentage, vaultIndex, tokenIndex) { const modifiedPoolTokens = userPoolTokens.map((upt) => (upt * percentage) / math_lib_1.WAD); const toWithdrawUnits = vaults[0].amplification === math_lib_1.WAD ? (0, liquidity_volatile_functions_1.poolTokensToUnitsVolatile)(vaults, modifiedPoolTokens) : (0, liquidity_amplified_functions_1.poolTokensToUnitsAmplified)(vaults, modifiedPoolTokens); const toVault = vaults[vaultIndex]; const toBalance = toVault.balances[tokenIndex]; const toWeight = toVault.weights[tokenIndex]; const amp = toVault.amplification; const tokenOut = amp === math_lib_1.WAD ? (0, math_volatile_functions_1.receiveAssetVol)(toBalance, (0, math_utils_1.bigNumberSum)(toWithdrawUnits), toWeight) : (0, math_amplified_functions_1.receiveAssetAmp)(toBalance, (0, math_utils_1.bigNumberSum)(toWithdrawUnits), toWeight, amp); const _vaultTokenOut = amp === math_lib_1.WAD ? (0, math_volatile_integrals_1.calcUnitsToVaultTokensVol)((0, math_utils_1.bigNumberSum)(toWithdrawUnits), toVault.totalSupply, (0, math_utils_1.bigNumberSum)(toVault.weights)) : (0, math_amplified_integrals_1.calcUnitsToVaultTokensAmp)((0, math_utils_1.bigNumberSum)(toWithdrawUnits), toVault.totalSupply, toVault.balances, toVault.weights, toVault.unitTracker, toVault.amplification); return tokenOut; } function findMeExpectedWithdrawnUnits(vaults, userVaultTokens, percentage, vaultIndex) { const modifiedPoolTokens = userVaultTokens.map((upt) => (upt * percentage) / math_lib_1.WAD); const valueOfWantToWithdrawTokens = vaults[0].amplification === math_lib_1.WAD ? (0, liquidity_volatile_functions_1.poolTokensToUnitsVolatile)(vaults, modifiedPoolTokens) : (0, liquidity_amplified_functions_1.poolTokensToUnitsAmplified)(vaults, modifiedPoolTokens); const toWithdrawUnits = vaults.map((_) => 0n); toWithdrawUnits[vaultIndex] = (0, math_utils_1.bigNumberSum)(valueOfWantToWithdrawTokens); const holdingUnits = vaults[0].amplification === math_lib_1.WAD ? (0, liquidity_volatile_functions_1.poolTokensToUnitsVolatile)(vaults, userVaultTokens) : (0, liquidity_amplified_functions_1.poolTokensToUnitsAmplified)(vaults, userVaultTokens); const unitSwaps = vaults[0].amplification === math_lib_1.WAD ? (0, liquidity_volatile_functions_1.findOptimalWithdrawalsVolatile)(vaults, toWithdrawUnits.map((U) => U * -1n), holdingUnits) : (0, liquidity_amplified_functions_1.findOptimalWithdrawalsAmplified)(vaults, toWithdrawUnits.map((U) => U * -1n), holdingUnits); const vaultTokenSwaps = unitSwaps.map((swap) => { const U = swap.units; const fromVault = vaults[swap.from]; const vaultTokens = fromVault.amplification === math_lib_1.WAD ? (0, math_volatile_integrals_1.calcUnitsForVaultTokensVol)(U, fromVault.totalSupply, (0, math_utils_1.bigNumberSum)(fromVault.weights)) : (0, math_amplified_integrals_1.calcUnitsForVaultTokensAmp)(U, fromVault.totalSupply, fromVault.balances, fromVault.weights, fromVault.unitTracker, fromVault.amplification); const userVaultToken = userVaultTokens[swap.from]; return { ...swap, vaultTokens: vaultTokens < userVaultToken ? vaultTokens : vaultTokens, }; }); return { vaultTokenSwaps }; } //# sourceMappingURL=math.functions.js.map