@ottochain/sdk 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/dist/cjs/apps/contracts/index.js +15 -8
  2. package/dist/cjs/apps/contracts/state-machines/contract-agreement.js +35 -40
  3. package/dist/cjs/apps/contracts/state-machines/contract-escrow.js +80 -37
  4. package/dist/cjs/apps/contracts/state-machines/contract-universal.js +4 -4
  5. package/dist/cjs/apps/corporate/index.js +2 -2
  6. package/dist/cjs/apps/corporate/state-machines/corp-board.js +169 -59
  7. package/dist/cjs/apps/corporate/state-machines/corp-entity.js +245 -47
  8. package/dist/cjs/apps/corporate/state-machines/corp-securities.js +407 -99
  9. package/dist/cjs/apps/corporate/state-machines/corp-shareholders.js +151 -37
  10. package/dist/cjs/apps/governance/index.js +14 -14
  11. package/dist/cjs/apps/governance/state-machines/dao-multisig.js +58 -40
  12. package/dist/cjs/apps/governance/state-machines/dao-reputation.js +46 -40
  13. package/dist/cjs/apps/governance/state-machines/dao-single.js +28 -11
  14. package/dist/cjs/apps/governance/state-machines/dao-token.js +67 -41
  15. package/dist/cjs/apps/governance/state-machines/governance-simple.js +93 -61
  16. package/dist/cjs/apps/governance/state-machines/governance-universal.js +2 -2
  17. package/dist/cjs/apps/identity/constants.js +55 -14
  18. package/dist/cjs/apps/identity/index.js +27 -11
  19. package/dist/cjs/apps/identity/state-machines/identity-agent.js +3 -3
  20. package/dist/cjs/apps/identity/state-machines/identity-oracle.js +25 -22
  21. package/dist/cjs/apps/identity/state-machines/identity-registry.js +288 -0
  22. package/dist/cjs/apps/identity/state-machines/identity-universal.js +3 -3
  23. package/dist/cjs/apps/identity/state-machines/index.js +3 -1
  24. package/dist/cjs/apps/index.js +19 -8
  25. package/dist/cjs/apps/lending/assets.js +223 -0
  26. package/dist/cjs/apps/lending/credit-scoring.js +87 -0
  27. package/dist/cjs/apps/lending/eligibility.js +121 -0
  28. package/dist/cjs/apps/lending/index.js +91 -0
  29. package/dist/cjs/apps/lending/state-machines/index.js +9 -0
  30. package/dist/cjs/apps/lending/state-machines/lending-zk-loan.js +412 -0
  31. package/dist/cjs/apps/markets/index.js +21 -11
  32. package/dist/cjs/apps/markets/state-machines/market-auction.js +14 -13
  33. package/dist/cjs/apps/markets/state-machines/market-crowdfund.js +29 -24
  34. package/dist/cjs/apps/markets/state-machines/market-group-buy.js +24 -26
  35. package/dist/cjs/apps/markets/state-machines/market-prediction.js +80 -53
  36. package/dist/cjs/apps/markets/state-machines/market-universal.js +5 -5
  37. package/dist/cjs/apps/oracles/index.js +2 -2
  38. package/dist/cjs/errors.js +3 -3
  39. package/dist/cjs/generated/google/protobuf/struct.js +4 -4
  40. package/dist/cjs/generated/index.js +11 -7
  41. package/dist/cjs/generated/openapi.js +6 -0
  42. package/dist/cjs/generated/ottochain/apps/contracts/v1/contract.js +50 -50
  43. package/dist/cjs/generated/ottochain/apps/corporate/v1/corporate.js +19 -20
  44. package/dist/cjs/generated/ottochain/apps/governance/v1/governance.js +13 -13
  45. package/dist/cjs/generated/ottochain/apps/identity/v1/attestation.js +4 -4
  46. package/dist/cjs/generated/ottochain/apps/identity/v1/identity.js +124 -130
  47. package/dist/cjs/generated/ottochain/apps/markets/v1/market.js +107 -107
  48. package/dist/cjs/generated/ottochain/v1/common.js +4 -4
  49. package/dist/cjs/generated/ottochain/v1/fiber.js +4 -4
  50. package/dist/cjs/index.js +41 -7
  51. package/dist/cjs/openapi.js +2 -0
  52. package/dist/cjs/ottochain/drop-nulls.js +1 -2
  53. package/dist/cjs/ottochain/genesis-manifest.js +11 -11
  54. package/dist/cjs/ottochain/index.js +23 -13
  55. package/dist/cjs/ottochain/metagraph-client.js +65 -8
  56. package/dist/cjs/ottochain/snapshot.js +11 -12
  57. package/dist/cjs/ottochain/transaction.js +57 -14
  58. package/dist/cjs/ottochain/types.js +16 -2
  59. package/dist/cjs/privacy/index.js +14 -0
  60. package/dist/cjs/privacy/sealed-bid.js +210 -0
  61. package/dist/cjs/privacy/shield-app.js +131 -0
  62. package/dist/cjs/schema/effects.js +40 -0
  63. package/dist/cjs/schema/fiber-app.js +19 -13
  64. package/dist/cjs/schema/guard-lint.js +352 -0
  65. package/dist/cjs/schema/guards.js +246 -0
  66. package/dist/cjs/signing.js +80 -0
  67. package/dist/cjs/types.js +2 -3
  68. package/dist/cjs/validation.js +8 -8
  69. package/dist/cjs/verify.js +9 -4
  70. package/dist/cjs/zk/commit.js +53 -0
  71. package/dist/cjs/zk/guard.js +107 -0
  72. package/dist/cjs/zk/index.js +48 -0
  73. package/dist/cjs/zk/preimage.js +37 -0
  74. package/dist/cjs/zk/prover.js +87 -0
  75. package/dist/cjs/zk/registry.js +62 -0
  76. package/dist/cjs/zk/types.js +28 -0
  77. package/dist/cjs/zk/witness.js +19 -0
  78. package/dist/esm/apps/contracts/index.js +7 -3
  79. package/dist/esm/apps/contracts/state-machines/contract-agreement.js +35 -40
  80. package/dist/esm/apps/contracts/state-machines/contract-escrow.js +80 -37
  81. package/dist/esm/apps/contracts/state-machines/contract-universal.js +4 -4
  82. package/dist/esm/apps/corporate/state-machines/corp-board.js +169 -59
  83. package/dist/esm/apps/corporate/state-machines/corp-entity.js +245 -47
  84. package/dist/esm/apps/corporate/state-machines/corp-securities.js +407 -99
  85. package/dist/esm/apps/corporate/state-machines/corp-shareholders.js +151 -37
  86. package/dist/esm/apps/governance/state-machines/dao-multisig.js +58 -40
  87. package/dist/esm/apps/governance/state-machines/dao-reputation.js +46 -40
  88. package/dist/esm/apps/governance/state-machines/dao-single.js +28 -11
  89. package/dist/esm/apps/governance/state-machines/dao-token.js +67 -41
  90. package/dist/esm/apps/governance/state-machines/governance-simple.js +93 -61
  91. package/dist/esm/apps/governance/state-machines/governance-universal.js +2 -2
  92. package/dist/esm/apps/identity/constants.js +51 -12
  93. package/dist/esm/apps/identity/index.js +12 -7
  94. package/dist/esm/apps/identity/state-machines/identity-agent.js +3 -3
  95. package/dist/esm/apps/identity/state-machines/identity-oracle.js +25 -22
  96. package/dist/esm/apps/identity/state-machines/identity-registry.js +285 -0
  97. package/dist/esm/apps/identity/state-machines/identity-universal.js +3 -3
  98. package/dist/esm/apps/identity/state-machines/index.js +1 -0
  99. package/dist/esm/apps/index.js +1 -0
  100. package/dist/esm/apps/lending/assets.js +207 -0
  101. package/dist/esm/apps/lending/credit-scoring.js +81 -0
  102. package/dist/esm/apps/lending/eligibility.js +115 -0
  103. package/dist/esm/apps/lending/index.js +69 -0
  104. package/dist/esm/apps/lending/state-machines/index.js +5 -0
  105. package/dist/esm/apps/lending/state-machines/lending-zk-loan.js +409 -0
  106. package/dist/esm/apps/markets/index.js +8 -4
  107. package/dist/esm/apps/markets/state-machines/market-auction.js +14 -13
  108. package/dist/esm/apps/markets/state-machines/market-crowdfund.js +29 -24
  109. package/dist/esm/apps/markets/state-machines/market-group-buy.js +24 -26
  110. package/dist/esm/apps/markets/state-machines/market-prediction.js +80 -53
  111. package/dist/esm/apps/markets/state-machines/market-universal.js +5 -5
  112. package/dist/esm/generated/index.js +9 -5
  113. package/dist/esm/generated/openapi.js +5 -0
  114. package/dist/esm/generated/ottochain/apps/contracts/v1/contract.js +46 -46
  115. package/dist/esm/generated/ottochain/apps/identity/v1/identity.js +114 -120
  116. package/dist/esm/generated/ottochain/apps/markets/v1/market.js +100 -100
  117. package/dist/esm/index.js +21 -2
  118. package/dist/esm/openapi.js +1 -0
  119. package/dist/esm/ottochain/genesis-manifest.js +9 -9
  120. package/dist/esm/ottochain/index.js +2 -3
  121. package/dist/esm/ottochain/metagraph-client.js +65 -8
  122. package/dist/esm/ottochain/snapshot.js +4 -4
  123. package/dist/esm/ottochain/transaction.js +43 -3
  124. package/dist/esm/ottochain/types.js +15 -1
  125. package/dist/esm/privacy/index.js +6 -0
  126. package/dist/esm/privacy/sealed-bid.js +206 -0
  127. package/dist/esm/privacy/shield-app.js +127 -0
  128. package/dist/esm/schema/effects.js +35 -0
  129. package/dist/esm/schema/fiber-app.js +13 -6
  130. package/dist/esm/schema/guard-lint.js +346 -0
  131. package/dist/esm/schema/guards.js +229 -0
  132. package/dist/esm/signing.js +74 -0
  133. package/dist/esm/verify.js +8 -2
  134. package/dist/esm/zk/commit.js +44 -0
  135. package/dist/esm/zk/guard.js +99 -0
  136. package/dist/esm/zk/index.js +19 -0
  137. package/dist/esm/zk/preimage.js +30 -0
  138. package/dist/esm/zk/prover.js +82 -0
  139. package/dist/esm/zk/registry.js +55 -0
  140. package/dist/esm/zk/types.js +25 -0
  141. package/dist/esm/zk/witness.js +15 -0
  142. package/dist/types/apps/contracts/index.d.ts +69 -209
  143. package/dist/types/apps/contracts/state-machines/contract-agreement.d.ts +20 -95
  144. package/dist/types/apps/contracts/state-machines/contract-escrow.d.ts +46 -112
  145. package/dist/types/apps/corporate/index.d.ts +1040 -304
  146. package/dist/types/apps/corporate/state-machines/corp-board.d.ts +188 -52
  147. package/dist/types/apps/corporate/state-machines/corp-entity.d.ts +267 -62
  148. package/dist/types/apps/corporate/state-machines/corp-securities.d.ts +355 -131
  149. package/dist/types/apps/corporate/state-machines/corp-shareholders.d.ts +225 -53
  150. package/dist/types/apps/governance/index.d.ts +296 -398
  151. package/dist/types/apps/governance/state-machines/dao-multisig.d.ts +77 -92
  152. package/dist/types/apps/governance/state-machines/dao-reputation.d.ts +42 -66
  153. package/dist/types/apps/governance/state-machines/dao-single.d.ts +25 -47
  154. package/dist/types/apps/governance/state-machines/dao-token.d.ts +60 -49
  155. package/dist/types/apps/governance/state-machines/governance-simple.d.ts +87 -117
  156. package/dist/types/apps/governance/state-machines/governance-universal.d.ts +2 -2
  157. package/dist/types/apps/identity/constants.d.ts +32 -4
  158. package/dist/types/apps/identity/index.d.ts +378 -94
  159. package/dist/types/apps/identity/state-machines/identity-oracle.d.ts +16 -87
  160. package/dist/types/apps/identity/state-machines/identity-registry.d.ts +379 -0
  161. package/dist/types/apps/identity/state-machines/index.d.ts +1 -0
  162. package/dist/types/apps/index.d.ts +1 -0
  163. package/dist/types/apps/lending/assets.d.ts +258 -0
  164. package/dist/types/apps/lending/credit-scoring.d.ts +80 -0
  165. package/dist/types/apps/lending/eligibility.d.ts +83 -0
  166. package/dist/types/apps/lending/index.d.ts +548 -0
  167. package/dist/types/apps/lending/state-machines/index.d.ts +5 -0
  168. package/dist/types/apps/lending/state-machines/lending-zk-loan.d.ts +528 -0
  169. package/dist/types/apps/markets/index.d.ts +108 -203
  170. package/dist/types/apps/markets/state-machines/market-auction.d.ts +13 -37
  171. package/dist/types/apps/markets/state-machines/market-crowdfund.d.ts +16 -34
  172. package/dist/types/apps/markets/state-machines/market-group-buy.d.ts +17 -43
  173. package/dist/types/apps/markets/state-machines/market-prediction.d.ts +51 -72
  174. package/dist/types/apps/markets/state-machines/market-universal.d.ts +5 -5
  175. package/dist/types/generated/index.d.ts +5 -5
  176. package/dist/types/generated/openapi.d.ts +1257 -0
  177. package/dist/types/generated/ottochain/apps/contracts/v1/contract.d.ts +5 -5
  178. package/dist/types/generated/ottochain/apps/identity/v1/identity.d.ts +12 -12
  179. package/dist/types/generated/ottochain/apps/markets/v1/market.d.ts +11 -11
  180. package/dist/types/index.d.ts +6 -2
  181. package/dist/types/openapi.d.ts +22 -0
  182. package/dist/types/ottochain/genesis-manifest.d.ts +5 -5
  183. package/dist/types/ottochain/index.d.ts +5 -6
  184. package/dist/types/ottochain/metagraph-client.d.ts +49 -7
  185. package/dist/types/ottochain/snapshot.d.ts +6 -6
  186. package/dist/types/ottochain/transaction.d.ts +33 -1
  187. package/dist/types/ottochain/types.d.ts +335 -30
  188. package/dist/types/privacy/index.d.ts +6 -0
  189. package/dist/types/privacy/sealed-bid.d.ts +348 -0
  190. package/dist/types/privacy/shield-app.d.ts +48 -0
  191. package/dist/types/schema/effects.d.ts +34 -0
  192. package/dist/types/schema/fiber-app.d.ts +1 -2
  193. package/dist/types/schema/guard-lint.d.ts +111 -0
  194. package/dist/types/schema/guards.d.ts +134 -0
  195. package/dist/types/signing.d.ts +45 -0
  196. package/dist/types/validation.d.ts +22 -217
  197. package/dist/types/verify.d.ts +4 -0
  198. package/dist/types/zk/commit.d.ts +28 -0
  199. package/dist/types/zk/guard.d.ts +46 -0
  200. package/dist/types/zk/index.d.ts +19 -0
  201. package/dist/types/zk/preimage.d.ts +10 -0
  202. package/dist/types/zk/prover.d.ts +34 -0
  203. package/dist/types/zk/registry.d.ts +34 -0
  204. package/dist/types/zk/types.d.ts +33 -0
  205. package/dist/types/zk/witness.d.ts +40 -0
  206. package/package.json +27 -13
  207. package/dist/cjs/ottochain/normalize.js +0 -186
  208. package/dist/esm/ottochain/normalize.js +0 -179
  209. package/dist/types/ottochain/normalize.d.ts +0 -79
@@ -1,4 +1,5 @@
1
1
  import { defineFiberApp } from "../../../schema/fiber-app.js";
2
+ import { signerIsParty, actorIsSigner } from "../../../schema/guards.js";
2
3
  /**
3
4
  * Token-weighted voting. Voting power proportional to token holdings.
4
5
  */
@@ -169,10 +170,18 @@ export const daoTokenDef = defineFiberApp({
169
170
  from: "ACTIVE",
170
171
  to: "VOTING",
171
172
  eventName: "propose",
173
+ // S1/A2 coupled fix: a CHAIN-VERIFIED signer must hold >= proposalThreshold
174
+ // tokens. Iterate proofs[].address and read each balance via `get` (getKey is
175
+ // not a JLVM opcode); never trust the forgeable event.agent for the lookup.
172
176
  guard: {
173
- ">=": [
174
- { getKey: [{ var: "state.balances" }, { var: "event.agent" }] },
175
- { var: "state.proposalThreshold" },
177
+ some: [
178
+ { map: [{ var: "proofs" }, { var: "address" }] },
179
+ {
180
+ ">=": [
181
+ { get: [{ var: "state.balances" }, { var: "" }] },
182
+ { var: "state.proposalThreshold" },
183
+ ],
184
+ },
176
185
  ],
177
186
  },
178
187
  effect: {
@@ -186,9 +195,9 @@ export const daoTokenDef = defineFiberApp({
186
195
  actionType: { var: "event.actionType" },
187
196
  payload: { var: "event.payload" },
188
197
  proposer: { var: "event.agent" },
189
- proposedAt: { var: "$timestamp" },
198
+ proposedAt: { var: "$ordinal" },
190
199
  votingEndsAt: {
191
- "+": [{ var: "$timestamp" }, { var: "state.votingPeriodMs" }],
200
+ "+": [{ var: "$ordinal" }, { var: "state.votingPeriodMs" }],
192
201
  },
193
202
  snapshotBlock: { var: "event.snapshotBlock" },
194
203
  },
@@ -203,26 +212,28 @@ export const daoTokenDef = defineFiberApp({
203
212
  from: "VOTING",
204
213
  to: "VOTING",
205
214
  eventName: "vote",
215
+ // S1+A2 coupled fix: bind event.agent to a verified signer (actorIsSigner) so the
216
+ // balance lookup, the no-double-vote check, and the voters write below all key on the
217
+ // CHAIN-VERIFIED actor — never a forgeable claim. getKey→get (value), getKey→has
218
+ // (presence), setKey→set are the rc.5 map opcodes (getKey/setKey do not exist).
206
219
  guard: {
207
220
  and: [
221
+ actorIsSigner(),
208
222
  {
209
223
  ">": [
210
- { getKey: [{ var: "state.balances" }, { var: "event.agent" }] },
224
+ { get: [{ var: "state.balances" }, { var: "event.agent" }] },
211
225
  0,
212
226
  ],
213
227
  },
214
228
  {
215
229
  "!": [
216
230
  {
217
- getKey: [{ var: "state.votes.voters" }, { var: "event.agent" }],
231
+ has: [{ var: "state.votes.voters" }, { var: "event.agent" }],
218
232
  },
219
233
  ],
220
234
  },
221
235
  {
222
- "<=": [
223
- { var: "$timestamp" },
224
- { var: "state.proposal.votingEndsAt" },
225
- ],
236
+ "<=": [{ var: "$ordinal" }, { var: "state.proposal.votingEndsAt" }],
226
237
  },
227
238
  ],
228
239
  },
@@ -241,7 +252,7 @@ export const daoTokenDef = defineFiberApp({
241
252
  "+": [
242
253
  { var: "state.votes.for" },
243
254
  {
244
- getKey: [
255
+ get: [
245
256
  { var: "state.balances" },
246
257
  { var: "event.agent" },
247
258
  ],
@@ -255,7 +266,7 @@ export const daoTokenDef = defineFiberApp({
255
266
  "+": [
256
267
  { var: "state.votes.against" },
257
268
  {
258
- getKey: [
269
+ get: [
259
270
  { var: "state.balances" },
260
271
  { var: "event.agent" },
261
272
  ],
@@ -268,7 +279,7 @@ export const daoTokenDef = defineFiberApp({
268
279
  "+": [
269
280
  { var: "state.votes.abstain" },
270
281
  {
271
- getKey: [
282
+ get: [
272
283
  { var: "state.balances" },
273
284
  { var: "event.agent" },
274
285
  ],
@@ -280,18 +291,18 @@ export const daoTokenDef = defineFiberApp({
280
291
  },
281
292
  {
282
293
  voters: {
283
- setKey: [
294
+ set: [
284
295
  { var: "state.votes.voters" },
285
296
  { var: "event.agent" },
286
297
  {
287
298
  vote: { var: "event.vote" },
288
299
  weight: {
289
- getKey: [
300
+ get: [
290
301
  { var: "state.balances" },
291
302
  { var: "event.agent" },
292
303
  ],
293
304
  },
294
- votedAt: { var: "$timestamp" },
305
+ votedAt: { var: "$ordinal" },
295
306
  },
296
307
  ],
297
308
  },
@@ -311,10 +322,7 @@ export const daoTokenDef = defineFiberApp({
311
322
  guard: {
312
323
  and: [
313
324
  {
314
- ">": [
315
- { var: "$timestamp" },
316
- { var: "state.proposal.votingEndsAt" },
317
- ],
325
+ ">": [{ var: "$ordinal" }, { var: "state.proposal.votingEndsAt" }],
318
326
  },
319
327
  { ">": [{ var: "state.votes.for" }, { var: "state.votes.against" }] },
320
328
  {
@@ -339,9 +347,9 @@ export const daoTokenDef = defineFiberApp({
339
347
  merge: [
340
348
  { var: "state.proposal" },
341
349
  {
342
- queuedAt: { var: "$timestamp" },
350
+ queuedAt: { var: "$ordinal" },
343
351
  executableAt: {
344
- "+": [{ var: "$timestamp" }, { var: "state.timelockMs" }],
352
+ "+": [{ var: "$ordinal" }, { var: "state.timelockMs" }],
345
353
  },
346
354
  },
347
355
  ],
@@ -357,7 +365,7 @@ export const daoTokenDef = defineFiberApp({
357
365
  to: "ACTIVE",
358
366
  eventName: "execute",
359
367
  guard: {
360
- ">=": [{ var: "$timestamp" }, { var: "state.proposal.executableAt" }],
368
+ ">=": [{ var: "$ordinal" }, { var: "state.proposal.executableAt" }],
361
369
  },
362
370
  effect: {
363
371
  merge: [
@@ -372,7 +380,7 @@ export const daoTokenDef = defineFiberApp({
372
380
  { var: "state.proposal" },
373
381
  {
374
382
  votes: { var: "state.votes" },
375
- executedAt: { var: "$timestamp" },
383
+ executedAt: { var: "$ordinal" },
376
384
  },
377
385
  ],
378
386
  },
@@ -381,10 +389,18 @@ export const daoTokenDef = defineFiberApp({
381
389
  },
382
390
  proposal: null,
383
391
  votes: null,
392
+ // A3 fix: transition-level `emits` is dropped by the chain; emit from INSIDE the effect
393
+ // under the reserved `_emit` key (extracted as an EmittedEvent, stripped from state).
394
+ _emit: [
395
+ {
396
+ name: "proposal_executed",
397
+ data: { proposalId: { var: "state.proposal.id" } },
398
+ destination: "external",
399
+ },
400
+ ],
384
401
  },
385
402
  ],
386
403
  },
387
- emits: [{ event: "proposal_executed", to: "external" }],
388
404
  dependencies: [],
389
405
  },
390
406
  // VOTING → ACTIVE: reject (voting ended, failed quorum or for <= against)
@@ -395,10 +411,7 @@ export const daoTokenDef = defineFiberApp({
395
411
  guard: {
396
412
  and: [
397
413
  {
398
- ">": [
399
- { var: "$timestamp" },
400
- { var: "state.proposal.votingEndsAt" },
401
- ],
414
+ ">": [{ var: "$ordinal" }, { var: "state.proposal.votingEndsAt" }],
402
415
  },
403
416
  {
404
417
  or: [
@@ -437,7 +450,7 @@ export const daoTokenDef = defineFiberApp({
437
450
  { var: "state.proposal" },
438
451
  {
439
452
  votes: { var: "state.votes" },
440
- rejectedAt: { var: "$timestamp" },
453
+ rejectedAt: { var: "$ordinal" },
441
454
  },
442
455
  ],
443
456
  },
@@ -456,9 +469,7 @@ export const daoTokenDef = defineFiberApp({
456
469
  from: "QUEUED",
457
470
  to: "ACTIVE",
458
471
  eventName: "cancel",
459
- guard: {
460
- "===": [{ var: "event.agent" }, { var: "state.proposal.proposer" }],
461
- },
472
+ guard: signerIsParty("state.proposal.proposer"),
462
473
  effect: {
463
474
  merge: [
464
475
  { var: "state" },
@@ -470,7 +481,7 @@ export const daoTokenDef = defineFiberApp({
470
481
  {
471
482
  merge: [
472
483
  { var: "state.proposal" },
473
- { cancelledAt: { var: "$timestamp" } },
484
+ { cancelledAt: { var: "$ordinal" } },
474
485
  ],
475
486
  },
476
487
  ],
@@ -488,10 +499,17 @@ export const daoTokenDef = defineFiberApp({
488
499
  from: "ACTIVE",
489
500
  to: "ACTIVE",
490
501
  eventName: "delegate",
502
+ // S1+A2: bind event.agent to a verified signer so the delegation is written under the
503
+ // CHAIN-VERIFIED delegator's key (set), keyed on the same actor whose balance is checked (get).
491
504
  guard: {
492
- ">": [
493
- { getKey: [{ var: "state.balances" }, { var: "event.agent" }] },
494
- 0,
505
+ and: [
506
+ actorIsSigner(),
507
+ {
508
+ ">": [
509
+ { get: [{ var: "state.balances" }, { var: "event.agent" }] },
510
+ 0,
511
+ ],
512
+ },
495
513
  ],
496
514
  },
497
515
  effect: {
@@ -499,7 +517,7 @@ export const daoTokenDef = defineFiberApp({
499
517
  { var: "state" },
500
518
  {
501
519
  delegations: {
502
- setKey: [
520
+ set: [
503
521
  { var: "state.delegations" },
504
522
  { var: "event.agent" },
505
523
  { var: "event.delegateTo" },
@@ -515,13 +533,21 @@ export const daoTokenDef = defineFiberApp({
515
533
  from: "ACTIVE",
516
534
  to: "ACTIVE",
517
535
  eventName: "undelegate",
518
- guard: { getKey: [{ var: "state.delegations" }, { var: "event.agent" }] },
536
+ // S1+A2: bind event.agent to a verified signer; presence via has, removal via unset (the rc.5
537
+ // map opcodes — getKey/deleteKey do not exist). Only the verified delegator can clear their own
538
+ // delegation.
539
+ guard: {
540
+ and: [
541
+ actorIsSigner(),
542
+ { has: [{ var: "state.delegations" }, { var: "event.agent" }] },
543
+ ],
544
+ },
519
545
  effect: {
520
546
  merge: [
521
547
  { var: "state" },
522
548
  {
523
549
  delegations: {
524
- deleteKey: [{ var: "state.delegations" }, { var: "event.agent" }],
550
+ unset: [{ var: "state.delegations" }, { var: "event.agent" }],
525
551
  },
526
552
  },
527
553
  ],
@@ -1,4 +1,5 @@
1
1
  import { defineFiberApp } from "../../../schema/fiber-app.js";
2
+ import { actorHasEntry, signerHasEntry, signerInSet, signerIsAnyParty, signerIsNotParty, } from "../../../schema/guards.js";
2
3
  /**
3
4
  * Simple org governance: manage members, update rules, resolve disputes.
4
5
  */
@@ -89,11 +90,8 @@ export const govSimpleDef = defineFiberApp({
89
90
  },
90
91
  },
91
92
  finalize: {
92
- description: "Finalize the voting period",
93
- required: ["forCount"],
94
- properties: {
95
- forCount: { type: "number" },
96
- },
93
+ description: "Finalize the voting period (for-count derived from recorded ballots)",
94
+ properties: {},
97
95
  },
98
96
  file_dispute: {
99
97
  description: "File a dispute against a member",
@@ -122,11 +120,8 @@ export const govSimpleDef = defineFiberApp({
122
120
  },
123
121
  },
124
122
  dissolve: {
125
- description: "Dissolve the organization (requires 90% approval)",
126
- required: ["approvalCount"],
127
- properties: {
128
- approvalCount: { type: "number" },
129
- },
123
+ description: "Dissolve the organization (requires every member to sign this op — verified unanimity)",
124
+ properties: {},
130
125
  },
131
126
  },
132
127
  states: {
@@ -174,16 +169,16 @@ export const govSimpleDef = defineFiberApp({
174
169
  from: "ACTIVE",
175
170
  to: "ACTIVE",
176
171
  eventName: "add_member",
177
- guard: { in: [{ var: "event.agent" }, { var: "state.admins" }] },
172
+ guard: signerInSet("state.admins"),
178
173
  effect: {
179
174
  merge: [
180
175
  { var: "state" },
181
176
  {
182
177
  members: {
183
- setKey: [
178
+ set: [
184
179
  { var: "state.members" },
185
180
  { var: "event.member" },
186
- { role: { var: "event.role" }, addedAt: { var: "$timestamp" } },
181
+ { role: { var: "event.role" }, addedAt: { var: "$ordinal" } },
187
182
  ],
188
183
  },
189
184
  },
@@ -196,13 +191,13 @@ export const govSimpleDef = defineFiberApp({
196
191
  from: "ACTIVE",
197
192
  to: "ACTIVE",
198
193
  eventName: "remove_member",
199
- guard: { in: [{ var: "event.agent" }, { var: "state.admins" }] },
194
+ guard: signerInSet("state.admins"),
200
195
  effect: {
201
196
  merge: [
202
197
  { var: "state" },
203
198
  {
204
199
  members: {
205
- deleteKey: [{ var: "state.members" }, { var: "event.member" }],
200
+ unset: [{ var: "state.members" }, { var: "event.member" }],
206
201
  },
207
202
  },
208
203
  ],
@@ -214,7 +209,9 @@ export const govSimpleDef = defineFiberApp({
214
209
  from: "ACTIVE",
215
210
  to: "VOTING",
216
211
  eventName: "propose",
217
- guard: { getKey: [{ var: "state.members" }, { var: "event.agent" }] },
212
+ // S1/A2 coupled fix: a CHAIN-VERIFIED signer must be a member (getKey is not a
213
+ // JLVM opcode; signerHasEntry checks signer ∈ keys(state.members) via `has`).
214
+ guard: signerHasEntry("state.members"),
218
215
  effect: {
219
216
  merge: [
220
217
  { var: "state" },
@@ -224,9 +221,9 @@ export const govSimpleDef = defineFiberApp({
224
221
  type: { var: "event.type" },
225
222
  changes: { var: "event.changes" },
226
223
  proposer: { var: "event.agent" },
227
- proposedAt: { var: "$timestamp" },
224
+ proposedAt: { var: "$ordinal" },
228
225
  deadline: {
229
- "+": [{ var: "$timestamp" }, { var: "state.votingPeriodMs" }],
226
+ "+": [{ var: "$ordinal" }, { var: "state.votingPeriodMs" }],
230
227
  },
231
228
  },
232
229
  votes: {},
@@ -240,12 +237,14 @@ export const govSimpleDef = defineFiberApp({
240
237
  from: "VOTING",
241
238
  to: "VOTING",
242
239
  eventName: "vote",
240
+ // S1/A2 coupled fix: bind event.agent to a verified signer who is a member (actorHasEntry),
241
+ // and block a re-vote by that SAME bound actor — so the ballot is recorded under, and deduped
242
+ // on, the chain-verified voter. Without the binding, signerHasEntry only proves SOME signer is a
243
+ // member, letting one member stuff votes under arbitrary keys (set is the rc.5 map-write opcode).
243
244
  guard: {
244
245
  and: [
245
- { getKey: [{ var: "state.members" }, { var: "event.agent" }] },
246
- {
247
- "!": [{ getKey: [{ var: "state.votes" }, { var: "event.agent" }] }],
248
- },
246
+ actorHasEntry("state.members"),
247
+ { "!": [{ has: [{ var: "state.votes" }, { var: "event.agent" }] }] },
249
248
  ],
250
249
  },
251
250
  effect: {
@@ -253,10 +252,10 @@ export const govSimpleDef = defineFiberApp({
253
252
  { var: "state" },
254
253
  {
255
254
  votes: {
256
- setKey: [
255
+ set: [
257
256
  { var: "state.votes" },
258
257
  { var: "event.agent" },
259
- { vote: { var: "event.vote" }, votedAt: { var: "$timestamp" } },
258
+ { vote: { var: "event.vote" }, votedAt: { var: "$ordinal" } },
260
259
  ],
261
260
  },
262
261
  },
@@ -269,12 +268,24 @@ export const govSimpleDef = defineFiberApp({
269
268
  from: "VOTING",
270
269
  to: "ACTIVE",
271
270
  eventName: "finalize",
271
+ // S2/A2 coupled fix: the for-count is DERIVED from recorded ballots in
272
+ // state.votes (length of the "for" entries), never read from the attacker's
273
+ // event.forCount. members is a Map so its count is length(keys(members)).
272
274
  guard: {
273
275
  ">=": [
274
- { var: "event.forCount" },
276
+ {
277
+ length: [
278
+ {
279
+ filter: [
280
+ { values: [{ var: "state.votes" }] },
281
+ { "===": [{ var: "vote" }, "for"] },
282
+ ],
283
+ },
284
+ ],
285
+ },
275
286
  {
276
287
  "*": [
277
- { size: { var: "state.members" } },
288
+ { length: [{ keys: [{ var: "state.members" }] }] },
278
289
  { var: "state.passingThreshold" },
279
290
  ],
280
291
  },
@@ -298,7 +309,7 @@ export const govSimpleDef = defineFiberApp({
298
309
  type: "rule_change",
299
310
  proposal: { var: "state.proposal" },
300
311
  outcome: "passed",
301
- finalizedAt: { var: "$timestamp" },
312
+ finalizedAt: { var: "$ordinal" },
302
313
  },
303
314
  ],
304
315
  ],
@@ -315,12 +326,23 @@ export const govSimpleDef = defineFiberApp({
315
326
  from: "VOTING",
316
327
  to: "ACTIVE",
317
328
  eventName: "finalize",
329
+ // S2/A2 coupled fix (failed arm): derive the for-count from recorded ballots in
330
+ // state.votes; never from event.forCount. members count = length(keys(members)).
318
331
  guard: {
319
332
  "<": [
320
- { var: "event.forCount" },
333
+ {
334
+ length: [
335
+ {
336
+ filter: [
337
+ { values: [{ var: "state.votes" }] },
338
+ { "===": [{ var: "vote" }, "for"] },
339
+ ],
340
+ },
341
+ ],
342
+ },
321
343
  {
322
344
  "*": [
323
- { size: { var: "state.members" } },
345
+ { length: [{ keys: [{ var: "state.members" }] }] },
324
346
  { var: "state.passingThreshold" },
325
347
  ],
326
348
  },
@@ -338,7 +360,7 @@ export const govSimpleDef = defineFiberApp({
338
360
  type: "rule_change",
339
361
  proposal: { var: "state.proposal" },
340
362
  outcome: "failed",
341
- finalizedAt: { var: "$timestamp" },
363
+ finalizedAt: { var: "$ordinal" },
342
364
  },
343
365
  ],
344
366
  ],
@@ -355,7 +377,9 @@ export const govSimpleDef = defineFiberApp({
355
377
  from: "ACTIVE",
356
378
  to: "DISPUTE",
357
379
  eventName: "file_dispute",
358
- guard: { getKey: [{ var: "state.members" }, { var: "event.agent" }] },
380
+ // S1/A2 coupled fix: only a CHAIN-VERIFIED member may file (getKey is not a JLVM
381
+ // opcode; signerHasEntry checks signer ∈ keys(state.members) via `has`).
382
+ guard: signerHasEntry("state.members"),
359
383
  effect: {
360
384
  merge: [
361
385
  { var: "state" },
@@ -365,7 +389,7 @@ export const govSimpleDef = defineFiberApp({
365
389
  plaintiff: { var: "event.agent" },
366
390
  defendant: { var: "event.defendant" },
367
391
  claim: { var: "event.claim" },
368
- filedAt: { var: "$timestamp" },
392
+ filedAt: { var: "$ordinal" },
369
393
  evidence: [],
370
394
  },
371
395
  votes: {},
@@ -379,16 +403,10 @@ export const govSimpleDef = defineFiberApp({
379
403
  from: "DISPUTE",
380
404
  to: "DISPUTE",
381
405
  eventName: "submit_evidence",
382
- guard: {
383
- or: [
384
- {
385
- "===": [{ var: "event.agent" }, { var: "state.dispute.plaintiff" }],
386
- },
387
- {
388
- "===": [{ var: "event.agent" }, { var: "state.dispute.defendant" }],
389
- },
390
- ],
391
- },
406
+ guard: signerIsAnyParty([
407
+ "state.dispute.plaintiff",
408
+ "state.dispute.defendant",
409
+ ]),
392
410
  effect: {
393
411
  merge: [
394
412
  { var: "state" },
@@ -404,7 +422,7 @@ export const govSimpleDef = defineFiberApp({
404
422
  {
405
423
  from: { var: "event.agent" },
406
424
  content: { var: "event.content" },
407
- at: { var: "$timestamp" },
425
+ at: { var: "$ordinal" },
408
426
  },
409
427
  ],
410
428
  ],
@@ -422,18 +440,16 @@ export const govSimpleDef = defineFiberApp({
422
440
  from: "DISPUTE",
423
441
  to: "DISPUTE",
424
442
  eventName: "vote",
443
+ // S1/A2 coupled fix: bind event.agent to a verified member (actorHasEntry), exclude the parties,
444
+ // and block a re-vote by that SAME bound actor — so the dispute ballot is recorded under, and
445
+ // deduped on, the chain-verified voter (set is the rc.5 map-write opcode; signerIsNotParty still
446
+ // excludes any signer who is a party, which covers the bound actor).
425
447
  guard: {
426
448
  and: [
427
- { getKey: [{ var: "state.members" }, { var: "event.agent" }] },
428
- {
429
- "!==": [{ var: "event.agent" }, { var: "state.dispute.plaintiff" }],
430
- },
431
- {
432
- "!==": [{ var: "event.agent" }, { var: "state.dispute.defendant" }],
433
- },
434
- {
435
- "!": [{ getKey: [{ var: "state.votes" }, { var: "event.agent" }] }],
436
- },
449
+ actorHasEntry("state.members"),
450
+ signerIsNotParty("state.dispute.plaintiff"),
451
+ signerIsNotParty("state.dispute.defendant"),
452
+ { "!": [{ has: [{ var: "state.votes" }, { var: "event.agent" }] }] },
437
453
  ],
438
454
  },
439
455
  effect: {
@@ -441,12 +457,12 @@ export const govSimpleDef = defineFiberApp({
441
457
  { var: "state" },
442
458
  {
443
459
  votes: {
444
- setKey: [
460
+ set: [
445
461
  { var: "state.votes" },
446
462
  { var: "event.agent" },
447
463
  {
448
464
  ruling: { var: "event.ruling" },
449
- votedAt: { var: "$timestamp" },
465
+ votedAt: { var: "$ordinal" },
450
466
  },
451
467
  ],
452
468
  },
@@ -460,9 +476,11 @@ export const govSimpleDef = defineFiberApp({
460
476
  from: "DISPUTE",
461
477
  to: "ACTIVE",
462
478
  eventName: "resolve",
479
+ // A2 fix: count recorded ballots. votes is a Map, and `length` rejects Maps, so
480
+ // count its keys: length(keys(state.votes)). (size is not a JLVM opcode.)
463
481
  guard: {
464
482
  ">=": [
465
- { size: { var: "state.votes" } },
483
+ { length: [{ keys: [{ var: "state.votes" }] }] },
466
484
  { var: "state.disputeQuorum" },
467
485
  ],
468
486
  },
@@ -479,7 +497,7 @@ export const govSimpleDef = defineFiberApp({
479
497
  dispute: { var: "state.dispute" },
480
498
  ruling: { var: "event.ruling" },
481
499
  remedy: { var: "event.remedy" },
482
- resolvedAt: { var: "$timestamp" },
500
+ resolvedAt: { var: "$ordinal" },
483
501
  },
484
502
  ],
485
503
  ],
@@ -496,14 +514,28 @@ export const govSimpleDef = defineFiberApp({
496
514
  from: "ACTIVE",
497
515
  to: "DISSOLVED",
498
516
  eventName: "dissolve",
517
+ // S2/A2 coupled fix: dissolution must not trust an attacker-supplied
518
+ // approvalCount. Derive consent from the CHAIN-VERIFIED signers — every member
519
+ // (a key in state.members) must be among proofs[].address, with a non-empty
520
+ // belt. members is a Map, so iterate keys(members); size is not a JLVM opcode.
499
521
  guard: {
500
- ">=": [
501
- { var: "event.approvalCount" },
502
- { "*": [{ size: { var: "state.members" } }, 0.9] },
522
+ and: [
523
+ { ">": [{ length: [{ keys: [{ var: "state.members" }] }] }, 0] },
524
+ {
525
+ all: [
526
+ { keys: [{ var: "state.members" }] },
527
+ {
528
+ in: [
529
+ { var: "" },
530
+ { map: [{ var: "proofs" }, { var: "address" }] },
531
+ ],
532
+ },
533
+ ],
534
+ },
503
535
  ],
504
536
  },
505
537
  effect: {
506
- merge: [{ var: "state" }, { dissolvedAt: { var: "$timestamp" } }],
538
+ merge: [{ var: "state" }, { dissolvedAt: { var: "$ordinal" } }],
507
539
  },
508
540
  dependencies: [],
509
541
  },
@@ -90,7 +90,7 @@ export const govUniversalDef = defineFiberApp({
90
90
  {
91
91
  status: "VOTING",
92
92
  proposal: { var: "event.proposal" },
93
- proposedAt: { var: "$timestamp" },
93
+ proposedAt: { var: "$ordinal" },
94
94
  votes: {},
95
95
  },
96
96
  ],
@@ -149,7 +149,7 @@ export const govUniversalDef = defineFiberApp({
149
149
  { var: "state" },
150
150
  {
151
151
  status: "DISSOLVED",
152
- dissolvedAt: { var: "$timestamp" },
152
+ dissolvedAt: { var: "$ordinal" },
153
153
  },
154
154
  ],
155
155
  },