UNPKG

@catalabs/catalyst-sdk

Version:
166 lines 6.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.bigNumberSum = bigNumberSum; exports.bigNumberMax = bigNumberMax; exports.bigNumberMin = bigNumberMin; exports.compareFunc = compareFunc; exports.weightedToProgressRatio = weightedToProgressRatio; exports.distributeUnitsSorted = distributeUnitsSorted; exports.selectDistributeUnits = selectDistributeUnits; const math_lib_1 = require("./math.lib"); function bigNumberSum(arr) { let s = 0n; for (const elm of arr) { s += elm; } return s; } function bigNumberMax(arr) { let max = arr[0]; for (const compare of arr.slice(1)) { if (compare > max) { max = compare; } } return max; } function bigNumberMin(arr) { let min = arr[0]; for (const compare of arr.slice(1)) { if (compare < min) { min = compare; } } return min; } function compareFunc(a, b) { if (a > b) { return 1; } if (a < b) { return -1; } return 0; } function weightedToProgressRatio(weightedRatio) { const progressiveRatio = []; let progressiveSum = 0n; for (let i = 0; i < weightedRatio.length; ++i) { const wr = weightedRatio[weightedRatio.length - i - 1]; progressiveSum = progressiveSum + wr; if (i === 0) { progressiveRatio.push(math_lib_1.WAD); continue; } if (progressiveSum === 0n) { progressiveRatio.push(0n); continue; } progressiveRatio.push((wr * math_lib_1.WAD) / progressiveSum); } if (progressiveSum === 0n) { throw new Error('Please provide at least 1 non zero weight'); } return progressiveRatio.reverse(); } function distributeUnitsSorted(vaults, differenceUnits) { const lessThanVaults = []; const greaterThanVaults = []; for (let vaultIndex = 0; vaultIndex < vaults.length; ++vaultIndex) { if (differenceUnits[vaultIndex] < 0n) { lessThanVaults.push(vaultIndex); } else { greaterThanVaults.push(vaultIndex); } } greaterThanVaults.sort((a, b) => compareFunc(differenceUnits[a], differenceUnits[b])); lessThanVaults.sort((a, b) => compareFunc(differenceUnits[a], differenceUnits[b]) * -1); const movements = []; let lastFilledVault = 0; for (let greaterThanVaultIndex = 0; greaterThanVaultIndex < greaterThanVaults.length; ++greaterThanVaultIndex) { const sourceVaultIndex = greaterThanVaults[greaterThanVaultIndex]; const sourceToDestinationUnits = differenceUnits[sourceVaultIndex]; for (; lastFilledVault < lessThanVaults.length;) { const destinationVaultIndex = lessThanVaults[lastFilledVault]; const destinationVaultUnits = differenceUnits[destinationVaultIndex] * -1n; if (sourceToDestinationUnits === destinationVaultUnits) { movements.push({ from: sourceVaultIndex, to: destinationVaultIndex, units: sourceToDestinationUnits, }); differenceUnits[sourceVaultIndex] -= destinationVaultUnits; differenceUnits[destinationVaultIndex] += sourceToDestinationUnits; ++lastFilledVault; break; } else if (sourceToDestinationUnits > destinationVaultUnits) { movements.push({ from: sourceVaultIndex, to: destinationVaultIndex, units: destinationVaultUnits, }); differenceUnits[sourceVaultIndex] -= destinationVaultUnits; differenceUnits[destinationVaultIndex] += destinationVaultUnits; ++lastFilledVault; continue; } else { movements.push({ from: sourceVaultIndex, to: destinationVaultIndex, units: sourceToDestinationUnits, }); differenceUnits[sourceVaultIndex] -= sourceToDestinationUnits; differenceUnits[destinationVaultIndex] += sourceToDestinationUnits; break; } } } return movements; } function selectDistributeUnits(vaults, units, differenceUnits, maximumUnitValue) { const vaultsWithWithdrawals = [...Array(vaults.length).keys()].filter((_v, i) => units[i] !== 0n); const sortedVaultsWithWithdrawals = vaultsWithWithdrawals.sort((a, b) => compareFunc(differenceUnits[a], differenceUnits[b]) * -1); const sortedExcessVaults = [...Array(vaults.length).keys()].sort((a, b) => compareFunc(differenceUnits[a], differenceUnits[b]) * -1); const movements = []; for (let vaultIndexer = 0; vaultIndexer < sortedVaultsWithWithdrawals.length; ++vaultIndexer) { sortedExcessVaults.sort((a, b) => compareFunc(differenceUnits[a], differenceUnits[b]) * -1); const excessIndex = sortedExcessVaults[0]; const excessUnits = differenceUnits[excessIndex]; const deficitIndex = sortedVaultsWithWithdrawals[vaultIndexer]; const deficitUnits = differenceUnits[deficitIndex] >= 0n ? differenceUnits[deficitIndex] : differenceUnits[deficitIndex] * -1n; const unitsToWithdraw = units[deficitIndex] * -1n; const swapAmount = excessIndex === deficitIndex ? 0n : bigNumberMin([excessUnits, deficitUnits, unitsToWithdraw]); if (swapAmount > 0n) { movements.push({ from: excessIndex, to: deficitIndex, units: swapAmount, }); } differenceUnits[excessIndex] = differenceUnits[excessIndex] - swapAmount; differenceUnits[deficitIndex] = differenceUnits[deficitIndex] + swapAmount; units[deficitIndex] = units[deficitIndex] + swapAmount; if (excessUnits === swapAmount) { if (excessUnits + maximumUnitValue[vaultIndexer] < unitsToWithdraw) { --vaultIndexer; continue; } } if (unitsToWithdraw - swapAmount > 0n) { movements.push({ from: deficitIndex, to: deficitIndex, units: unitsToWithdraw - swapAmount, }); } } return movements; } //# sourceMappingURL=math.utils.js.map