@node-dlc/core
Version:
137 lines • 6.8 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HyperbolaPayoutCurve = 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 HyperbolaPayoutCurve {
constructor(a, b, c, d, translateOutcome, translatePayout, positive = true) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.translateOutcome = translateOutcome;
this.translatePayout = translatePayout;
this.positive = positive;
}
getPayout(_x) {
const { a, b, c, d, translateOutcome, translatePayout } = this;
const x = new bignumber_js_1.default(Number(_x));
const payout = c
.times(x
.minus(translateOutcome)
.plus(x
.minus(translateOutcome)
.exponentiatedBy(2)
.minus(a.times(b).times(4))
.squareRoot())
.div(a.times(2)))
.plus(a
.times(d)
.times(2)
.div(x
.minus(translateOutcome)
.plus(x
.minus(translateOutcome)
.exponentiatedBy(2)
.minus(a.times(b).times(4))
.squareRoot())))
.plus(translatePayout);
return payout;
}
getOutcomeForPayout(payout) {
const { a, b, c, d, translateOutcome, translatePayout } = this;
// Inverse function
// y=(-ad^{2}-bf_{2}^{2}+2bf_{2}x-bx^{2}+df_{1}f_{2}-df_{1}x)/(d(f_{2}-x))
if (c.eq(0)) {
const outcome = a
.negated()
.times(d.exponentiatedBy(2))
.minus(b.times(translatePayout.exponentiatedBy(2)))
.plus(b.times(translatePayout).times(payout).times(2))
.minus(b.times(payout.exponentiatedBy(2)))
.plus(d.times(translateOutcome).times(translatePayout))
.minus(d.times(translateOutcome).times(payout))
.dividedBy(d.times(translatePayout.minus(payout)))
.integerValue();
if (outcome.isFinite())
return BigInt(outcome.toString());
return BigInt(-1);
}
else {
// y=\left((\sqrt{((adf_{2}-adx+bcf_{2}-bcx-2c\cdot d\cdot f_{1})^{2}-4cd(a^{2}d^{2}-2abcd+abf_{2}^{2}-2abf_{2}x+abx^{2}-adf_{1}f_{2}+adf_{1}x+b^{2}c^{2}-bcf_{1}f_{2}+bcf_{1}x+c\cdot d\cdot f_{1}^{2}))}-adf_{2}+adx-bcf_{2}+bcx+2c\cdot d\cdot f_{1})\right)/(2cd)
throw new Error('Not supported');
}
}
toPayoutCurvePiece() {
const { a, b, c, d, translateOutcome, translatePayout, positive } = this;
const piece = new messaging_1.HyperbolaPayoutCurvePiece();
piece.usePositivePiece = positive;
piece.translateOutcomeSign = translateOutcome.isPositive();
piece.translateOutcome = BigInt(translateOutcome.abs().toString());
piece.translateOutcomeExtraPrecision = (0, Precision_1.getPrecision)(translateOutcome);
piece.translatePayoutSign = translatePayout.isPositive();
piece.translatePayout = BigInt(translatePayout.abs().toString());
piece.translatePayoutExtraPrecision = (0, Precision_1.getPrecision)(translatePayout);
piece.aSign = a.isPositive();
piece.a = BigInt(a.abs().toString());
piece.aExtraPrecision = (0, Precision_1.getPrecision)(a);
piece.bSign = b.isPositive();
piece.b = BigInt(b.abs().toString());
piece.bExtraPrecision = (0, Precision_1.getPrecision)(b);
piece.cSign = c.isPositive();
piece.c = BigInt(c.abs().toString());
piece.cExtraPrecision = (0, Precision_1.getPrecision)(c);
piece.dSign = d.isPositive();
piece.d = BigInt(d.integerValue().toString());
piece.dExtraPrecision = (0, Precision_1.getPrecision)(d);
return piece;
}
equals(curve) {
return (this.a.eq(curve.a) &&
this.b.eq(curve.b) &&
this.c.eq(curve.c) &&
this.d.eq(curve.d) &&
this.translateOutcome.eq(curve.translateOutcome) &&
this.translatePayout.eq(curve.translatePayout) &&
this.positive === curve.positive);
}
static fromPayoutCurvePiece(piece) {
const a = new bignumber_js_1.default(piece.a.toString())
.times(piece.aSign ? 1 : -1)
.plus((0, Precision_1.fromPrecision)(piece.aExtraPrecision));
const b = new bignumber_js_1.default(piece.b.toString())
.times(piece.bSign ? 1 : -1)
.plus((0, Precision_1.fromPrecision)(piece.bExtraPrecision));
const c = new bignumber_js_1.default(piece.c.toString())
.times(piece.cSign ? 1 : -1)
.plus((0, Precision_1.fromPrecision)(piece.cExtraPrecision));
const d = new bignumber_js_1.default(piece.d.toString())
.times(piece.dSign ? 1 : -1)
.plus((0, Precision_1.fromPrecision)(piece.dExtraPrecision));
const translateOutcome = new bignumber_js_1.default(piece.translateOutcome.toString())
.times(piece.translateOutcomeSign ? 1 : -1)
.plus((0, Precision_1.fromPrecision)(piece.translateOutcomeExtraPrecision));
const translatePayout = new bignumber_js_1.default(piece.translatePayout.toString())
.times(piece.translatePayoutSign ? 1 : -1)
.plus((0, Precision_1.fromPrecision)(piece.translatePayoutExtraPrecision));
return new HyperbolaPayoutCurve(a, b, c, d, translateOutcome, translatePayout, piece.usePositivePiece);
}
static computePayouts(payoutFunction, totalCollateral, roundingIntervals) {
if (payoutFunction.pieces.length !== 1)
throw new Error('Must have at least one piece');
const { endpoint, endpointPayout, payoutCurvePiece, } = payoutFunction.pieces[0];
if (payoutCurvePiece.type !== messaging_1.MessageType.HyperbolaPayoutCurvePiece &&
payoutCurvePiece.type !== messaging_1.MessageType.OldHyperbolaPayoutCurvePiece)
throw new Error('Payout curve piece must be a hyperbola');
const _payoutCurvePiece = payoutCurvePiece;
const curve = this.fromPayoutCurvePiece(_payoutCurvePiece);
return (0, CETCalculator_1.splitIntoRanges)(payoutFunction.endpoint0, endpoint, payoutFunction.endpointPayout0, endpointPayout, totalCollateral, curve, roundingIntervals.intervals);
}
}
exports.HyperbolaPayoutCurve = HyperbolaPayoutCurve;
//# sourceMappingURL=HyperbolaPayoutCurve.js.map