All files / lib/dlc/finance CoveredCall.ts

96.3% Statements 26/27
50% Branches 1/2
100% Functions 2/2
96.3% Lines 26/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 1111x 1x   1x 1x   1x                   8x 8x 8x 8x   8x 8x   8x                 8x     8x       8x                           1x           4x             4x     4x       4x     4x         4x           4x                 4x           4x           1x  
import { PayoutFunction } from '@node-dlc/messaging';
import BN from 'bignumber.js';
 
import { toBigInt } from '../../utils/BigIntUtils';
import { HyperbolaPayoutCurve } from '../HyperbolaPayoutCurve';
 
const buildCurve = (
  strikePrice: bigint,
  contractSize: bigint,
  oracleBase: number,
  oracleDigits: number,
): {
  maxOutcome: bigint;
  totalCollateral: bigint;
  payoutCurve: HyperbolaPayoutCurve;
} => {
  const a = new BN(1);
  const b = new BN(0);
  const c = new BN(0);
  const d = new BN((strikePrice * contractSize).toString());
 
  const f_1 = new BN(0);
  const _f_2 = new BN(0);
 
  const _tempHyperbolaPayoutCurve = new HyperbolaPayoutCurve(
    a,
    b,
    c,
    d,
    f_1,
    _f_2,
  );
 
  const maxOutcome = BigInt(
    new BN(oracleBase).pow(oracleDigits).minus(1).toString(10),
  );
  const maxOutcomePayout = _tempHyperbolaPayoutCurve
    .getPayout(maxOutcome)
    .integerValue();
 
  return {
    maxOutcome,
    totalCollateral: contractSize - toBigInt(maxOutcomePayout),
    payoutCurve: new HyperbolaPayoutCurve(
      a,
      b,
      c,
      d,
      f_1,
      maxOutcomePayout.negated(),
    ),
  };
};
 
const buildPayoutFunction = (
  strikePrice: bigint,
  contractSize: bigint,
  oracleBase: number,
  oracleDigits: number,
): { payoutFunction: PayoutFunction; totalCollateral: bigint } => {
  const { maxOutcome, totalCollateral, payoutCurve } = buildCurve(
    strikePrice,
    contractSize,
    oracleBase,
    oracleDigits,
  );
 
  const payoutFunction = new PayoutFunction();
 
  // Defensive fix: ensure payoutFunctionPieces is initialized as an array
  Iif (!payoutFunction.payoutFunctionPieces) {
    payoutFunction.payoutFunctionPieces = [];
  }
 
  const curvePiece = payoutCurve.toPayoutCurvePiece();
 
  // Set the left and right endpoints for the hyperbola piece (matching rust-dlc structure)
  curvePiece.leftEndPoint = {
    eventOutcome: BigInt(0),
    outcomePayout: totalCollateral,
    extraPrecision: 0,
  };
  curvePiece.rightEndPoint = {
    eventOutcome: maxOutcome,
    outcomePayout: BigInt(0),
    extraPrecision: 0,
  };
 
  payoutFunction.payoutFunctionPieces.push({
    endPoint: {
      eventOutcome: maxOutcome,
      outcomePayout: BigInt(0),
      extraPrecision: 0,
    },
    payoutCurvePiece: curvePiece,
  });
 
  payoutFunction.lastEndpoint = {
    eventOutcome: maxOutcome,
    outcomePayout: BigInt(0),
    extraPrecision: 0,
  };
 
  return {
    payoutFunction,
    totalCollateral,
  };
};
 
export const CoveredCall = { buildCurve, buildPayoutFunction };