@catalabs/catalyst-sdk
Version:
Catalyst AMM SDK
166 lines • 6.47 kB
JavaScript
;
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