@node-dlc/core
Version:
122 lines • 5.43 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PolynomialPayoutCurve = void 0;
const messaging_1 = require("@node-dlc/messaging");
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const Precision_1 = require("../utils/Precision");
const CETCalculator_1 = require("./CETCalculator");
class PolynomialPayoutCurve {
constructor(points) {
if (points.length !== 2)
throw new Error('Must have two points');
this.points = points;
this.left = points[0];
this.right = points[points.length - 1];
// m = (y2 - y1) / (x2 - x1)
this.slope = this.right.payout
.minus(this.left.payout)
.dividedBy(this.right.outcome.minus(this.left.outcome));
}
/**
* Get the payout for a given outcome
* @param outcome The outcome to get the payout for
* @returns The payout for the outcome
*/
getPayout(outcome) {
const { left, slope } = this;
const x = new bignumber_js_1.default(Number(outcome));
// y = mx + b
const payout = slope.times(x.minus(left.outcome)).plus(left.payout);
return payout;
}
/**
* Get the outcome for a given payout
* @param payout The payout to get the outcome for
* @returns The outcome for the payout
*/
getOutcomeForPayout(payout) {
const { left, slope } = this;
const y = new bignumber_js_1.default(Number(payout));
// Find the x value for the given y
// slope = (y2 - y1) / (x2 - x1)
// x1 = (y2 - y1) / slope + x2
const outcome = y
.minus(left.payout)
.dividedBy(slope)
.plus(left.outcome)
.integerValue();
return BigInt(outcome.toString());
}
/**
* Serializes PolynomialPayoutCurve to a PolynomialPayoutCurvePiece (for transport)
* @returns A PolynomialPayoutCurvePiece
*/
toPayoutCurvePiece() {
const { points } = this;
const piece = new messaging_1.PolynomialPayoutCurvePiece();
piece.points = points.map((point) => {
const eventOutcome = BigInt(point.outcome.toString());
const outcomePayout = BigInt(point.payout.toString());
const extraPrecision = (0, Precision_1.getPrecision)(point.payout);
return { eventOutcome, outcomePayout, extraPrecision };
});
return piece;
}
/**
* Determine if the payout curve is equal to another
* @param curve A PolynomialPayoutCurve
* @returns True if the curves are the same
*/
equals(curve) {
return this.points.every((point, i) => {
const otherPoint = curve.points[i];
return (point.outcome.eq(otherPoint.outcome) &&
point.payout.eq(otherPoint.payout));
});
}
/**
* Creates a PolynomialPayoutCurve from a PolynomialPayoutCurvePiece
* @param piece
* @returns A PolynomialPayoutCurve
*/
static fromPayoutCurvePiece(piece) {
const points = piece.points.map((point) => {
const outcome = new bignumber_js_1.default(point.eventOutcome.toString());
const payout = new bignumber_js_1.default(point.outcomePayout.toString()).plus((0, Precision_1.fromPrecision)(point.extraPrecision));
return { outcome, payout };
});
return new PolynomialPayoutCurve(points);
}
/**
* Computes all CETs for a given payout curve
* @param payoutFunction The payout function
* @param totalCollateral The total collateral
* @param roundingIntervals The rounding intervals
* @returns A list of CETs
*/
static computePayouts(payoutFunction, totalCollateral, roundingIntervals) {
if (payoutFunction.pieces.length < 1)
throw new Error('Must have at least one piece');
payoutFunction.pieces.forEach((piece) => {
if (piece.payoutCurvePiece.type !== messaging_1.MessageType.PolynomialPayoutCurvePiece)
throw new Error('Payout curve piece must be a polynomial');
});
const CETS = [];
// 1. Add the first piece to the list
const { payoutCurvePiece } = payoutFunction.pieces[0];
const curve = this.fromPayoutCurvePiece(payoutCurvePiece);
CETS.push(...(0, CETCalculator_1.splitIntoRanges)(payoutFunction.endpoint0, payoutFunction.pieces[0].endpoint, payoutFunction.endpointPayout0, payoutFunction.pieces[0].endpointPayout, totalCollateral, curve, roundingIntervals.intervals));
// 2. If there are subsequent pieces, add them to the list
for (let i = 1; i < payoutFunction.pieces.length; i++) {
const { payoutCurvePiece } = payoutFunction.pieces[i];
const curve = this.fromPayoutCurvePiece(payoutCurvePiece);
CETS.push(...(0, CETCalculator_1.splitIntoRanges)(payoutFunction.pieces[i - 1].endpoint, payoutFunction.pieces[i].endpoint, payoutFunction.pieces[i - 1].endpointPayout, payoutFunction.pieces[i].endpointPayout, totalCollateral, curve, roundingIntervals.intervals));
}
return (0, CETCalculator_1.mergePayouts)(CETS);
}
}
exports.PolynomialPayoutCurve = PolynomialPayoutCurve;
//# sourceMappingURL=PolynomialPayoutCurve.js.map