@xlink-network/xlink-sdk
Version:
186 lines (184 loc) • 6.04 kB
JavaScript
import {
checkNever
} from "./chunk-E5Y3FGR6.mjs";
import {
BigNumber
} from "./chunk-KHTJNOQE.mjs";
import {
concat,
last,
reduce
} from "./chunk-PRLWYSC3.mjs";
// src/utils/feeRateHelpers.ts
var applyTransferProphets = (transferProphets, amount) => {
return reduce(
(acc, transferProphet) => concat(acc, [applyTransferProphet(transferProphet, last(acc).netAmount)]),
[{ fees: [], netAmount: amount }],
transferProphets
);
};
var applyTransferProphet = (transferProphet, amount) => {
const fees = [];
let totalFeeAmount = BigNumber.ZERO;
for (const f of transferProphet.fees) {
let feeAmount = BigNumber.ZERO;
if (f.type === "rate") {
if (f.token !== transferProphet.bridgeToken) {
throw new Error(
`[XLinkSDK#applyTransferProphet] transferProphet.bridgeToken (${transferProphet.bridgeToken}) does not match rateFee.token (${f.token}), which is not expected`
);
}
feeAmount = BigNumber.max([
f.minimumAmount,
BigNumber.mul(f.rate, amount)
]);
fees.push({ ...f, amount: feeAmount });
} else if (f.type === "fixed") {
if (f.token === transferProphet.bridgeToken) {
feeAmount = f.amount;
}
fees.push(f);
} else {
checkNever(f);
}
totalFeeAmount = BigNumber.add(totalFeeAmount, feeAmount);
}
const netAmount = BigNumber.max([
BigNumber.ZERO,
BigNumber.minus(amount, totalFeeAmount)
]);
return { fees, netAmount };
};
var composeTransferProphets = (transferProphets, exchangeRates) => {
const cumulativeExchangeRates = calcCumulativeExchangeRates(exchangeRates);
return reduce(
(res, transferProphet, idx) => ({
...composeTransferProphet2(
res,
transferProphet,
cumulativeExchangeRates[idx]
),
transferProphets: [...res.transferProphets, transferProphet]
}),
composeTransferProphet2(
transferProphets[0],
transferProphets[1],
cumulativeExchangeRates[0]
),
transferProphets.slice(2)
);
};
var calcCumulativeExchangeRates = (exchangeRates) => {
return BigNumber.cumulativeMul(BigNumber.ONE, exchangeRates).slice(1);
};
var composeTransferProphet2 = (transferProphet1, transferProphet2, exchangeRate) => {
if (exchangeRate == null) {
throw new Error(
"[XLinkSDK#composeTransferProphet2] exchangeRate is required"
);
}
const bridgeTokenMinFeeAmount = BigNumber.sum([
...transferProphet1.fees.flatMap(
(f) => f.type === "rate" && f.token === transferProphet1.bridgeToken ? [f.minimumAmount] : []
),
...transferProphet2.fees.flatMap(
(f) => f.type === "rate" && f.token === transferProphet2.bridgeToken ? [
/**
* convert to the denomination of the first step token
*/
BigNumber.div(f.minimumAmount, exchangeRate)
] : []
)
]);
const step1FlatFeeRate = BigNumber.minus(
BigNumber.ONE,
last(
BigNumber.cumulativeMul(
BigNumber.ONE,
transferProphet1.fees.flatMap(
(f) => f.type === "rate" && f.token === transferProphet1.bridgeToken ? [BigNumber.minus(1, f.rate)] : []
)
)
)
);
const step1ToStep2Rate = BigNumber.mul(
BigNumber.minus(1, step1FlatFeeRate),
exchangeRate
);
let minBridgeAmount = null;
if (BigNumber.isZero(bridgeTokenMinFeeAmount) && transferProphet1.minBridgeAmount == null && transferProphet2.minBridgeAmount == null) {
minBridgeAmount = null;
} else {
minBridgeAmount = BigNumber.max([
bridgeTokenMinFeeAmount,
transferProphet1.minBridgeAmount ?? 0,
transferProphet2.minBridgeAmount == null ? 0 : BigNumber.div(transferProphet2.minBridgeAmount, step1ToStep2Rate)
]);
}
let maxBridgeAmount = null;
if (transferProphet1.maxBridgeAmount == null && transferProphet2.maxBridgeAmount == null) {
maxBridgeAmount = null;
} else if (transferProphet1.maxBridgeAmount != null && transferProphet2.maxBridgeAmount != null) {
maxBridgeAmount = BigNumber.min([
transferProphet1.maxBridgeAmount,
BigNumber.div(transferProphet2.maxBridgeAmount, step1ToStep2Rate)
]);
} else {
maxBridgeAmount = transferProphet1.maxBridgeAmount ?? transferProphet2.maxBridgeAmount;
}
return {
isPaused: transferProphet1.isPaused || transferProphet2.isPaused,
bridgeToken: transferProphet1.bridgeToken,
minBridgeAmount,
maxBridgeAmount,
fees: [
...transferProphet1.fees,
...transferProphet2.fees.map((fee) => {
if (fee.type === "fixed") {
if (fee.token !== transferProphet2.bridgeToken) return fee;
return {
type: "fixed",
token: transferProphet1.bridgeToken,
amount: BigNumber.div(fee.amount, step1ToStep2Rate)
};
}
if (fee.type === "rate") {
if (fee.token !== transferProphet2.bridgeToken) return fee;
return {
type: "rate",
token: transferProphet1.bridgeToken,
/**
* feeAmount = step2Amount * fee.rate
* feeAmount = (step1Amount * (1 - step1FlatFeeRate) * exchangeRate) * fee.rate
* step1Amount * newFeeRate = (step1Amount * (1 - step1FlatFeeRate) * exchangeRate) * fee.rate
* newFeeRate = (1 - step1FlatFeeRate) * exchangeRate * fee.rate
* newFeeRate = step1ToStep2Rate * fee.rate
*/
rate: BigNumber.mul(step1ToStep2Rate, fee.rate),
minimumAmount: BigNumber.div(fee.minimumAmount, step1ToStep2Rate)
};
}
checkNever(fee);
return fee;
})
],
transferProphets: [transferProphet1, transferProphet2]
};
};
var composeRates2 = (rate1, rate2) => {
return BigNumber.sum([
rate1,
BigNumber.mul(
BigNumber.minus(1, rate1),
rate2
)
]);
};
export {
applyTransferProphets,
applyTransferProphet,
composeTransferProphets,
composeTransferProphet2,
composeRates2
};
//# sourceMappingURL=chunk-HJVY3USW.mjs.map