@atomicfinance/bitcoin-wallet-provider 4.2.8 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +5 -4
- package/.turbo/turbo-lint$colon$fix.log +4 -0
- package/.turbo/turbo-lint.log +5 -0
- package/.turbo/turbo-test.log +0 -0
- package/.yalc/@node-dlc/core/.nyc_output/687a3c14-9765-45fd-a1fe-f7db3d56fee4.json +1 -0
- package/.yalc/@node-dlc/core/.nyc_output/processinfo/687a3c14-9765-45fd-a1fe-f7db3d56fee4.json +1 -0
- package/.yalc/@node-dlc/core/.nyc_output/processinfo/index.json +1 -0
- package/.yalc/@node-dlc/core/README.md +11 -0
- package/.yalc/@node-dlc/core/__tests__/core.spec.ts +7 -0
- package/.yalc/@node-dlc/core/__tests__/dlc/CETCalculator.spec.ts +1029 -0
- package/.yalc/@node-dlc/core/__tests__/dlc/CoinSelect.spec.ts +179 -0
- package/.yalc/@node-dlc/core/__tests__/dlc/PolynomialPayoutCurve.spec.ts +345 -0
- package/.yalc/@node-dlc/core/__tests__/dlc/TxBuilder.spec.ts +424 -0
- package/.yalc/@node-dlc/core/__tests__/dlc/finance/Builder.spec.ts +492 -0
- package/.yalc/@node-dlc/core/__tests__/dlc/finance/CoveredCall.spec.ts +112 -0
- package/.yalc/@node-dlc/core/__tests__/dlc/finance/CsoInfo.spec.ts +1124 -0
- package/.yalc/@node-dlc/core/__tests__/dlc/finance/LongCall.spec.ts +55 -0
- package/.yalc/@node-dlc/core/__tests__/dlc/finance/LongPut.spec.ts +55 -0
- package/.yalc/@node-dlc/core/__tests__/dlc/finance/OptionInfo.spec.ts +226 -0
- package/.yalc/@node-dlc/core/__tests__/dlc/finance/ShortPut.spec.ts +62 -0
- package/.yalc/@node-dlc/core/__tests__/tsconfig.json +8 -0
- package/.yalc/@node-dlc/core/__tests__/utils/precision.spec.ts +40 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/base.css +224 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/block-navigation.js +79 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/favicon.png +0 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/index.html +171 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/AsyncProcessingQueue.ts.html +269 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/Base32.ts.html +86 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/BigIntUtils.ts.html +86 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/BitField.ts.html +86 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/ChannelId.ts.html +86 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/LinkedList.ts.html +413 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/LinkedListNode.ts.html +122 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/Queue.ts.html +188 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/ShortChannelId.ts.html +86 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/ShortChannelIdUtils.ts.html +107 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/CETCalculator.ts.html +1430 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/CoinSelect.ts.html +431 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/HyperbolaPayoutCurve.ts.html +644 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/PolynomialPayoutCurve.ts.html +878 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/TxBuilder.ts.html +1088 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/TxFinalizer.ts.html +731 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/Builder.ts.html +2270 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/CoveredCall.ts.html +410 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/CsoInfo.ts.html +1574 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/LinearPayout.ts.html +362 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/LongCall.ts.html +302 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/LongPut.ts.html +302 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/OptionInfo.ts.html +626 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/ShortPut.ts.html +305 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/finance/index.html +216 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/dlc/index.html +186 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/index.html +261 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/index.ts.html +278 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/ChannelId.ts.html +242 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/ChannelKeys.ts.html +407 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/CommitmentNumber.ts.html +362 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/CommitmentSecret.ts.html +203 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/CommitmentSecretStore.ts.html +332 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/Htlc.ts.html +236 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/HtlcDirection.ts.html +131 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/ScriptFactory.ts.html +530 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/TxFactory.ts.html +1094 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/lightning/index.html +231 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/utils/BigIntUtils.ts.html +272 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/utils/Precision.ts.html +149 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/lib/utils/index.html +126 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/prettify.css +1 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/prettify.js +2 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/.yalc/@node-dlc/core/coverage/lcov-report/sorter.js +170 -0
- package/.yalc/@node-dlc/core/coverage/lcov.info +2426 -0
- package/.yalc/@node-dlc/core/dist/AsyncProcessingQueue.d.ts +22 -0
- package/.yalc/@node-dlc/core/dist/AsyncProcessingQueue.js +55 -0
- package/.yalc/@node-dlc/core/dist/AsyncProcessingQueue.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/Base32.d.ts +1 -0
- package/.yalc/@node-dlc/core/dist/Base32.js +7 -0
- package/.yalc/@node-dlc/core/dist/Base32.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/BigIntUtils.d.ts +1 -0
- package/.yalc/@node-dlc/core/dist/BigIntUtils.js +8 -0
- package/.yalc/@node-dlc/core/dist/BigIntUtils.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/BitField.d.ts +1 -0
- package/.yalc/@node-dlc/core/dist/BitField.js +7 -0
- package/.yalc/@node-dlc/core/dist/BitField.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/ChannelId.d.ts +1 -0
- package/.yalc/@node-dlc/core/dist/ChannelId.js +7 -0
- package/.yalc/@node-dlc/core/dist/ChannelId.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/LinkedList.d.ts +30 -0
- package/.yalc/@node-dlc/core/dist/LinkedList.js +104 -0
- package/.yalc/@node-dlc/core/dist/LinkedList.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/LinkedListNode.d.ts +9 -0
- package/.yalc/@node-dlc/core/dist/LinkedListNode.js +15 -0
- package/.yalc/@node-dlc/core/dist/LinkedListNode.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/Queue.d.ts +22 -0
- package/.yalc/@node-dlc/core/dist/Queue.js +38 -0
- package/.yalc/@node-dlc/core/dist/Queue.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/ShortChannelId.d.ts +1 -0
- package/.yalc/@node-dlc/core/dist/ShortChannelId.js +7 -0
- package/.yalc/@node-dlc/core/dist/ShortChannelId.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/ShortChannelIdUtils.d.ts +1 -0
- package/.yalc/@node-dlc/core/dist/ShortChannelIdUtils.js +12 -0
- package/.yalc/@node-dlc/core/dist/ShortChannelIdUtils.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/CETCalculator.d.ts +50 -0
- package/.yalc/@node-dlc/core/dist/dlc/CETCalculator.js +332 -0
- package/.yalc/@node-dlc/core/dist/dlc/CETCalculator.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/CoinSelect.d.ts +23 -0
- package/.yalc/@node-dlc/core/dist/dlc/CoinSelect.js +77 -0
- package/.yalc/@node-dlc/core/dist/dlc/CoinSelect.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/HyperbolaPayoutCurve.d.ts +20 -0
- package/.yalc/@node-dlc/core/dist/dlc/HyperbolaPayoutCurve.js +117 -0
- package/.yalc/@node-dlc/core/dist/dlc/HyperbolaPayoutCurve.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/PayoutCurve.d.ts +5 -0
- package/.yalc/@node-dlc/core/dist/dlc/PayoutCurve.js +3 -0
- package/.yalc/@node-dlc/core/dist/dlc/PayoutCurve.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/PolynomialPayoutCurve.d.ts +52 -0
- package/.yalc/@node-dlc/core/dist/dlc/PolynomialPayoutCurve.js +173 -0
- package/.yalc/@node-dlc/core/dist/dlc/PolynomialPayoutCurve.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/TxBuilder.d.ts +55 -0
- package/.yalc/@node-dlc/core/dist/dlc/TxBuilder.js +217 -0
- package/.yalc/@node-dlc/core/dist/dlc/TxBuilder.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/TxFinalizer.d.ts +40 -0
- package/.yalc/@node-dlc/core/dist/dlc/TxFinalizer.js +146 -0
- package/.yalc/@node-dlc/core/dist/dlc/TxFinalizer.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/Builder.d.ts +193 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/Builder.js +422 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/Builder.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/CoveredCall.d.ts +13 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/CoveredCall.js +67 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/CoveredCall.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/CsoInfo.d.ts +114 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/CsoInfo.js +290 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/CsoInfo.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/LinearPayout.d.ts +6 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/LinearPayout.js +79 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/LinearPayout.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/LongCall.d.ts +13 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/LongCall.js +47 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/LongCall.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/LongPut.d.ts +13 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/LongPut.js +47 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/LongPut.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/OptionInfo.d.ts +20 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/OptionInfo.js +101 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/OptionInfo.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/ShortPut.d.ts +12 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/ShortPut.js +46 -0
- package/.yalc/@node-dlc/core/dist/dlc/finance/ShortPut.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/index.d.ts +39 -0
- package/.yalc/@node-dlc/core/dist/index.js +78 -0
- package/.yalc/@node-dlc/core/dist/index.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/lightning/ChannelId.d.ts +31 -0
- package/.yalc/@node-dlc/core/dist/lightning/ChannelId.js +52 -0
- package/.yalc/@node-dlc/core/dist/lightning/ChannelId.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/lightning/ChannelKeys.d.ts +55 -0
- package/.yalc/@node-dlc/core/dist/lightning/ChannelKeys.js +105 -0
- package/.yalc/@node-dlc/core/dist/lightning/ChannelKeys.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/lightning/CommitmentNumber.d.ts +55 -0
- package/.yalc/@node-dlc/core/dist/lightning/CommitmentNumber.js +76 -0
- package/.yalc/@node-dlc/core/dist/lightning/CommitmentNumber.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecret.d.ts +26 -0
- package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecret.js +44 -0
- package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecret.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecretStore.d.ts +41 -0
- package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecretStore.js +79 -0
- package/.yalc/@node-dlc/core/dist/lightning/CommitmentSecretStore.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/lightning/Htlc.d.ts +46 -0
- package/.yalc/@node-dlc/core/dist/lightning/Htlc.js +46 -0
- package/.yalc/@node-dlc/core/dist/lightning/Htlc.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/lightning/HtlcDirection.d.ts +16 -0
- package/.yalc/@node-dlc/core/dist/lightning/HtlcDirection.js +21 -0
- package/.yalc/@node-dlc/core/dist/lightning/HtlcDirection.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/lightning/ScriptFactory.d.ts +76 -0
- package/.yalc/@node-dlc/core/dist/lightning/ScriptFactory.js +102 -0
- package/.yalc/@node-dlc/core/dist/lightning/ScriptFactory.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/lightning/TxFactory.d.ts +83 -0
- package/.yalc/@node-dlc/core/dist/lightning/TxFactory.js +222 -0
- package/.yalc/@node-dlc/core/dist/lightning/TxFactory.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/utils/BigIntUtils.d.ts +9 -0
- package/.yalc/@node-dlc/core/dist/utils/BigIntUtils.js +59 -0
- package/.yalc/@node-dlc/core/dist/utils/BigIntUtils.js.map +1 -0
- package/.yalc/@node-dlc/core/dist/utils/Precision.d.ts +13 -0
- package/.yalc/@node-dlc/core/dist/utils/Precision.js +28 -0
- package/.yalc/@node-dlc/core/dist/utils/Precision.js.map +1 -0
- package/.yalc/@node-dlc/core/lib/AsyncProcessingQueue.ts +63 -0
- package/.yalc/@node-dlc/core/lib/Base32.ts +2 -0
- package/.yalc/@node-dlc/core/lib/BigIntUtils.ts +2 -0
- package/.yalc/@node-dlc/core/lib/BitField.ts +2 -0
- package/.yalc/@node-dlc/core/lib/ChannelId.ts +2 -0
- package/.yalc/@node-dlc/core/lib/LinkedList.ts +111 -0
- package/.yalc/@node-dlc/core/lib/LinkedListNode.ts +14 -0
- package/.yalc/@node-dlc/core/lib/Queue.ts +36 -0
- package/.yalc/@node-dlc/core/lib/ShortChannelId.ts +2 -0
- package/.yalc/@node-dlc/core/lib/ShortChannelIdUtils.ts +9 -0
- package/.yalc/@node-dlc/core/lib/dlc/CETCalculator.ts +450 -0
- package/.yalc/@node-dlc/core/lib/dlc/CoinSelect.ts +117 -0
- package/.yalc/@node-dlc/core/lib/dlc/HyperbolaPayoutCurve.ts +188 -0
- package/.yalc/@node-dlc/core/lib/dlc/PayoutCurve.ts +6 -0
- package/.yalc/@node-dlc/core/lib/dlc/PolynomialPayoutCurve.ts +266 -0
- package/.yalc/@node-dlc/core/lib/dlc/TxBuilder.ts +336 -0
- package/.yalc/@node-dlc/core/lib/dlc/TxFinalizer.ts +217 -0
- package/.yalc/@node-dlc/core/lib/dlc/finance/Builder.ts +730 -0
- package/.yalc/@node-dlc/core/lib/dlc/finance/CoveredCall.ts +110 -0
- package/.yalc/@node-dlc/core/lib/dlc/finance/CsoInfo.ts +498 -0
- package/.yalc/@node-dlc/core/lib/dlc/finance/LinearPayout.ts +94 -0
- package/.yalc/@node-dlc/core/lib/dlc/finance/LongCall.ts +74 -0
- package/.yalc/@node-dlc/core/lib/dlc/finance/LongPut.ts +74 -0
- package/.yalc/@node-dlc/core/lib/dlc/finance/OptionInfo.ts +182 -0
- package/.yalc/@node-dlc/core/lib/dlc/finance/ShortPut.ts +75 -0
- package/.yalc/@node-dlc/core/lib/index.ts +66 -0
- package/.yalc/@node-dlc/core/lib/lightning/ChannelId.ts +54 -0
- package/.yalc/@node-dlc/core/lib/lightning/ChannelKeys.ts +109 -0
- package/.yalc/@node-dlc/core/lib/lightning/CommitmentNumber.ts +94 -0
- package/.yalc/@node-dlc/core/lib/lightning/CommitmentSecret.ts +41 -0
- package/.yalc/@node-dlc/core/lib/lightning/CommitmentSecretStore.ts +84 -0
- package/.yalc/@node-dlc/core/lib/lightning/Htlc.ts +52 -0
- package/.yalc/@node-dlc/core/lib/lightning/HtlcDirection.ts +17 -0
- package/.yalc/@node-dlc/core/lib/lightning/ScriptFactory.ts +150 -0
- package/.yalc/@node-dlc/core/lib/lightning/TxFactory.ts +338 -0
- package/.yalc/@node-dlc/core/lib/utils/BigIntUtils.ts +64 -0
- package/.yalc/@node-dlc/core/lib/utils/Precision.ts +23 -0
- package/.yalc/@node-dlc/core/package.json +38 -0
- package/.yalc/@node-dlc/core/tsconfig.json +8 -0
- package/.yalc/@node-dlc/core/yalc.sig +1 -0
- package/CHANGELOG.md +11 -0
- package/package.json +6 -6
- package/yalc.lock +10 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
import { Value } from '@node-dlc/bitcoin';
|
|
2
|
+
import {
|
|
3
|
+
ContractDescriptorV1,
|
|
4
|
+
ContractInfoV0,
|
|
5
|
+
OracleAnnouncement,
|
|
6
|
+
PayoutFunctionV0,
|
|
7
|
+
} from '@node-dlc/messaging';
|
|
8
|
+
import { BitcoinNetworks } from 'bitcoin-networks';
|
|
9
|
+
import { expect } from 'chai';
|
|
10
|
+
import sinon from 'sinon';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
buildCoveredCallOrderOffer,
|
|
14
|
+
buildCustomStrategyOrderOffer,
|
|
15
|
+
buildLongCallOrderOffer,
|
|
16
|
+
buildLongPutOrderOffer,
|
|
17
|
+
buildRoundingIntervalsFromIntervals,
|
|
18
|
+
buildShortPutOrderOffer,
|
|
19
|
+
computeRoundingModulus,
|
|
20
|
+
UNIT_MULTIPLIER,
|
|
21
|
+
} from '../../../lib/dlc/finance/Builder';
|
|
22
|
+
|
|
23
|
+
describe('OrderOffer Builder', () => {
|
|
24
|
+
describe('buildCoveredCallOrderOffer', () => {
|
|
25
|
+
const strikePrice = 50000;
|
|
26
|
+
const contractSize = Value.fromSats(100000000);
|
|
27
|
+
const premium = Value.fromSats(25000);
|
|
28
|
+
const threeXPremium = Value.fromSats(75000);
|
|
29
|
+
const totalCollateral = contractSize;
|
|
30
|
+
const oracleAnnouncementBuf = Buffer.from(
|
|
31
|
+
'fdd824fd02ab1efe41fa42ea1dcd103a0251929dd2b192d2daece8a4ce4d81f68a183b750d92d6f02d796965dc79adf4e7786e08f861a1ecc897afbba2dab9cff6eb0a81937eb8b005b07acf849ad2cec22107331dedbf5a607654fad4eafe39c278e27dde68fdd822fd02450011f9313f1edd903fab297d5350006b669506eb0ffda0bb58319b4df89ac24e14fd15f9791dc78d1596b06f4969bdb37d9e394dc9fedaa18d694027fa32b5ea2a5e60080c58e13727367c3a4ce1ad65dfb3c7e3ca1ea912b0299f6e383bab2875058aa96a1c74633130af6fbd008788de6ac9db76da4ecc7303383cc1a49f525316413850f7e3ac385019d560e84c5b3a3e9ae6c83f59fe4286ddfd23ea46d7ae04610a175cd28a9bf5f574e245c3dfe230dc4b0adf4daaea96780e594f6464f676505f4b74cfe3ffc33415a23de795bf939ce64c0c02033bbfc6c9ff26fb478943a1ece775f38f5db067ca4b2a9168b40792398def9164bfe5c46838472dc3c162af16c811b7a116e9417d5bccb9e5b8a5d7d26095aba993696188c3f85a02f7ab8d12ada171c352785eb63417228c7e248909fc2d673e1bb453140bf8bf429375819afb5e9556663b76ff09c2a7ba9779855ffddc6d360cb459cf8c42a2b949d0de19fe96163d336fd66a4ce2f1791110e679572a20036ffae50204ef520c01058ff4bef28218d1c0e362ee3694ad8b2ae83a51c86c4bc1630ed6202a158810096726f809fc828fafdcf053496affdf887ae8c54b6ca4323ccecf6a51121c4f0c60e790536dab41b221db1c6b35065dc19a9d31cf75901aa35eefecbb6fefd07296cda13cb34ce3b58eba20a0eb8f9614994ec7fee3cc290e30e6b1e3211ae1f3a85b6de6abdbb77d6d9ed33a1cee3bd5cd93a71f12c9c45e385d744ad0e7286660305100fdd80a11000200076274632f75736400000000001109425443205072696365',
|
|
32
|
+
'hex',
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const oracleAnnouncement = OracleAnnouncement.deserialize(
|
|
36
|
+
oracleAnnouncementBuf,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
it('should build a covered call OrderOffer correctly', () => {
|
|
40
|
+
sinon.stub(Date.prototype, 'getTime').returns(Date.UTC(2021, 1, 5));
|
|
41
|
+
|
|
42
|
+
const orderOffer = buildCoveredCallOrderOffer(
|
|
43
|
+
oracleAnnouncement,
|
|
44
|
+
contractSize,
|
|
45
|
+
strikePrice,
|
|
46
|
+
premium,
|
|
47
|
+
12,
|
|
48
|
+
10000,
|
|
49
|
+
'bitcoin',
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(() => orderOffer.validate()).to.not.throw(Error);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('should build a short put OrderOffer correctly', () => {
|
|
56
|
+
const orderOffer = buildShortPutOrderOffer(
|
|
57
|
+
oracleAnnouncement,
|
|
58
|
+
contractSize,
|
|
59
|
+
strikePrice,
|
|
60
|
+
totalCollateral,
|
|
61
|
+
premium,
|
|
62
|
+
12,
|
|
63
|
+
10000,
|
|
64
|
+
'bitcoin',
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
expect(() => orderOffer.validate()).to.not.throw(Error);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should build a long call OrderOffer correctly', () => {
|
|
71
|
+
const orderOffer = buildLongCallOrderOffer(
|
|
72
|
+
oracleAnnouncement,
|
|
73
|
+
contractSize,
|
|
74
|
+
strikePrice,
|
|
75
|
+
threeXPremium,
|
|
76
|
+
premium,
|
|
77
|
+
12,
|
|
78
|
+
10000,
|
|
79
|
+
'bitcoin',
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
expect(() => orderOffer.validate()).to.not.throw(Error);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should build a long put OrderOffer correctly', () => {
|
|
86
|
+
const orderOffer = buildLongPutOrderOffer(
|
|
87
|
+
oracleAnnouncement,
|
|
88
|
+
contractSize,
|
|
89
|
+
strikePrice,
|
|
90
|
+
threeXPremium,
|
|
91
|
+
premium,
|
|
92
|
+
12,
|
|
93
|
+
10000,
|
|
94
|
+
'bitcoin',
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
expect(() => orderOffer.validate()).to.not.throw(Error);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should fail to build an OrderOffer with an invalid oracleAnnouncement', () => {
|
|
101
|
+
oracleAnnouncement.announcementSig = Buffer.from('deadbeef', 'hex');
|
|
102
|
+
|
|
103
|
+
const orderOffer = buildShortPutOrderOffer(
|
|
104
|
+
oracleAnnouncement,
|
|
105
|
+
contractSize,
|
|
106
|
+
strikePrice,
|
|
107
|
+
totalCollateral,
|
|
108
|
+
premium,
|
|
109
|
+
12,
|
|
110
|
+
10000,
|
|
111
|
+
'bitcoin',
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
expect(() => orderOffer.validate()).to.throw(Error);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe('buildCustomStrategyOrderOffer', () => {
|
|
119
|
+
const contractSizes: Value[] = [
|
|
120
|
+
Value.fromBitcoin(1),
|
|
121
|
+
Value.fromBitcoin(0.1),
|
|
122
|
+
Value.fromBitcoin(0.5),
|
|
123
|
+
Value.fromBitcoin(1.5),
|
|
124
|
+
Value.fromBitcoin(2),
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
const defaultContractSize = Value.fromBitcoin(1);
|
|
128
|
+
|
|
129
|
+
const maxLoss = Value.fromBitcoin(0.2);
|
|
130
|
+
const maxGain = Value.fromBitcoin(0.04);
|
|
131
|
+
const feeRate = 2n;
|
|
132
|
+
|
|
133
|
+
const highestPrecisionRounding = Value.fromSats(10000);
|
|
134
|
+
const highPrecisionRounding = Value.fromSats(25000);
|
|
135
|
+
const mediumPrecisionRounding = Value.fromSats(100000);
|
|
136
|
+
const lowPrecisionRounding = Value.fromSats(200000);
|
|
137
|
+
|
|
138
|
+
const network = BitcoinNetworks.bitcoin;
|
|
139
|
+
|
|
140
|
+
const oracleAnnouncementBuf = Buffer.from(
|
|
141
|
+
'fdd824fd032e4a2b121973a7d2be4784fb6fb0c7b97405b757fb078b58bb729756a7372bf1bdc05c373472fc57fde0a07dcdad027f48f313fa1e349ab8bb936472735fce5221ff9c4885aa0c5987046ada7e729dac33591777a37af8bf14dedb95997d0c7d4bfdd822fd02c800154a2b121973a7d2be4784fb6fb0c7b97405b757fb078b58bb729756a7372bf1bdd7cb55eee59faac9a590e7d3bab782276daa0744786aaff3f69a1e51de99012339492f00198932d8057eb6742bd5245e37fd22b44e0bfaa68577ce5654b478786eb7dc091559699292dc060ee82864cffd863eb8fa876682099af34a8f3eab9174773231e6950b077df212df3fc91c199c34200cd8ce00f1c8a050ad471bfc1478e90d06bd77f11fc3804435556ed5dc1eb19b95a978f595ba127ea225c4662e22ea614cab60054d9b21da904cd9eac5b514a6a011de635ad08e0c72766a7bbc9144df24fe6bf3e0d631a61a1da27e93c6f4ea6829795f4c63628747415a41ffe199129639d7a6c430184aa925b9ab224c9180b64c86959bd7abc9ffa08fe4421952114839d5120f4ea9c9437364b4956b25a141aeefbc30d3e6cc811f9424d266671dc330b7f3d00f1f7a521e14697a0259499e6cc8fa0da13a095279f827cfe2cf11508c6d8d1405f6cb337d68fbe29fde5acbb094ff397c14c24f084ac6ef466b1d85d5160de41ed8ed435ab52f948788dc45406e07f02683c9822431d91d95a04e11e4fdb521485aa8737bdd8c67cfefd0d103f86005491181e704adafc7f49cc9700ce8cffda9c9b265bc64ed19b42d4b5e4449f6b0da81342923c45f37b1381b3a29b9acce9818f4ec6af0ecbddc063e64868f350281054d13599e6e35d503532b6fa9c0db85db703dde1de21142b351ecce626128f98ddb5dab11f669c16de45d3dd054786aa5e3fb6369114b97bee6c26d21be0f71258dfa3e8ec8b8890719eef8e817b69072f74325088781a50b4cd5fe74493828dfe9cb21b698901e48f9f4d7b70a636794feae500aac237add2630bad1257b0cac1b71a8fcd5dbd7540a84ccac5d48b76afae2b3dfe3ea8eb8cd6e67febb6a1433504329948e426064108cfdd80a0e00020004626974730000000000150f73747261746567794f7574636f6d65',
|
|
142
|
+
'hex',
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const oracleAnnouncement = OracleAnnouncement.deserialize(
|
|
146
|
+
oracleAnnouncementBuf,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const unit = 'bits';
|
|
150
|
+
|
|
151
|
+
for (const contractSize of contractSizes) {
|
|
152
|
+
it(`should build a CSO OrderOffer with contract size ${contractSize.bitcoin} BTC correctly`, () => {
|
|
153
|
+
const roundingIntervals = buildRoundingIntervalsFromIntervals(
|
|
154
|
+
contractSize,
|
|
155
|
+
[
|
|
156
|
+
{ beginInterval: 0n, rounding: lowPrecisionRounding },
|
|
157
|
+
{ beginInterval: 750000n, rounding: mediumPrecisionRounding },
|
|
158
|
+
{ beginInterval: 850000n, rounding: highPrecisionRounding },
|
|
159
|
+
{ beginInterval: 950000n, rounding: highestPrecisionRounding },
|
|
160
|
+
],
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
const orderOffer = buildCustomStrategyOrderOffer(
|
|
164
|
+
oracleAnnouncement,
|
|
165
|
+
contractSize,
|
|
166
|
+
maxLoss,
|
|
167
|
+
maxGain,
|
|
168
|
+
feeRate,
|
|
169
|
+
roundingIntervals,
|
|
170
|
+
network,
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
const payoutCurvePieces = (((orderOffer.contractInfo as ContractInfoV0)
|
|
174
|
+
.contractDescriptor as ContractDescriptorV1)
|
|
175
|
+
.payoutFunction as PayoutFunctionV0).payoutFunctionPieces;
|
|
176
|
+
|
|
177
|
+
expect(() => orderOffer.validate()).to.not.throw(Error);
|
|
178
|
+
expect(orderOffer.contractInfo.totalCollateral).to.equal(
|
|
179
|
+
contractSize.sats,
|
|
180
|
+
);
|
|
181
|
+
expect(orderOffer.offerCollateralSatoshis).to.equal(
|
|
182
|
+
contractSize.sats - (contractSize.sats * maxGain.sats) / BigInt(1e8),
|
|
183
|
+
);
|
|
184
|
+
expect(payoutCurvePieces[0].endPoint.eventOutcome).to.equal(
|
|
185
|
+
(defaultContractSize.sats - maxLoss.sats) /
|
|
186
|
+
BigInt(UNIT_MULTIPLIER[unit]),
|
|
187
|
+
);
|
|
188
|
+
expect(payoutCurvePieces[1].endPoint.eventOutcome).to.equal(
|
|
189
|
+
(defaultContractSize.sats + maxGain.sats) /
|
|
190
|
+
BigInt(UNIT_MULTIPLIER[unit]),
|
|
191
|
+
);
|
|
192
|
+
expect(payoutCurvePieces[0].endPoint.outcomePayout).to.equal(
|
|
193
|
+
contractSize.sats -
|
|
194
|
+
(maxLoss.sats * contractSize.sats) / BigInt(1e8) -
|
|
195
|
+
(maxGain.sats * contractSize.sats) / BigInt(1e8),
|
|
196
|
+
);
|
|
197
|
+
expect(payoutCurvePieces[1].endPoint.outcomePayout).to.equal(
|
|
198
|
+
contractSize.sats,
|
|
199
|
+
);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
it('should build a CSO OrderOffer and shift the payout curve correctly for offeror fees', () => {
|
|
204
|
+
const contractSize = contractSizes[0];
|
|
205
|
+
|
|
206
|
+
const roundingIntervals = buildRoundingIntervalsFromIntervals(
|
|
207
|
+
contractSize,
|
|
208
|
+
[
|
|
209
|
+
{ beginInterval: 0n, rounding: lowPrecisionRounding },
|
|
210
|
+
{ beginInterval: 750000n, rounding: mediumPrecisionRounding },
|
|
211
|
+
{ beginInterval: 850000n, rounding: highPrecisionRounding },
|
|
212
|
+
{ beginInterval: 950000n, rounding: highestPrecisionRounding },
|
|
213
|
+
],
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
const offerFees = Value.fromSats(10000);
|
|
217
|
+
|
|
218
|
+
const orderOffer = buildCustomStrategyOrderOffer(
|
|
219
|
+
oracleAnnouncement,
|
|
220
|
+
contractSize,
|
|
221
|
+
maxLoss,
|
|
222
|
+
maxGain,
|
|
223
|
+
feeRate,
|
|
224
|
+
roundingIntervals,
|
|
225
|
+
network,
|
|
226
|
+
'offeror',
|
|
227
|
+
offerFees,
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
const payoutCurvePieces = (((orderOffer.contractInfo as ContractInfoV0)
|
|
231
|
+
.contractDescriptor as ContractDescriptorV1)
|
|
232
|
+
.payoutFunction as PayoutFunctionV0).payoutFunctionPieces;
|
|
233
|
+
|
|
234
|
+
expect(() => orderOffer.validate()).to.not.throw(Error);
|
|
235
|
+
expect(orderOffer.contractInfo.totalCollateral).to.equal(
|
|
236
|
+
contractSize.sats,
|
|
237
|
+
);
|
|
238
|
+
expect(orderOffer.offerCollateralSatoshis).to.equal(
|
|
239
|
+
contractSize.sats - (contractSize.sats * maxGain.sats) / BigInt(1e8),
|
|
240
|
+
);
|
|
241
|
+
expect(payoutCurvePieces[0].endPoint.eventOutcome).to.equal(
|
|
242
|
+
(defaultContractSize.sats - maxLoss.sats + offerFees.sats) /
|
|
243
|
+
BigInt(UNIT_MULTIPLIER[unit]),
|
|
244
|
+
);
|
|
245
|
+
expect(payoutCurvePieces[1].endPoint.eventOutcome).to.equal(
|
|
246
|
+
(defaultContractSize.sats + maxGain.sats + offerFees.sats) /
|
|
247
|
+
BigInt(UNIT_MULTIPLIER[unit]),
|
|
248
|
+
);
|
|
249
|
+
expect(payoutCurvePieces[0].endPoint.outcomePayout).to.equal(
|
|
250
|
+
contractSize.sats -
|
|
251
|
+
(maxLoss.sats * contractSize.sats) / BigInt(1e8) -
|
|
252
|
+
(maxGain.sats * contractSize.sats) / BigInt(1e8),
|
|
253
|
+
);
|
|
254
|
+
expect(payoutCurvePieces[1].endPoint.outcomePayout).to.equal(
|
|
255
|
+
contractSize.sats,
|
|
256
|
+
);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('should build a CSO OrderOffer and shift the payout curve correctly for acceptor fees', () => {
|
|
260
|
+
const acceptFees = Value.fromSats(10000);
|
|
261
|
+
|
|
262
|
+
const contractSize = contractSizes[0];
|
|
263
|
+
|
|
264
|
+
const roundingIntervals = buildRoundingIntervalsFromIntervals(
|
|
265
|
+
contractSize,
|
|
266
|
+
[
|
|
267
|
+
{ beginInterval: 0n, rounding: lowPrecisionRounding },
|
|
268
|
+
{ beginInterval: 750000n, rounding: mediumPrecisionRounding },
|
|
269
|
+
{ beginInterval: 850000n, rounding: highPrecisionRounding },
|
|
270
|
+
{ beginInterval: 950000n, rounding: highestPrecisionRounding },
|
|
271
|
+
],
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
const orderOffer = buildCustomStrategyOrderOffer(
|
|
275
|
+
oracleAnnouncement,
|
|
276
|
+
contractSize,
|
|
277
|
+
maxLoss,
|
|
278
|
+
maxGain,
|
|
279
|
+
feeRate,
|
|
280
|
+
roundingIntervals,
|
|
281
|
+
network,
|
|
282
|
+
'acceptor',
|
|
283
|
+
acceptFees,
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
const payoutCurvePieces = (((orderOffer.contractInfo as ContractInfoV0)
|
|
287
|
+
.contractDescriptor as ContractDescriptorV1)
|
|
288
|
+
.payoutFunction as PayoutFunctionV0).payoutFunctionPieces;
|
|
289
|
+
|
|
290
|
+
expect(() => orderOffer.validate()).to.not.throw(Error);
|
|
291
|
+
expect(orderOffer.contractInfo.totalCollateral).to.equal(
|
|
292
|
+
contractSize.sats,
|
|
293
|
+
);
|
|
294
|
+
expect(orderOffer.offerCollateralSatoshis).to.equal(
|
|
295
|
+
contractSize.sats - (contractSize.sats * maxGain.sats) / BigInt(1e8),
|
|
296
|
+
);
|
|
297
|
+
expect(payoutCurvePieces[0].endPoint.eventOutcome).to.equal(
|
|
298
|
+
(defaultContractSize.sats - maxLoss.sats - acceptFees.sats) /
|
|
299
|
+
BigInt(UNIT_MULTIPLIER[unit]),
|
|
300
|
+
);
|
|
301
|
+
expect(payoutCurvePieces[1].endPoint.eventOutcome).to.equal(
|
|
302
|
+
(defaultContractSize.sats + maxGain.sats - acceptFees.sats) /
|
|
303
|
+
BigInt(UNIT_MULTIPLIER[unit]),
|
|
304
|
+
);
|
|
305
|
+
expect(payoutCurvePieces[0].endPoint.outcomePayout).to.equal(
|
|
306
|
+
contractSize.sats -
|
|
307
|
+
(maxLoss.sats * contractSize.sats) / BigInt(1e8) -
|
|
308
|
+
(maxGain.sats * contractSize.sats) / BigInt(1e8),
|
|
309
|
+
);
|
|
310
|
+
expect(payoutCurvePieces[1].endPoint.outcomePayout).to.equal(
|
|
311
|
+
contractSize.sats,
|
|
312
|
+
);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
it('should fail to build a CSO OrderOffer with contractSize 0', () => {
|
|
316
|
+
const contractSize = Value.zero();
|
|
317
|
+
|
|
318
|
+
const roundingIntervals = buildRoundingIntervalsFromIntervals(
|
|
319
|
+
contractSize,
|
|
320
|
+
[
|
|
321
|
+
{ beginInterval: 0n, rounding: lowPrecisionRounding },
|
|
322
|
+
{ beginInterval: 750000n, rounding: mediumPrecisionRounding },
|
|
323
|
+
{ beginInterval: 850000n, rounding: highPrecisionRounding },
|
|
324
|
+
{ beginInterval: 950000n, rounding: highestPrecisionRounding },
|
|
325
|
+
],
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
try {
|
|
329
|
+
buildCustomStrategyOrderOffer(
|
|
330
|
+
oracleAnnouncement,
|
|
331
|
+
contractSize,
|
|
332
|
+
maxLoss,
|
|
333
|
+
maxGain,
|
|
334
|
+
feeRate,
|
|
335
|
+
roundingIntervals,
|
|
336
|
+
network,
|
|
337
|
+
);
|
|
338
|
+
// If the function call does not throw, fail the test
|
|
339
|
+
expect.fail(
|
|
340
|
+
'Expected buildCustomStrategyOrderOffer to throw an error due to contractSize being 0',
|
|
341
|
+
);
|
|
342
|
+
} catch (error) {
|
|
343
|
+
// Assert that the error message is as expected
|
|
344
|
+
expect(error.message).to.equal('contractSize must be greater than 0');
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it('should fail to build a CSO OrderOffer with an invalid oracleAnnouncement', () => {
|
|
349
|
+
const contractSize = contractSizes[0];
|
|
350
|
+
|
|
351
|
+
const roundingIntervals = buildRoundingIntervalsFromIntervals(
|
|
352
|
+
contractSize,
|
|
353
|
+
[
|
|
354
|
+
{ beginInterval: 0n, rounding: lowPrecisionRounding },
|
|
355
|
+
{ beginInterval: 750000n, rounding: mediumPrecisionRounding },
|
|
356
|
+
{ beginInterval: 850000n, rounding: highPrecisionRounding },
|
|
357
|
+
{ beginInterval: 950000n, rounding: highestPrecisionRounding },
|
|
358
|
+
],
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
oracleAnnouncement.announcementSig = Buffer.from(
|
|
362
|
+
'deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef',
|
|
363
|
+
'hex',
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
const skipValidation = true;
|
|
367
|
+
|
|
368
|
+
const orderOffer = buildCustomStrategyOrderOffer(
|
|
369
|
+
oracleAnnouncement,
|
|
370
|
+
contractSize,
|
|
371
|
+
maxLoss,
|
|
372
|
+
maxGain,
|
|
373
|
+
feeRate,
|
|
374
|
+
roundingIntervals,
|
|
375
|
+
network,
|
|
376
|
+
undefined,
|
|
377
|
+
undefined,
|
|
378
|
+
undefined,
|
|
379
|
+
undefined,
|
|
380
|
+
undefined,
|
|
381
|
+
skipValidation,
|
|
382
|
+
);
|
|
383
|
+
|
|
384
|
+
expect(() => orderOffer.validate()).to.throw(Error);
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
describe('computeRoundingModulus', () => {
|
|
389
|
+
describe('with satoshi inputs (existing functionality)', () => {
|
|
390
|
+
it('should properly compute the rounding modulus for 0.0001 BTC', () => {
|
|
391
|
+
const modulus = computeRoundingModulus(BigInt(100000), BigInt(10000));
|
|
392
|
+
expect(modulus).to.equal(BigInt(10));
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
it('should properly compute the rounding modulus for 1 BTC', () => {
|
|
396
|
+
const modulus = computeRoundingModulus(
|
|
397
|
+
BigInt(100000),
|
|
398
|
+
BigInt(100000000),
|
|
399
|
+
);
|
|
400
|
+
expect(modulus).to.equal(BigInt(100000));
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
it('should properly compute the rounding modulus for 1.25 BTC', () => {
|
|
404
|
+
const modulus = computeRoundingModulus(BigInt(5000), BigInt(125000000));
|
|
405
|
+
expect(modulus).to.equal(BigInt(6250));
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
it('should properly compute the rounding modulus for 0.9 BTC', () => {
|
|
409
|
+
const modulus = computeRoundingModulus(
|
|
410
|
+
BigInt(100000),
|
|
411
|
+
BigInt(90000000),
|
|
412
|
+
);
|
|
413
|
+
expect(modulus).to.equal(BigInt(90000));
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
describe('with bitcoin amount inputs (new functionality)', () => {
|
|
418
|
+
it('should properly compute the rounding modulus for 0.001 BTC rounding with 0.1 BTC contract size', () => {
|
|
419
|
+
const modulus = computeRoundingModulus(0.001, 0.1); // 0.001 BTC rounding, 0.1 BTC contract
|
|
420
|
+
expect(modulus).to.equal(BigInt(10000)); // (0.001 * 1e8) * (0.1 * 1e8) / 1e8 = 10000
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
it('should properly compute the rounding modulus for 0.0001 BTC rounding with 1 BTC contract size', () => {
|
|
424
|
+
const modulus = computeRoundingModulus(0.0001, 1); // 0.0001 BTC rounding, 1 BTC contract
|
|
425
|
+
expect(modulus).to.equal(BigInt(10000)); // (0.0001 * 1e8) * (1 * 1e8) / 1e8 = 10000
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
it('should properly compute the rounding modulus for 0.001 BTC rounding with 1.5 BTC contract size', () => {
|
|
429
|
+
const modulus = computeRoundingModulus(0.001, 1.5); // 0.001 BTC rounding, 1.5 BTC contract
|
|
430
|
+
expect(modulus).to.equal(BigInt(150000)); // (0.001 * 1e8) * (1.5 * 1e8) / 1e8 = 150000
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
it('should properly compute the rounding modulus for 0.0005 BTC rounding with 0.5 BTC contract size', () => {
|
|
434
|
+
const modulus = computeRoundingModulus(0.0005, 0.5); // 0.0005 BTC rounding, 0.5 BTC contract
|
|
435
|
+
expect(modulus).to.equal(BigInt(25000)); // (0.0005 * 1e8) * (0.5 * 1e8) / 1e8 = 25000
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
it('should handle fractional bitcoin amounts correctly', () => {
|
|
439
|
+
const modulus = computeRoundingModulus(0.00001, 0.12345); // Very small amounts
|
|
440
|
+
expect(modulus).to.equal(BigInt(123)); // (0.00001 * 1e8) * (0.12345 * 1e8) / 1e8 = 123.45 -> 123 (rounded down)
|
|
441
|
+
});
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
describe('with Value object inputs', () => {
|
|
445
|
+
it('should properly compute the rounding modulus with Value objects', () => {
|
|
446
|
+
const rounding = Value.fromBitcoin(0.001);
|
|
447
|
+
const contractSize = Value.fromBitcoin(1);
|
|
448
|
+
const modulus = computeRoundingModulus(rounding, contractSize);
|
|
449
|
+
expect(modulus).to.equal(BigInt(100000)); // (0.001 * 1e8) * (1 * 1e8) / 1e8 = 100000
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
it('should properly compute the rounding modulus with mixed Value and number inputs', () => {
|
|
453
|
+
const rounding = Value.fromBitcoin(0.001);
|
|
454
|
+
const contractSize = 1.5; // number input
|
|
455
|
+
const modulus = computeRoundingModulus(rounding, contractSize);
|
|
456
|
+
expect(modulus).to.equal(BigInt(150000)); // (0.001 * 1e8) * (1.5 * 1e8) / 1e8 = 150000
|
|
457
|
+
});
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
describe('with BigInt inputs', () => {
|
|
461
|
+
it('should properly compute the rounding modulus with BigInt inputs', () => {
|
|
462
|
+
const modulus = computeRoundingModulus(
|
|
463
|
+
BigInt(100000),
|
|
464
|
+
BigInt(100000000),
|
|
465
|
+
);
|
|
466
|
+
expect(modulus).to.equal(BigInt(100000));
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
it('should properly compute the rounding modulus with mixed BigInt and number inputs', () => {
|
|
470
|
+
const modulus = computeRoundingModulus(BigInt(100000), 1); // BigInt rounding, number contract size
|
|
471
|
+
expect(modulus).to.equal(BigInt(100000)); // 100000 * (1 * 1e8) / 1e8 = 100000
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
describe('edge cases', () => {
|
|
476
|
+
it('should handle zero rounding correctly', () => {
|
|
477
|
+
const modulus = computeRoundingModulus(0, 1);
|
|
478
|
+
expect(modulus).to.equal(BigInt(0));
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
it('should handle zero contract size correctly', () => {
|
|
482
|
+
const modulus = computeRoundingModulus(0.001, 0);
|
|
483
|
+
expect(modulus).to.equal(BigInt(0));
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it('should handle very small bitcoin amounts', () => {
|
|
487
|
+
const modulus = computeRoundingModulus(0.00000001, 0.00000001); // 1 satoshi each
|
|
488
|
+
expect(modulus).to.equal(BigInt(0)); // (1 * 1) / 1e8 = 0 (rounded down)
|
|
489
|
+
});
|
|
490
|
+
});
|
|
491
|
+
});
|
|
492
|
+
});
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { HyperbolaPayoutCurvePiece } from '@node-dlc/messaging';
|
|
2
|
+
import { expect } from 'chai';
|
|
3
|
+
|
|
4
|
+
import { CoveredCall } from '../../../lib/dlc/finance/CoveredCall';
|
|
5
|
+
import { HyperbolaPayoutCurve } from '../../../lib/dlc/HyperbolaPayoutCurve';
|
|
6
|
+
|
|
7
|
+
describe('CoveredCall', () => {
|
|
8
|
+
describe('1BTC-50k-base2-20digit curve', () => {
|
|
9
|
+
const strikePrice = BigInt(50000);
|
|
10
|
+
const contractSize = BigInt(10) ** BigInt(8);
|
|
11
|
+
const oracleBase = 2;
|
|
12
|
+
const oracleDigits = 20;
|
|
13
|
+
|
|
14
|
+
const { maxOutcome, totalCollateral, payoutCurve } = CoveredCall.buildCurve(
|
|
15
|
+
strikePrice,
|
|
16
|
+
contractSize,
|
|
17
|
+
oracleBase,
|
|
18
|
+
oracleDigits,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
describe('payout', () => {
|
|
22
|
+
it('should be a negative past max outcome', () => {
|
|
23
|
+
expect(
|
|
24
|
+
payoutCurve.getPayout(maxOutcome + BigInt(1)).toNumber(),
|
|
25
|
+
).to.be.lessThan(0);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should be equal to totalCollateral at strike price', () => {
|
|
29
|
+
expect(payoutCurve.getPayout(strikePrice).toNumber()).to.equal(
|
|
30
|
+
Number(totalCollateral),
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('buildPayoutFunction', () => {
|
|
36
|
+
it('should build payout function', () => {
|
|
37
|
+
const {
|
|
38
|
+
payoutFunction,
|
|
39
|
+
totalCollateral,
|
|
40
|
+
} = CoveredCall.buildPayoutFunction(4000n, 1000000n, 2, 17);
|
|
41
|
+
|
|
42
|
+
// Test basic structure
|
|
43
|
+
expect(payoutFunction).to.not.be.undefined;
|
|
44
|
+
expect(totalCollateral).to.not.be.undefined;
|
|
45
|
+
|
|
46
|
+
// Test payout function structure
|
|
47
|
+
expect(payoutFunction.payoutFunctionPieces).to.have.length(1);
|
|
48
|
+
expect(payoutFunction.lastEndpoint).to.not.be.undefined;
|
|
49
|
+
|
|
50
|
+
// Test the payout function piece
|
|
51
|
+
const piece = payoutFunction.payoutFunctionPieces[0];
|
|
52
|
+
expect(piece.endPoint).to.not.be.undefined;
|
|
53
|
+
expect(piece.payoutCurvePiece).to.not.be.undefined;
|
|
54
|
+
|
|
55
|
+
// Test end point values - should be at maxOutcome (2^17 - 1 = 131071)
|
|
56
|
+
const maxOutcome = BigInt(2 ** 17 - 1); // 131071
|
|
57
|
+
expect(piece.endPoint.eventOutcome).to.equal(maxOutcome);
|
|
58
|
+
expect(piece.endPoint.outcomePayout).to.equal(0n);
|
|
59
|
+
expect(piece.endPoint.extraPrecision).to.equal(0);
|
|
60
|
+
|
|
61
|
+
// Test last endpoint matches the piece endpoint
|
|
62
|
+
expect(payoutFunction.lastEndpoint.eventOutcome).to.equal(maxOutcome);
|
|
63
|
+
expect(payoutFunction.lastEndpoint.outcomePayout).to.equal(0n);
|
|
64
|
+
expect(payoutFunction.lastEndpoint.extraPrecision).to.equal(0);
|
|
65
|
+
|
|
66
|
+
// Test hyperbola curve piece properties
|
|
67
|
+
const curvePiece = piece.payoutCurvePiece as HyperbolaPayoutCurvePiece;
|
|
68
|
+
expect(curvePiece.usePositivePiece).to.equal(true);
|
|
69
|
+
expect(curvePiece.leftEndPoint).to.not.be.undefined;
|
|
70
|
+
expect(curvePiece.rightEndPoint).to.not.be.undefined;
|
|
71
|
+
|
|
72
|
+
// Test left endpoint (start of curve)
|
|
73
|
+
expect(curvePiece.leftEndPoint.eventOutcome).to.equal(0n);
|
|
74
|
+
expect(curvePiece.leftEndPoint.outcomePayout).to.equal(totalCollateral);
|
|
75
|
+
expect(curvePiece.leftEndPoint.extraPrecision).to.equal(0);
|
|
76
|
+
|
|
77
|
+
// Test right endpoint (end of curve)
|
|
78
|
+
expect(curvePiece.rightEndPoint.eventOutcome).to.equal(maxOutcome);
|
|
79
|
+
expect(curvePiece.rightEndPoint.outcomePayout).to.equal(0n);
|
|
80
|
+
expect(curvePiece.rightEndPoint.extraPrecision).to.equal(0);
|
|
81
|
+
|
|
82
|
+
// Test hyperbola parameters
|
|
83
|
+
expect(curvePiece.a.toNumber()).to.equal(1);
|
|
84
|
+
expect(curvePiece.b.toNumber()).to.equal(0);
|
|
85
|
+
expect(curvePiece.c.toNumber()).to.equal(0);
|
|
86
|
+
expect(curvePiece.d.toNumber()).to.equal(4000000000); // strikePrice * contractSize
|
|
87
|
+
expect(curvePiece.translateOutcome.toNumber()).to.equal(0);
|
|
88
|
+
|
|
89
|
+
// Test total collateral is reasonable (should be less than contract size)
|
|
90
|
+
expect(Number(totalCollateral)).to.be.greaterThan(0);
|
|
91
|
+
expect(Number(totalCollateral)).to.be.lessThan(1000000); // less than contractSize
|
|
92
|
+
|
|
93
|
+
// For a covered call with strike=4000, contractSize=1000000:
|
|
94
|
+
// At maxOutcome, payout should be ~0, so most collateral is retained
|
|
95
|
+
expect(Number(totalCollateral)).to.be.greaterThan(900000); // Should retain most collateral
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should serialize and deserialize properly', () => {
|
|
100
|
+
const payout = payoutCurve.getPayout(strikePrice);
|
|
101
|
+
|
|
102
|
+
const _tlv = payoutCurve.toPayoutCurvePiece().serialize();
|
|
103
|
+
const pf = HyperbolaPayoutCurvePiece.deserialize(_tlv);
|
|
104
|
+
|
|
105
|
+
const deserializedCurve = HyperbolaPayoutCurve.fromPayoutCurvePiece(pf);
|
|
106
|
+
|
|
107
|
+
expect(payout.toNumber()).to.be.eq(
|
|
108
|
+
deserializedCurve.getPayout(strikePrice).toNumber(),
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
});
|