UNPKG

@node-dlc/core

Version:
122 lines 5.43 kB
"use strict"; 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