@enclave-e3/contracts 0.1.11 → 0.1.13

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 (257) hide show
  1. package/artifacts/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol/ProxyAdmin.json +3 -3
  2. package/artifacts/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol/artifacts.d.ts +3 -3
  3. package/artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/ITransparentUpgradeableProxy.json +1 -1
  4. package/artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json +3 -3
  5. package/artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/artifacts.d.ts +4 -4
  6. package/artifacts/build-info/{solc-0_8_28-c77ac33099bb85c15f46d194dd2b735e036cb799.json → solc-0_8_28-e60a5d7c133605edcf61acdd5ba43ab44ee0928e.json} +27 -12
  7. package/artifacts/build-info/solc-0_8_28-e60a5d7c133605edcf61acdd5ba43ab44ee0928e.output.json +1 -0
  8. package/artifacts/contracts/E3RefundManager.sol/E3RefundManager.json +684 -0
  9. package/artifacts/contracts/E3RefundManager.sol/artifacts.d.ts +27 -0
  10. package/artifacts/contracts/Enclave.sol/Enclave.json +530 -182
  11. package/artifacts/contracts/Enclave.sol/artifacts.d.ts +4 -4
  12. package/artifacts/contracts/interfaces/IBondingRegistry.sol/IBondingRegistry.json +14 -1
  13. package/artifacts/contracts/interfaces/IBondingRegistry.sol/artifacts.d.ts +2 -2
  14. package/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json +55 -5
  15. package/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/artifacts.d.ts +2 -2
  16. package/artifacts/contracts/interfaces/IComputeProvider.sol/IComputeProvider.json +1 -1
  17. package/artifacts/contracts/interfaces/IComputeProvider.sol/artifacts.d.ts +1 -1
  18. package/artifacts/contracts/interfaces/IDecryptionVerifier.sol/IDecryptionVerifier.json +1 -1
  19. package/artifacts/contracts/interfaces/IDecryptionVerifier.sol/artifacts.d.ts +1 -1
  20. package/artifacts/contracts/interfaces/IE3Program.sol/IE3Program.json +19 -24
  21. package/artifacts/contracts/interfaces/IE3Program.sol/artifacts.d.ts +2 -2
  22. package/artifacts/contracts/interfaces/IE3RefundManager.sol/IE3RefundManager.json +470 -0
  23. package/artifacts/contracts/interfaces/IE3RefundManager.sol/artifacts.d.ts +27 -0
  24. package/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json +383 -128
  25. package/artifacts/contracts/interfaces/IEnclave.sol/artifacts.d.ts +2 -2
  26. package/artifacts/contracts/interfaces/ISlashVerifier.sol/ISlashVerifier.json +1 -1
  27. package/artifacts/contracts/interfaces/ISlashVerifier.sol/artifacts.d.ts +1 -1
  28. package/artifacts/contracts/interfaces/ISlashingManager.sol/ISlashingManager.json +1 -1
  29. package/artifacts/contracts/interfaces/ISlashingManager.sol/artifacts.d.ts +1 -1
  30. package/artifacts/contracts/lib/ExitQueueLib.sol/ExitQueueLib.json +1 -1
  31. package/artifacts/contracts/lib/ExitQueueLib.sol/artifacts.d.ts +1 -1
  32. package/artifacts/contracts/registry/BondingRegistry.sol/BondingRegistry.json +16 -3
  33. package/artifacts/contracts/registry/BondingRegistry.sol/artifacts.d.ts +4 -4
  34. package/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/CiphernodeRegistryOwnable.json +91 -25
  35. package/artifacts/contracts/registry/CiphernodeRegistryOwnable.sol/artifacts.d.ts +6 -6
  36. package/artifacts/contracts/slashing/SlashingManager.sol/SlashingManager.json +3 -3
  37. package/artifacts/contracts/slashing/SlashingManager.sol/artifacts.d.ts +3 -3
  38. package/artifacts/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistry.json +57 -7
  39. package/artifacts/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistryEmptyKey.json +57 -7
  40. package/artifacts/contracts/test/MockCiphernodeRegistry.sol/artifacts.d.ts +8 -8
  41. package/artifacts/contracts/test/MockComputeProvider.sol/MockComputeProvider.json +3 -3
  42. package/artifacts/contracts/test/MockComputeProvider.sol/artifacts.d.ts +3 -3
  43. package/artifacts/contracts/test/MockDecryptionVerifier.sol/MockDecryptionVerifier.json +1 -1
  44. package/artifacts/contracts/test/MockDecryptionVerifier.sol/artifacts.d.ts +1 -1
  45. package/artifacts/contracts/test/MockE3Program.sol/MockE3Program.json +21 -26
  46. package/artifacts/contracts/test/MockE3Program.sol/artifacts.d.ts +4 -4
  47. package/artifacts/contracts/test/MockSlashingVerifier.sol/MockSlashingVerifier.json +1 -1
  48. package/artifacts/contracts/test/MockSlashingVerifier.sol/artifacts.d.ts +1 -1
  49. package/artifacts/contracts/test/MockStableToken.sol/MockUSDC.json +3 -3
  50. package/artifacts/contracts/test/MockStableToken.sol/artifacts.d.ts +3 -3
  51. package/artifacts/contracts/token/EnclaveTicketToken.sol/EnclaveTicketToken.json +14 -22
  52. package/artifacts/contracts/token/EnclaveTicketToken.sol/artifacts.d.ts +4 -4
  53. package/artifacts/contracts/token/EnclaveToken.sol/EnclaveToken.json +10 -10
  54. package/artifacts/contracts/token/EnclaveToken.sol/artifacts.d.ts +4 -4
  55. package/artifacts/contracts/verifier/DkgPkVerifier.sol/BaseZKHonkVerifier.json +89 -0
  56. package/artifacts/contracts/verifier/DkgPkVerifier.sol/CommitmentSchemeLib.json +13 -0
  57. package/artifacts/contracts/verifier/DkgPkVerifier.sol/DkgPkVerifier.json +186 -0
  58. package/artifacts/contracts/verifier/DkgPkVerifier.sol/FrLib.json +13 -0
  59. package/artifacts/contracts/verifier/DkgPkVerifier.sol/Honk.json +13 -0
  60. package/artifacts/contracts/verifier/DkgPkVerifier.sol/HonkVerificationKey.json +13 -0
  61. package/artifacts/contracts/verifier/DkgPkVerifier.sol/IVerifier.json +38 -0
  62. package/artifacts/contracts/verifier/DkgPkVerifier.sol/RelationsLib.json +13 -0
  63. package/artifacts/contracts/verifier/DkgPkVerifier.sol/ZKTranscriptLib.json +400 -0
  64. package/artifacts/contracts/verifier/DkgPkVerifier.sol/artifacts.d.ts +155 -0
  65. package/artifacts/poseidon-solidity/PoseidonT3.sol/PoseidonT3.json +1 -1
  66. package/artifacts/poseidon-solidity/PoseidonT3.sol/artifacts.d.ts +1 -1
  67. package/contracts/E3RefundManager.sol +365 -0
  68. package/contracts/Enclave.sol +426 -119
  69. package/contracts/interfaces/IBondingRegistry.sol +6 -0
  70. package/contracts/interfaces/ICiphernodeRegistry.sol +29 -7
  71. package/contracts/interfaces/IE3.sol +2 -6
  72. package/contracts/interfaces/IE3Program.sol +3 -7
  73. package/contracts/interfaces/IE3RefundManager.sol +150 -0
  74. package/contracts/interfaces/IEnclave.sol +186 -64
  75. package/contracts/registry/BondingRegistry.sol +9 -0
  76. package/contracts/registry/CiphernodeRegistryOwnable.sol +89 -42
  77. package/contracts/test/MockCiphernodeRegistry.sol +20 -6
  78. package/contracts/test/MockE3Program.sol +3 -8
  79. package/contracts/verifier/DkgPkVerifier.sol +3140 -0
  80. package/dist/hardhat.config.d.ts.map +1 -1
  81. package/dist/hardhat.config.js +4 -4
  82. package/dist/ignition/modules/dkgPkVerifier.d.ts +3 -0
  83. package/dist/ignition/modules/dkgPkVerifier.d.ts.map +1 -0
  84. package/dist/ignition/modules/dkgPkVerifier.js +10 -0
  85. package/dist/ignition/modules/e3RefundManager.d.ts +3 -0
  86. package/dist/ignition/modules/e3RefundManager.d.ts.map +1 -0
  87. package/dist/ignition/modules/e3RefundManager.js +23 -0
  88. package/dist/ignition/modules/enclave.d.ts.map +1 -1
  89. package/dist/ignition/modules/enclave.js +10 -0
  90. package/dist/scripts/deployAndSave/e3RefundManager.d.ts +20 -0
  91. package/dist/scripts/deployAndSave/e3RefundManager.d.ts.map +1 -0
  92. package/dist/scripts/deployAndSave/e3RefundManager.js +55 -0
  93. package/dist/scripts/deployAndSave/enclave.d.ts +13 -1
  94. package/dist/scripts/deployAndSave/enclave.d.ts.map +1 -1
  95. package/dist/scripts/deployAndSave/enclave.js +8 -1
  96. package/dist/scripts/deployAndSave/verifiers.d.ts +29 -0
  97. package/dist/scripts/deployAndSave/verifiers.d.ts.map +1 -0
  98. package/dist/scripts/deployAndSave/verifiers.js +109 -0
  99. package/dist/scripts/deployEnclave.d.ts.map +1 -1
  100. package/dist/scripts/deployEnclave.js +36 -0
  101. package/dist/scripts/deployVerifiers.d.ts +2 -0
  102. package/dist/scripts/deployVerifiers.d.ts.map +1 -0
  103. package/dist/scripts/deployVerifiers.js +33 -0
  104. package/dist/scripts/index.d.ts +1 -0
  105. package/dist/scripts/index.d.ts.map +1 -1
  106. package/dist/scripts/index.js +1 -0
  107. package/dist/tasks/enclave.d.ts +0 -2
  108. package/dist/tasks/enclave.d.ts.map +1 -1
  109. package/dist/tasks/enclave.js +8 -72
  110. package/dist/tasks/program.d.ts +2 -0
  111. package/dist/tasks/program.d.ts.map +1 -0
  112. package/dist/tasks/program.js +55 -0
  113. package/dist/test/E3Lifecycle/E3Integration.spec.d.ts +2 -0
  114. package/dist/test/E3Lifecycle/E3Integration.spec.d.ts.map +1 -0
  115. package/dist/test/E3Lifecycle/E3Integration.spec.js +757 -0
  116. package/dist/test/Enclave.spec.js +83 -406
  117. package/dist/test/Registry/CiphernodeRegistryOwnable.spec.js +133 -59
  118. package/dist/types/contracts/E3RefundManager.d.ts +379 -0
  119. package/dist/types/contracts/E3RefundManager.d.ts.map +1 -0
  120. package/dist/types/contracts/E3RefundManager.js +24 -0
  121. package/dist/types/contracts/Enclave.d.ts +325 -73
  122. package/dist/types/contracts/Enclave.d.ts.map +1 -1
  123. package/dist/types/contracts/Enclave.js +27 -3
  124. package/dist/types/contracts/index.d.ts +3 -0
  125. package/dist/types/contracts/index.d.ts.map +1 -1
  126. package/dist/types/contracts/interfaces/IBondingRegistry.d.ts +11 -1
  127. package/dist/types/contracts/interfaces/IBondingRegistry.d.ts.map +1 -1
  128. package/dist/types/contracts/interfaces/ICiphernodeRegistry.d.ts +35 -7
  129. package/dist/types/contracts/interfaces/ICiphernodeRegistry.d.ts.map +1 -1
  130. package/dist/types/contracts/interfaces/ICiphernodeRegistry.js +4 -0
  131. package/dist/types/contracts/interfaces/IE3Program.d.ts +16 -18
  132. package/dist/types/contracts/interfaces/IE3Program.d.ts.map +1 -1
  133. package/dist/types/contracts/interfaces/IE3RefundManager.d.ts +238 -0
  134. package/dist/types/contracts/interfaces/IE3RefundManager.d.ts.map +1 -0
  135. package/dist/types/contracts/interfaces/IE3RefundManager.js +16 -0
  136. package/dist/types/contracts/interfaces/IEnclave.d.ts +290 -62
  137. package/dist/types/contracts/interfaces/IEnclave.d.ts.map +1 -1
  138. package/dist/types/contracts/interfaces/IEnclave.js +27 -3
  139. package/dist/types/contracts/interfaces/index.d.ts +1 -0
  140. package/dist/types/contracts/interfaces/index.d.ts.map +1 -1
  141. package/dist/types/contracts/registry/BondingRegistry.d.ts +11 -1
  142. package/dist/types/contracts/registry/BondingRegistry.d.ts.map +1 -1
  143. package/dist/types/contracts/registry/CiphernodeRegistryOwnable.d.ts +35 -7
  144. package/dist/types/contracts/registry/CiphernodeRegistryOwnable.d.ts.map +1 -1
  145. package/dist/types/contracts/registry/CiphernodeRegistryOwnable.js +4 -0
  146. package/dist/types/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistry.d.ts +35 -7
  147. package/dist/types/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistry.d.ts.map +1 -1
  148. package/dist/types/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistry.js +4 -0
  149. package/dist/types/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistryEmptyKey.d.ts +35 -7
  150. package/dist/types/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistryEmptyKey.d.ts.map +1 -1
  151. package/dist/types/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistryEmptyKey.js +4 -0
  152. package/dist/types/contracts/test/MockE3Program.d.ts +16 -18
  153. package/dist/types/contracts/test/MockE3Program.d.ts.map +1 -1
  154. package/dist/types/contracts/verifier/DkgPkVerifier.sol/BaseZKHonkVerifier.d.ts +36 -0
  155. package/dist/types/contracts/verifier/DkgPkVerifier.sol/BaseZKHonkVerifier.d.ts.map +1 -0
  156. package/dist/types/contracts/verifier/DkgPkVerifier.sol/BaseZKHonkVerifier.js +1 -0
  157. package/dist/types/contracts/verifier/DkgPkVerifier.sol/DkgPkVerifier.d.ts +36 -0
  158. package/dist/types/contracts/verifier/DkgPkVerifier.sol/DkgPkVerifier.d.ts.map +1 -0
  159. package/dist/types/contracts/verifier/DkgPkVerifier.sol/DkgPkVerifier.js +1 -0
  160. package/dist/types/contracts/verifier/DkgPkVerifier.sol/IVerifier.d.ts +36 -0
  161. package/dist/types/contracts/verifier/DkgPkVerifier.sol/IVerifier.d.ts.map +1 -0
  162. package/dist/types/contracts/verifier/DkgPkVerifier.sol/IVerifier.js +1 -0
  163. package/dist/types/contracts/verifier/DkgPkVerifier.sol/ZKTranscriptLib.d.ts +138 -0
  164. package/dist/types/contracts/verifier/DkgPkVerifier.sol/ZKTranscriptLib.d.ts.map +1 -0
  165. package/dist/types/contracts/verifier/DkgPkVerifier.sol/ZKTranscriptLib.js +1 -0
  166. package/dist/types/contracts/verifier/DkgPkVerifier.sol/index.d.ts +5 -0
  167. package/dist/types/contracts/verifier/DkgPkVerifier.sol/index.d.ts.map +1 -0
  168. package/dist/types/contracts/verifier/DkgPkVerifier.sol/index.js +1 -0
  169. package/dist/types/contracts/verifier/index.d.ts +3 -0
  170. package/dist/types/contracts/verifier/index.d.ts.map +1 -0
  171. package/dist/types/contracts/verifier/index.js +1 -0
  172. package/dist/types/factories/@openzeppelin/contracts/proxy/transparent/ProxyAdmin__factory.d.ts +1 -1
  173. package/dist/types/factories/@openzeppelin/contracts/proxy/transparent/ProxyAdmin__factory.d.ts.map +1 -1
  174. package/dist/types/factories/@openzeppelin/contracts/proxy/transparent/ProxyAdmin__factory.js +1 -1
  175. package/dist/types/factories/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy__factory.d.ts +1 -1
  176. package/dist/types/factories/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy__factory.d.ts.map +1 -1
  177. package/dist/types/factories/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy__factory.js +1 -1
  178. package/dist/types/factories/contracts/E3RefundManager__factory.d.ts +540 -0
  179. package/dist/types/factories/contracts/E3RefundManager__factory.d.ts.map +1 -0
  180. package/dist/types/factories/contracts/E3RefundManager__factory.js +706 -0
  181. package/dist/types/factories/contracts/Enclave__factory.d.ts +412 -143
  182. package/dist/types/factories/contracts/Enclave__factory.d.ts.map +1 -1
  183. package/dist/types/factories/contracts/Enclave__factory.js +528 -180
  184. package/dist/types/factories/contracts/index.d.ts +2 -0
  185. package/dist/types/factories/contracts/index.d.ts.map +1 -1
  186. package/dist/types/factories/contracts/index.js +2 -0
  187. package/dist/types/factories/contracts/interfaces/IBondingRegistry__factory.d.ts +10 -0
  188. package/dist/types/factories/contracts/interfaces/IBondingRegistry__factory.d.ts.map +1 -1
  189. package/dist/types/factories/contracts/interfaces/IBondingRegistry__factory.js +13 -0
  190. package/dist/types/factories/contracts/interfaces/ICiphernodeRegistry__factory.d.ts +42 -4
  191. package/dist/types/factories/contracts/interfaces/ICiphernodeRegistry__factory.d.ts.map +1 -1
  192. package/dist/types/factories/contracts/interfaces/ICiphernodeRegistry__factory.js +54 -4
  193. package/dist/types/factories/contracts/interfaces/IE3Program__factory.d.ts +14 -18
  194. package/dist/types/factories/contracts/interfaces/IE3Program__factory.d.ts.map +1 -1
  195. package/dist/types/factories/contracts/interfaces/IE3Program__factory.js +18 -23
  196. package/dist/types/factories/contracts/interfaces/IE3RefundManager__factory.d.ts +358 -0
  197. package/dist/types/factories/contracts/interfaces/IE3RefundManager__factory.d.ts.map +1 -0
  198. package/dist/types/factories/contracts/interfaces/IE3RefundManager__factory.js +471 -0
  199. package/dist/types/factories/contracts/interfaces/IEnclave__factory.d.ts +303 -103
  200. package/dist/types/factories/contracts/interfaces/IEnclave__factory.d.ts.map +1 -1
  201. package/dist/types/factories/contracts/interfaces/IEnclave__factory.js +382 -127
  202. package/dist/types/factories/contracts/interfaces/index.d.ts +1 -0
  203. package/dist/types/factories/contracts/interfaces/index.d.ts.map +1 -1
  204. package/dist/types/factories/contracts/interfaces/index.js +1 -0
  205. package/dist/types/factories/contracts/registry/BondingRegistry__factory.d.ts +11 -1
  206. package/dist/types/factories/contracts/registry/BondingRegistry__factory.d.ts.map +1 -1
  207. package/dist/types/factories/contracts/registry/BondingRegistry__factory.js +14 -1
  208. package/dist/types/factories/contracts/registry/CiphernodeRegistryOwnable__factory.d.ts +62 -12
  209. package/dist/types/factories/contracts/registry/CiphernodeRegistryOwnable__factory.d.ts.map +1 -1
  210. package/dist/types/factories/contracts/registry/CiphernodeRegistryOwnable__factory.js +79 -13
  211. package/dist/types/factories/contracts/slashing/SlashingManager__factory.d.ts +1 -1
  212. package/dist/types/factories/contracts/slashing/SlashingManager__factory.d.ts.map +1 -1
  213. package/dist/types/factories/contracts/slashing/SlashingManager__factory.js +1 -1
  214. package/dist/types/factories/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistryEmptyKey__factory.d.ts +43 -5
  215. package/dist/types/factories/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistryEmptyKey__factory.d.ts.map +1 -1
  216. package/dist/types/factories/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistryEmptyKey__factory.js +55 -5
  217. package/dist/types/factories/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistry__factory.d.ts +43 -5
  218. package/dist/types/factories/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistry__factory.d.ts.map +1 -1
  219. package/dist/types/factories/contracts/test/MockCiphernodeRegistry.sol/MockCiphernodeRegistry__factory.js +55 -5
  220. package/dist/types/factories/contracts/test/MockComputeProvider__factory.d.ts +1 -1
  221. package/dist/types/factories/contracts/test/MockComputeProvider__factory.d.ts.map +1 -1
  222. package/dist/types/factories/contracts/test/MockComputeProvider__factory.js +1 -1
  223. package/dist/types/factories/contracts/test/MockE3Program__factory.d.ts +15 -19
  224. package/dist/types/factories/contracts/test/MockE3Program__factory.d.ts.map +1 -1
  225. package/dist/types/factories/contracts/test/MockE3Program__factory.js +19 -24
  226. package/dist/types/factories/contracts/test/MockStableToken.sol/MockUSDC__factory.d.ts +1 -1
  227. package/dist/types/factories/contracts/test/MockStableToken.sol/MockUSDC__factory.d.ts.map +1 -1
  228. package/dist/types/factories/contracts/test/MockStableToken.sol/MockUSDC__factory.js +1 -1
  229. package/dist/types/factories/contracts/token/EnclaveTicketToken__factory.d.ts +1 -1
  230. package/dist/types/factories/contracts/token/EnclaveTicketToken__factory.d.ts.map +1 -1
  231. package/dist/types/factories/contracts/token/EnclaveTicketToken__factory.js +1 -1
  232. package/dist/types/factories/contracts/token/EnclaveToken__factory.d.ts +1 -1
  233. package/dist/types/factories/contracts/token/EnclaveToken__factory.d.ts.map +1 -1
  234. package/dist/types/factories/contracts/token/EnclaveToken__factory.js +1 -1
  235. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/BaseZKHonkVerifier__factory.d.ts +66 -0
  236. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/BaseZKHonkVerifier__factory.d.ts.map +1 -0
  237. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/BaseZKHonkVerifier__factory.js +90 -0
  238. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/DkgPkVerifier__factory.d.ts +87 -0
  239. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/DkgPkVerifier__factory.d.ts.map +1 -0
  240. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/DkgPkVerifier__factory.js +122 -0
  241. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/IVerifier__factory.d.ts +26 -0
  242. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/IVerifier__factory.d.ts.map +1 -0
  243. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/IVerifier__factory.js +39 -0
  244. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/ZKTranscriptLib__factory.d.ts +323 -0
  245. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/ZKTranscriptLib__factory.d.ts.map +1 -0
  246. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/ZKTranscriptLib__factory.js +422 -0
  247. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/index.d.ts +5 -0
  248. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/index.d.ts.map +1 -0
  249. package/dist/types/factories/contracts/verifier/DkgPkVerifier.sol/index.js +7 -0
  250. package/dist/types/factories/contracts/verifier/index.d.ts +2 -0
  251. package/dist/types/factories/contracts/verifier/index.d.ts.map +1 -0
  252. package/dist/types/factories/contracts/verifier/index.js +4 -0
  253. package/dist/types/index.d.ts +12 -0
  254. package/dist/types/index.d.ts.map +1 -1
  255. package/dist/types/index.js +6 -0
  256. package/package.json +17 -3
  257. package/artifacts/build-info/solc-0_8_28-c77ac33099bb85c15f46d194dd2b735e036cb799.output.json +0 -1
@@ -0,0 +1,757 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ //
3
+ // This file is provided WITHOUT ANY WARRANTY;
4
+ // without even the implied warranty of MERCHANTABILITY
5
+ // or FITNESS FOR A PARTICULAR PURPOSE.
6
+ import { expect } from "chai";
7
+ import { network } from "hardhat";
8
+ import BondingRegistryModule from "../../ignition/modules/bondingRegistry";
9
+ import CiphernodeRegistryModule from "../../ignition/modules/ciphernodeRegistry";
10
+ import E3RefundManagerModule from "../../ignition/modules/e3RefundManager";
11
+ import EnclaveModule from "../../ignition/modules/enclave";
12
+ import EnclaveTicketTokenModule from "../../ignition/modules/enclaveTicketToken";
13
+ import EnclaveTokenModule from "../../ignition/modules/enclaveToken";
14
+ import MockDecryptionVerifierModule from "../../ignition/modules/mockDecryptionVerifier";
15
+ import MockE3ProgramModule from "../../ignition/modules/mockE3Program";
16
+ import MockStableTokenModule from "../../ignition/modules/mockStableToken";
17
+ import SlashingManagerModule from "../../ignition/modules/slashingManager";
18
+ import { BondingRegistry__factory as BondingRegistryFactory, CiphernodeRegistryOwnable__factory as CiphernodeRegistryOwnableFactory, E3RefundManager__factory as E3RefundManagerFactory, Enclave__factory as EnclaveFactory, EnclaveToken__factory as EnclaveTokenFactory, MockDecryptionVerifier__factory as MockDecryptionVerifierFactory, MockE3Program__factory as MockE3ProgramFactory, MockUSDC__factory as MockUSDCFactory, } from "../../types";
19
+ const { ethers, ignition, networkHelpers } = await network.connect();
20
+ const { loadFixture, time } = networkHelpers;
21
+ /**
22
+ * Integration tests for E3 Refund/Timeout Mechanism
23
+ *
24
+ * These tests verify the full integration between:
25
+ * - Enclave.sol (main coordinator with integrated lifecycle management)
26
+ * - E3RefundManager.sol (refund calculation and claiming)
27
+ * - CiphernodeRegistryOwnable.sol (committee management)
28
+ */
29
+ describe("E3 Integration - Refund/Timeout Mechanism", function () {
30
+ // Time constants
31
+ const ONE_HOUR = 60 * 60;
32
+ const ONE_DAY = 24 * ONE_HOUR;
33
+ const THREE_DAYS = 3 * ONE_DAY;
34
+ const SEVEN_DAYS = 7 * ONE_DAY;
35
+ const THIRTY_DAYS = 30 * ONE_DAY;
36
+ const SORTITION_SUBMISSION_WINDOW = 10;
37
+ const addressOne = "0x0000000000000000000000000000000000000001";
38
+ // Default timeout configuration
39
+ const defaultTimeoutConfig = {
40
+ committeeFormationWindow: ONE_DAY,
41
+ dkgWindow: ONE_DAY,
42
+ computeWindow: THREE_DAYS,
43
+ decryptionWindow: ONE_DAY,
44
+ gracePeriod: ONE_HOUR,
45
+ };
46
+ const abiCoder = ethers.AbiCoder.defaultAbiCoder();
47
+ const polynomial_degree = ethers.toBigInt(2048);
48
+ const plaintext_modulus = ethers.toBigInt(1032193);
49
+ const moduli = [ethers.toBigInt("18014398492704769")];
50
+ const encodedE3ProgramParams = abiCoder.encode(["uint256", "uint256", "uint256[]"], [polynomial_degree, plaintext_modulus, moduli]);
51
+ const encryptionSchemeId = "0x2c2a814a0495f913a3a312fc4771e37552bc14f8a2d4075a08122d356f0849c6";
52
+ const setup = async () => {
53
+ const [owner, requester, treasury, operator1, operator2, computeProvider] = await ethers.getSigners();
54
+ const ownerAddress = await owner.getAddress();
55
+ const treasuryAddress = await treasury.getAddress();
56
+ const requesterAddress = await requester.getAddress();
57
+ // Deploy USDC mock
58
+ const usdcContract = await ignition.deploy(MockStableTokenModule, {
59
+ parameters: {
60
+ MockUSDC: {
61
+ initialSupply: 10000000,
62
+ },
63
+ },
64
+ });
65
+ const usdcToken = MockUSDCFactory.connect(await usdcContract.mockUSDC.getAddress(), owner);
66
+ // Deploy ENCL token
67
+ const enclTokenContract = await ignition.deploy(EnclaveTokenModule, {
68
+ parameters: {
69
+ EnclaveToken: {
70
+ owner: ownerAddress,
71
+ },
72
+ },
73
+ });
74
+ const enclToken = EnclaveTokenFactory.connect(await enclTokenContract.enclaveToken.getAddress(), owner);
75
+ // Deploy ticket token
76
+ const ticketTokenContract = await ignition.deploy(EnclaveTicketTokenModule, {
77
+ parameters: {
78
+ EnclaveTicketToken: {
79
+ baseToken: await usdcToken.getAddress(),
80
+ registry: addressOne,
81
+ owner: ownerAddress,
82
+ },
83
+ },
84
+ });
85
+ // Deploy slashing manager
86
+ const slashingManagerContract = await ignition.deploy(SlashingManagerModule, {
87
+ parameters: {
88
+ SlashingManager: {
89
+ admin: ownerAddress,
90
+ bondingRegistry: addressOne, // Will be updated
91
+ },
92
+ },
93
+ });
94
+ // Deploy bonding registry
95
+ const bondingRegistryContract = await ignition.deploy(BondingRegistryModule, {
96
+ parameters: {
97
+ BondingRegistry: {
98
+ owner: ownerAddress,
99
+ ticketToken: await ticketTokenContract.enclaveTicketToken.getAddress(),
100
+ licenseToken: await enclToken.getAddress(),
101
+ registry: addressOne, // Will be updated
102
+ slashedFundsTreasury: treasuryAddress,
103
+ ticketPrice: ethers.parseUnits("10", 6),
104
+ licenseRequiredBond: ethers.parseEther("1000"),
105
+ minTicketBalance: 5,
106
+ exitDelay: SEVEN_DAYS,
107
+ },
108
+ },
109
+ });
110
+ const bondingRegistry = BondingRegistryFactory.connect(await bondingRegistryContract.bondingRegistry.getAddress(), owner);
111
+ // Deploy Enclave (with addressOne as temp registry)
112
+ const enclaveContract = await ignition.deploy(EnclaveModule, {
113
+ parameters: {
114
+ Enclave: {
115
+ params: encodedE3ProgramParams,
116
+ owner: ownerAddress,
117
+ maxDuration: THIRTY_DAYS,
118
+ registry: addressOne,
119
+ e3RefundManager: addressOne,
120
+ bondingRegistry: await bondingRegistry.getAddress(),
121
+ feeToken: await usdcToken.getAddress(),
122
+ timeoutConfig: defaultTimeoutConfig,
123
+ },
124
+ },
125
+ });
126
+ const enclaveAddress = await enclaveContract.enclave.getAddress();
127
+ const enclave = EnclaveFactory.connect(enclaveAddress, owner);
128
+ // Deploy CiphernodeRegistry
129
+ const ciphernodeRegistry = await ignition.deploy(CiphernodeRegistryModule, {
130
+ parameters: {
131
+ CiphernodeRegistry: {
132
+ enclaveAddress: enclaveAddress,
133
+ owner: ownerAddress,
134
+ submissionWindow: SORTITION_SUBMISSION_WINDOW,
135
+ },
136
+ },
137
+ });
138
+ const ciphernodeRegistryAddress = await ciphernodeRegistry.cipherNodeRegistry.getAddress();
139
+ const registry = CiphernodeRegistryOwnableFactory.connect(ciphernodeRegistryAddress, owner);
140
+ // Deploy E3RefundManager
141
+ const e3RefundManagerContract = await ignition.deploy(E3RefundManagerModule, {
142
+ parameters: {
143
+ E3RefundManager: {
144
+ owner: ownerAddress,
145
+ enclave: enclaveAddress,
146
+ treasury: treasuryAddress,
147
+ },
148
+ },
149
+ });
150
+ const e3RefundManagerAddress = await e3RefundManagerContract.e3RefundManager.getAddress();
151
+ const e3RefundManager = E3RefundManagerFactory.connect(e3RefundManagerAddress, owner);
152
+ // Deploy mock E3 Program
153
+ const e3ProgramContract = await ignition.deploy(MockE3ProgramModule, {
154
+ parameters: {
155
+ MockE3Program: {
156
+ encryptionSchemeId: encryptionSchemeId,
157
+ },
158
+ },
159
+ });
160
+ const e3Program = MockE3ProgramFactory.connect(await e3ProgramContract.mockE3Program.getAddress(), owner);
161
+ // Deploy mock decryption verifier
162
+ const decryptionVerifierContract = await ignition.deploy(MockDecryptionVerifierModule);
163
+ const decryptionVerifier = MockDecryptionVerifierFactory.connect(await decryptionVerifierContract.mockDecryptionVerifier.getAddress(), owner);
164
+ // Wire up all the contracts
165
+ await enclave.setCiphernodeRegistry(ciphernodeRegistryAddress);
166
+ await enclave.setE3RefundManager(e3RefundManagerAddress);
167
+ await enclave.enableE3Program(await e3Program.getAddress());
168
+ await enclave.setDecryptionVerifier(encryptionSchemeId, await decryptionVerifier.getAddress());
169
+ // Setup bonding registry connections
170
+ await bondingRegistry.setRewardDistributor(enclaveAddress);
171
+ await bondingRegistry.setRegistry(ciphernodeRegistryAddress);
172
+ await bondingRegistry.setSlashingManager(await slashingManagerContract.slashingManager.getAddress());
173
+ await slashingManagerContract.slashingManager.setBondingRegistry(await bondingRegistry.getAddress());
174
+ await registry.setBondingRegistry(await bondingRegistry.getAddress());
175
+ // Update ticket token registry
176
+ await ticketTokenContract.enclaveTicketToken.setRegistry(await bondingRegistry.getAddress());
177
+ // Mint tokens to requester
178
+ await usdcToken.mint(requesterAddress, ethers.parseUnits("10000", 6));
179
+ // Mint tokens to refund manager for distribution tests
180
+ await usdcToken.mint(e3RefundManagerAddress, ethers.parseUnits("10000", 6));
181
+ // Helper to make E3 request
182
+ const makeRequest = async (signer = requester) => {
183
+ const startTime = (await time.latest()) + 100;
184
+ const requestParams = {
185
+ threshold: [2, 2],
186
+ inputWindow: [startTime + 100, startTime + ONE_DAY],
187
+ e3Program: await e3Program.getAddress(),
188
+ e3ProgramParams: encodedE3ProgramParams,
189
+ // computeProviderParams must be exactly 32 bytes for MockE3Program.validate
190
+ computeProviderParams: abiCoder.encode(["address"], [await decryptionVerifier.getAddress()]),
191
+ customParams: abiCoder.encode(["address"], ["0x1234567890123456789012345678901234567890"]),
192
+ };
193
+ const fee = await enclave.getE3Quote(requestParams);
194
+ await usdcToken.connect(signer).approve(enclaveAddress, fee);
195
+ await enclave.connect(signer).request(requestParams);
196
+ // Get e3Id from event (it's 0 for first request)
197
+ return { e3Id: 0 };
198
+ };
199
+ async function setupOperator(operator) {
200
+ const operatorAddress = await operator.getAddress();
201
+ await enclToken.setTransferRestriction(false);
202
+ await enclToken.mintAllocation(operatorAddress, ethers.parseEther("10000"), "Test allocation");
203
+ await usdcToken.mint(operatorAddress, ethers.parseUnits("100000", 6));
204
+ await enclToken
205
+ .connect(operator)
206
+ .approve(await bondingRegistry.getAddress(), ethers.parseEther("2000"));
207
+ await bondingRegistry
208
+ .connect(operator)
209
+ .bondLicense(ethers.parseEther("1000"));
210
+ await bondingRegistry.connect(operator).registerOperator();
211
+ const ticketTokenAddress = await bondingRegistry.ticketToken();
212
+ const ticketAmount = ethers.parseUnits("100", 6);
213
+ await usdcToken
214
+ .connect(operator)
215
+ .approve(ticketTokenAddress, ticketAmount);
216
+ await bondingRegistry.connect(operator).addTicketBalance(ticketAmount);
217
+ }
218
+ return {
219
+ enclave,
220
+ e3RefundManager,
221
+ bondingRegistry,
222
+ registry,
223
+ usdcToken,
224
+ enclToken,
225
+ e3Program,
226
+ decryptionVerifier,
227
+ owner,
228
+ requester,
229
+ treasury,
230
+ operator1,
231
+ operator2,
232
+ computeProvider,
233
+ makeRequest,
234
+ setupOperator,
235
+ };
236
+ };
237
+ describe("E3 Request with Lifecycle Integration", function () {
238
+ it("initializes E3 lifecycle when request is made", async function () {
239
+ const { enclave, makeRequest, requester, operator1, operator2, setupOperator, } = await loadFixture(setup);
240
+ await setupOperator(operator1);
241
+ await setupOperator(operator2);
242
+ await makeRequest();
243
+ // Check that E3 lifecycle was initialized
244
+ const stage = await enclave.getE3Stage(0);
245
+ expect(stage).to.equal(1); // E3Stage.Requested
246
+ // Check requester is tracked
247
+ const storedRequester = await enclave.getRequester(0);
248
+ expect(storedRequester).to.equal(await requester.getAddress());
249
+ });
250
+ });
251
+ describe("Committee Formed Integration", function () {
252
+ it("transitions to CommitteeFormed when publishCommittee is called", async function () {
253
+ const { enclave, registry, makeRequest, operator1, operator2, setupOperator, } = await loadFixture(setup);
254
+ await setupOperator(operator1);
255
+ await setupOperator(operator2);
256
+ // Make a request first
257
+ await makeRequest();
258
+ // Verify stage is Requested
259
+ let stage = await enclave.getE3Stage(0);
260
+ expect(stage).to.equal(1); // E3Stage.Requested
261
+ // Submit tickets for sortition
262
+ await registry.connect(operator1).submitTicket(0, 1);
263
+ await registry.connect(operator2).submitTicket(0, 1);
264
+ // Fast forward past submission window
265
+ await time.increase(SORTITION_SUBMISSION_WINDOW + 1);
266
+ // Finalize committee
267
+ await registry.finalizeCommittee(0);
268
+ // Publish committee (this triggers onCommitteePublished -> onCommitteeFormed)
269
+ const nodes = [
270
+ await operator1.getAddress(),
271
+ await operator2.getAddress(),
272
+ ];
273
+ const publicKey = "0x1234567890abcdef1234567890abcdef";
274
+ const publicKeyHash = ethers.keccak256(publicKey);
275
+ await registry.publishCommittee(0, nodes, publicKey, publicKeyHash);
276
+ // Verify stage transitioned to KeyPublished (after publishCommittee which calls onKeyPublished)
277
+ stage = await enclave.getE3Stage(0);
278
+ expect(stage).to.equal(3); // E3Stage.KeyPublished
279
+ // Verify deadlines were set
280
+ const deadlines = await enclave.getDeadlines(0);
281
+ expect(deadlines.dkgDeadline).to.be.gt(0);
282
+ });
283
+ it("emits CommitteeFormed event when committee is published", async function () {
284
+ const { enclave, registry, makeRequest, operator1, operator2, setupOperator, } = await loadFixture(setup);
285
+ await setupOperator(operator1);
286
+ await setupOperator(operator2);
287
+ // Make a request
288
+ await makeRequest();
289
+ // Complete sortition process
290
+ await registry.connect(operator1).submitTicket(0, 1);
291
+ await registry.connect(operator2).submitTicket(0, 1);
292
+ await time.increase(SORTITION_SUBMISSION_WINDOW + 1);
293
+ await registry.finalizeCommittee(0);
294
+ // Publish committee and expect CommitteeFormed event
295
+ const nodes = [
296
+ await operator1.getAddress(),
297
+ await operator2.getAddress(),
298
+ ];
299
+ const publicKey = "0x1234567890abcdef1234567890abcdef";
300
+ const publicKeyHash = ethers.keccak256(publicKey);
301
+ await expect(registry.publishCommittee(0, nodes, publicKey, publicKeyHash))
302
+ .to.emit(enclave, "CommitteeFormed")
303
+ .withArgs(0);
304
+ });
305
+ });
306
+ describe("processE3Failure()", function () {
307
+ it("reverts if lifecycle is not a valid contract", async function () {
308
+ const { enclave, owner, makeRequest, operator1, operator2, setupOperator, } = await loadFixture(setup);
309
+ await setupOperator(operator1);
310
+ await setupOperator(operator2);
311
+ await makeRequest();
312
+ // Create a new enclave with addressOne as lifecycle placeholder (not a real contract)
313
+ const newEnclaveContract = await ignition.deploy(EnclaveModule, {
314
+ parameters: {
315
+ Enclave: {
316
+ params: encodedE3ProgramParams,
317
+ owner: await owner.getAddress(),
318
+ maxDuration: THIRTY_DAYS,
319
+ registry: await enclave.ciphernodeRegistry(),
320
+ bondingRegistry: await enclave.bondingRegistry(),
321
+ e3RefundManager: addressOne,
322
+ feeToken: await enclave.feeToken(),
323
+ },
324
+ },
325
+ });
326
+ const newEnclave = EnclaveFactory.connect(await newEnclaveContract.enclave.getAddress(), owner);
327
+ // Calling processE3Failure with a placeholder lifecycle should revert
328
+ // (it will try to call getE3Stage on an EOA which will fail)
329
+ await expect(newEnclave.processE3Failure(0)).to.be.revert(ethers);
330
+ });
331
+ it("reverts if E3 not in failed state", async function () {
332
+ const { enclave, makeRequest, operator1, operator2, setupOperator } = await loadFixture(setup);
333
+ await setupOperator(operator1);
334
+ await setupOperator(operator2);
335
+ await makeRequest();
336
+ // E3 is in Requested state, not Failed
337
+ await expect(enclave.processE3Failure(0)).to.be.revertedWith("E3 not failed");
338
+ });
339
+ it("processes failure and calculates refund for committee formation timeout", async function () {
340
+ const { enclave, e3RefundManager, makeRequest, operator1, operator2, setupOperator, } = await loadFixture(setup);
341
+ await setupOperator(operator1);
342
+ await setupOperator(operator2);
343
+ await makeRequest();
344
+ // Fast forward past committee formation deadline
345
+ await time.increase(defaultTimeoutConfig.committeeFormationWindow + 1);
346
+ // Mark E3 as failed
347
+ await enclave.markE3Failed(0);
348
+ const stage = await enclave.getE3Stage(0);
349
+ expect(stage).to.equal(6); // E3Stage.Failed
350
+ // Process the failure
351
+ await expect(enclave.processE3Failure(0)).to.emit(enclave, "E3FailureProcessed");
352
+ const distribution = await e3RefundManager.getRefundDistribution(0);
353
+ expect(distribution.calculated).to.be.true;
354
+ expect(distribution.requesterAmount).to.be.gt(0);
355
+ });
356
+ it("allows requester to claim refund after failure processing", async function () {
357
+ const { enclave, e3RefundManager, makeRequest, requester, usdcToken, operator1, operator2, setupOperator, } = await loadFixture(setup);
358
+ await setupOperator(operator1);
359
+ await setupOperator(operator2);
360
+ await makeRequest();
361
+ // Get initial balance
362
+ const balanceBefore = await usdcToken.balanceOf(await requester.getAddress());
363
+ // Fast forward and fail E3
364
+ await time.increase(defaultTimeoutConfig.committeeFormationWindow + 1);
365
+ await enclave.markE3Failed(0);
366
+ await enclave.processE3Failure(0);
367
+ // Claim refund
368
+ await e3RefundManager.connect(requester).claimRequesterRefund(0);
369
+ const balanceAfter = await usdcToken.balanceOf(await requester.getAddress());
370
+ expect(balanceAfter).to.be.gt(balanceBefore);
371
+ });
372
+ it("reverts if trying to process failure twice", async function () {
373
+ const { enclave, makeRequest, operator1, operator2, setupOperator } = await loadFixture(setup);
374
+ await setupOperator(operator1);
375
+ await setupOperator(operator2);
376
+ await makeRequest();
377
+ await time.increase(defaultTimeoutConfig.committeeFormationWindow + 1);
378
+ await enclave.markE3Failed(0);
379
+ await enclave.processE3Failure(0);
380
+ // Second call should fail - payment already cleared
381
+ await expect(enclave.processE3Failure(0)).to.be.revertedWith("No payment to refund");
382
+ });
383
+ it("reverts if requester tries to claim refund twice", async function () {
384
+ const { enclave, e3RefundManager, makeRequest, requester, operator1, operator2, setupOperator, } = await loadFixture(setup);
385
+ await setupOperator(operator1);
386
+ await setupOperator(operator2);
387
+ await makeRequest();
388
+ await time.increase(defaultTimeoutConfig.committeeFormationWindow + 1);
389
+ await enclave.markE3Failed(0);
390
+ await enclave.processE3Failure(0);
391
+ // First claim succeeds
392
+ await e3RefundManager.connect(requester).claimRequesterRefund(0);
393
+ // Second claim should fail
394
+ await expect(e3RefundManager.connect(requester).claimRequesterRefund(0)).to.be.revertedWithCustomError(e3RefundManager, "AlreadyClaimed");
395
+ });
396
+ it("reverts if refund not yet calculated", async function () {
397
+ const { e3RefundManager, makeRequest, requester, operator1, operator2, setupOperator, } = await loadFixture(setup);
398
+ await setupOperator(operator1);
399
+ await setupOperator(operator2);
400
+ await makeRequest();
401
+ // Try to claim before failure is processed
402
+ await expect(e3RefundManager.connect(requester).claimRequesterRefund(0)).to.be.revertedWithCustomError(e3RefundManager, "RefundNotCalculated");
403
+ });
404
+ });
405
+ describe("E3RefundManager Initialization", function () {
406
+ it("correctly sets enclave address", async function () {
407
+ const { enclave, e3RefundManager } = await loadFixture(setup);
408
+ expect(await e3RefundManager.enclave()).to.equal(await enclave.getAddress());
409
+ });
410
+ });
411
+ describe("Full Failure Flow - Committee Formation Timeout", function () {
412
+ it("complete flow: request -> timeout -> fail -> process -> claim", async function () {
413
+ const { enclave, e3RefundManager, makeRequest, requester, usdcToken, operator1, operator2, setupOperator, } = await loadFixture(setup);
414
+ await setupOperator(operator1);
415
+ await setupOperator(operator2);
416
+ // 1. Make request
417
+ await makeRequest();
418
+ // Verify stage
419
+ let stage = await enclave.getE3Stage(0);
420
+ expect(stage).to.equal(1); // Requested
421
+ // 2. Fast forward past deadline
422
+ await time.increase(defaultTimeoutConfig.committeeFormationWindow + 1);
423
+ // 3. Anyone can mark as failed
424
+ const [canFail, reason] = await enclave.checkFailureCondition(0);
425
+ expect(canFail).to.be.true;
426
+ expect(reason).to.equal(1); // CommitteeFormationTimeout
427
+ await enclave.markE3Failed(0);
428
+ stage = await enclave.getE3Stage(0);
429
+ expect(stage).to.equal(6); // Failed
430
+ // 4. Process failure
431
+ await enclave.processE3Failure(0);
432
+ // 5. Requester claims refund
433
+ const balanceBefore = await usdcToken.balanceOf(await requester.getAddress());
434
+ await e3RefundManager.connect(requester).claimRequesterRefund(0);
435
+ const balanceAfter = await usdcToken.balanceOf(await requester.getAddress());
436
+ const distribution = await e3RefundManager.getRefundDistribution(0);
437
+ expect(balanceAfter - balanceBefore).to.equal(distribution.requesterAmount);
438
+ });
439
+ });
440
+ describe("Slashed Funds Routing", function () {
441
+ it("routes slashed funds 50/50 to requester and honest nodes", async function () {
442
+ const { enclave, e3RefundManager, makeRequest, owner, operator1, operator2, setupOperator, } = await loadFixture(setup);
443
+ await setupOperator(operator1);
444
+ await setupOperator(operator2);
445
+ await makeRequest();
446
+ // Fail the E3
447
+ await time.increase(defaultTimeoutConfig.committeeFormationWindow + 1);
448
+ await enclave.markE3Failed(0);
449
+ await enclave.processE3Failure(0);
450
+ const distributionBefore = await e3RefundManager.getRefundDistribution(0);
451
+ const slashedAmount = ethers.parseUnits("100", 6);
452
+ // Route slashed funds (normally called by SlashingManager through Enclave)
453
+ // For testing, temporarily set enclave to owner to call this permissioned function
454
+ const originalEnclave = await e3RefundManager.enclave();
455
+ await e3RefundManager.setEnclave(await owner.getAddress());
456
+ await e3RefundManager.connect(owner).routeSlashedFunds(0, slashedAmount);
457
+ await e3RefundManager.setEnclave(originalEnclave);
458
+ const distributionAfter = await e3RefundManager.getRefundDistribution(0);
459
+ // Verify slashed funds are split 50/50 between requester and honest nodes
460
+ expect(distributionAfter.requesterAmount).to.equal(distributionBefore.requesterAmount + slashedAmount / 2n);
461
+ expect(distributionAfter.honestNodeAmount).to.equal(distributionBefore.honestNodeAmount + slashedAmount / 2n);
462
+ expect(distributionAfter.totalSlashed).to.equal(slashedAmount);
463
+ });
464
+ });
465
+ describe("Full Failure Flow - DKG Timeout", function () {
466
+ it("complete flow: request -> committee formed -> DKG timeout -> fail -> process -> claim", async function () {
467
+ const { enclave, e3RefundManager, registry, usdcToken, makeRequest, requester, operator1, operator2, setupOperator, } = await loadFixture(setup);
468
+ await setupOperator(operator1);
469
+ await setupOperator(operator2);
470
+ // 1. Make request
471
+ await makeRequest();
472
+ let stage = await enclave.getE3Stage(0);
473
+ expect(stage).to.equal(1); // Requested
474
+ // 2. Complete sortition (committee finalized, DKG starts)
475
+ await registry.connect(operator1).submitTicket(0, 1);
476
+ await registry.connect(operator2).submitTicket(0, 1);
477
+ await time.increase(SORTITION_SUBMISSION_WINDOW + 1);
478
+ await registry.finalizeCommittee(0);
479
+ stage = await enclave.getE3Stage(0);
480
+ expect(stage).to.equal(2); // CommitteeFinalized
481
+ // 3. Fast forward past DKG deadline (key never published - simulating DKG failure)
482
+ await time.increase(defaultTimeoutConfig.dkgWindow + 1);
483
+ // 4. Check failure condition and mark as failed
484
+ const [canFail, reason] = await enclave.checkFailureCondition(0);
485
+ expect(canFail).to.be.true;
486
+ expect(reason).to.equal(3); // DKGTimeout
487
+ await enclave.markE3Failed(0);
488
+ stage = await enclave.getE3Stage(0);
489
+ expect(stage).to.equal(6); // Failed
490
+ const failureReason = await enclave.getFailureReason(0);
491
+ expect(failureReason).to.equal(3); // DKGTimeout
492
+ // 5. Process failure and claim refund
493
+ await enclave.processE3Failure(0);
494
+ const balanceBefore = await usdcToken.balanceOf(await requester.getAddress());
495
+ await e3RefundManager.connect(requester).claimRequesterRefund(0);
496
+ const balanceAfter = await usdcToken.balanceOf(await requester.getAddress());
497
+ const distribution = await e3RefundManager.getRefundDistribution(0);
498
+ expect(balanceAfter - balanceBefore).to.equal(distribution.requesterAmount);
499
+ });
500
+ });
501
+ describe("Full Failure Flow - Compute Timeout", function () {
502
+ it("complete flow: request -> activated -> compute timeout -> fail -> process -> claim", async function () {
503
+ const { enclave, e3RefundManager, registry, usdcToken, makeRequest, requester, operator1, operator2, setupOperator, } = await loadFixture(setup);
504
+ await setupOperator(operator1);
505
+ await setupOperator(operator2);
506
+ // 1. Make request
507
+ await makeRequest();
508
+ let stage = await enclave.getE3Stage(0);
509
+ expect(stage).to.equal(1); // Requested
510
+ // 2. Complete sortition and DKG
511
+ await registry.connect(operator1).submitTicket(0, 1);
512
+ await registry.connect(operator2).submitTicket(0, 1);
513
+ await time.increase(SORTITION_SUBMISSION_WINDOW + 1);
514
+ await registry.finalizeCommittee(0);
515
+ const nodes = [
516
+ await operator1.getAddress(),
517
+ await operator2.getAddress(),
518
+ ];
519
+ const publicKey = "0x1234567890abcdef1234567890abcdef";
520
+ const publicKeyHash = ethers.keccak256(publicKey);
521
+ await registry.publishCommittee(0, nodes, publicKey, publicKeyHash);
522
+ stage = await enclave.getE3Stage(0);
523
+ expect(stage).to.equal(3); // KeyPublished
524
+ // 3. Wait past compute deadline (ciphertext never published)
525
+ const e3 = await enclave.getE3(0);
526
+ const computeDeadline = Number(e3.inputWindow[1]) + defaultTimeoutConfig.computeWindow;
527
+ await time.increaseTo(computeDeadline + 1);
528
+ // 4. Check failure condition and mark as failed
529
+ const [canFail, reason] = await enclave.checkFailureCondition(0);
530
+ expect(canFail).to.be.true;
531
+ expect(reason).to.equal(6); // ComputeTimeout
532
+ await enclave.markE3Failed(0);
533
+ stage = await enclave.getE3Stage(0);
534
+ expect(stage).to.equal(6); // Failed
535
+ const failureReason = await enclave.getFailureReason(0);
536
+ expect(failureReason).to.equal(6); // ComputeTimeout
537
+ // 5. Process and claim
538
+ await enclave.processE3Failure(0);
539
+ const balanceBefore = await usdcToken.balanceOf(await requester.getAddress());
540
+ await e3RefundManager.connect(requester).claimRequesterRefund(0);
541
+ const balanceAfter = await usdcToken.balanceOf(await requester.getAddress());
542
+ const distribution = await e3RefundManager.getRefundDistribution(0);
543
+ expect(balanceAfter - balanceBefore).to.equal(distribution.requesterAmount);
544
+ });
545
+ });
546
+ describe("Full Failure Flow - Decryption Timeout", function () {
547
+ it("complete flow: request -> ciphertext published -> decryption timeout -> fail -> process -> claim", async function () {
548
+ const { enclave, e3RefundManager, registry, usdcToken, makeRequest, requester, operator1, operator2, setupOperator, } = await loadFixture(setup);
549
+ await setupOperator(operator1);
550
+ await setupOperator(operator2);
551
+ // 1. Make request
552
+ await makeRequest();
553
+ let stage = await enclave.getE3Stage(0);
554
+ expect(stage).to.equal(1); // Requested
555
+ // 2. Complete sortition and DKG
556
+ await registry.connect(operator1).submitTicket(0, 1);
557
+ await registry.connect(operator2).submitTicket(0, 1);
558
+ await time.increase(SORTITION_SUBMISSION_WINDOW + 1);
559
+ await registry.finalizeCommittee(0);
560
+ const nodes = [
561
+ await operator1.getAddress(),
562
+ await operator2.getAddress(),
563
+ ];
564
+ const publicKey = "0x1234567890abcdef1234567890abcdef";
565
+ const publicKeyHash = ethers.keccak256(publicKey);
566
+ await registry.publishCommittee(0, nodes, publicKey, publicKeyHash);
567
+ stage = await enclave.getE3Stage(0);
568
+ expect(stage).to.equal(3); // KeyPublished
569
+ // 3. Publish ciphertext output
570
+ const e3 = await enclave.getE3(0);
571
+ await time.increaseTo(Number(e3.inputWindow[1]));
572
+ const ciphertextOutput = "0x" + "ab".repeat(100);
573
+ const proof = "0x1337";
574
+ await enclave.publishCiphertextOutput(0, ciphertextOutput, proof);
575
+ stage = await enclave.getE3Stage(0);
576
+ expect(stage).to.equal(4); // CiphertextReady
577
+ // 4. Wait past decryption deadline (plaintext never published)
578
+ await time.increase(defaultTimeoutConfig.decryptionWindow + 1);
579
+ // 5. Check failure condition and mark as failed
580
+ const [canFail, reason] = await enclave.checkFailureCondition(0);
581
+ expect(canFail).to.be.true;
582
+ expect(reason).to.equal(10); // DecryptionTimeout
583
+ await enclave.markE3Failed(0);
584
+ stage = await enclave.getE3Stage(0);
585
+ expect(stage).to.equal(6); // Failed
586
+ const failureReason = await enclave.getFailureReason(0);
587
+ expect(failureReason).to.equal(10); // DecryptionTimeout
588
+ // 6. Process failure and claim refund
589
+ await enclave.processE3Failure(0);
590
+ const balanceBefore = await usdcToken.balanceOf(await requester.getAddress());
591
+ await e3RefundManager.connect(requester).claimRequesterRefund(0);
592
+ const balanceAfter = await usdcToken.balanceOf(await requester.getAddress());
593
+ const distribution = await e3RefundManager.getRefundDistribution(0);
594
+ expect(balanceAfter - balanceBefore).to.equal(distribution.requesterAmount);
595
+ expect(distribution.requesterAmount).to.be.gt(0);
596
+ });
597
+ });
598
+ describe("Multiple E3 Requests Isolation", function () {
599
+ it("tracks multiple E3s independently", async function () {
600
+ const { enclave, usdcToken, requester, e3Program, decryptionVerifier, operator1, operator2, setupOperator, } = await loadFixture(setup);
601
+ await setupOperator(operator1);
602
+ await setupOperator(operator2);
603
+ const enclaveAddress = await enclave.getAddress();
604
+ // Helper to make requests
605
+ const makeRequestN = async (n) => {
606
+ const startTime = (await time.latest()) + 100;
607
+ const requestParams = {
608
+ threshold: [2, 2],
609
+ inputWindow: [startTime, startTime + ONE_DAY],
610
+ e3Program: await e3Program.getAddress(),
611
+ e3ProgramParams: encodedE3ProgramParams,
612
+ computeProviderParams: abiCoder.encode(["address"], [await decryptionVerifier.getAddress()]),
613
+ customParams: abiCoder.encode(["address"], ["0x1234567890123456789012345678901234567890"]),
614
+ };
615
+ const fee = await enclave.getE3Quote(requestParams);
616
+ await usdcToken.connect(requester).approve(enclaveAddress, fee);
617
+ await enclave.connect(requester).request(requestParams);
618
+ return n;
619
+ };
620
+ // Make 3 requests
621
+ await makeRequestN(0);
622
+ await makeRequestN(1);
623
+ await makeRequestN(2);
624
+ // Verify all are in Requested stage
625
+ expect(await enclave.getE3Stage(0)).to.equal(1);
626
+ expect(await enclave.getE3Stage(1)).to.equal(1);
627
+ expect(await enclave.getE3Stage(2)).to.equal(1);
628
+ // Fail E3 #0 by waiting past its deadline
629
+ await time.increase(defaultTimeoutConfig.committeeFormationWindow + 1);
630
+ await enclave.markE3Failed(0);
631
+ // E3 #0 is failed, but E3 #1 and #2 are still active
632
+ expect(await enclave.getE3Stage(0)).to.equal(6); // Failed
633
+ expect(await enclave.getE3Stage(1)).to.equal(1); // Still Requested
634
+ expect(await enclave.getE3Stage(2)).to.equal(1); // Still Requested
635
+ // E3 #1 and #2 also can be failed now (their deadlines have also passed)
636
+ const [canFail1] = await enclave.checkFailureCondition(1);
637
+ const [canFail2] = await enclave.checkFailureCondition(2);
638
+ expect(canFail1).to.be.true;
639
+ expect(canFail2).to.be.true;
640
+ // But they haven't auto-failed - must be explicitly marked
641
+ expect(await enclave.getE3Stage(1)).to.equal(1);
642
+ expect(await enclave.getE3Stage(2)).to.equal(1);
643
+ // Now mark E3 #2 as failed (but not #1)
644
+ await enclave.markE3Failed(2);
645
+ expect(await enclave.getE3Stage(2)).to.equal(6); // Now Failed
646
+ expect(await enclave.getE3Stage(1)).to.equal(1); // Still Requested
647
+ // Verify each E3 has independent failure reasons
648
+ expect(await enclave.getFailureReason(0)).to.equal(1); // CommitteeFormationTimeout
649
+ expect(await enclave.getFailureReason(2)).to.equal(1); // CommitteeFormationTimeout
650
+ });
651
+ it("allows claiming refunds for each failed E3 independently", async function () {
652
+ const { enclave, e3RefundManager, usdcToken, requester, e3Program, decryptionVerifier, operator1, operator2, setupOperator, } = await loadFixture(setup);
653
+ await setupOperator(operator1);
654
+ await setupOperator(operator2);
655
+ const enclaveAddress = await enclave.getAddress();
656
+ // Make 2 requests
657
+ for (let i = 0; i < 2; i++) {
658
+ const startTime = (await time.latest()) + 100;
659
+ const requestParams = {
660
+ threshold: [2, 2],
661
+ inputWindow: [startTime, startTime + ONE_DAY],
662
+ e3Program: await e3Program.getAddress(),
663
+ e3ProgramParams: encodedE3ProgramParams,
664
+ computeProviderParams: abiCoder.encode(["address"], [await decryptionVerifier.getAddress()]),
665
+ customParams: abiCoder.encode(["address"], ["0x1234567890123456789012345678901234567890"]),
666
+ };
667
+ const fee = await enclave.getE3Quote(requestParams);
668
+ await usdcToken.connect(requester).approve(enclaveAddress, fee);
669
+ await enclave.connect(requester).request(requestParams);
670
+ }
671
+ // Fail both
672
+ await time.increase(defaultTimeoutConfig.committeeFormationWindow + 1);
673
+ await enclave.markE3Failed(0);
674
+ await enclave.markE3Failed(1);
675
+ // Process both
676
+ await enclave.processE3Failure(0);
677
+ await enclave.processE3Failure(1);
678
+ // Claim both refunds independently
679
+ const balanceBefore = await usdcToken.balanceOf(await requester.getAddress());
680
+ await e3RefundManager.connect(requester).claimRequesterRefund(0);
681
+ const balanceAfterFirst = await usdcToken.balanceOf(await requester.getAddress());
682
+ expect(balanceAfterFirst).to.be.gt(balanceBefore);
683
+ await e3RefundManager.connect(requester).claimRequesterRefund(1);
684
+ const balanceAfterSecond = await usdcToken.balanceOf(await requester.getAddress());
685
+ expect(balanceAfterSecond).to.be.gt(balanceAfterFirst);
686
+ // Verify can't claim twice
687
+ await expect(e3RefundManager.connect(requester).claimRequesterRefund(0)).to.be.revertedWithCustomError(e3RefundManager, "AlreadyClaimed");
688
+ });
689
+ });
690
+ describe("Success Path (Complete E3)", function () {
691
+ it("transitions through all stages to completion", async function () {
692
+ const { enclave, registry, makeRequest, operator1, operator2, setupOperator, } = await loadFixture(setup);
693
+ await setupOperator(operator1);
694
+ await setupOperator(operator2);
695
+ // 1. Make request
696
+ await makeRequest();
697
+ expect(await enclave.getE3Stage(0)).to.equal(1); // Requested
698
+ // 2. Complete sortition and publish committee (CommitteeFinalized -> KeyPublished)
699
+ await registry.connect(operator1).submitTicket(0, 1);
700
+ await registry.connect(operator2).submitTicket(0, 1);
701
+ await time.increase(SORTITION_SUBMISSION_WINDOW + 1);
702
+ await registry.finalizeCommittee(0);
703
+ expect(await enclave.getE3Stage(0)).to.equal(2); // CommitteeFinalized
704
+ const nodes = [
705
+ await operator1.getAddress(),
706
+ await operator2.getAddress(),
707
+ ];
708
+ const publicKey = "0x1234567890abcdef1234567890abcdef";
709
+ const publicKeyHash = ethers.keccak256(publicKey);
710
+ await registry.publishCommittee(0, nodes, publicKey, publicKeyHash);
711
+ expect(await enclave.getE3Stage(0)).to.equal(3); // KeyPublished
712
+ // 3. Publish ciphertext output (after input deadline)
713
+ const e3 = await enclave.getE3(0);
714
+ await time.increaseTo(Number(e3.inputWindow[1]));
715
+ const ciphertextOutput = "0x" + "ab".repeat(100);
716
+ const proof = "0x1337";
717
+ await enclave.publishCiphertextOutput(0, ciphertextOutput, proof);
718
+ expect(await enclave.getE3Stage(0)).to.equal(4); // CiphertextReady
719
+ // 4. Publish plaintext output
720
+ const plaintextOutput = "0x" + "cd".repeat(100);
721
+ await enclave.publishPlaintextOutput(0, plaintextOutput, proof);
722
+ expect(await enclave.getE3Stage(0)).to.equal(5); // Complete
723
+ // Cannot mark completed E3 as failed
724
+ await expect(enclave.markE3Failed(0)).to.be.revertedWithCustomError(enclave, "E3AlreadyComplete");
725
+ });
726
+ it("prevents refund claims for completed E3", async function () {
727
+ const { enclave, e3RefundManager, registry, makeRequest, requester, operator1, operator2, setupOperator, } = await loadFixture(setup);
728
+ await setupOperator(operator1);
729
+ await setupOperator(operator2);
730
+ // Complete full E3 flow
731
+ await makeRequest();
732
+ // Complete sortition
733
+ await registry.connect(operator1).submitTicket(0, 1);
734
+ await registry.connect(operator2).submitTicket(0, 1);
735
+ await time.increase(SORTITION_SUBMISSION_WINDOW + 1);
736
+ await registry.finalizeCommittee(0);
737
+ const nodes = [
738
+ await operator1.getAddress(),
739
+ await operator2.getAddress(),
740
+ ];
741
+ const publicKey = "0x1234567890abcdef1234567890abcdef";
742
+ const publicKeyHash = ethers.keccak256(publicKey);
743
+ await registry.publishCommittee(0, nodes, publicKey, publicKeyHash);
744
+ // Publish outputs
745
+ const e3 = await enclave.getE3(0);
746
+ await time.increaseTo(Number(e3.inputWindow[1]));
747
+ const ciphertextOutput = "0x" + "ab".repeat(100);
748
+ const proof = "0x1337";
749
+ await enclave.publishCiphertextOutput(0, ciphertextOutput, proof);
750
+ const plaintextOutput = "0x" + "cd".repeat(100);
751
+ await enclave.publishPlaintextOutput(0, plaintextOutput, proof);
752
+ // Verify E3 is complete
753
+ expect(await enclave.getE3Stage(0)).to.equal(5); // Complete
754
+ await expect(e3RefundManager.connect(requester).claimRequesterRefund(0)).to.be.revertedWithCustomError(e3RefundManager, "RefundNotCalculated");
755
+ });
756
+ });
757
+ });