-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcontracts.html
More file actions
1023 lines (1013 loc) · 111 KB
/
Copy pathcontracts.html
File metadata and controls
1023 lines (1013 loc) · 111 KB
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Contract interactions</title>
<link rel="stylesheet" href="../assets/css/shared-docs.css" />
<link rel="stylesheet" href="../assets/css/docsShell.css" />
</head>
<body class="doc-openoracle reference-page">
<main>
<article>
<!-- Generated by scripts/generate-contract-interaction-reference.mts. Do not edit directly. -->
<header>
<h1>Contract interactions</h1>
<p class="lede">For developers and operators: find the contract that handles each state change, who can call it, and what the call does.</p>
<nav aria-label="Contract quick index">
<strong>Quick index</strong>
<ul>
<li><a href="#zoltarquestiondata">ZoltarQuestionData</a></li>
<li><a href="#zoltar">Zoltar</a></li>
<li><a href="#reputationtoken">ReputationToken</a></li>
<li><a href="#securitypoolfactory">SecurityPoolFactory</a></li>
<li><a href="#securitypool">SecurityPool</a></li>
<li><a href="#securitypoolforker">SecurityPoolForker</a></li>
<li><a href="#escalationgame">EscalationGame</a></li>
<li><a href="#liquidationapprovalregistry">LiquidationApprovalRegistry</a></li>
<li><a href="#openoraclepricecoordinator">OpenOraclePriceCoordinator</a></li>
<li><a href="#sharetoken">ShareToken</a></li>
<li><a href="#uniformpricedualcapbatchauction">UniformPriceDualCapBatchAuction</a></li>
</ul>
</nav>
</header>
<h2 id="zoltarquestiondata">ZoltarQuestionData</h2>
<p>Creates immutable, content-addressed scalar or categorical questions and exposes their display metadata. <a href="../../solidity/contracts/ZoltarQuestionData.sol">Source</a></p>
<p>Read surface: Use <code>getQuestionId</code> before submission; <code>questionCreatedTimestamp</code> and <code>questions</code> for direct lookup; <code>getQuestionCount</code> and <code>getQuestions</code> for indexed or paged discovery; and <code>getQuestionEndDate</code>, <code>getOutcomeLabels</code>, <code>splitUint256IntoTwoWithInvalid</code>, <code>hasNonZeroScalarReservedBits</code>, <code>isMalformedAnswerOption</code>, and <code>getAnswerOptionName</code> when validating or displaying answers. In the <code>QuestionData</code> tuple, <code>startTime</code> and <code>endTime</code> are <code>uint48</code>, while <code>numTicks</code> is <code>uint120</code>; clients must use these exact widths because they determine the <code>getQuestionId</code> and <code>createQuestion</code> selectors.</p>
<!-- Validated read ABI fingerprint: 964d0ce318d2890011ff485c8d78e933cabc8d10e489a0c22f0e266fa2563ded -->
<!-- Validated complete compiled ABI fingerprint: 580109cfcebb3ce505def01895f7b6567e75bbd8e8ccac857bdd00d54f15c37f -->
<table>
<thead>
<tr>
<th>Transaction</th>
<th>Caller</th>
<th>Main prerequisites</th>
<th>State or asset effect</th>
<th>Primary signals</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>createQuestion(questionData, outcomeOptions)</code></td>
<td>Anyone</td>
<td>Question ID not already created; end time is on or after start time. Scalar questions use no labels, require display maximum greater than minimum, and positive ticks. Categorical questions require nonempty labels whose <code>keccak256(abi.encode(label))</code> values are strictly descending.</td>
<td>Stores the question at its deterministic content hash, records the creation timestamp, appends it to discovery order, and stores categorical labels when supplied.</td>
<td><code>QuestionCreated</code></td>
</tr>
</tbody>
</table>
<h2 id="zoltar">Zoltar</h2>
<p>Registers universe forks, charges the fork admission haircut, and mints branch-specific child REP. <a href="../../solidity/contracts/Zoltar.sol">Source</a></p>
<p>Read surface: Use <code>universes</code>, <code>forkThresholdDivisor</code>, <code>forkBurnDivisor</code>, <code>zoltarQuestionData</code>, <code>genesisReputationToken</code>, <code>getForkTime</code>, <code>forkQuestionMatches</code>, <code>getRepToken</code>, <code>getForkThresholdAttoRep</code>, <code>getNonDecisionThresholdAttoRep</code>, <code>getUniverseTheoreticalSupplyAttoRep</code>, <code>getChildUniverseId</code>, <code>getDeployedChildUniverses</code>, and <code>getMigrationRepBalanceAttoRep</code> to reconstruct universe and migration state. Construction requires a deployed genesis REP token with theoretical supply from one attoREP through 11 million REP and <code>forkBurnDivisor >= 5</code>, which caps the uncredited fork haircut at 20% of the threshold.</p>
<p>Security boundaries for these calls are <a href="./security-model.html#assumption-a15">A15 intended question selection</a> and <a href="./security-model.html#assumption-a25">A25 safe immutable parameters</a>.</p>
<!-- Validated read ABI fingerprint: 1916e3480c70c4ccd5962f4b8069988d7dc36f0ea89337ebe04b8bca089d1492 -->
<!-- Validated complete compiled ABI fingerprint: 023e5a38bcf613044e07d23e84095e1125be871017388a0c5a6cf7a41958b350 -->
<table>
<thead>
<tr>
<th>Transaction</th>
<th>Caller</th>
<th>Main prerequisites</th>
<th>State or asset effect</th>
<th>Primary signals</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>forkUniverse(universeId, questionId)</code></td>
<td>Any address able to fund the current fork threshold</td>
<td>Initialized and unforked universe; existing ended question; sufficient caller REP. Genesis REP requires allowance; child REP is burned directly without allowance.</td>
<td>Records the fork, removes threshold REP from the parent universe, and credits the caller with the threshold minus the configured uncredited haircut.</td>
<td><code>UniverseForked</code></td>
</tr>
<tr>
<td><code>burnRep(universeId, amountAttoRep)</code></td>
<td>Any REP holder; the caller can burn only its own balance</td>
<td>Initialized universe; positive amount; sufficient caller REP and theoretical supply. Genesis REP requires allowance.</td>
<td>Permanently removes REP without creating migration credit; escalation settlement uses this when the haircut was not paid through its own fork.</td>
<td><code>RepBurned</code> and the token burn or transfer event</td>
</tr>
<tr>
<td><code>deployChild(universeId, outcomeIndex)</code></td>
<td>Anyone</td>
<td>Parent forked; outcome is well formed; child is not already deployed.</td>
<td>Deploys the deterministic child REP token and initializes the child universe.</td>
<td><code>DeployChild</code></td>
</tr>
<tr>
<td><code>addRepToMigrationBalance(universeId, amountAttoRep)</code></td>
<td>Parent REP holder</td>
<td>Universe forked; sufficient caller REP. Genesis REP requires allowance; child REP is burned directly without allowance.</td>
<td>Burns or sinks additional parent REP and increases the caller's reusable migration balance.</td>
<td><code>MigrationRepAdded</code></td>
</tr>
<tr>
<td><code>splitMigrationRep(universeId, amountAttoRep, outcomeIndexes)</code></td>
<td>Migration-balance holder</td>
<td>Universe forked. A nonempty list additionally requires every outcome to be well formed and the cumulative amount per child not to exceed the caller's migration balance.</td>
<td>Mints <code>amount</code> of child REP into every selected branch, deploying missing children lazily. An empty outcome list returns after the universe-fork guard without outcome validation, deployment, minting, or events. A nonempty zero-amount call still validates every outcome, may deploy missing children, performs zero-value child REP mints, and records a zero split for every branch.</td>
<td><code>TheoreticalSupplySet</code> and <code>DeployChild</code> when needed; child REP <code>Transfer</code> and <code>Mint</code>, then <code>MigrationRepSplit</code>, per selected branch, including at zero amount; no event for an empty list</td>
</tr>
</tbody>
</table>
<h2 id="reputationtoken">ReputationToken</h2>
<p>Implements universe-specific ERC-20 REP and enforces the supply ceiling maintained by Zoltar. <a href="../../solidity/contracts/ReputationToken.sol">Source</a></p>
<p>Read surface: Use <code>getTotalTheoreticalSupplyAttoRep</code>, <code>zoltar</code>, and the standard ERC-20 <code>name</code>, <code>symbol</code>, <code>decimals</code>, <code>totalSupply</code>, <code>balanceOf</code>, and <code>allowance</code> reads.</p>
<!-- Validated read ABI fingerprint: 1385406a6e5989eb754a8adeb36f946309659127e088734528cdffa7f8bbe7c8 -->
<!-- Validated complete compiled ABI fingerprint: 14cee3c68c22f454d0d83f16aad27d40b686fa8abc7fb0220c03ba19ba609f64 -->
<table>
<thead>
<tr>
<th>Transaction</th>
<th>Caller</th>
<th>Main prerequisites</th>
<th>State or asset effect</th>
<th>Primary signals</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>setMaxTheoreticalSupplyAttoRep(totalTheoreticalSupplyAttoRep)</code></td>
<td><code>Zoltar</code> only</td>
<td>Called by Zoltar as part of child-universe creation; theoretical supply does not exceed 11 million REP.</td>
<td>Sets the child token theoretical-supply ceiling used to bound subsequent migration mints.</td>
<td><code>TheoreticalSupplySet</code></td>
</tr>
<tr>
<td><code>mint(account, valueAttoRep)</code></td>
<td><code>Zoltar</code> only</td>
<td><code>account</code> is nonzero; resulting ERC-20 supply does not exceed theoretical supply.</td>
<td>Mints branch REP to an account.</td>
<td><code>Mint</code> and ERC-20 <code>Transfer</code></td>
</tr>
<tr>
<td><code>burn(account, valueAttoRep)</code></td>
<td><code>Zoltar</code> only</td>
<td><code>account</code> is nonzero and has sufficient REP; theoretical supply covers the burn.</td>
<td>Burns account REP and reduces both actual and theoretical supply by the same amount.</td>
<td><code>Burn</code> and ERC-20 <code>Transfer</code></td>
</tr>
<tr>
<td><code>transfer(to, value)</code></td>
<td>REP holder</td>
<td>Destination is nonzero; caller has sufficient balance.</td>
<td>Moves REP from the caller without changing actual or theoretical supply.</td>
<td><code>Transfer</code></td>
</tr>
<tr>
<td><code>approve(spender, value)</code></td>
<td>Any REP account setting its own allowance</td>
<td>Spender is nonzero.</td>
<td>Replaces the named spender allowance without moving REP.</td>
<td><code>Approval</code></td>
</tr>
<tr>
<td><code>transferFrom(from, to, value)</code></td>
<td>A spender with sufficient allowance from <code>from</code></td>
<td>Source and destination are nonzero; source has sufficient balance; caller has sufficient allowance, including when caller equals source.</td>
<td>Moves REP from <code>from</code>; a finite allowance decreases by <code>value</code>, while an infinite allowance remains unchanged. Neither allowance path emits <code>Approval</code>.</td>
<td><code>Transfer</code> only</td>
</tr>
</tbody>
</table>
<h2 id="securitypoolfactory">SecurityPoolFactory</h2>
<p>Creates and canonically registers origin and child security pools with their share token, oracle coordinator, and optional truth auction. <a href="../../solidity/contracts/statoblast/factories/SecurityPoolFactory.sol">Source</a></p>
<p>Read surface: Use <code>initialEscalationGameDepositAttoRep</code>, <code>minimumSecurityBondDebtAttoEth</code>, and <code>minimumVaultRepDepositAttoRep</code> for immutable deployment floors. The factory requires the escalation baseline to equal 1 REP, so each pool fixes its effective escalation deposit at construction as exactly <code>max(1 REP, theoretical REP supply / 10,000,000)</code>. A zero configured vault REP floor selects the default <code>theoretical REP supply / 100,000</code>; a nonzero constructor value is the exact override. The security-bond debt floor defaults to 1 ETH. Use <code>securityPoolDeploymentCount</code> with the strict <code>securityPoolDeploymentsRange(startIndex, count)</code> pager, which reverts rather than truncating when the requested range exceeds the array. Use <code>getOriginId</code>, <code>getPoolId</code>, <code>getSecurityPool</code>, <code>getSecurityPoolOriginId</code>, and <code>getSecurityPoolHasInheritedForkOutcome</code> for canonical lookup.</p>
<!-- Validated read ABI fingerprint: 855853487a8ab201b9e990820bac4f51ec6ae6520ae2dcf49efcc93e81c9a474 -->
<!-- Validated complete compiled ABI fingerprint: c502f414482a9872fb01eaa78dccd3c19d5e1af5227c10047ba645da00fb3406 -->
<table>
<thead>
<tr>
<th>Transaction</th>
<th>Caller</th>
<th>Main prerequisites</th>
<th>State or asset effect</th>
<th>Primary signals</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>deployOriginSecurityPool(universeId, questionId, statoblastSecurityMultiplierBps, initialReportPriorityFeeAttoEthPerGas)</code></td>
<td>Anyone</td>
<td><code>statoblastSecurityMultiplierBps > 10_001</code>, which makes the halfway migration component strictly greater than one; the effective pool-held vault REP backing multiplier separately floors that component at the 10,500-BPS liquidation-award reserve described by the <a href="../explanation/liquidations.html#rule">liquidation design</a>. <code>initialReportPriorityFeeAttoEthPerGas > 0</code> and remains within the coordinator-computed OpenOracle <code>uint128</code> report/escalation-halt capacity bound; question exists and has exactly the categorical labels <code>Yes</code>, then <code>No</code>; universe is unforked and has a REP token; the non-decision threshold exceeds the construction-time effective escalation deposit <code>max(1 REP, theoretical REP supply / 10,000,000)</code>; the origin/universe/priority-fee slot has not already been claimed.</td>
<td>Creates the canonical origin pool, its lineage-wide share token, and its price coordinator with the configured initial-report priority fee, then wires and registers them atomically.</td>
<td><code>SecurityPoolRegistered</code>, then <code>DeploySecurityPool</code></td>
</tr>
<tr>
<td><code>deployChildSecurityPool(parent, shareToken, universeId, questionId, statoblastSecurityMultiplierBps, currentRetentionRate, settlementCollateralAttoEth)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td>Parent is the canonical pool for its lineage; supplied share token equals the parent share token; target origin/universe slot is unclaimed; deployment arguments satisfy downstream constructors and wiring.</td>
<td>Creates and registers a canonical child pool with a coordinator that inherits <code>initialReportPriorityFeeAttoEthPerGas</code> from the parent coordinator and a forker-owned truth auction, while retaining the parent lineage share token.</td>
<td><code>SecurityPoolRegistered</code>, then <code>DeploySecurityPool</code></td>
</tr>
</tbody>
</table>
<h2 id="securitypool">SecurityPool</h2>
<p>Holds ETH collateral and REP underwriting, accounts for vaults and fees, mints shares, and routes local escalation. <a href="../../solidity/contracts/statoblast/SecurityPool.sol">Source</a></p>
<p>Read surface: Immutable relationship and configuration getters are <code>questionId</code>, <code>universeId</code>, <code>initialEscalationGameDepositAttoRep</code>, <code>zoltar</code>, <code>parent</code>, <code>shareToken</code>, <code>repToken</code>, <code>priceOracleManagerAndOperatorQueuer</code>, <code>openOracle</code>, <code>escalationGameFactory</code>, <code>questionData</code>, <code>securityPoolForker</code>, <code>truthAuction</code>, <code>securityPoolFactory</code>, and <code>statoblastSecurityMultiplierBps</code>; the current game is <code>escalationGame</code>. Accounting getters include <code>totalCapacityOwnershipAttoRep</code>, <code>settlementCollateralAttoEth</code>, <code>totalRepBackingUnits</code>, <code>shareTokenSupplyAttoShares</code>, <code>securityVaults</code>, <code>minimumSecurityBondDebtAttoEth</code>, <code>minimumVaultRepDepositAttoRep</code>, <code>totalBadDebtAttoEth</code>, and <code>vaultBadDebtAttoEth</code>. <code>lastDepositTargetHealthFactorBpsByVault</code> is deposit-instruction metadata, not a vault health measurement. Use <code>getVaultCapacityBackingFactorsBps</code> for current associated and pool-held REP-per-capacity ratios, <code>getCurrentMintingCapacityAttoEth</code> for price-converted aggregate capacity, and <code>getVaultOpenInterestAttoEth</code> for a vault’s live proportional obligation. Other derived and paged reads are <code>getVaultCount</code>, <code>getVaults</code>, <code>attoSharesToAttoEth</code>, <code>attoEthToAttoShares</code>, <code>attoRepToBackingUnits</code>, <code>backingUnitsToAttoRep</code>, <code>getTotalPoolHeldAttoRep</code>, <code>totalAccruedFeesAttoEth</code>, <code>getPoolAccountingSnapshot</code>, <code>getVaultFeeRemainder</code>, and <code>isEscalationResolved</code>. The backing-factor ratios are not current vault health: associated REP includes dispute-staked principal as at-risk security, while current health also depends on OI, REP/ETH price, the security multiplier, and both protocol constraints. The vault registry is append-only and newest-registered first. Registration requires only a nonzero address and can occur without economic state; consumers filter current positions from <code>securityVaults</code>, escalation stake, and bad debt. <code>isEscalationResolved()</code> is true when the pool inherits a fixed fork outcome, or when a local escalation game is configured and the forker routes a non-<code>None</code> outcome. An operational fixed-outcome child remains available for settlement and redemption but rejects new collateralized operations. Lifecycle and fee getters are <code>totalClaimableVaultFeesAttoEth</code>, <code>lastUpdatedFeeAccumulator</code>, <code>feeIndex</code>, <code>currentRetentionRate</code>, <code>awaitingForkContinuation</code>, and <code>systemState</code>.</p>
<p>Price-sensitive withdrawal, dynamic-capacity, and liquidation calls depend on <a href="./security-model.html#assumption-a16">A16 timely inclusion</a>, <a href="./security-model.html#assumption-a21">A21 genesis REP and WETH behavior</a>, <a href="./security-model.html#assumption-a19">A19 observable correctable price</a>, and <a href="./security-model.html#assumption-a06">A06 lifecycle executors</a>. User-initiated pool calls additionally depend on <a href="./security-model.html#assumption-a28">A28 account authority</a>.</p>
<!-- Validated read ABI fingerprint: 4aa6f532ffca94b25b9de71ebb35b258d20c3789ddeb63325a04a52847568ca9 -->
<!-- Validated complete compiled ABI fingerprint: adf6de72251995da0be0c70433cf48361433cdf637b2ede48d063aa34b38d211 -->
<table>
<thead>
<tr>
<th>Transaction</th>
<th>Caller</th>
<th>Main prerequisites</th>
<th>State or asset effect</th>
<th>Primary signals</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>burnEscalationWinnerHaircut(amountAttoRep)</code></td>
<td>This pool's <code>EscalationGame</code> only</td>
<td>Caller is the configured escalation game; amount is positive and the game has already transferred enough REP to the pool.</td>
<td>Burns the winning-deposit haircut from REP already escrowed in the game.</td>
<td><code>RepBurned</code> and ERC-20 <code>Transfer</code>; child REP also emits <code>Burn</code></td>
</tr>
<tr>
<td><code>depositRepToVault(attoRepAmount, targetHealthFactorBps)</code></td>
<td>Vault owner</td>
<td>Operational and unforked; <code>isEscalationResolved()</code> is false; the transaction timestamp is strictly before the question end time unless the pool has an inherited fork-continuation game; deposit amount is positive; deposit target factor is at least 10,000; resulting vault REP meets the configured supply-scaled minimum.</td>
<td>Transfers REP into the pool, credits proportional REP backing units, and creates REP-denominated fee-earning capacity ownership from this deposit and its selected deposit target factor.</td>
<td><code>RepDepositedToVault</code>, <code>VaultDepositTargetHealthFactorRecorded</code>, and accounting checkpoints</td>
</tr>
<tr>
<td><code>redeemFees(vault)</code></td>
<td>Anyone; any nonzero ETH payment is always sent to <code>vault</code></td>
<td>A nonzero payment path requires <code>vault</code> to accept ETH.</td>
<td>First accrues the vault's fees. If resulting claimable fees are zero, returns without payment; otherwise clears and pays the full amount.</td>
<td>Accrual checkpoints only when accrual state changes; both <code>VaultAccountingCheckpoint</code> and <code>PoolAccountingCheckpoint</code> for a nonzero redemption; no event when fees and accrual state are unchanged</td>
</tr>
<tr>
<td><code>createCompleteSet()</code> with ETH</td>
<td>Trader</td>
<td>Operational and unforked; <code>isEscalationResolved()</code> is false; not awaiting continuation; positive ETH converts to at least one complete-set unit; live oracle-priced minting capacity covers the resulting settlement collateral, not merely this deposit; actual pool-held REP satisfies both live backing constraints for resulting collateral net of recorded bad debt, with dispute-staked REP counting only toward the associated-REP constraint; any explicit unassigned auction position remains healthy after the mint; under <a href="./security-model.html#assumption-a22">A22 asset-recipient compatibility</a>, a contract trader accepts <code>onERC1155BatchReceived</code>.</td>
<td>Adds collateral and mints one <code>Invalid</code>, <code>Yes</code>, and <code>No</code> share per complete-set unit, then invokes the ERC-1155 batch-receiver callback for a contract trader. Callback rejection rolls back the ETH, pool accounting, events, and share mint.</td>
<td><code>CompleteSetCreated</code>, <code>PoolAccountingCheckpoint</code>, then ERC-1155 <code>TransferBatch</code> on a successful callback</td>
</tr>
<tr>
<td><code>redeemCompleteSet(amountAttoShares)</code></td>
<td>Anyone; positive redemption requires the caller to hold the complete set</td>
<td>Operational and unforked; caller holds every outcome amount requested; caller accepts the resulting ETH call, including zero value. Zero is accepted without a token balance.</td>
<td>Burns equal balances of all three outcomes and pays <code>amountAttoShares * settlementCollateralAttoEth / shareTokenSupplyAttoShares</code> using the pool's remaining economic claim supply as its collateral denominator. Complete-set issuance adds to that denominator, while complete-set and winning-share redemption consume it; fork-time source entitlements materialize without changing it because their claims are already reserved. Zero passes the token and accounting checks and follows the normal zero-value event, checkpoint, and ETH-send path; rejection of that ETH call reverts the transaction.</td>
<td><code>CompleteSetRedeemed</code> and <code>PoolAccountingCheckpoint</code></td>
</tr>
<tr>
<td><code>redeemShares()</code></td>
<td>Anyone; a positive payout requires the caller to hold winning shares</td>
<td>Operational pool with a final outcome; caller accepts the resulting ETH call, including zero value.</td>
<td>Burns the caller's full winning balance and pays its pro-rata remaining collateral. A zero winning balance passes token and accounting checks and follows the normal zero-value event, checkpoint, and ETH-send path; rejection of that ETH call reverts the transaction.</td>
<td><code>SharesRedeemed</code> and <code>PoolAccountingCheckpoint</code></td>
</tr>
<tr>
<td><code>redeemRepFromVault(vault)</code></td>
<td>Vault owner; caller must equal <code>vault</code>, and REP is sent to <code>vault</code></td>
<td>Operational pool with a final outcome; the specified <code>vault</code> has no escalation escrow and has redeemable REP.</td>
<td>Burns the vault's REP backing units and returns its proportional vault REP backing.</td>
<td><code>RepRedeemedFromVault</code></td>
</tr>
<tr>
<td><code>depositToEscalationGame(outcome, maxAmount)</code></td>
<td>Vault owner</td>
<td>Question end has passed; pool operational in an unforked universe, without an inherited fixed outcome, and not awaiting continuation. On the first deposit, the live non-decision threshold must exceed one attoREP; outcome and amount accepted; the remaining vault and aggregate pool totals each preserve both live open-interest health branches; a fresh price is required when total capacity ownership is nonzero.</td>
<td>Deploys the local game on the first deposit. The game factory uses the configured start bond while it is below the live non-decision threshold; if tracked REP supply later makes it too large, the factory uses <code>nonDecisionThresholdAttoRep - 1</code> instead. Repeat deposits use the existing game's stored <code>startBondAttoRep</code> and <code>nonDecisionThresholdAttoRep</code>. Every accepted deposit removes enough REP backing units and escrows dispute-staked REP on the selected outcome.</td>
<td><code>EscalationGameSet</code> on first deposit; <code>DepositToEscalationGame</code></td>
</tr>
<tr>
<td><code>withdrawFromEscalationGame(outcome, depositIndexes)</code></td>
<td>Anyone; a nonempty list must select deposits belonging to one original depositor</td>
<td>Game configured; operational pool; valid final outcome. If an external fork interrupted the game, parent withdrawal stays unavailable: winners settle in the child by carried proof, inherited losers require no transaction, and unresolved parent escalation-deposit accounting cleanup is optional. A nonempty list additionally requires valid local indexes and one common depositor.</td>
<td>A nonempty list settles local deposits and pays winning REP to the immutable depositor recorded by each deposit. Liquidation cannot change that payout address. An empty list returns after the outer lifecycle checks without settlement, state change, or event.</td>
<td>Per processed deposit, escalation-game <code>CarryDepositConsumed</code>; additionally <code>ClaimDeposit</code> for a winning payout. No event for an empty list</td>
</tr>
<tr>
<td><code>withdrawForkedEscalationDeposits(outcome, proofs)</code></td>
<td>Anyone; a nonempty list must name one original depositor across all proofs</td>
<td>Game configured; operational child pool; valid final outcome. A nonempty list additionally requires an initialized and fully resumed continuation game, valid unconsumed winning proofs, and one common depositor.</td>
<td>A nonempty list verifies and consumes carried proofs, then pays winning child REP to the immutable depositor committed in each leaf. Stable continuation identities retain the creating game, and the cumulative retention-index ratio applies every intervening auction haircut in constant ancestry work. An empty list returns after the outer lifecycle checks without proof verification, state change, or event.</td>
<td>Per processed proof, escalation-game <code>CarryDepositConsumed</code> and <code>ClaimDeposit</code>. No event for an empty list</td>
</tr>
<tr>
<td><code>updateSettlementCollateral()</code></td>
<td>Anyone</td>
<td>No caller or lifecycle restriction. It returns unchanged when the accumulator is already at or beyond the clamped timestamp.</td>
<td>Accrues elapsed fees through question end while this pool's universe remains unforked; after that universe forks, its fork timestamp replaces question end as this pool epoch's cutoff, including a later question-end-to-fork interval. The cutoff is local to this pool: an activated child starts a separate fee epoch. It moves whole credited fees from settlement collateral into the unallocated accrued-fee reserve and advances the accumulator. With positive elapsed time but zero fee-eligible capacity ownership it clears denominator-specific remainder and advances the timestamp without charging fees.</td>
<td><code>PoolAccountingCheckpoint</code> whenever positive elapsed time is processed, including the zero-capacity-ownership branch; no event for an unchanged timestamp</td>
</tr>
<tr>
<td><code>updateRetentionRate()</code></td>
<td>Anyone</td>
<td>No caller restriction. It returns unchanged when the pool is not <code>Operational</code> or the calculated rate equals the stored rate. Zero live minting capacity selects the maximum retention rate.</td>
<td>Recalculates the retention rate from current collateral and live oracle-priced minting capacity.</td>
<td><code>PoolAccountingCheckpoint</code> only when the stored retention rate changes; no event for a no-op</td>
</tr>
<tr>
<td><code>updateVaultFees(vault)</code></td>
<td>Anyone for any address</td>
<td>No caller, nonzero-vault, or lifecycle restriction.</td>
<td>First updates pool accrual, then advances the vault fee index and fractional remainder, moves whole assigned fees from reserve to the vault, registers any previously unseen nonzero vault address regardless of economic state, and returns leftover reserve to settlement collateral once a forked pool has checkpointed all fee-eligible capacity ownership.</td>
<td>Accrual <code>PoolAccountingCheckpoint</code> when due; <code>VaultAccountingCheckpoint</code> when the vault index, remainder, or claimable fee balance changes; an additional <code>PoolAccountingCheckpoint</code> when pool accounting changes; no event when neither accrual nor vault or pool accounting changes</td>
</tr>
<tr>
<td><code>withdrawRepFromVault(vault, attoRepAmount)</code></td>
<td>This pool's <code>OpenOraclePriceCoordinator</code> only</td>
<td>Fresh coordinator price; operational pool in an unforked universe; <code>isEscalationResolved()</code> is false; no vault REP escrow. A withdrawal that would reduce capacity ownership requires zero settlement collateral; a backing-only withdrawal does not. The remaining vault and aggregate pool totals each meet the upward-rounded associated-REP and free-REP backing requirements, with equality healthy.</td>
<td>Removes the requested proportional REP backing units, or all backing units when the requested remainder would fall below the REP minimum; proportionally reduces vault and pool capacity ownership when the vault has positive capacity ownership; recalculates retention; and transfers the resulting withdrawable REP to <code>vault</code>.</td>
<td>REP <code>Transfer</code>; <code>RepWithdrawnFromVault</code>; <code>VaultAccountingCheckpoint</code>; and applicable fee-accrual or retention <code>PoolAccountingCheckpoint</code> events</td>
</tr>
<tr>
<td><code>performLiquidation(request)</code></td>
<td>This pool's <code>OpenOraclePriceCoordinator</code> only</td>
<td>In ABI order, <code>request</code> contains <code>operationId</code>, <code>operator</code>, <code>receiverVault</code>, <code>targetVault</code>, <code>requestedDebtAttoEth</code>, <code>snapshot</code>, <code>minimumReceiverHealthFactorBps</code>, and <code>minLiquidationPriceDistanceBps</code>. The nested snapshot contains <code>targetBackingUnits</code>, <code>targetCapacityOwnershipAttoRep</code>, <code>totalPoolHeldAttoRep</code>, and <code>totalRepBackingUnits</code>. Fresh settled coordinator price; operational pool in an unforked universe; <code>isEscalationResolved()</code> is false; receiver differs from target. The target backing and capacity-ownership snapshot fields must match; the two pool-total snapshot fields are reconstruction evidence, while execution uses live pool totals. After target and receiver fee checkpoints, the liquidation delegate requires live target backing, dispute-staked REP, and open interest to remain at least <code>minLiquidationPriceDistanceBps</code> beyond the liquidation threshold and requires the live target state to remain unhealthy. When debt moves, the receiver must satisfy the protocol backing checks multiplied by its approved minimum health factor, using live post-liquidation state and upward-rounded requirements; its resulting debt must meet the configured debt floor and its REP must meet the vault floor. The target resulting debt must be zero or meet the debt floor; when debt remains, target REP must meet the vault floor.</td>
<td>Capped by the target vault's open interest and fundable REP award, a nominal debt quote selects proportional capacity ownership rounded downward and moves that ownership to the explicitly selected receiver vault. Moved security-bond debt is the receiver's exact live open-interest increase and cannot exceed the nominal quote or request. On a delegated route, the coordinator additionally bounds it by the staged approval reservation; the self-receiving route has no approval reservation. The operator only submits the transaction. Dispute-staked REP claims, accrued claimable fees, surplus vault REP backing, and unmatched ownership remain with the target. On a full-target request, target open interest minus exact moved debt is recorded as attoETH-denominated bad debt; that residual can include both an award-unfunded slice and integer-allocation residue. Receiver or target dust cannot turn otherwise funded debt into bad debt.</td>
<td>Fee-accrual and target or receiver <code>VaultAccountingCheckpoint</code> events as needed; <code>VaultLiquidated</code> identifies operation, operator, receiver, target, moved debt, moved ownership, and bad debt; <code>VaultBadDebtRecorded</code> records residual target debt on a full-target request; final pool accounting checkpoint</td>
</tr>
<tr>
<td><code>setStartingParams(...)</code></td>
<td><code>SecurityPoolFactory</code> only</td>
<td>Factory caller. The pool has no internal one-shot or lifecycle guard; the factory exposes it only through atomic deployment wiring.</td>
<td>Sets the fee timestamp, retention, and collateral, seeds the coordinator with zero for an origin or the parent's last price for a child, then checkpoints initialization.</td>
<td>Coordinator <code>RepEthPriceSet</code> and <code>CoordinatorStateCheckpoint</code>, then pool <code>PoolAccountingCheckpoint</code>, even for zero or repeated values if the factory were to call again</td>
</tr>
<tr>
<td><code>activateForkMode()</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td>The pool has no inherited fixed outcome, so a fixed child cannot reopen for a later universe fork. There is no current-state guard otherwise. A configured game's drain must succeed or the entire activation reverts without propagating its reason data.</td>
<td>Sets <code>PoolForked</code>, accrues through the fork clamp, transfers the pool's entire REP balance to the forker, then makes the pool drain its configured escalation game's entire REP balance to the forker. Repeated calls are not lifecycle-guarded and transfer any balances replenished since the prior call before repeating the checkpoints.</td>
<td>Pool-held REP <code>Transfer</code> always, including at zero; configured-game REP <code>Transfer</code> only for a positive game balance; accrual checkpoint when due; always <code>PoolForkModeActivated</code> and fork-activation <code>PoolAccountingCheckpoint</code></td>
</tr>
<tr>
<td><code>initializeForkedEscalationGame(...)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td>No game is configured; downstream <code>startFromFork</code> parameters are valid.</td>
<td>Deploys and starts the pool's paused fork-continuation game with inherited timing and optional fixed outcome.</td>
<td>Escalation <code>GameContinuedFromFork</code>, then pool <code>EscalationGameSet</code></td>
</tr>
<tr>
<td><code>initializeForkCarrySnapshotWithResolutionBalances(...)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td>A game is configured; it is a fork continuation with no prior snapshot; leaf counts fit the MMR; supplied or computed snapshot ID matches the data.</td>
<td>Installs the continuation game's immutable carry peaks, counts, totals, resolution balances, and normalized nullifier roots.</td>
<td><code>ForkCarryCheckpoint</code></td>
</tr>
<tr>
<td><code>resumeForkedEscalationGame()</code></td>
<td>Anyone</td>
<td>Pool is operational, awaiting a configured fork continuation, and the game has not resumed.</td>
<td>Checks the already-installed immutable carry commitment and aggregate REP funding, clears the pool wait flag, records the resume timestamp, and starts the continuation's remaining escalation clock in one bounded call.</td>
<td><code>ForkContinuationResumed</code> and <code>AwaitingForkContinuationSet(false)</code></td>
</tr>
<tr>
<td><code>setAwaitingForkContinuation(shouldAwait)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td>No lifecycle or value-change guard.</td>
<td>Stores whether complete-set minting must wait for continuation initialization.</td>
<td><code>AwaitingForkContinuationSet</code>, including for a repeated value</td>
</tr>
<tr>
<td><code>setSystemState(newState)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td>No transition or value-change guard.</td>
<td>Replaces the pool lifecycle state directly.</td>
<td><code>SystemStateSet</code>, including for a repeated state</td>
</tr>
<tr>
<td><code>configureVault(vault, repBackingUnits, capacityOwnershipAttoRep, vaultFeeIndex, lastDepositTargetHealthFactorBps, newVaultBadDebtAttoEth, newTotalBadDebtAttoEth)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td><code>vault</code> is nonzero; no lifecycle or value-change guard.</td>
<td>Replaces the vault REP backing units, price-independent capacity ownership, fee index, latest-deposit preference metadata, vault bad debt, and aggregate pool bad debt, clears pooled fee-index remainder when capacity ownership changes, and registers the nonzero vault address regardless of the supplied state.</td>
<td>Always <code>VaultAccountingCheckpoint</code> and <code>PoolAccountingCheckpoint</code>, including when all supplied values repeat current state</td>
</tr>
<tr>
<td><code>configureFinalizedAuctionVault(vault, repBackingUnits, capacityOwnershipAttoRep, vaultFeeIndex, lastDepositTargetHealthFactorBps, newVaultBadDebtAttoEth, newTotalBadDebtAttoEth)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td><code>vault</code> is nonzero; the forker has already included the sold capacity ownership in the pool fee denominator at auction finalization.</td>
<td>Assigns finalized-auction REP backing and already-fee-eligible capacity ownership to the winning vault without clearing the pool-wide fee-index remainder, preserves its latest-deposit preference metadata without inventing one for a new vault, then replaces the vault fee index, bad debt, and aggregate pool bad debt and registers the vault.</td>
<td>Always <code>VaultAccountingCheckpoint</code> and <code>PoolAccountingCheckpoint</code>, including when all supplied values repeat current state</td>
</tr>
<tr>
<td><code>setTotalRepBackingUnits(newDenominator)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td>No lifecycle or value-change guard.</td>
<td>Replaces the REP backing units denominator.</td>
<td><code>TotalRepBackingUnitsSet</code>, including for zero or a repeated value</td>
</tr>
<tr>
<td><code>setTotalSharesAttoShares(newTotalSharesAttoShares)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td>No lifecycle or value-change guard.</td>
<td>Replaces stored <code>shareTokenSupplyAttoShares</code>, the denominator used by <code>attoSharesToAttoEth</code> and complete-set redemption.</td>
<td><code>ShareTokenSupplySet</code>, including for zero or a repeated value</td>
</tr>
<tr>
<td><code>setPoolFinancials(newSettlementCollateralAttoEth, newTotalCapacityOwnershipAttoRep, newFeeEligibleCapacityOwnershipAttoRep, newTotalBadDebtAttoEth)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td>Fee-eligible capacity ownership does not exceed total capacity ownership; supplied settlement collateral does not exceed the current price-converted minting capacity; actual pool-held REP satisfies both live backing constraints for supplied collateral net of supplied aggregate bad debt, with dispute-staked REP counting only toward the associated-REP constraint; no lifecycle or value-change guard.</td>
<td>Replaces settlement collateral, both price-independent capacity-ownership totals, and aggregate pool bad debt, resets the fee timestamp to the current block, and clears fee-index rounding carry.</td>
<td><code>PoolAccountingCheckpoint</code>, including for repeated financial values</td>
</tr>
<tr>
<td><code>authorizeChildPool(pool)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td>This parent pool is already authorized; candidate reports this share token; candidate universe has no different canonical pool. No pool-lifecycle guard.</td>
<td>Asks the lineage share token to establish <code>pool</code> as the canonical authorized pool for its universe; reauthorizing the same pool is a no-op.</td>
<td><code>AuthorizationUpdated</code> only on first authorization; no event when already authorized</td>
</tr>
<tr>
<td><code>transferEth(receiver, amountAttoEth)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td>Fee liabilities are covered; <code>amount</code> fits both unreserved pool ETH and tracked settlement collateral; <code>receiver</code> accepts the ETH call, including zero value.</td>
<td>Reduces tracked settlement collateral by <code>amount</code>, checkpoints the reconciliation, and calls <code>receiver</code> with that ETH. At zero amount it reduces no settlement collateral but still emits the checkpoint and performs a zero-value call; callback rejection rolls back the transaction and checkpoint.</td>
<td><code>PoolAccountingCheckpoint</code>, including at zero amount; no dedicated ETH-transfer event</td>
</tr>
<tr>
<td><code>assignFinalizedAuctionFees(vault, amountAttoRep, auctionFeeIndexAtFinalization)</code></td>
<td><code>SecurityPoolForker</code> only</td>
<td>The supplied finalization index does not exceed the current fee index; the forker credit workflow has already checkpointed the vault and added the claimed capacity ownership.</td>
<td>Assigns to the claiming vault the fees its auctioned capacity ownership accrued from truth-auction finalization through the current fee index, combines fractional carry with the vault remainder, and removes whole assigned fees from the unallocated reserve. The ownership was already included in the fee denominator and total ownership at finalization. This call preserves aggregate fees and settlement collateral; after every eligible ownership is reconciled on a forked pool, a subsequent permissionless <code>updateVaultFees</code> checkpoint returns any reserve that no vault can individually claim to settlement collateral.</td>
<td><code>VaultAccountingCheckpoint</code> and auction-claim <code>PoolAccountingCheckpoint</code>; the calling forker emits <code>ClaimAuctionProceeds</code> only after the broader credit workflow completes</td>
</tr>
<tr>
<td>Direct ETH transfer to <code>receive()</code></td>
<td>Forker, this pool's truth auction, or parent pool only</td>
<td>Sender is one of the three authorized protocol addresses. Forced ETH bypasses this ordinary-call guard.</td>
<td>Accepts protocol-routed ETH used by migration and auction settlement. Forced ETH remains raw, unaccounted surplus rather than settlement collateral or fees.</td>
<td>No dedicated receive event; the calling protocol step emits its own event</td>
</tr>
</tbody>
</table>
<h2 id="securitypoolforker">SecurityPoolForker</h2>
<p>Freezes parent pools, creates selected child pools, migrates vault and escalation state, and settles collateral-repair auctions. <a href="../../solidity/contracts/statoblast/SecurityPoolForker.sol">Source</a></p>
<p>Read surface: Use <code>zoltar</code>, <code>forkData</code>, <code>getMigratedAttoRep</code>, <code>getForkActivationTime</code>, <code>getUnassignedPosition</code>, <code>getUnassignedPositionFeeIndex</code>, <code>isEscalationDepositClaimedDirectly</code>, <code>getEscalationDepositId</code>, <code>getDirectlyClaimedEscalationPrincipal</code>, <code>isEscalationWinnerHaircutPaidByFork</code>, <code>getEscalationMigrationEntitlementStatus</code>, <code>getOwnForkRepBuckets</code>, <code>getOwnForkMigrationStatus</code>, <code>getMigrationProxyAddress</code>, <code>getQuestionOutcome</code>, <code>attoRepToBackingUnits</code>, and <code>backingUnitsToAttoRep</code> to reconstruct fork progress and preview migration conversions.</p>
<h3 id="child-game-trust-boundary">Child-game trust boundary</h3>
<p>Fork entrypoints and child setup may receive contracts through unauthenticated pool lineages. External-universe initiation requires the supplied pool to be authorized by its declared share token, but that relationship alone does not prove factory registration; own-game initiation does not perform that authorization check. Canonicality comes from the configured <code>SecurityPoolFactory</code> registry. A game relationship check is point-in-time: the reported nonzero game address must return the supplied pool or child from <code>securityPool()</code> when validated. This does not prove that an arbitrary game getter is immutable or that the address was factory-deployed. Child setup captures one reported game address, validates it before privileged use, and reuses that exact address for continuation backing and escrow work. When unresolved escalation requires a continuation and setup initially reports no game, initialization creates one; the forker then captures and validates it before continuation use. Combined vault migration passes the captured child/game pair into unresolved cleanup without reading the child getter again. Truth-auction completion performs a fresh point-in-time validation of the game reported then before checking continuation readiness. Genuine factory-deployed <code>EscalationGame</code> instances store their pool immutably, but safety on unauthenticated paths does not assume arbitrary contracts do.</p>
<!-- Validated read ABI fingerprint: a86dd34e9af6508b8a182c6f507e5b3af94b0a1b5482ad3911b2a8e4de0b4ad4 -->
<!-- Validated complete compiled ABI fingerprint: a020c5bd3f76bb764fe16b469c8fc7eb408befe2742df714b1a25a013d118da1 -->
<table>
<thead>
<tr>
<th>Transaction</th>
<th>Caller</th>
<th>Main prerequisites</th>
<th>State or asset effect</th>
<th>Primary signals</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>initiateSecurityPoolFork(securityPool)</code></td>
<td>Anyone</td>
<td>Pool operational with no inherited fixed outcome; the pool is authorized by its declared share token; its universe already forked; fork state not initialized; if an escalation game exists, it reports the supplied pool from <code>securityPool()</code> when validated and the universe fork occurred before that game settled. Declared-token authorization is not configured-factory registration; see the <a href="#child-game-trust-boundary">child-game trust boundary</a>.</td>
<td>Freezes the supplied pool after an external universe fork, drains its pool and game REP, and records a migration snapshot keyed by that address. The snapshot is canonical only when the supplied pool is already registered by the configured <code>SecurityPoolFactory</code>.</td>
<td><code>SecurityPoolForkSnapshot</code> and <code>ParentRepLocked</code>; additionally <code>DisputeStakedRepDrainedAtFork</code> when unresolved escalation exists</td>
</tr>
<tr>
<td><code>forkZoltarWithOwnEscalationGame(securityPool)</code></td>
<td>Anyone</td>
<td>Pool operational with no inherited fixed outcome; its escalation game reports the supplied pool from <code>securityPool()</code> when validated and <code>canTriggerOwnFork()</code> is true because it recorded a local non-decision or inherited a threshold tie without a game-level fixed outcome; universe not already forked. The game-local predicate does not bypass the pool guard. Unlike external-universe initiation, this entrypoint does not require declared-share-token authorization; neither path authenticates the supplied address against the configured pool factory. See the <a href="#child-game-trust-boundary">child-game trust boundary</a>.</td>
<td>Uses the supplied pool game's non-decision to fork Zoltar, freezes that pool, and records own-fork REP buckets and snapshot state keyed by its address. The snapshot is canonical only when the supplied pool is already registered by the configured <code>SecurityPoolFactory</code>.</td>
<td><code>SecurityPoolForkSnapshot</code>, <code>ParentRepLocked</code>, and Zoltar fork events; additionally <code>DisputeStakedRepDrainedAtFork</code> when unresolved escalation exists</td>
</tr>
<tr>
<td><code>migrateRepToZoltar(securityPool, outcomeIndices)</code></td>
<td>Anyone</td>
<td>Migration proxy exists and the pool is <code>PoolForked</code>. Only a positive migration amount with at least one selected outcome checks the eight-week window, existing child <code>ForkMigration</code> state, outcome validity, and cumulative split bound. A zero amount skips those checks even when outcome values are supplied.</td>
<td>For a positive migration amount and nonempty list, ensures that the forker's recorded pool migration amount has been split into each selected child REP branch. A zero migration amount or empty list returns after the proxy and pool-state guards without per-outcome validation or events.</td>
<td><code>MigrationRepSplit</code> and <code>ChildRepSplit</code> when a selected branch requires a new split; no event for a zero amount, empty list, or already-satisfied branch</td>
</tr>
<tr>
<td><code>createChildUniverse(securityPool, outcomeIndex)</code></td>
<td>Anyone</td>
<td>Parent in migration window; selected fork outcome is well formed; child pool is not already deployed. The returned auction is nonzero, deployed, and has never been trusted by this forker; the child's fork-data slot is unused; and the child reports the expected parent, universe, source factory, forker, and auction. The selected child's reported nonzero escalation game passes the <a href="#child-game-trust-boundary">child-game trust boundary</a>. These relationship checks do not independently prove configured-factory registration.</td>
<td>Loads an already deployed child universe and REP token or deploys them when absent, then lazily deploys the selected child pool, coordinator, and auction; authorizes and links the child; captures and validates the child's escalation game; and initializes any continuation snapshot and materializes or sweeps child backing through that validated game.</td>
<td><code>DeployChild</code> only when child REP was absent; always <code>SecurityPoolRegistered</code>, <code>DeploySecurityPool</code>, <code>AuthorizationUpdated</code>, <code>ChildPoolLinked</code>, and <code>TotalRepBackingUnitsSet</code>; <code>AwaitingForkContinuationSet</code>, <code>EscalationGameSet</code>, <code>GameContinuedFromFork</code>, <code>ForkCarryCheckpoint</code>, <code>MigrationRepSplit</code>, <code>ChildDisputeStakedRepMaterialized</code>, and <code>PoolHeldRepSweptToChild</code> as continuation and backing state requires</td>
</tr>
<tr>
<td><code>migrateVault(securityPool, outcomeIndex)</code></td>
<td>Vault owner for their non-escrowed position</td>
<td>Migration window open; the selected child's reported nonzero escalation game passes the <a href="#child-game-trust-boundary">child-game trust boundary</a>. The optional unresolved parent escalation-deposit accounting cleanup wrapper calls this function first to migrate transferable vault state.</td>
<td>Converts the caller's parent REP backing-unit claim to REP at the fork snapshot and credits that REP amount as child-local backing units; transfers REP-denominated capacity ownership, latest-positive-deposit target preference metadata, and vault bad debt into one child pool; checkpoints but retains claimable fees in the parent vault; and separately routes proportional pool-level settlement collateral while preserving aggregate bad debt. Repeat calls can have no additional REP backing units, capacity ownership, or vault bad debt to move.</td>
<td><code>VaultBadDebtMigrated</code> and <code>VaultMigrationCheckpoint</code></td>
</tr>
<tr>
<td><code>migrateVaultWithUnresolvedEscalation(securityPool, vault, childOutcomeIndex)</code></td>
<td>The named vault owner</td>
<td>Migration window open; caller equals <code>vault</code>; selected child not already recorded for this optional cleanup; the selected child's reported nonzero escalation game passes the <a href="#child-game-trust-boundary">child-game trust boundary</a>.</td>
<td>First runs ordinary migration for the same vault, which may convert its parent REP backing-unit claim to REP and credit that REP as child-local backing units; transfer capacity ownership, latest-positive-deposit target preference metadata, and vault bad debt to the selected child while preserving aggregate bad debt; checkpoint but retain claimable fees in the parent vault; and separately route proportional pool-level settlement collateral. It returns the selected child and its captured, validated escalation game to the unresolved-accounting cleanup phase, which reuses those exact addresses without reading the child's game again. The cleanup then clears that vault's unresolved parent escalation-deposit accounting in constant-size work and records it; the cleanup neither funds dispute-staked REP backing nor authorizes carried proofs.</td>
<td>Vault migration events, including <code>VaultBadDebtMigrated</code>, plus <code>EscalationMigrationEntitlementInitialized</code> on first export and <code>EscalationMigrationEntitlementMaterialized</code> for the selected child</td>
</tr>
<tr>
<td><code>claimForkedEscalationDeposits(...)</code></td>
<td>The named vault owner</td>
<td>Caller equals <code>vault</code>; unresolved escalation existed when the pool initiated its own fork and the parent game still satisfies <code>canTriggerOwnFork()</code> by having either a local non-decision or an inherited threshold tie without a fixed outcome; selected child can be created or loaded, remains in <code>ForkMigration</code>, has a continuation game that passes the <a href="#child-game-trust-boundary">child-game trust boundary</a>, and is inside the eight-week claim window. A nonempty list additionally requires the matching winning outcome, unclaimed deposit identities, and every deposit to commit <code>vault</code> as its immutable depositor.</td>
<td>First gets or lazily deploys the selected child universe, REP token, pool, coordinator, and auction, then captures and validates the child's escalation game and uses that same game for continuation backing and escrow payment. A nonempty list claims winning own-fork parent deposits and records their stable identities against descendant replay. An empty list still performs child setup and emits a zero-valued claim summary.</td>
<td><code>DeployChild</code>, <code>SecurityPoolRegistered</code>, <code>DeploySecurityPool</code>, <code>AuthorizationUpdated</code>, <code>ChildPoolLinked</code>, <code>TotalRepBackingUnitsSet</code>, <code>AwaitingForkContinuationSet</code>, <code>EscalationGameSet</code>, <code>GameContinuedFromFork</code>, <code>ForkCarryCheckpoint</code>, <code>MigrationRepSplit</code>, <code>ChildDisputeStakedRepMaterialized</code>, and <code>PoolHeldRepSweptToChild</code> as setup requires; per claimed deposit, <code>CarryDepositConsumed</code> and <code>ClaimDeposit</code>; escrow record/export events when REP is paid; always <code>ClaimForkedEscalationDepositsToWallet</code>, including for an empty list</td>
</tr>
<tr>
<td><code>startTruthAuction(securityPool)</code></td>
<td>Anyone</td>
<td>Child migration window ended; pool is in fork migration; required child REP is available. If unresolved escalation existed at fork, any game reported during immediate completion passes the <a href="#child-game-trust-boundary">child-game trust boundary</a>.</td>
<td>Copies the frozen parent's remaining economic claim supply into the child, closes migration accounting, and either reopens a fully backed child or starts its repair auction.</td>
<td><code>ShareTokenSupplySet</code> and <code>TruthAuctionStarted</code>; immediate no-auction completion also emits <code>TruthAuctionFinalized</code>, pool accounting checkpoints, and <code>ForkContinuationResumed</code> for an unresolved continuation</td>
</tr>
<tr>
<td><code>finalizeTruthAuction(securityPool)</code></td>
<td>Anyone</td>
<td>Truth auction started, its one-week window has passed, and <code>msg.value</code> is zero. Migrated collateral plus accepted bid ETH does not exceed current price-converted minting capacity, and actual pool-held REP satisfies both live backing constraints for that collateral net of aggregate bad debt; dispute-staked REP counts only toward the associated-REP constraint. If unresolved escalation existed at fork, the game reported at completion passes the <a href="#child-game-trust-boundary">child-game trust boundary</a>.</td>
<td>Finalizes the ended auction, accounts migration-routed settlement collateral plus accepted bid ETH, and records every unmigrated REP backing unit, capacity unit, and proportional bad debt in an explicit nonwithdrawable unassigned position. It activates the child, fixes bidder REP-backing-unit and capacity-ownership rates, and saves the fee index. Positive-purchase auction ownership becomes fee eligible immediately; after a zero-purchase auction, the unassigned capacity remains outside fee eligibility. A nonzero repair contribution is rejected.</td>
<td><code>TruthAuctionFinalized</code>, auction <code>AuctionFinalized</code>, and pool accounting checkpoints; <code>TruthAuctionHaircutApplied</code> when purchased REP removes a positive escalation allocation; <code>ForkContinuationResumed</code> for an unresolved continuation</td>
</tr>
<tr>
<td><code>settleAuctionBids(securityPool, vault, claimTickIndices, refundTickIndices)</code></td>
<td>Anyone on behalf of the named bidder vault</td>
<td>At least one index; before finalization the claim list must be empty and refund indexes must be eligible; after finalization all indexes must belong to the named vault owner and remain unsettled.</td>
<td>Before finalization, refunds only provably losing bids. After finalization, combines claim and refund indexes into one settlement withdrawal and transfers each claim's proportional REP backing units, capacity ownership, bad debt, and finalization-to-claim fees from the unassigned position to the bidder vault. Capacity and bad-debt division dust follows each bid's deterministic cumulative ETH position, so claim order cannot change individual or aggregate settlement. The transfer does not change total capacity, fee eligibility, active open interest, total bad debt, retention, or aggregate accrued fees. A winning dust bid may receive capacity ownership even when its REP allocation rounds to zero. A positive ETH push is gas-bounded and defers on rejection, revert, or gas exhaustion.</td>
<td>Underlying auction <code>BidSettled</code>; <code>EthRefundDeferred</code> when the named bidder rejects a positive refund; <code>ClaimAuctionProceeds</code> with cumulative claimed and total auctioned bad debt when REP backing, capacity ownership, or bad debt is credited</td>
</tr>
<tr>
<td><code>claimAuctionProceeds(securityPool, vault, tickIndices)</code></td>
<td>Anyone on behalf of the named bidder vault</td>
<td>Auction finalized. A nonempty list additionally requires every index to belong to the named vault owner and remain unsettled.</td>
<td>For a nonempty list, withdraws finalized bid settlements and transfers each claim's proportional REP backing units, capacity ownership, bad debt, and finalization-to-claim fees from the unassigned position to the bidder vault. Capacity and bad-debt division dust follows each bid's deterministic cumulative ETH position, so claim order cannot change individual or aggregate settlement. The transfer does not change total capacity, fee eligibility, active open interest, total bad debt, retention, or aggregate accrued fees. A winning dust bid can receive positive capacity ownership when its REP allocation rounds to zero. A positive ETH push is gas-bounded and defers on rejection, revert, or gas exhaustion, so recipient code cannot block the subsequent credit. For an empty list, the underlying auction withdrawal returns four zeros and the wrapper exits after the finalization guard without validating bids or the named beneficiary, calling it, changing state, or emitting events.</td>
<td>For processed bids, underlying auction <code>BidSettled</code>; <code>EthRefundDeferred</code> when the named bidder rejects a positive refund; <code>ClaimAuctionProceeds</code> with cumulative claimed and total auctioned bad debt when REP backing, capacity ownership, or bad debt is credited; no event for an empty list</td>
</tr>
<tr>
<td><code>initializeChildForkedEscalationGameIfNeeded(parent, child, childEscalationGame)</code></td>
<td>This <code>SecurityPoolForker</code> contract only, through its migration delegate callback</td>
<td>External caller is the forker itself; parent and child match the active migration path; a supplied nonzero game passes the <a href="#child-game-trust-boundary">child-game trust boundary</a>.</td>
<td>Allows delegated migration code to initialize a child continuation while preserving the forker as the authoritative caller and the already captured child-game identity. When unresolved escalation requires a continuation and no game existed, it captures and validates the game created by initialization before any continuation use.</td>
<td><code>ChildDisputeStakedRepMaterialized</code> and escalation-continuation events when initialization is required</td>
</tr>
<tr>
<td>Direct ETH transfer to <code>receive()</code></td>
<td>A child-pool truth auction trusted by this forker during <code>ChildPoolLinked</code></td>
<td><code>trustedAuctionAddresses[msg.sender]</code> was set when the forker linked the child and emitted <code>ChildPoolLinked</code>; configured-factory registration determines whether that lineage is canonical.</td>
<td>Accepts auction ETH during forker-controlled auction finalization.</td>
<td>No dedicated receive event; auction <code>AuctionFinalized</code> is followed by forker <code>TruthAuctionFinalized</code> and pool accounting checkpoints</td>
</tr>
</tbody>
</table>
<h2 id="escalationgame">EscalationGame</h2>
<p>Escrows outcome REP, raises the running resolution cost, detects non-decision, and settles local or carried deposits. <a href="../../solidity/contracts/statoblast/EscalationGame.sol">Source</a></p>
<p>Read surface: Base getters are <code>securityPool</code>, <code>repToken</code>, <code>activationTime</code>, <code>nonDecisionThresholdAttoRep</code>, <code>startBondAttoRep</code>, <code>nonDecisionTimestamp</code>, <code>nonDecisionState</code>, <code>forkContinuation</code>, <code>forkElapsedAtStart</code>, <code>forkResumedAt</code>, <code>fixedQuestionOutcome</code>, <code>nodes</code>, <code>disputeStakedRepByVaultAttoRep</code>, <code>totalDisputeStakedAttoRep</code>, <code>truthAuctionRepBeforeAttoRep</code>, <code>truthAuctionRepRemainingAttoRep</code>, <code>cumulativeClaimRetention</code>, and <code>cumulativeClaimRetentionExponent</code>. The claim delegate fallback exposes <code>rootClaimSourceGame</code>, <code>applyInheritedClaimRetention</code>, and <code>applyInheritedSourceStorageBasis</code>. The source-storage-basis read allocates retained carry by cumulative-prefix differences so leaf allocations sum to the aggregate checkpoint. <code>disputeStakedRepByVaultAttoRep</code> is locally attributed current-game escrow used for health; inherited carry remains aggregate commitment state until proof settlement. Use <code>previewDepositOnOutcome</code>, <code>computeIterativeAttritionCostAttoRep</code>, <code>computeTimeSinceStartFromAttritionCostAttoRep</code>, <code>totalCostAttoRep</code>, <code>getEscalationGameEndDate</code>, <code>getQuestionResolution</code>, <code>getFinalQuestionResolution</code>, <code>hasReachedNonDecision</code>, <code>canTriggerOwnFork</code>, <code>getBindingCapitalAttoRep</code>, <code>getOutcomeBalancesAttoRep</code>, <code>getDepositsByOutcome</code>, <code>getDepositsByOutcomeLength</code>, <code>forkCarrySnapshotInitialized</code>, <code>getOutcomeState</code>, <code>getForkCarrySnapshot</code>, <code>getForkCarryRoots</code>, <code>isForkCarryFundingComplete</code>, <code>getCarryLeafPageByOutcome</code>, <code>getProofConsumedCarriedDepositIndexesByOutcome</code>, <code>getLocalUnresolvedPrincipalByVaultAndOutcome</code>, and <code>getForkedEscrowByVaultAndOutcome</code> for calculations, lifecycle authorization, pages, carry state, and escrow. Vault-funded deposits and all withdrawals route through <code>SecurityPool</code>; after an ordinary game starts, caller-funded deposits use <code>depositRepOnOutcome</code> and mint no pool backing units.</p>
<!-- Validated read ABI fingerprint: ed587e847ca84dfb0faa31896f294197b8e84a13c229b3bab68447f262dae58d -->
<!-- Validated complete compiled ABI fingerprint: fc3251d94de8ecab58eb38c59b0d03481b0707fda722b27063ac998ddc23cf93 -->
<table>
<thead>
<tr>
<th>Transaction</th>
<th>Caller</th>
<th>Main prerequisites</th>
<th>State or asset effect</th>
<th>Primary signals</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>start(startBondAttoRep, nonDecisionThresholdAttoRep)</code></td>
<td><code>EscalationGameFactory</code> contract during atomic deployment</td>
<td>Game not already started; threshold exceeds the positive start bond. Positive attoREP values are valid.</td>
<td>Initializes a local game and sets activation three days after deployment. For ordinary pool games, the factory lowers an oversized configured bond to <code>nonDecisionThresholdAttoRep - 1</code> before this call.</td>
<td><code>GameStarted</code></td>
</tr>
<tr>
<td><code>startFromFork(startBondAttoRep, nonDecisionThresholdAttoRep, elapsedAtFork, fixedQuestionOutcome, winnerHaircutPaidByFork, forkCarryInitialBackingAttoRep)</code></td>
<td>Immutable owner (<code>EscalationGameFactory</code>) during atomic continuation deployment</td>
<td>Game not started; threshold exceeds the positive start bond; inherited elapsed time is no greater than seven weeks. Positive attoREP values are valid.</td>
<td>Initializes a paused continuation with inherited elapsed time, an optional fixed matching child outcome, and immutable fork-time haircut/backing accounting. It does not start the remaining clock until <code>resumeFromFork</code>.</td>
<td><code>GameContinuedFromFork</code></td>
</tr>
<tr>
<td><code>resumeFromFork()</code></td>
<td>Owning <code>SecurityPool</code> only</td>
<td>Fork-continuation mode; not previously resumed; immutable carry snapshot installed; aggregate REP funding complete. An unrelated fork requires one-to-one backing of effective unresolved principal. For an own-fork continuation, recorded initial backing must be at least <code>sourcePrincipalAtForkAttoRep - ⌊sourcePrincipalAtForkAttoRep / 5⌋</code>, where <code>sourcePrincipalAtForkAttoRep</code> is the aggregate raw unresolved principal installed by the snapshot before effective direct-claim deductions. The live balance must cover that initial backing minus child REP already exported by valid direct pre-resume claims.</td>
<td>Records the resume timestamp once the immutable carry commitment is installed and funded. The new deadline is <code>max(rebasedCurveEnd, forkResumedAt + 3 days)</code>, so even an exhausted inherited clock receives a fresh response period. After that deadline, <code>getFinalQuestionResolution</code> returns the fixed outcome when the continuation has one.</td>
<td><code>ForkContinuationResumed</code></td>
</tr>
<tr>
<td><code>applyTruthAuctionHaircut(repToRemove)</code></td>
<td>The child pool's <code>SecurityPoolForker</code> only</td>
<td>Paused fork continuation; no prior auction haircut; the requested amount is below the game's live REP balance.</td>
<td>Transfers the sold child REP to the pool, applies one retention ratio to escrow and outcome balances, and rebases elapsed curve time. The fork remains final and the game remains paused until the pool resumes it.</td>
<td><code>TruthAuctionHaircutApplied</code> and REP <code>Transfer</code></td>
</tr>
<tr>
<td><code>depositRepOnOutcome(outcome, maximumDepositAttoRep)</code></td>
<td>Any REP holder</td>
<td>Current game is the pool's ordinary unresolved game; pool operational; universe unforked; outcome non-<code>None</code>; caller allowance to this game covers the accepted REP; preview accepts a positive amount within the remaining threshold room.</td>
<td>Transfers the accepted REP directly from the caller into dispute escrow, appends a local deposit, and records its carry leaf without minting pool backing units.</td>
<td><code>LocalDepositAppended</code>, <code>DepositOnOutcome</code>, REP <code>Transfer</code>, optionally <code>NonDecisionReached</code></td>
</tr>
<tr>
<td><code>recordDepositFromSecurityPool(...)</code></td>
<td>Owning <code>SecurityPool</code> only</td>
<td>Explicit non-decision state is <code>None</code>; game unresolved; valid outcome; preview and accepted cumulative amount match; room remains below threshold.</td>
<td>Appends an accepted local deposit, updates outcome and vault escrow, and records its carry leaf.</td>
<td><code>LocalDepositAppended</code>, <code>DepositOnOutcome</code>, optionally <code>NonDecisionReached</code></td>
</tr>
<tr>
<td><code>withdrawDeposit(uint256 depositIndex, outcome)</code></td>
<td>Owning <code>SecurityPool</code> only</td>
<td>Explicit non-decision state is <code>None</code>; non-<code>None</code> supplied outcome; game final; game and pool final outcomes match; valid unsettled local deposit index.</td>
<td>Consumes one local deposit after resolution. A winner pays the deposit's immutable depositor after its haircut; a loser only retires its escrow accounting.</td>
<td><code>CarryDepositConsumed</code> and <code>VaultEscrowUpdated</code>; for a winner, <code>ClaimDeposit</code>, positive REP payout <code>Transfer</code>, and haircut burn signals when nonzero</td>
</tr>
<tr>
<td><code>initializeForkCarrySnapshotWithResolutionBalances(...)</code></td>
<td>Owning <code>SecurityPool</code> only</td>
<td>Fork-continuation mode; no prior snapshot; each leaf count fits the MMR; supplied nonzero snapshot ID equals the hash of the normalized data.</td>
<td>Installs the immutable inherited peaks, leaf counts, carry totals, resolution balances, and normalized nullifier roots; zero snapshot ID selects the computed ID. Two or more threshold-full inherited balances set <code>nonDecisionState</code> to <code>InheritedThresholdTie</code> without creating a local timestamp.</td>
<td><code>ForkCarryCheckpoint</code>; additionally <code>InheritedThresholdTie</code> when the installed balances meet the non-decision threshold</td>
</tr>
<tr>
<td><code>claimDepositForWinning(depositIndex, outcome)</code></td>
<td>Owning <code>SecurityPool</code> or its <code>SecurityPoolForker</code></td>
<td>Non-<code>None</code> supplied outcome and valid unsettled local deposit with sufficient escrow. This entrypoint itself does not check final resolution or that the supplied outcome won; its trusted caller selects that path.</td>
<td>Consumes a selected local deposit as a winner, consumes its vault escrow, burns the computed haircut when nonzero, and transfers the remaining positive REP payout to the deposit's immutable depositor.</td>
<td><code>CarryDepositConsumed</code>, <code>VaultEscrowUpdated</code>, <code>ClaimDeposit</code> with <code>transferredRep = true</code>; REP payout <code>Transfer</code> and haircut burn signals only when their amounts are positive</td>
</tr>
<tr>
<td><code>claimDepositForWinningWithoutTransfer(depositIndex, outcome)</code></td>
<td>Owning <code>SecurityPool</code> or its <code>SecurityPoolForker</code></td>
<td>Valid in-range supplied outcome and unsettled local deposit with sufficient escrow. Unlike the transferring form, it has no explicit non-<code>None</code> guard; neither form checks final resolution or that the outcome won.</td>
<td>Consumes a selected local deposit and its vault escrow. The depositor's raw escrow backing decreases by the inverse-retention claim units corresponding to the deposit's original principal: the principal itself with no local auction checkpoint, or <code>⌈originalPrincipal × truthAuctionRepBeforeAttoRep / truthAuctionRepRemainingAttoRep⌉</code> after a local haircut. Other unconsumed deposits by the same depositor remain backed. The game returns the computed winner amount to the trusted caller but deliberately neither transfers REP nor burns the computed haircut.</td>
<td><code>CarryDepositConsumed</code>, <code>VaultEscrowUpdated</code>, and <code>ClaimDeposit</code> with <code>transferredRep = false</code>; no REP transfer or haircut burn</td>
</tr>
<tr>
<td><code>exportUnresolvedDeposit(depositIndex, outcome)</code></td>
<td>Owning <code>SecurityPool</code> or its <code>SecurityPoolForker</code></td>
<td>Non-<code>None</code> outcome and a valid unsettled local deposit. Final resolution is not required.</td>
<td>Returns deposit identity and amount to the trusted caller while consuming the local deposit from unresolved/escrow accounting without transferring REP.</td>
<td><code>CarryDepositConsumed</code> and <code>VaultEscrowUpdated</code>; no <code>ClaimDeposit</code> or REP transfer</td>
</tr>
<tr>
<td><code>withdrawDeposit(CarriedDepositProof proof, outcome)</code></td>
<td>Owning <code>SecurityPool</code> or its <code>SecurityPoolForker</code></td>
<td>Non-<code>None</code> supplied outcome; game final and matching the pool final outcome; supplied outcome is the winner; parent deposit was not directly claimed; valid unconsumed Merkle/nullifier proof.</td>
<td>Consumes an inherited proof, transfers any positive winning payout, and burns the positive haircut unless the fork already paid it.</td>
<td><code>CarryDepositConsumed</code> and <code>ClaimDeposit</code> with <code>transferredRep = true</code>; REP payout <code>Transfer</code> and haircut burn signals only when positive</td>
</tr>
<tr>
<td><code>exportVaultUnresolvedTotals(vault, repReceiver)</code></td>
<td>Owning <code>SecurityPool</code> or its <code>SecurityPoolForker</code></td>
<td><code>vault</code> is nonzero and has not exported before. There is no explicit nonzero-receiver guard: a zero receiver succeeds when the total is zero but the token rejects it when a positive transfer is attempted.</td>
<td>Marks the vault's local unresolved totals exported exactly once, clears each outcome amount, consumes aggregate unresolved and escrow accounting when positive, and transfers the positive total to <code>repReceiver</code>.</td>
<td>Always <code>VaultUnresolvedTotalsExported</code>, including when every amount is zero; <code>VaultEscrowUpdated</code> and REP <code>Transfer</code> only for a positive total</td>
</tr>
<tr>
<td><code>exportVaultUnresolvedTotalsWithoutTransfer(vault)</code></td>
<td>Owning <code>SecurityPool</code> or its <code>SecurityPoolForker</code></td>
<td><code>vault</code> is nonzero and has not exported before.</td>
<td>Marks the vault's local unresolved totals exported exactly once, clears each outcome amount, and consumes aggregate unresolved and escrow accounting when positive, but leaves token movement to its caller.</td>
<td>Always <code>VaultUnresolvedTotalsExported</code> with <code>transferredRep = false</code>, including when every amount is zero; <code>VaultEscrowUpdated</code> only for a positive total; no REP transfer</td>
</tr>
<tr>
<td><code>drainAllRep(receiver)</code></td>
<td>Owning <code>SecurityPool</code> only</td>
<td><code>receiver</code> is nonzero; no positive-balance requirement. The protocol reaches this call from the owning pool after <code>activateForkMode</code> enters <code>PoolForked</code>.</td>
<td>Transfers the game's full REP balance to <code>receiver</code>. A zero balance returns zero without a transfer or event.</td>
<td>REP <code>Transfer</code> for a positive balance; no event at zero balance</td>
</tr>
<tr>
<td><code>recordForkedEscrowForOutcome(depositor, outcome, sourcePrincipalAttoRep, childRepAmountAttoRep)</code></td>
<td>Owning <code>SecurityPool</code> or its <code>SecurityPoolForker</code></td>
<td>Outcome is not <code>None</code>; depositor is nonzero. Source principal and child REP may independently be zero; when both are zero, the call is a no-op.</td>
<td>Accumulates source principal and child REP escrow for the depositor and outcome. The depositor remains the immutable payout owner; inherited claims remain in the carry commitment and are not copied into child-local ownership state. When both amounts are zero, returns without changing state or emitting an event.</td>
<td><code>ForkedEscrowRecorded</code> for a nonzero record; no event when both amounts are zero</td>
</tr>
<tr>
<td><code>exportForkedEscrowByOutcome(vault, repReceiver)</code></td>
<td>Owning <code>SecurityPool</code> or its <code>SecurityPoolForker</code></td>
<td><code>vault</code> and <code>repReceiver</code> are nonzero.</td>
<td>Marks every remaining per-outcome escrow amount exported and transfers its positive child REP. When all outcomes were already empty or exported, returns zero arrays without state change, token transfer, or event.</td>
<td><code>ForkedEscrowExported</code> when any source principal or child REP remains; REP <code>Transfer</code> when positive child REP is transferred; no event for an already-empty export</td>
</tr>
<tr>
<td><code>exportForkedEscrowByOutcomeWithoutTransfer(vault)</code></td>
<td>Owning <code>SecurityPool</code> or its <code>SecurityPoolForker</code></td>
<td><code>vault</code> is nonzero.</td>
<td>Marks every remaining per-outcome escrow amount exported without transferring child REP. When all outcomes were already empty or exported, returns zero arrays without state change or event.</td>
<td><code>ForkedEscrowExported</code> with <code>transferredRep = false</code> when any source principal or child REP remains; no REP transfer; no event for an already-empty export</td>
</tr>
<tr>
<td><code>sweepResidualRepToSecurityPool()</code></td>
<td>Anyone</td>
<td>Final outcome; no unresolved principal; no vault escrow; positive residual balance.</td>
<td>Returns ordinary-game residual REP to the owning pool. Burns fork-continuation residual so pre-child capital cannot accrue to late or nonexistent child owners.</td>
<td><code>ResidualRepSweptToSecurityPool</code> for an ordinary game; <code>ForkContinuationResidualRepBurned</code> for a fork continuation</td>
</tr>
</tbody>
</table>
<h2 id="liquidationapprovalregistry">LiquidationApprovalRegistry</h2>
<p>Stores coordinator-local, bounded authorization for a receiver vault to accept liquidation debt from an exact operator. <a href="../../solidity/contracts/statoblast/LiquidationApprovalRegistry.sol">Source</a></p>
<p>Read surface: Use <code>coordinator</code> to identify the validating coordinator and implied security pool. <code>LIQUIDATION_APPROVAL_TYPEHASH</code>, <code>DOMAIN_SEPARATOR</code>, and <code>liquidationApprovalDigest</code> define the chain- and registry-bound EIP-712 message. <code>getLiquidationApproval</code> reports parameters plus available, reserved, consumed, and revoked state; <code>minimumLiquidationApprovalNonce</code> reports receiver invalidation state; <code>liquidationReservations</code> and <code>minimumHealthFactorBps</code> expose operation reservation state and its execution-time health floor.</p>
<!-- Validated read ABI fingerprint: 04465d90cef2bd37454bf8496fffcaccf07f0ec5808f31ffd6481d4cdc46f810 -->
<!-- Validated complete compiled ABI fingerprint: 24fef7375af443bf5477c0c4afa6d6ce6ef852f82a8b17d46bd1cea15bc3c264 -->
<table>
<thead>
<tr>
<th>Transaction</th>
<th>Caller</th>
<th>Main prerequisites</th>
<th>State or asset effect</th>
<th>Primary signals</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>initialize(coordinator)</code></td>
<td>Anyone while the registry remains uninitialized; normal factory deployment initializes the clone atomically</td>
<td>Coordinator is nonzero and the registry has not been initialized.</td>
<td>Binds this registry clone to one coordinator and therefore one security pool.</td>
<td>No event; the public <code>coordinator</code> getter records the binding.</td>
</tr>
<tr>
<td><code>setLiquidationApproval(params)</code></td>
<td>The receiver vault named by <code>params</code></td>
<td>Correct local pool; nonzero receiver and operator; positive cumulative and per-operation limits with per-operation no greater than cumulative; health factor at least 10,000 BPS; live ordered validity window; unused, non-invalidated nonce.</td>
<td>Installs explicit onchain bounded approval state and consumes the receiver-scoped nonce.</td>
<td><code>LiquidationApprovalSet</code></td>
</tr>
<tr>
<td><code>permitLiquidationApproval(params, signature)</code></td>
<td>Anyone relaying the receiver vault signature</td>
<td>Signature is valid for <code>params.receiverVault</code>; the chain ID, registry address, stable name/version, pool, receiver, operator, target scope, limits, health factor, window, and nonce are bound by the digest; direct-install validation rules also pass.</td>
<td>Validates an EIP-712 EOA or ERC-1271 signature immediately, installs explicit approval state, and consumes the receiver-scoped nonce.</td>
<td><code>LiquidationApprovalSet</code></td>
</tr>
<tr>
<td><code>revokeLiquidationApproval(approvalId)</code></td>
<td>Approval receiver vault only</td>
<td>Approval exists and is not already revoked.</td>
<td>Prevents new reservations while leaving reservations already attached to staged operations intact.</td>
<td><code>LiquidationApprovalRevoked</code> with available, reserved, and consumed totals</td>
</tr>
<tr>
<td><code>invalidateLiquidationApprovalNonce(newNonce)</code></td>
<td>Receiver vault invalidating its own older nonce range</td>
<td>New nonce is greater than the receiver current minimum.</td>
<td>Raises the minimum nonce accepted for new approval installation or reservation.</td>
<td><code>LiquidationApprovalNonceInvalidated</code></td>
</tr>
<tr>
<td><code>reserve(operationId, approvalId, receiverVault, targetVault, operator, requestedDebtAttoEth, snapshotTargetDebtAttoEth, latestExecutionTimestamp)</code></td>
<td>Bound coordinator only</td>
<td>Approval matches local pool, receiver, exact operator, and exact or wildcard target; it is active, unrevoked, non-invalidated, valid through latest execution, and has positive reservable quota.</td>
<td>Moves quota from available to pending reserved at staging, bounded by requested debt, target snapshot debt, per-operation limit, and available cumulative quota.</td>
<td><code>LiquidationApprovalReserved</code></td>
</tr>
<tr>
<td><code>release(operationId)</code></td>
<td>Bound coordinator only</td>
<td>Coordinator terminal cleanup path.</td>
<td>Returns an unsettled delegated reservation to available quota. A missing, self-route, or already settled reservation is a no-op.</td>
<td><code>LiquidationApprovalReleased</code> when quota is returned</td>
</tr>
<tr>
<td><code>consume(operationId, debtMovedAttoEth)</code></td>
<td>Bound coordinator only</td>
<td>For a delegated reservation, it is unsettled and moved debt does not exceed reserved debt. A self route is a no-op.</td>
<td>Permanently consumes exactly moved debt, releases unused reservation, and settles the reservation once.</td>
<td><code>LiquidationApprovalConsumed</code></td>
</tr>
</tbody>
</table>
<h2 id="openoraclepricecoordinator">OpenOraclePriceCoordinator</h2>
<p>Obtains a fresh REP-per-ETH price and coordinates withdrawals, delegated liquidation routing, approval reservations, and terminal cleanup. <a href="../../solidity/contracts/statoblast/OpenOraclePriceCoordinator.sol">Source</a></p>
<p>Read surface: Configuration getters are <code>MAX_PENDING_SETTLEMENT_OPERATIONS</code>, <code>OPEN_INTEREST_DIVIDER</code>, <code>reputationToken</code>, <code>securityPool</code>, <code>openOracle</code>, <code>weth</code>, <code>liquidationApprovalRegistry</code>, <code>gasConsumedOpenOracleReportPrice</code>, <code>gasConsumedSettlement</code>, <code>gasUnitsForOneDispute</code>, <code>initialReportPriorityFeeAttoEthPerGas</code>, <code>targetPriceErrorForDispute</code>, <code>openOracleSecurityMultiplierBps</code>, <code>settlementTime</code>, <code>disputeDelay</code>, <code>protocolFee</code>, <code>feePercentage</code>, <code>multiplier</code>, <code>timeType</code>, <code>trackDisputes</code>, <code>protocolFeeRecipient</code>, <code>escalationHaltMultiplierBps</code>, <code>maxSettlementBaseFeeMultiplierBps</code>, and <code>minLiquidationPriceDistanceBps</code>. Current report and operation getters are <code>pendingReportId</code>, <code>pendingReportSponsor</code>, <code>pendingOperationSlotId</code>, <code>lastSettlementTimestamp</code>, <code>lastPrice</code>, <code>pendingReportMaxSettlementBaseFeeAttoEthPerGas</code>, <code>stagedOperationCounter</code>, and <code>stagedOperations</code>. Use <code>isPriceValid</code>, <code>minimumToken1ReportAttoEth</code>, <code>getRequestPriceCostAttoEth</code>, <code>getQueuedOperationCostAttoEth</code>, <code>getSettlementCallbackGasLimit</code>, <code>getPendingOperationSlot</code>, <code>getActiveStagedOperationCount</code>, <code>getActiveStagedOperations</code>, <code>getPendingSettlementOperationCount</code>, and <code>getPendingSettlementOperationIds</code> for derived or paged state.</p>
<p>Report and staged-operation liveness depends on <a href="./security-model.html#assumption-a16">A16 timely inclusion</a>, <a href="./security-model.html#assumption-a17">A17 corrector capability</a>, <a href="./security-model.html#assumption-a18">A18 independent correction incentive</a>, <a href="./security-model.html#assumption-a19">A19 observable correctable price</a>, and <a href="./security-model.html#assumption-a06">A06 lifecycle executors</a>. When <code>lastPrice</code> is zero, the official client currently needs an offchain market quote to propose the first report; quote availability is a client limitation rather than a protocol security assumption. Proposals copied from a nonzero cached price do not use that quote path.</p>
<!-- Validated read ABI fingerprint: 288a73d13de5a0f593226105eb11eb177bf085ac2ee708a31645c3d7c4eb7237 -->
<!-- Validated complete compiled ABI fingerprint: 60cd10890a685efe179e17e93a783c660542bd6368f86fed87f46de03695b243 -->
<table>
<thead>
<tr>
<th>Transaction</th>
<th>Caller</th>
<th>Main prerequisites</th>
<th>State or asset effect</th>
<th>Primary signals</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>requestPriceIfNeededAndStageLiquidation(targetVault, receiverVault, requestedDebtAttoEth, approvalId, ...)</code></td>
<td>Liquidation operator; a delegated receiver must have approved this exact operator</td>
<td>Receiver differs from target; delegated approval matches pool, receiver, operator, and target scope, has available cumulative and per-operation quota, and remains valid through latest execution.</td>
<td>Stages explicit operator, receiver, and target roles and reserves bounded receiver quota before any oracle work. The self-receiving operator path uses a zero approval ID.</td>
<td><code>LiquidationRouteStaged</code>; <code>LiquidationApprovalReserved</code> on a delegated route; staged-operation lifecycle events</td>
</tr>
<tr>
<td><code>requestPriceIfNeededAndStageOperation(...)</code> with funding when stale</td>
<td>Vault owner for self withdrawal; legacy self-receiving liquidation callers remain supported. While a report is pending, only that report sponsor may stage more operations.</td>
<td><code>securityPool.isEscalationResolved()</code> is false; valid target, nonzero amount, and timeout from 1 second through 5 minutes. Bounty, buffered report funding, matching REP, and token approvals are required only when this call opens a new report. The caller must accept any positive unused-ETH refund.</td>
<td>Records the operation, executes immediately with a fresh price, or attaches it to a bounded pending settlement batch and opens a report when required. If unused ETH is positive, the final caller refund uses a low-level callback; rejection rolls back the entire transaction, including any queueing, immediate execution, or newly opened report.</td>
<td><code>StagedOperationQueued</code>, possibly <code>PriceRequested</code>, then <code>ExecutedStagedOperation</code>; authoritative <code>CoordinatorStateCheckpoint</code> records</td>
</tr>
<tr>
<td><code>requestPrice(proposedRepPerEthPrice, requestedInitialAttoWeth)</code> with report funding</td>
<td>Anyone when no fresh price or report is pending</td>
<td>Cached price stale; no pending report; nonzero proposed REP/ETH price, ETH bounty, and funding and approvals for at least the configured priority report plus the larger of the base-fee and open-interest WETH reports, plus matching REP. Zero requested WETH uses the minimum; a larger request voluntarily increases the initial report. The caller must accept any positive excess-ETH refund.</td>
<td>Opens and atomically funds a fresh WETH/REP report without staging a new operation, then refunds any positive excess ETH through a low-level caller callback. Callback rejection rolls back the report and initial position.</td>
<td><code>PriceRequested</code> and <code>CoordinatorStateCheckpoint</code></td>
</tr>
<tr>
<td><code>executeStagedOperation(operationId)</code></td>
<td>Anyone</td>
<td>Operation exists. Expired cleanup requires no valid price; a non-expired operation requires a fresh coordinator price. Lifecycle failures are emitted rather than retried.</td>
<td>Consumes an expired operation and releases its delegated reservation without requiring a valid price. Otherwise, consumes and attempts the active operation using the current fresh price. Price-report funding is independent of the operation's notional; the downstream operation applies its own protocol bounds.</td>
<td><code>ExecutedStagedOperation</code>, either <code>LiquidationApprovalConsumed</code> or <code>LiquidationApprovalReleased</code> for a delegated liquidation, and <code>CoordinatorStateCheckpoint</code></td>
</tr>
<tr>
<td><code>expireStagedOperation(operationId)</code></td>
<td>Anyone</td>
<td>Operation exists and its settlement-plus-validity window has elapsed.</td>
<td>Permissionlessly consumes an expired operation and releases its liquidation reservation without requiring a valid oracle price.</td>
<td><code>ExecutedStagedOperation</code>, <code>LiquidationApprovalReleased</code> for a delegated liquidation, and <code>CoordinatorStateCheckpoint</code></td>
</tr>
<tr>
<td><code>recoverSettledPendingReport()</code></td>
<td>Anyone</td>
<td>A pending report ID exists and its stored OpenOracle <code>storedGame(reportId).settlementTimestamp</code> is nonzero.</td>
<td>Clears a pending report whose normal callback path did not clear coordinator state, consumes every live operation attached to that report, and releases each delegated-liquidation reservation. Operations that were active but outside the bounded pending callback batch remain active.</td>
<td><code>PendingReportRecovered</code>, failed <code>ExecutedStagedOperation</code> for each live attached operation, <code>LiquidationApprovalReleased</code> for each attached delegated liquidation, and <code>CoordinatorStateCheckpoint</code></td>
</tr>
<tr>
<td><code>openOracleCallback(...)</code></td>
<td>Configured <code>OpenOracle</code> only</td>
<td>Callback report matches the pending report; excessive settlement basefee, a saturated <code>uint24</code> report counter, an uneconomic final history record at its recorded base fee plus configured priority fee, or zero values reject the price after clearing pending report state.</td>
<td>A valid settlement updates the price and auto-executes the bounded pending batch. A terminally rejected settlement consumes the pending batch and releases every liquidation reservation.</td>
<td><code>PriceReported</code> or <code>PriceReportRejected</code>; operation execution events; authoritative <code>CoordinatorStateCheckpoint</code> records</td>
</tr>
<tr>
<td><code>setLiquidationApprovalRegistry(registry)</code></td>
<td>Coordinator deployment factory only</td>
<td>Registry is nonzero and no registry was previously installed.</td>
<td>Binds the coordinator-local approval registry once.</td>
<td>No event; deterministic factory deployment and the public getter identify the registry.</td>
</tr>
<tr>
<td><code>setSecurityPool(pool)</code></td>
<td>Anyone while <code>securityPool</code> remains zero; normal factory deployment calls atomically</td>
<td>Current <code>securityPool</code> is zero; the argument itself is not required to be nonzero.</td>
<td>A nonzero value binds the pool permanently. A zero value emits and checkpoints zero but leaves the setter callable. Normal factory deployment supplies the nonzero canonical pool before returning the coordinator.</td>
<td><code>SecurityPoolSet</code> and <code>CoordinatorStateCheckpoint</code></td>
</tr>
<tr>
<td><code>setRepEthPrice(price)</code></td>
<td>Configured nonzero <code>SecurityPool</code> only</td>
<td>Caller equals the configured pool.</td>
<td>Seeds the coordinator's price value, including zero, for inherited child state.</td>
<td><code>RepEthPriceSet</code> and <code>CoordinatorStateCheckpoint</code></td>
</tr>
</tbody>
</table>
<h2 id="sharetoken">ShareToken</h2>
<p>Stores universe-aware ERC-1155 outcome shares and materializes a holder's persistent source entitlement in selected fork branches. <a href="../../solidity/contracts/statoblast/tokens/ShareToken.sol">Source</a></p>
<p>Read surface: Base and relationship getters are <code>name</code>, <code>symbol</code>, <code>zoltar</code>, <code>canonicalPoolByUniverse</code>, <code>_balances</code>, <code>_supplies</code>, and <code>_operatorApprovals</code>. Standard ERC-1155 reads are <code>supportsInterface</code>, <code>balanceOf</code>, <code>totalSupply</code>, <code>balanceOfBatch</code>, and <code>isApprovedForAll</code>; protocol-specific reads are <code>isAuthorized</code>, <code>totalSupplyForOutcome</code>, <code>maximumOutcomeSupply</code>, <code>balanceOfOutcome</code>, <code>balanceOfShares</code>, <code>getMigratedShareAmountAttoShares</code>, <code>getTokenId</code>, <code>getTokenIds</code>, and <code>unpackTokenId</code>.</p>
<!-- Validated read ABI fingerprint: 6093653de73a0e5fa1e400d77bbded71a92de1197f58bd89da82a657887f349e -->
<!-- Validated complete compiled ABI fingerprint: b4d43db4a275c3118a700ca255a7f63d42dfdca1fb1e7c554d681e589a76ac85 -->
<table>
<thead>
<tr>
<th>Transaction</th>
<th>Caller</th>
<th>Main prerequisites</th>
<th>State or asset effect</th>
<th>Primary signals</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>setApprovalForAll(operator, approved)</code></td>
<td>Any token account setting its own operator approval</td>
<td>The operator differs from the caller.</td>
<td>Sets or clears the operator's authority over all of the caller's outcome-token balances.</td>
<td><code>ApprovalForAll</code></td>
</tr>
<tr>
<td>Both <code>safeTransferFrom(...)</code> overloads</td>
<td>Share holder or approved ERC-1155 operator</td>
<td>Caller holds the source balance or has operator approval; the source account has not materialized that token into any child branch; destination is nonzero; the source balance is sufficient; under <a href="./security-model.html#assumption-a22">A22 asset-recipient compatibility</a>, a contract recipient accepts the ERC-1155 callback.</td>
<td>Transfers one outcome-token balance without changing supply.</td>
<td><code>TransferSingle</code></td>
</tr>
<tr>
<td>Both <code>safeBatchTransferFrom(...)</code> overloads</td>
<td>Share holder or approved ERC-1155 operator for a nonempty batch; any caller for an empty batch</td>
<td>ID and value array lengths match. A nonempty batch also requires holder or operator authority, no listed source token that the source account has already materialized into a child branch, a nonzero destination, sufficient source balances, and, under <a href="./security-model.html#assumption-a22">A22 asset-recipient compatibility</a>, an accepting ERC-1155 callback from a contract recipient; the empty-batch no-op performs none of those checks.</td>
<td>A nonempty batch transfers each listed outcome-token balance without changing supply. Equal empty ID and value arrays return as a no-op without an event.</td>
<td><code>TransferBatch</code> for a nonempty batch; no event for an empty batch</td>
</tr>
<tr>
<td><code>migrate(fromId, targetOutcomeIndexes)</code></td>
<td>Holder of the source token ID</td>
<td>Source universe forked; canonical source pool is <code>Operational</code> or <code>PoolForked</code>, and an <code>Operational</code> source has no inherited fixed outcome because auto-fork activation rejects one; positive source balance; nonempty, strictly increasing, well-formed outcomes; every target in a multi-target call already has a canonical child pool; after the branch-creation window, a single target must also already exist; at least one selected child has an unmaterialized balance; under <a href="./security-model.html#assumption-a22">A22 asset-recipient compatibility</a>, a contract holder accepts <code>onERC1155Received</code> for every target mint.</td>
<td>If needed, first freezes the operational source pool and records its fork snapshot. A single-target call may lazily create that child while the branch-creation window is open. It keeps and locks the holder's source entitlement, then mints each selected child-universe token ID up to the current source balance. Later source additions materialize only the unminted delta. A contract holder receives the ERC-1155 single-receiver callback for each mint; rejection rolls back the mint and preceding fork or child setup.</td>
<td><code>PoolForkModeActivated</code>, <code>PoolAccountingCheckpoint</code>, <code>SecurityPoolForkSnapshot</code>, <code>ParentRepLocked</code>, and optionally <code>DisputeStakedRepDrainedAtFork</code> when auto-forking; <code>SecurityPoolRegistered</code>, <code>DeploySecurityPool</code>, <code>AuthorizationUpdated</code>, and <code>ChildPoolLinked</code> when lazily deploying, plus <code>DeployChild</code>, <code>ChildRepSplit</code>, <code>PoolHeldRepSweptToChild</code>, <code>EscalationGameSet</code>, <code>GameContinuedFromFork</code>, <code>ForkCarryCheckpoint</code>, and <code>ChildDisputeStakedRepMaterialized</code> as applicable; then one ERC-1155 mint <code>TransferSingle</code> and <code>Migrate</code> per materialized target on successful callbacks</td>
</tr>
<tr>
<td><code>authorize(securityPoolCandidate)</code></td>
<td>Initially authorized <code>SecurityPoolFactory</code> for an origin pool; an authorized parent <code>SecurityPool</code> for a child pool</td>
<td>Caller is already authorized; the candidate reports this exact share token; its universe has no different canonical pool.</td>
<td>Establishes the candidate as <code>canonicalPoolByUniverse</code> for its universe and adds it to the set allowed to mint, burn, and authorize descendants. Reauthorizing the same candidate is a no-op.</td>
<td><code>AuthorizationUpdated</code> on first authorization; no event when the same candidate is already authorized</td>
</tr>
<tr>
<td><code>mintCompleteSets(universeId, account, amountAttoShares)</code></td>
<td>An authorized <code>SecurityPool</code></td>
<td>Caller is authorized; <code>account</code> is nonzero; <code>amount</code> is positive; under <a href="./security-model.html#assumption-a22">A22 asset-recipient compatibility</a>, a contract account accepts <code>onERC1155BatchReceived</code>.</td>
<td>Mints <code>amount</code> each of Invalid, Yes, and No to <code>account</code>, then invokes its ERC-1155 batch-receiver callback when it is a contract. Rejection rolls back the mint and the authorized pool's surrounding transaction.</td>
<td><code>TransferBatch</code> on a successful callback</td>
</tr>
<tr>
<td><code>burnCompleteSets(universeId, account, amountAttoShares)</code></td>
<td>An authorized <code>SecurityPool</code></td>
<td>Caller is authorized; <code>account</code> is nonzero and has at least <code>amount</code> of every outcome.</td>
<td>Burns <code>amount</code> each of Invalid, Yes, and No from <code>account</code>; global outcome supplies may differ.</td>
<td><code>TransferBatch</code></td>
</tr>
<tr>
<td><code>burnTokenIdAndGetRemainingSupply(tokenId, account)</code></td>
<td>An authorized <code>SecurityPool</code></td>
<td><code>account</code> is nonzero; caller is authorized.</td>
<td>Burns <code>account</code>'s full balance of <code>tokenId</code> and returns the burned amount and that token ID's remaining supply.</td>
<td><code>TransferSingle</code>, including when the burned balance is zero</td>
</tr>
</tbody>
</table>
<h2 id="uniformpricedualcapbatchauction">UniformPriceDualCapBatchAuction</h2>
<p>Collects ETH bids under ETH-raise and REP-sale caps, computes one clearing result, and supports paged settlement. AVL, cumulative-allocation, and refund-prefix mechanics live in <a href="../../solidity/contracts/statoblast/UniformPriceDualCapBatchAuctionStorage.sol">UniformPriceDualCapBatchAuctionStorage</a>, an internal storage library. <a href="../../solidity/contracts/statoblast/UniformPriceDualCapBatchAuction.sol">Source</a></p>
<p>Read surface: Auction summary getters are <code>maxAttoRepBeingSold</code>, <code>attoEthRaiseCap</code>, <code>finalized</code>, <code>clearingTick</code>, <code>ethFilledAtClearingAttoEth</code>, <code>attoEthRaised</code>, <code>totalAttoRepPurchased</code>, <code>auctionStarted</code>, <code>minBidSizeAttoEth</code>, <code>owner</code>, <code>underfunded</code>, <code>underfundedThreshold</code>, <code>underfundedWinningAttoEth</code>, and <code>activeTickCount</code>. <code>pendingEthRefundsAttoEth</code> reports ETH whose gas-bounded push failed during settlement and can still be pulled. Use <code>computeClearing</code>, <code>previewFinalization</code>, <code>tickToPrice</code>, <code>getTickSummary</code>, <code>getTickCount</code>, <code>getTickPage</code>, <code>getActiveTickPage</code>, <code>getBidCountAtTick</code>, <code>getBidPageAtTick</code>, <code>getBidderBidCount</code>, and <code>getBidderBidPage</code> before finalizing or submitting settlement indexes.</p>
<!-- Validated read ABI fingerprint: e4ad6ab91244711a2008716cfbdf62b6237d39321eefa984a4fdc7856267b8bc -->
<!-- Validated complete compiled ABI fingerprint: 7f8e3a156ea1b286628b95a387a696bd86c7f8365411a6c9c39b5dca8644cb76 -->
<table>
<thead>
<tr>
<th>Transaction</th>
<th>Caller</th>
<th>Main prerequisites</th>
<th>State or asset effect</th>
<th>Primary signals</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>startAuction(attoEthRaiseCap, maxAttoRepBeingSold)</code></td>
<td>Auction owner (<code>SecurityPoolForker</code>) only</td>
<td>Auction not previously started; both caps are positive; the REP cap does not exceed 11 million REP; the ETH cap fits in <code>uint128</code>; the block timestamp fits in <code>uint48</code>.</td>
<td>Starts the one-week auction and fixes its two caps and minimum bid.</td>
<td><code>AuctionStarted</code></td>
</tr>
<tr>
<td><code>submitBid(tick)</code> with ETH</td>
<td>Any bidder</td>
<td>Auction active and unfinalized; before one-week deadline; bid meets <code>minBidSizeAttoEth</code>; tick maps to nonzero price; the individual bid and the resulting cumulative ETH at that tick each fit in <code>uint128</code>.</td>
<td>Adds ETH demand at the selected positive-price tick while extending that tick's append-only cumulative bid and refund history, including when a fully refunded tick becomes active again.</td>
<td><code>BidSubmitted</code></td>
</tr>
<tr>
<td><code>refundLosingBids(tickIndices)</code></td>
<td>Bidder for its own bids</td>
<td>Auction started and unfinalized; auction has reached a clearing price. Nonempty indexes additionally belong to the caller and are strictly losing and unrefunded.</td>
<td>A nonempty list marks the caller's bids already provably below the current clearing tick and attempts an immediate gas-bounded ETH refund. Rejected, reverted, or gas-exhausted pushes are recorded in <code>pendingEthRefundsAttoEth</code> without restoring the bid. An empty list changes no bids and makes no external call.</td>
<td><code>BidSettled</code> per refunded bid; <code>EthRefundDeferred</code> when a positive push fails</td>
</tr>
<tr>
<td><code>refundLosingBidsFor(bidder, tickIndices)</code></td>
<td>Auction owner (<code>SecurityPoolForker</code>) only; public callers use <code>settleAuctionBids</code></td>
<td>Named bidder is nonzero; auction started and unfinalized; auction has reached a clearing price. Nonempty indexes additionally belong to that bidder and are strictly losing and unrefunded.</td>
<td>A nonempty list marks and attempts a gas-bounded refund of a named bidder's bids already provably below the current clearing tick. Rejected, reverted, or gas-exhausted pushes are recorded in <code>pendingEthRefundsAttoEth</code> without restoring the bid. An empty list changes no bids and makes no external call.</td>
<td><code>BidSettled</code> per refunded bid; <code>EthRefundDeferred</code> when a positive push fails</td>
</tr>
<tr>
<td><code>finalize()</code></td>
<td>Auction owner (<code>SecurityPoolForker</code>) only; users reach it through <code>finalizeTruthAuction</code></td>
<td>Auction started, not finalized, and one-week deadline reached; owner accepts the proceeds ETH call, including zero value.</td>
<td>Fixes the clearing mode, clearing tick, ETH totals, and aggregate REP allocation, then calls the owner with the resulting proceeds, including when zero. A rejected call reverts finalization and its event.</td>
<td><code>AuctionFinalized</code></td>
</tr>