hex-audit 0.6.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +137 -77
- package/DEMO.md +41 -105
- package/README.md +205 -353
- package/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/app-build-manifest.json +65 -99
- package/dashboard/.next/app-path-routes-manifest.json +1 -1
- package/dashboard/.next/build-manifest.json +14 -14
- package/dashboard/.next/next-minimal-server.js.nft.json +1 -1
- package/dashboard/.next/next-server.js.nft.json +1 -1
- package/dashboard/.next/prerender-manifest.js +1 -1
- package/dashboard/.next/prerender-manifest.json +1 -1
- package/dashboard/.next/react-loadable-manifest.json +540 -119
- package/dashboard/.next/routes-manifest.json +1 -1
- package/dashboard/.next/server/app/_not-found/page.js +1 -1
- package/dashboard/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/api/code/route.js +1 -1
- package/dashboard/.next/server/app/api/code/route.js.nft.json +1 -1
- package/dashboard/.next/server/app/api/comments/route.js +1 -0
- package/dashboard/.next/server/app/api/comments/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/diagrams/[name]/export/route.js +1 -0
- package/dashboard/.next/server/app/api/diagrams/[name]/export/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/diagrams/[name]/resolve/route.js +1 -0
- package/dashboard/.next/server/app/api/diagrams/[name]/resolve/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/diagrams/[name]/route.js +1 -0
- package/dashboard/.next/server/app/api/diagrams/[name]/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/figures/[name]/route.js +1 -0
- package/dashboard/.next/server/app/api/figures/[name]/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/focus/route.js +1 -0
- package/dashboard/.next/server/app/api/focus/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/github-status/route.js +1 -1
- package/dashboard/.next/server/app/api/invariants/[id]/route.js +1 -0
- package/dashboard/.next/server/app/api/invariants/[id]/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/issues/[id]/revert-auto/route.js +1 -0
- package/dashboard/.next/server/app/api/issues/[id]/revert-auto/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/nav/route.js +1 -0
- package/dashboard/.next/server/app/api/nav/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/notes/done/route.js +1 -1
- package/dashboard/.next/server/app/api/notes/done/route.js.nft.json +1 -1
- package/dashboard/.next/server/app/api/notes/lead/route.js +1 -1
- package/dashboard/.next/server/app/api/notes/lead/route.js.nft.json +1 -1
- package/dashboard/.next/server/app/api/notes/question/route.js +1 -1
- package/dashboard/.next/server/app/api/notes/question/route.js.nft.json +1 -1
- package/dashboard/.next/server/app/api/notes/record/route.js +3 -3
- package/dashboard/.next/server/app/api/notes/route.js +2 -2
- package/dashboard/.next/server/app/api/palette/route.js +1 -0
- package/dashboard/.next/server/app/api/palette/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/progress/route.js +1 -1
- package/dashboard/.next/server/app/api/progress/route.js.nft.json +1 -1
- package/dashboard/.next/server/app/api/watch/route.js +2 -2
- package/dashboard/.next/server/app/api/watch/route.js.nft.json +1 -1
- package/dashboard/.next/server/app/api/xref/route.js +1 -0
- package/dashboard/.next/server/app/changes/page.js +1 -0
- package/dashboard/.next/server/app/{access → changes}/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/changes/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/excalidraw-assets/[...path]/route.js +1 -0
- package/dashboard/.next/server/app/issues/page.js +5 -28
- package/dashboard/.next/server/app/issues/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/issues/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/model/page.js +1 -0
- package/dashboard/.next/server/app/{calls → model}/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/model/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/page.js +1 -20
- package/dashboard/.next/server/app/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/report/page.js +1 -1
- package/dashboard/.next/server/app/report/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/report/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/review/page.js +1 -0
- package/dashboard/.next/server/app/{conformance → review}/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/review/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app-paths-manifest.json +20 -16
- package/dashboard/.next/server/chunks/310.js +4 -0
- package/dashboard/.next/server/chunks/370.js +1 -0
- package/dashboard/.next/server/chunks/42.js +1 -1
- package/dashboard/.next/server/chunks/624.js +14 -0
- package/dashboard/.next/server/chunks/645.js +1 -1
- package/dashboard/.next/server/chunks/649.js +1 -1
- package/dashboard/.next/server/chunks/653.js +1 -0
- package/dashboard/.next/server/functions-config-manifest.json +1 -1
- package/dashboard/.next/server/middleware-build-manifest.js +1 -1
- package/dashboard/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dashboard/.next/server/next-font-manifest.js +1 -1
- package/dashboard/.next/server/next-font-manifest.json +1 -1
- package/dashboard/.next/server/pages/500.html +1 -1
- package/dashboard/.next/server/pages/_error.js +1 -1
- package/dashboard/.next/server/pages-manifest.json +1 -1
- package/dashboard/.next/server/server-reference-manifest.js +1 -1
- package/dashboard/.next/server/server-reference-manifest.json +1 -1
- package/dashboard/.next/static/bGV1ry1vvIbM5b506eVBR/_buildManifest.js +1 -0
- package/dashboard/.next/static/chunks/0bbe10ee.8e7ffa06d2170dfe.js +84 -0
- package/dashboard/.next/static/chunks/{1.8868c4d131111be7.js → 1.a666047ea18866fb.js} +2 -2
- package/dashboard/.next/static/chunks/1015.39008440ab15e196.js +226 -0
- package/dashboard/.next/static/chunks/1026.0ef689a305302427.js +1 -0
- package/dashboard/.next/static/chunks/1151.497fa63c5b9eba52.js +1 -0
- package/dashboard/.next/static/chunks/1164.34eb76767ebea46f.js +8 -0
- package/dashboard/.next/static/chunks/119.a9a79633900a235f.js +5 -0
- package/dashboard/.next/static/chunks/1199.f30cbfa151e56076.js +148 -0
- package/dashboard/.next/static/chunks/1291.6c486c9b1d4b1b3a.js +1 -0
- package/dashboard/.next/static/chunks/1375.64c20f1064a38a10.js +43 -0
- package/dashboard/.next/static/chunks/139.4691848fc5a46253.js +10 -0
- package/dashboard/.next/static/chunks/145.1bf74fecdb4022e3.js +11 -0
- package/dashboard/.next/static/chunks/1517.8e7075f78e22b3a0.js +8 -0
- package/dashboard/.next/static/chunks/165.6f174060a0ce2db4.js +6 -0
- package/dashboard/.next/static/chunks/1741.5c370b7702d2eb40.js +8 -0
- package/dashboard/.next/static/chunks/1799.8dc56017eede704e.js +9 -0
- package/dashboard/.next/static/chunks/1e36816c.5748c83adc8a6bd6.js +108 -0
- package/dashboard/.next/static/chunks/20154aaa.e87f69fe10483f8b.js +1 -0
- package/dashboard/.next/static/chunks/2061.eab75b3c1dfa068a.js +1 -0
- package/dashboard/.next/static/chunks/2077.5603adeb156c7d10.js +1 -0
- package/dashboard/.next/static/chunks/2148.3ce718f62d1b2f7c.js +10 -0
- package/dashboard/.next/static/chunks/2166.9f6592b9399eadd8.js +215 -0
- package/dashboard/.next/static/chunks/217-1d5b680ffd10e3f9.js +1 -0
- package/dashboard/.next/static/chunks/2208.fb884379aa3ae968.js +1 -0
- package/dashboard/.next/static/chunks/2276.112c7855333fca5f.js +6 -0
- package/dashboard/.next/static/chunks/{2291.85a70cb0c228157b.js → 2291.584b42ccad079b99.js} +1 -1
- package/dashboard/.next/static/chunks/2325.7decd077edfb81d9.js +24 -0
- package/dashboard/.next/static/chunks/2374-8c6f137938f8518a.js +1 -0
- package/dashboard/.next/static/chunks/{2383.62c035a052272594.js → 2383.ca81f980ce6528a4.js} +1 -1
- package/dashboard/.next/static/chunks/2445.18a86507d2996b95.js +1 -0
- package/dashboard/.next/static/chunks/2694.7dfa5fef28851903.js +1 -0
- package/dashboard/.next/static/chunks/2712.15dd8577973baf22.js +10 -0
- package/dashboard/.next/static/chunks/275.38af87389c1d33d7.js +34 -0
- package/dashboard/.next/static/chunks/2759.533dec5317e0a1d1.js +1 -0
- package/dashboard/.next/static/chunks/2781.fba46046dbf2693b.js +93 -0
- package/dashboard/.next/static/chunks/2805.35b4cd8a94978aaf.js +1 -0
- package/dashboard/.next/static/chunks/2812.62b213bef580b69a.js +1 -0
- package/dashboard/.next/static/chunks/{2879.51436986f93981d9.js → 2879.74d65e33e60505ee.js} +1 -1
- package/dashboard/.next/static/chunks/2895.bb57cacb7aaf42a1.js +9 -0
- package/dashboard/.next/static/chunks/2972.e5a9251b538dcf19.js +9 -0
- package/dashboard/.next/static/chunks/3205-fd963acf2fdfd080.js +2 -0
- package/dashboard/.next/static/chunks/3206.8d9a10db2b04b93f.js +1 -0
- package/dashboard/.next/static/chunks/3236.eac9855778a54518.js +1 -0
- package/dashboard/.next/static/chunks/3480.853a445a3784642a.js +1 -0
- package/dashboard/.next/static/chunks/3485.36766504793b7237.js +9 -0
- package/dashboard/.next/static/chunks/3626.c5dacee11c8fbc4d.js +64 -0
- package/dashboard/.next/static/chunks/3725.de9376dc994735d4.js +9 -0
- package/dashboard/.next/static/chunks/3774.1df377928e8387f7.js +9 -0
- package/dashboard/.next/static/chunks/3865.5e6d2d501380e03b.js +90 -0
- package/dashboard/.next/static/chunks/3887.073cece834a4eae2.js +1 -0
- package/dashboard/.next/static/chunks/3924-f1f85ccc7d59d7ab.js +1 -0
- package/dashboard/.next/static/chunks/3948.74201b9f0672234d.js +287 -0
- package/dashboard/.next/static/chunks/3963.39d72b3875dfe2e9.js +13 -0
- package/dashboard/.next/static/chunks/4013.73884b23bfaebdde.js +11 -0
- package/dashboard/.next/static/chunks/4117.278aff1fa23fd36e.js +6 -0
- package/dashboard/.next/static/chunks/4210.cc8594110017c579.js +11 -0
- package/dashboard/.next/static/chunks/4282.28485875540886cc.js +7 -0
- package/dashboard/.next/static/chunks/4318.a2f469a88d88f6d0.js +8 -0
- package/dashboard/.next/static/chunks/4363.8999a6e727c48003.js +1 -0
- package/dashboard/.next/static/chunks/4641.e03d118fffebd580.js +5 -0
- package/dashboard/.next/static/chunks/4728.e69372b5e5b61b8d.js +24 -0
- package/dashboard/.next/static/chunks/4787.821a6ad2816cdc60.js +23 -0
- package/dashboard/.next/static/chunks/483.a910dab7734a1074.js +8 -0
- package/dashboard/.next/static/chunks/4926.76693f542e9cc062.js +6 -0
- package/dashboard/.next/static/chunks/4938.03f6d04dabf38745.js +10 -0
- package/dashboard/.next/static/chunks/5060.47402abc10273699.js +1 -0
- package/dashboard/.next/static/chunks/5112.0757c2b0c285e62e.js +1 -0
- package/dashboard/.next/static/chunks/5199.c83ea7efb0eec705.js +11 -0
- package/dashboard/.next/static/chunks/5284.334c7c0587d5d47a.js +1 -0
- package/dashboard/.next/static/chunks/530.849957a8907eb288.js +1 -0
- package/dashboard/.next/static/chunks/5424.4e8ca0711a32bccf.js +7 -0
- package/dashboard/.next/static/chunks/55.a593a78be9714679.js +1 -0
- package/dashboard/.next/static/chunks/5535.6cd0bd8d368d8902.js +4 -0
- package/dashboard/.next/static/chunks/5626.7d4e93d7acbeffc9.js +10 -0
- package/dashboard/.next/static/chunks/5715.e16b1230cc4b4652.js +115 -0
- package/dashboard/.next/static/chunks/5775.a0d7c1b1e89b9a93.js +9 -0
- package/dashboard/.next/static/chunks/6014.641a2c53ba506241.js +104 -0
- package/dashboard/.next/static/chunks/6024.f099c15f75aa6722.js +79 -0
- package/dashboard/.next/static/chunks/{6052.033a6f1013c666eb.js → 6052.3001318955e5b36c.js} +2 -2
- package/dashboard/.next/static/chunks/6118.266956b3333b1d7a.js +9 -0
- package/dashboard/.next/static/chunks/6121.a2e6d93720b1205e.js +77 -0
- package/dashboard/.next/static/chunks/6177.a01cf0a03734cf09.js +1 -0
- package/dashboard/.next/static/chunks/618f8807-fbb1466bc29c17c6.js +1 -0
- package/dashboard/.next/static/chunks/6434.f560693253fea8de.js +1 -0
- package/dashboard/.next/static/chunks/6468.976d89ba133185f1.js +77 -0
- package/dashboard/.next/static/chunks/6540.6f3c4f2c6877ed89.js +1 -0
- package/dashboard/.next/static/chunks/6549.e3c4c1766cff1449.js +1 -0
- package/dashboard/.next/static/chunks/6853.d3ad43614e8ca0ab.js +1 -0
- package/dashboard/.next/static/chunks/690f35d0.ab57e02a04c7e9e0.js +119 -0
- package/dashboard/.next/static/chunks/6951.02a3a158d02158c9.js +5 -0
- package/dashboard/.next/static/chunks/6970.013f24568c87d918.js +11 -0
- package/dashboard/.next/static/chunks/7013.39d41e82b37be63b.js +9 -0
- package/dashboard/.next/static/chunks/{7020.831e16e26d91abc1.js → 7020.b718b1b9cea36e60.js} +2 -2
- package/dashboard/.next/static/chunks/7107.1c5412197912b8ed.js +8 -0
- package/dashboard/.next/static/chunks/7498-7cf464d8af69cd0a.js +1 -0
- package/dashboard/.next/static/chunks/7508.dd60e2d06d149f5f.js +9 -0
- package/dashboard/.next/static/chunks/7524.0fde4c61553d1491.js +3 -0
- package/dashboard/.next/static/chunks/7802.f0134c792fccd382.js +80 -0
- package/dashboard/.next/static/chunks/7834-47f318a04a05688f.js +1 -0
- package/dashboard/.next/static/chunks/{7a04ac15.1c6cea694301806c.js → 7a04ac15.e49de94ece135900.js} +1 -1
- package/dashboard/.next/static/chunks/8216.1138ec313908a708.js +5 -0
- package/dashboard/.next/static/chunks/{8233babc.780b8e272eda298f.js → 8233babc.09872dcb3ff44064.js} +1 -1
- package/dashboard/.next/static/chunks/8317.d0b3eddef4cae0d5.js +1 -0
- package/dashboard/.next/static/chunks/838.2b2aa006519ba44c.js +10 -0
- package/dashboard/.next/static/chunks/8398.924fd8f4c83417c0.js +7 -0
- package/dashboard/.next/static/chunks/8428b36f.8ac4e67061c01307.js +34 -0
- package/dashboard/.next/static/chunks/8514.85ccbbea8ab21d04.js +5 -0
- package/dashboard/.next/static/chunks/8538.5f7ebe76c4b63162.js +1 -0
- package/dashboard/.next/static/chunks/8645.98a43217d406500e.js +1 -0
- package/dashboard/.next/static/chunks/8687.9406baa8b5601fd0.js +1 -0
- package/dashboard/.next/static/chunks/8721.47346e2cb6412376.js +10 -0
- package/dashboard/.next/static/chunks/8770.4f544bd1a6f03a62.js +8 -0
- package/dashboard/.next/static/chunks/8812.3d96fd54dba566f8.js +9 -0
- package/dashboard/.next/static/chunks/8962.d22aa67a97970dd8.js +1 -0
- package/dashboard/.next/static/chunks/8986.b327224b83f4399a.js +5 -0
- package/dashboard/.next/static/chunks/9173.a7160f7d0b685fa7.js +1 -0
- package/dashboard/.next/static/chunks/9178.998a8c49996de8e4.js +1 -0
- package/dashboard/.next/static/chunks/9271.5f66c19a8ee1ff36.js +10 -0
- package/dashboard/.next/static/chunks/9282.f8d01442bab4c0da.js +2 -0
- package/dashboard/.next/static/chunks/9366.0ec24a0791b9b00f.js +1 -0
- package/dashboard/.next/static/chunks/9466.a914ce0de7d3bb84.js +1 -0
- package/dashboard/.next/static/chunks/9660.b1c8deae2c449d14.js +1 -0
- package/dashboard/.next/static/chunks/9707.5cd7d2ee933a4af5.js +6 -0
- package/dashboard/.next/static/chunks/9716.15fffc0b0038601d.js +4 -0
- package/dashboard/.next/static/chunks/{9717.6cf5c8c89403b651.js → 9717.bba51b78ebd8fd29.js} +1 -1
- package/dashboard/.next/static/chunks/9720.d63a0696776bcc60.js +1 -0
- package/dashboard/.next/static/chunks/9791.e3b3f5a367f63c8a.js +1 -0
- package/dashboard/.next/static/chunks/9811.2993c4cbd28e8d1b.js +1 -0
- package/dashboard/.next/static/chunks/9820.8c1efad5260e8137.js +1 -0
- package/dashboard/.next/static/chunks/985.50150e9eaa4bde33.js +39 -0
- package/dashboard/.next/static/chunks/997.56901b86e1b8a87b.js +8 -0
- package/dashboard/.next/static/chunks/app/_not-found/page-5ff5d54b6fd6f17e.js +1 -0
- package/dashboard/.next/static/chunks/app/changes/page-f8a860034221cad4.js +1 -0
- package/dashboard/.next/static/chunks/app/issues/page-da4da93188c414a6.js +1 -0
- package/dashboard/.next/static/chunks/app/layout-27a9da4610423c1e.js +1 -0
- package/dashboard/.next/static/chunks/app/model/page-9680e22fdd6ddb81.js +1 -0
- package/dashboard/.next/static/chunks/app/page-0e67750d99fb2836.js +1 -0
- package/dashboard/.next/static/chunks/app/report/page-b56b1db9b9dcf2b6.js +1 -0
- package/dashboard/.next/static/chunks/app/review/page-3ef69f0e0badd333.js +1 -0
- package/dashboard/.next/static/chunks/{b7167ec1.7afbab6f609e3326.js → b7167ec1.708a3d61698ca2e6.js} +1 -1
- package/dashboard/.next/static/chunks/c75e29e3.d91220f782934d80.js +1 -0
- package/dashboard/.next/static/chunks/c7ea4e13.3073a2f551aa5ac8.js +1 -0
- package/dashboard/.next/static/chunks/framework-a117d81bf1b91f9a.js +33 -0
- package/dashboard/.next/static/chunks/main-9c95a7ffedc7afb4.js +1 -0
- package/dashboard/.next/static/chunks/main-app-5662c64b50ba40d1.js +1 -0
- package/dashboard/.next/static/chunks/pages/_app-308fef0bf9b328f2.js +1 -0
- package/dashboard/.next/static/chunks/pages/_error-c91b5eabd7ac9382.js +1 -0
- package/dashboard/.next/static/chunks/webpack-6da70e4f9fcf1799.js +1 -0
- package/dashboard/.next/static/css/ceafd91ca8dd753d.css +3 -0
- package/dashboard/.next/static/css/e4aad1f9c715b79a.css +1 -0
- package/dashboard/.next/static/media/39f449c8730c2295-s.woff2 +0 -0
- package/dashboard/.next/static/media/86f65e8637cc94e3-s.woff2 +0 -0
- package/dashboard/.next/static/media/8760c4774489e4ba-s.p.woff2 +0 -0
- package/dashboard/.next/static/media/9fabb9c65b63d798-s.woff2 +0 -0
- package/dashboard/.next/static/media/Assistant-Bold.c8f39f24.woff2 +0 -0
- package/dashboard/.next/static/media/Assistant-Medium.1e75d8e6.woff2 +0 -0
- package/dashboard/.next/static/media/Assistant-Regular.7acbabb8.woff2 +0 -0
- package/dashboard/.next/static/media/Assistant-SemiBold.167acbf8.woff2 +0 -0
- package/dashboard/.next/static/media/a1f87af3f44fadbb-s.woff2 +0 -0
- package/dashboard/.next/static/media/f9e1dbe9676d9bb6-s.woff2 +0 -0
- package/dashboard/app/api/code/route.ts +26 -20
- package/dashboard/app/api/comments/route.ts +158 -0
- package/dashboard/app/api/diagrams/[name]/export/route.ts +26 -0
- package/dashboard/app/api/diagrams/[name]/resolve/route.ts +25 -0
- package/dashboard/app/api/diagrams/[name]/route.ts +37 -0
- package/dashboard/app/api/figures/[name]/route.ts +15 -0
- package/dashboard/app/api/focus/route.ts +35 -0
- package/dashboard/app/api/invariants/[id]/route.ts +35 -0
- package/dashboard/app/api/issues/[id]/revert-auto/route.ts +18 -0
- package/dashboard/app/api/nav/route.ts +120 -0
- package/dashboard/app/api/palette/route.ts +68 -0
- package/dashboard/app/api/progress/route.ts +54 -23
- package/dashboard/app/api/xref/route.ts +30 -0
- package/dashboard/app/changes/ChangesClient.tsx +838 -0
- package/dashboard/app/changes/page.tsx +44 -0
- package/dashboard/app/excalidraw-assets/[...path]/route.ts +56 -0
- package/dashboard/app/globals.css +231 -77
- package/dashboard/app/issues/BoardClient.tsx +817 -0
- package/dashboard/app/issues/page.tsx +27 -272
- package/dashboard/app/layout.tsx +37 -10
- package/dashboard/app/model/ModelClient.tsx +1303 -0
- package/dashboard/app/model/page.tsx +98 -0
- package/dashboard/app/page.tsx +195 -239
- package/dashboard/app/report/ReportClient.tsx +147 -74
- package/dashboard/app/report/page.tsx +25 -14
- package/dashboard/app/review/ReviewClient.tsx +1180 -0
- package/dashboard/app/review/page.tsx +93 -0
- package/dashboard/components/AutoRefresh.tsx +22 -19
- package/dashboard/components/CodeComments.tsx +303 -0
- package/dashboard/components/CodeNav.tsx +523 -0
- package/dashboard/components/CodeReference.tsx +92 -99
- package/dashboard/components/CodeViewer.tsx +526 -0
- package/dashboard/components/CommandPalette.tsx +141 -66
- package/dashboard/components/DiagramCanvas.tsx +275 -0
- package/dashboard/components/DianeNote.tsx +244 -0
- package/dashboard/components/LiveStatus.tsx +30 -68
- package/dashboard/components/MarkdownRenderer.tsx +34 -32
- package/dashboard/components/RecordButton.tsx +132 -0
- package/dashboard/components/ui/Button.tsx +39 -0
- package/dashboard/components/ui/Chip.tsx +37 -0
- package/dashboard/components/ui/EmptyState.tsx +31 -0
- package/dashboard/components/ui/Icons.tsx +126 -0
- package/dashboard/components/ui/Inspector.tsx +122 -0
- package/dashboard/components/ui/Kbd.tsx +15 -0
- package/dashboard/components/ui/ListRow.tsx +92 -0
- package/dashboard/components/ui/LocalTime.tsx +14 -0
- package/dashboard/components/ui/ProgressRing.tsx +54 -0
- package/dashboard/components/ui/ResizeHandle.tsx +93 -0
- package/dashboard/components/ui/RiskMeter.tsx +27 -0
- package/dashboard/components/ui/SearchField.tsx +55 -0
- package/dashboard/components/ui/SegmentedControl.tsx +71 -0
- package/dashboard/components/ui/SeverityDot.tsx +57 -0
- package/dashboard/components/ui/Sidebar.tsx +236 -0
- package/dashboard/components/ui/SplitView.tsx +122 -0
- package/dashboard/components/ui/StateGlyph.tsx +66 -0
- package/dashboard/components/ui/Toast.tsx +91 -0
- package/dashboard/lib/api.ts +17 -0
- package/dashboard/lib/cn.ts +4 -0
- package/dashboard/lib/data.ts +2 -21
- package/dashboard/lib/finding-markdown.ts +1 -1
- package/dashboard/lib/focus.ts +42 -0
- package/dashboard/lib/hotkeys.ts +41 -0
- package/dashboard/lib/inline-markdown.test.ts +11 -0
- package/dashboard/lib/live.ts +32 -0
- package/dashboard/lib/pane-width.ts +36 -0
- package/dashboard/lib/server/board.ts +229 -0
- package/dashboard/lib/server/diagrams.ts +191 -0
- package/dashboard/lib/server/safe-path.ts +28 -0
- package/dashboard/lib/server/workspace.ts +113 -0
- package/dashboard/lib/server/xref.ts +42 -0
- package/dashboard/lib/solidity.test.ts +37 -0
- package/dashboard/lib/solidity.ts +191 -0
- package/dashboard/lib/source.ts +28 -0
- package/dashboard/lib/types.ts +164 -0
- package/dashboard/lib/url.ts +18 -0
- package/dashboard/lib/watcher.ts +31 -22
- package/dashboard/tailwind.config.ts +6 -3
- package/dist/analysis/code-model.d.ts +113 -0
- package/dist/analysis/code-model.d.ts.map +1 -0
- package/dist/analysis/code-model.js +532 -0
- package/dist/analysis/code-model.js.map +1 -0
- package/dist/analysis/diff.d.ts +75 -0
- package/dist/analysis/diff.d.ts.map +1 -0
- package/dist/analysis/diff.js +787 -0
- package/dist/analysis/diff.js.map +1 -0
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +25 -40
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/claude.d.ts.map +1 -1
- package/dist/commands/claude.js +5 -0
- package/dist/commands/claude.js.map +1 -1
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +10 -2
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/diagram.d.ts +3 -0
- package/dist/commands/diagram.d.ts.map +1 -0
- package/dist/commands/diagram.js +71 -0
- package/dist/commands/diagram.js.map +1 -0
- package/dist/commands/diff.d.ts +25 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +257 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +5 -18
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/facts.d.ts +23 -0
- package/dist/commands/facts.d.ts.map +1 -0
- package/dist/commands/facts.js +121 -0
- package/dist/commands/facts.js.map +1 -0
- package/dist/commands/fix-review.d.ts +9 -0
- package/dist/commands/fix-review.d.ts.map +1 -0
- package/dist/commands/fix-review.js +367 -0
- package/dist/commands/fix-review.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +106 -42
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/issue.d.ts.map +1 -1
- package/dist/commands/issue.js +154 -5
- package/dist/commands/issue.js.map +1 -1
- package/dist/commands/mcp.d.ts +3 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +11 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/model.d.ts +4 -0
- package/dist/commands/model.d.ts.map +1 -0
- package/dist/commands/model.js +275 -0
- package/dist/commands/model.js.map +1 -0
- package/dist/commands/note.d.ts.map +1 -1
- package/dist/commands/note.js +61 -3
- package/dist/commands/note.js.map +1 -1
- package/dist/commands/review.d.ts +4 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +164 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/core/comments.d.ts +59 -0
- package/dist/core/comments.d.ts.map +1 -0
- package/dist/core/comments.js +263 -0
- package/dist/core/comments.js.map +1 -0
- package/dist/core/config.d.ts +9 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +18 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/dedup.d.ts +56 -0
- package/dist/core/dedup.d.ts.map +1 -0
- package/dist/core/dedup.js +208 -0
- package/dist/core/dedup.js.map +1 -0
- package/dist/core/errors.d.ts +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +16 -15
- package/dist/core/errors.js.map +1 -1
- package/dist/core/external-tools.d.ts +0 -14
- package/dist/core/external-tools.d.ts.map +1 -1
- package/dist/core/external-tools.js +2 -52
- package/dist/core/external-tools.js.map +1 -1
- package/dist/core/fix-review.d.ts +54 -0
- package/dist/core/fix-review.d.ts.map +1 -0
- package/dist/core/fix-review.js +98 -0
- package/dist/core/fix-review.js.map +1 -0
- package/dist/core/fuzz-sync.d.ts +93 -0
- package/dist/core/fuzz-sync.d.ts.map +1 -0
- package/dist/core/fuzz-sync.js +516 -0
- package/dist/core/fuzz-sync.js.map +1 -0
- package/dist/core/git.d.ts +31 -0
- package/dist/core/git.d.ts.map +1 -0
- package/dist/core/git.js +157 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/issues.d.ts +35 -2
- package/dist/core/issues.d.ts.map +1 -1
- package/dist/core/issues.js +201 -30
- package/dist/core/issues.js.map +1 -1
- package/dist/core/mcp-config.d.ts +12 -0
- package/dist/core/mcp-config.d.ts.map +1 -0
- package/dist/core/mcp-config.js +29 -0
- package/dist/core/mcp-config.js.map +1 -0
- package/dist/core/model.d.ts +38 -0
- package/dist/core/model.d.ts.map +1 -0
- package/dist/core/model.js +160 -0
- package/dist/core/model.js.map +1 -0
- package/dist/core/notes.d.ts +27 -1
- package/dist/core/notes.d.ts.map +1 -1
- package/dist/core/notes.js +47 -5
- package/dist/core/notes.js.map +1 -1
- package/dist/core/review.d.ts +47 -0
- package/dist/core/review.d.ts.map +1 -1
- package/dist/core/review.js +177 -1
- package/dist/core/review.js.map +1 -1
- package/dist/core/rules.d.ts +12 -0
- package/dist/core/rules.d.ts.map +1 -0
- package/dist/core/rules.js +66 -0
- package/dist/core/rules.js.map +1 -0
- package/dist/core/schema.d.ts +5458 -2189
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +605 -114
- package/dist/core/schema.js.map +1 -1
- package/dist/core/scope.d.ts +8 -0
- package/dist/core/scope.d.ts.map +1 -0
- package/dist/core/scope.js +18 -0
- package/dist/core/scope.js.map +1 -0
- package/dist/core/skills.d.ts +10 -4
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +100 -37
- package/dist/core/skills.js.map +1 -1
- package/dist/diagrams/build.d.ts +18 -0
- package/dist/diagrams/build.d.ts.map +1 -0
- package/dist/diagrams/build.js +135 -0
- package/dist/diagrams/build.js.map +1 -0
- package/dist/diagrams/excalidraw.d.ts +27 -0
- package/dist/diagrams/excalidraw.d.ts.map +1 -0
- package/dist/diagrams/excalidraw.js +219 -0
- package/dist/diagrams/excalidraw.js.map +1 -0
- package/dist/diagrams/layout.d.ts +48 -0
- package/dist/diagrams/layout.d.ts.map +1 -0
- package/dist/diagrams/layout.js +686 -0
- package/dist/diagrams/layout.js.map +1 -0
- package/dist/facts/build.d.ts +23 -0
- package/dist/facts/build.d.ts.map +1 -0
- package/dist/facts/build.js +112 -0
- package/dist/facts/build.js.map +1 -0
- package/dist/facts/extract.d.ts +53 -0
- package/dist/facts/extract.d.ts.map +1 -0
- package/dist/facts/extract.js +635 -0
- package/dist/facts/extract.js.map +1 -0
- package/dist/facts/fallback.d.ts +7 -0
- package/dist/facts/fallback.d.ts.map +1 -0
- package/dist/facts/fallback.js +156 -0
- package/dist/facts/fallback.js.map +1 -0
- package/dist/facts/implementations.d.ts +29 -0
- package/dist/facts/implementations.d.ts.map +1 -0
- package/dist/facts/implementations.js +43 -0
- package/dist/facts/implementations.js.map +1 -0
- package/dist/facts/query.d.ts +35 -0
- package/dist/facts/query.d.ts.map +1 -0
- package/dist/facts/query.js +157 -0
- package/dist/facts/query.js.map +1 -0
- package/dist/facts/xref.d.ts +53 -0
- package/dist/facts/xref.d.ts.map +1 -0
- package/dist/facts/xref.js +282 -0
- package/dist/facts/xref.js.map +1 -0
- package/dist/index.js +16 -16
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +400 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/skills/ai-audit/LICENSE +21 -0
- package/dist/skills/ai-audit/SKILL.md +486 -0
- package/dist/skills/ai-audit/UPSTREAM.md +51 -0
- package/dist/skills/ai-audit/references/agent-prompts.md +133 -0
- package/dist/skills/ai-audit/references/assemble.sh +357 -0
- package/dist/skills/ai-audit/references/dedup-and-assembly.md +420 -0
- package/dist/skills/ai-audit/references/hacking-agents/access-control-agent.md +27 -0
- package/dist/skills/ai-audit/references/hacking-agents/asymmetry-agent.md +77 -0
- package/dist/skills/ai-audit/references/hacking-agents/boundary-agent.md +79 -0
- package/dist/skills/ai-audit/references/hacking-agents/economic-security-agent.md +35 -0
- package/dist/skills/ai-audit/references/hacking-agents/execution-trace-agent.md +33 -0
- package/dist/skills/ai-audit/references/hacking-agents/first-principles-agent.md +36 -0
- package/dist/skills/ai-audit/references/hacking-agents/flow-gap-agent.md +49 -0
- package/dist/skills/ai-audit/references/hacking-agents/invariant-agent.md +44 -0
- package/dist/skills/ai-audit/references/hacking-agents/math-precision-agent.md +48 -0
- package/dist/skills/ai-audit/references/hacking-agents/numerical-gap-agent.md +46 -0
- package/dist/skills/ai-audit/references/hacking-agents/periphery-agent.md +27 -0
- package/dist/skills/ai-audit/references/hacking-agents/shared-rules.md +61 -0
- package/dist/skills/ai-audit/references/hacking-agents/trust-gap-agent.md +40 -0
- package/dist/skills/ai-audit/references/hex-board.md +211 -0
- package/dist/skills/ai-audit/references/hex-export.sh +71 -0
- package/dist/skills/ai-audit/references/judging.md +75 -0
- package/dist/skills/ai-audit/references/report-formatting.md +385 -0
- package/dist/skills/ai-audit/references/report-language.md +151 -0
- package/dist/skills/ai-audit/references/senior-auditor-sop.md +63 -0
- package/dist/skills/diane.md +26 -12
- package/dist/skills/fix-review.md +58 -0
- package/dist/skills/fuzz/LICENSE +21 -0
- package/dist/skills/fuzz/SKILL.md +655 -0
- package/dist/skills/fuzz/UPSTREAM.md +119 -0
- package/dist/skills/fuzz/agents/implementers/global-property-implementer.md +81 -0
- package/dist/skills/fuzz/agents/implementers/specific-property-implementer.md +121 -0
- package/dist/skills/fuzz/agents/invariant-discovery/adversarial-profit-maximizer.md +123 -0
- package/dist/skills/fuzz/agents/invariant-discovery/conservation-auditor.md +92 -0
- package/dist/skills/fuzz/agents/invariant-discovery/protocol-type-specialist.md +173 -0
- package/dist/skills/fuzz/agents/invariant-discovery/roundtrip-rounding-analyst.md +164 -0
- package/dist/skills/fuzz/agents/invariant-discovery/state-transition-mapper.md +92 -0
- package/dist/skills/fuzz/agents/invariant-discovery/synthesizer.md +261 -0
- package/dist/skills/fuzz/agents/protocol-analyzer.md +80 -0
- package/dist/skills/fuzz/agents/report-writer.md +135 -0
- package/dist/skills/fuzz/references/handler-patterns.md +222 -0
- package/dist/skills/fuzz/references/hex-invariants.md +102 -0
- package/dist/skills/fuzz/references/property-generation.md +149 -0
- package/dist/skills/fuzz/references/selection-policy.md +49 -0
- package/dist/skills/fuzz/references/setup-playbook.md +92 -0
- package/dist/skills/fuzz/references/template-map.md +121 -0
- package/dist/skills/fuzz/scripts/ensure_foundry.sh +125 -0
- package/dist/skills/fuzz/scripts/estimate_cost.js +157 -0
- package/dist/skills/fuzz/scripts/extract_abis.js +303 -0
- package/dist/skills/fuzz/scripts/fizz_sync.js +692 -0
- package/dist/skills/fuzz/scripts/generate_handlers.js +370 -0
- package/dist/skills/fuzz/scripts/generate_suite.js +254 -0
- package/dist/skills/fuzz/scripts/lib/log-viewer.js +332 -0
- package/dist/skills/fuzz/scripts/run_echidna.js +192 -0
- package/dist/skills/fuzz/scripts/run_medusa.js +329 -0
- package/dist/skills/fuzz/scripts/select_functions.js +637 -0
- package/dist/skills/fuzz/scripts/setup_fuzz_profile.sh +142 -0
- package/dist/skills/fuzz/templates/Actor.sol +63 -0
- package/dist/skills/fuzz/templates/Base.sol +121 -0
- package/dist/skills/fuzz/templates/FoundryTester.sol +29 -0
- package/dist/skills/fuzz/templates/FuzzTester.sol +11 -0
- package/dist/skills/fuzz/templates/Properties.sol +17 -0
- package/dist/skills/fuzz/templates/README.md +56 -0
- package/dist/skills/fuzz/templates/Snapshots.sol +26 -0
- package/dist/skills/fuzz/templates/echidna.yaml +18 -0
- package/dist/skills/fuzz/templates/handlers/Handlers.sol +13 -0
- package/dist/skills/fuzz/templates/medusa.json +93 -0
- package/dist/skills/fuzz/templates/utils/Clamp.sol +223 -0
- package/dist/skills/fuzz/templates/utils/DecimalPrinter.sol +63 -0
- package/dist/skills/fuzz/templates/utils/Deployer.sol +17 -0
- package/dist/skills/fuzz/templates/utils/EnumerableSet.sol +206 -0
- package/dist/skills/fuzz/templates/utils/Hevm.sol +62 -0
- package/dist/skills/fuzz/templates/utils/Logger.sol +619 -0
- package/dist/skills/fuzz/templates/utils/Math.sol +52 -0
- package/dist/skills/fuzz/templates/utils/MockERC20.sol +279 -0
- package/dist/skills/fuzz/templates/utils/PropertiesAsserts.sol +238 -0
- package/dist/skills/fuzz/templates/utils/StringUtils.sol +85 -0
- package/dist/skills/fuzz-convert/SKILL.md +249 -0
- package/dist/skills/fuzz-sync/SKILL.md +342 -0
- package/dist/skills/generate-poc.md +8 -26
- package/dist/skills/generate-report.md +24 -8
- package/dist/skills/ingest-aa-report.md +11 -30
- package/dist/skills/init-audit/SKILL.md +155 -0
- package/dist/skills/init-audit/references/agents/conformance-checker.md +36 -0
- package/dist/skills/init-audit/references/agents/contract-reader.md +59 -0
- package/dist/skills/init-audit/references/agents/diagram-composer.md +48 -0
- package/dist/skills/init-audit/references/agents/docs-extractor.md +26 -0
- package/dist/skills/init-audit/references/agents/prior-audit.md +32 -0
- package/dist/skills/init-audit/references/agents/regression-checker.md +28 -0
- package/dist/skills/init-audit/references/agents/skeptic.md +31 -0
- package/dist/skills/init-audit/references/agents/standards-checker.md +39 -0
- package/dist/skills/init-audit/references/agents/synthesizer.md +50 -0
- package/dist/skills/prevalidate.md +62 -0
- package/dist/skills/sync-issues.md +11 -25
- package/dist/skills/validate-all-findings.md +3 -3
- package/dist/skills/validate-finding.md +33 -28
- package/dist/skills/write-finding.md +6 -5
- package/dist/types/index.d.ts +22 -12
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +6 -4
- package/dashboard/.next/server/app/_not-found.html +0 -1
- package/dashboard/.next/server/app/_not-found.meta +0 -6
- package/dashboard/.next/server/app/_not-found.rsc +0 -12
- package/dashboard/.next/server/app/access/page.js +0 -1
- package/dashboard/.next/server/app/access/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/api/flows/route.js +0 -1
- package/dashboard/.next/server/app/api/mermaid/route.js +0 -1
- package/dashboard/.next/server/app/calls/page.js +0 -1
- package/dashboard/.next/server/app/calls/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/conformance/page.js +0 -1
- package/dashboard/.next/server/app/conformance/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/diagram/page.js +0 -1
- package/dashboard/.next/server/app/diagram/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/diagram/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/diagram.html +0 -1
- package/dashboard/.next/server/app/diagram.meta +0 -5
- package/dashboard/.next/server/app/diagram.rsc +0 -10
- package/dashboard/.next/server/app/flows/page.js +0 -1
- package/dashboard/.next/server/app/flows/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/flows/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/flows.html +0 -1
- package/dashboard/.next/server/app/flows.meta +0 -5
- package/dashboard/.next/server/app/flows.rsc +0 -10
- package/dashboard/.next/server/app/functions/page.js +0 -1
- package/dashboard/.next/server/app/functions/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/functions/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/notes/page.js +0 -22
- package/dashboard/.next/server/app/notes/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/notes/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/progress/page.js +0 -1
- package/dashboard/.next/server/app/progress/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/progress/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/stats/page.js +0 -1
- package/dashboard/.next/server/app/stats/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/stats/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/chunks/44.js +0 -1
- package/dashboard/.next/server/chunks/530.js +0 -1
- package/dashboard/.next/server/chunks/622.js +0 -3
- package/dashboard/.next/server/chunks/665.js +0 -13
- package/dashboard/.next/server/pages/404.html +0 -1
- package/dashboard/.next/static/AyrRAwu4mazjp8iX4Yjbb/_buildManifest.js +0 -1
- package/dashboard/.next/static/chunks/1015.3ab89142e5f44120.js +0 -226
- package/dashboard/.next/static/chunks/1151.b6ef5c786e587ed7.js +0 -1
- package/dashboard/.next/static/chunks/1199.a072929dbec89965.js +0 -148
- package/dashboard/.next/static/chunks/1375.d4d2f7fc9c9c2ff1.js +0 -43
- package/dashboard/.next/static/chunks/1799.83206776abbbf1fc.js +0 -9
- package/dashboard/.next/static/chunks/20154aaa.ccc347c04ab5ad4a.js +0 -1
- package/dashboard/.next/static/chunks/2077.7011a570c87aa7b1.js +0 -1
- package/dashboard/.next/static/chunks/2166.cc0fabeb2e89b840.js +0 -215
- package/dashboard/.next/static/chunks/2325.2c55cb9a6282ae3f.js +0 -24
- package/dashboard/.next/static/chunks/2694.92bbe252063e4786.js +0 -1
- package/dashboard/.next/static/chunks/275.0d761aa0e5b030b8.js +0 -34
- package/dashboard/.next/static/chunks/2781.8536b644a480aede.js +0 -93
- package/dashboard/.next/static/chunks/2805.a8d71d2f92bb6ba9.js +0 -1
- package/dashboard/.next/static/chunks/3017.e55781da9dd32d37.js +0 -1
- package/dashboard/.next/static/chunks/3205-728c260fbb4f89c6.js +0 -2
- package/dashboard/.next/static/chunks/3236.dff44fa7961d9d5e.js +0 -1
- package/dashboard/.next/static/chunks/3480.9451396ad7ee7613.js +0 -1
- package/dashboard/.next/static/chunks/3626.ba1cf848a9f2e93d.js +0 -64
- package/dashboard/.next/static/chunks/3865.a432a7910a2f5281.js +0 -90
- package/dashboard/.next/static/chunks/3887.c22cbfa3f095826c.js +0 -1
- package/dashboard/.next/static/chunks/3924-4a05057b5450abe1.js +0 -1
- package/dashboard/.next/static/chunks/3948.fe3c7d758568d98b.js +0 -287
- package/dashboard/.next/static/chunks/4728.07d87640a3e7dd0d.js +0 -24
- package/dashboard/.next/static/chunks/4787.4e5f6a0e0e40a583.js +0 -23
- package/dashboard/.next/static/chunks/5060.baca226af35ed016.js +0 -1
- package/dashboard/.next/static/chunks/5284.f949ac90c95ff143.js +0 -1
- package/dashboard/.next/static/chunks/5715.1524bcc9591e180b.js +0 -115
- package/dashboard/.next/static/chunks/6014.700ae4969b64d728.js +0 -104
- package/dashboard/.next/static/chunks/6024.4d23707c65514679.js +0 -79
- package/dashboard/.next/static/chunks/6177.e5c84cfc4c0dea51.js +0 -1
- package/dashboard/.next/static/chunks/618f8807-547c5614e1318888.js +0 -1
- package/dashboard/.next/static/chunks/6434.9481771c33195d29.js +0 -1
- package/dashboard/.next/static/chunks/6468.f4a3e8fa6accc6da.js +0 -77
- package/dashboard/.next/static/chunks/6540.86f367d7390738d4.js +0 -1
- package/dashboard/.next/static/chunks/6549.4d0d472df96429a5.js +0 -1
- package/dashboard/.next/static/chunks/690f35d0.3e40ca0930e4bbdb.js +0 -119
- package/dashboard/.next/static/chunks/7397-f6f4dddc7a20bfc1.js +0 -1
- package/dashboard/.next/static/chunks/7498-ea83cb9e30ec5491.js +0 -1
- package/dashboard/.next/static/chunks/7802.89aec9ee11680850.js +0 -80
- package/dashboard/.next/static/chunks/7973.8b526f589aca5d84.js +0 -79
- package/dashboard/.next/static/chunks/8216.1bead812eb126c35.js +0 -5
- package/dashboard/.next/static/chunks/8452-e616b5f43bceb95f.js +0 -13
- package/dashboard/.next/static/chunks/8645.a5ca76f11edc9633.js +0 -1
- package/dashboard/.next/static/chunks/8928-60c623ee89d2e6ad.js +0 -1
- package/dashboard/.next/static/chunks/9173.2486ffca31131ec5.js +0 -1
- package/dashboard/.next/static/chunks/9178.469341860bf8caec.js +0 -1
- package/dashboard/.next/static/chunks/9466.e904660d38c03eea.js +0 -1
- package/dashboard/.next/static/chunks/9660.84a85811380c5f33.js +0 -1
- package/dashboard/.next/static/chunks/9720.67d4d0d15a96d691.js +0 -1
- package/dashboard/.next/static/chunks/9811.65e1d080c2d256af.js +0 -1
- package/dashboard/.next/static/chunks/app/_not-found/page-548ab392d0e890d1.js +0 -1
- package/dashboard/.next/static/chunks/app/access/page-3668562e7464eb5d.js +0 -1
- package/dashboard/.next/static/chunks/app/calls/page-d07f5b8664cc8303.js +0 -1
- package/dashboard/.next/static/chunks/app/conformance/page-2fede1d7b5f9265d.js +0 -1
- package/dashboard/.next/static/chunks/app/diagram/page-b228444265546495.js +0 -1
- package/dashboard/.next/static/chunks/app/flows/page-fa67783d8cd79cab.js +0 -1
- package/dashboard/.next/static/chunks/app/functions/page-686f0296639133a3.js +0 -1
- package/dashboard/.next/static/chunks/app/issues/page-98a298e1c1045c91.js +0 -1
- package/dashboard/.next/static/chunks/app/layout-49f2496c7637d931.js +0 -1
- package/dashboard/.next/static/chunks/app/notes/page-17af94c67ba79c00.js +0 -1
- package/dashboard/.next/static/chunks/app/page-24bac51dfe007c66.js +0 -1
- package/dashboard/.next/static/chunks/app/progress/page-427fb18da3afb061.js +0 -1
- package/dashboard/.next/static/chunks/app/report/page-796f2f4a8a5ac8f7.js +0 -1
- package/dashboard/.next/static/chunks/app/stats/page-db81f600a086f252.js +0 -1
- package/dashboard/.next/static/chunks/c7ea4e13.5effeeba6618bdb7.js +0 -1
- package/dashboard/.next/static/chunks/framework-cf6f5bdca6ba0184.js +0 -33
- package/dashboard/.next/static/chunks/main-63ff429eab01f5bf.js +0 -1
- package/dashboard/.next/static/chunks/main-app-9d2f6b8a47133e9b.js +0 -1
- package/dashboard/.next/static/chunks/pages/_app-6ad2b50514c24ab4.js +0 -1
- package/dashboard/.next/static/chunks/pages/_error-d5eb11c5c4626811.js +0 -1
- package/dashboard/.next/static/chunks/webpack-08869f2b18792e51.js +0 -1
- package/dashboard/.next/static/css/4a38d8f6f6b7a68f.css +0 -3
- package/dashboard/.next/static/media/438aa629764e75f3-s.woff2 +0 -0
- package/dashboard/.next/static/media/4c9affa5bc8f420e-s.p.woff2 +0 -0
- package/dashboard/.next/static/media/51251f8b9793cdb3-s.woff2 +0 -0
- package/dashboard/.next/static/media/875ae681bfde4580-s.woff2 +0 -0
- package/dashboard/.next/static/media/cc978ac5ee68c2b6-s.woff2 +0 -0
- package/dashboard/.next/static/media/e857b654a2caa584-s.woff2 +0 -0
- package/dashboard/app/access/AccessClient.tsx +0 -402
- package/dashboard/app/access/ReadOnlyFunctions.tsx +0 -114
- package/dashboard/app/access/page.tsx +0 -125
- package/dashboard/app/api/flows/route.ts +0 -32
- package/dashboard/app/api/mermaid/route.ts +0 -25
- package/dashboard/app/calls/CallsClient.tsx +0 -170
- package/dashboard/app/calls/page.tsx +0 -57
- package/dashboard/app/conformance/ConformanceTable.tsx +0 -214
- package/dashboard/app/conformance/page.tsx +0 -186
- package/dashboard/app/diagram/page.tsx +0 -65
- package/dashboard/app/flows/page.tsx +0 -102
- package/dashboard/app/functions/FunctionsClient.tsx +0 -167
- package/dashboard/app/functions/page.tsx +0 -178
- package/dashboard/app/issues/IssuesBoardClient.tsx +0 -803
- package/dashboard/app/notes/NotesClient.tsx +0 -701
- package/dashboard/app/notes/page.tsx +0 -47
- package/dashboard/app/progress/ProgressClient.tsx +0 -354
- package/dashboard/app/progress/page.tsx +0 -127
- package/dashboard/app/stats/StatsClient.tsx +0 -452
- package/dashboard/app/stats/page.tsx +0 -50
- package/dashboard/components/ConfidenceBadge.tsx +0 -53
- package/dashboard/components/DashboardLayout.tsx +0 -485
- package/dashboard/components/FilterableTable.tsx +0 -293
- package/dashboard/components/MermaidViewer.tsx +0 -267
- package/dashboard/components/NotYetGenerated.tsx +0 -32
- package/dashboard/components/SeverityBadge.tsx +0 -28
- package/dashboard/components/SignalBars.tsx +0 -27
- package/dashboard/components/SortableTable.tsx +0 -122
- package/dashboard/lib/conformance-tokens.ts +0 -49
- package/dist/skills/init-audit.md +0 -284
- /package/dashboard/.next/server/app/api/{flows → xref}/route.js.nft.json +0 -0
- /package/dashboard/.next/server/app/{api/mermaid → excalidraw-assets/[...path]}/route.js.nft.json +0 -0
- /package/dashboard/.next/static/{AyrRAwu4mazjp8iX4Yjbb → bGV1ry1vvIbM5b506eVBR}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Handler Patterns
|
|
2
|
+
|
|
3
|
+
Use this guide during Step 7.
|
|
4
|
+
|
|
5
|
+
## Shape
|
|
6
|
+
|
|
7
|
+
Each handler file should have two sections:
|
|
8
|
+
|
|
9
|
+
- `Unclamped`: raw protocol-action functions that perform the target call with unrestricted parameters
|
|
10
|
+
- `Clamped`: handlers that restrict arbitrary fuzz input into sensible, high-signal calls
|
|
11
|
+
|
|
12
|
+
Both sections may be called by the fuzzer. The unclamped section is not just an internal helper layer: unclamped handlers are also direct fuzz entry points, specifically so the campaign can still hit edge cases that the clamped layer intentionally filters out.
|
|
13
|
+
|
|
14
|
+
The clamped layer should stay thin and usually forward into the corresponding unclamped function. The unclamped layer should usually just perform the target call with the appropriate acting modifier.
|
|
15
|
+
|
|
16
|
+
## Unclamped
|
|
17
|
+
|
|
18
|
+
The `Unclamped` section is the raw-call layer.
|
|
19
|
+
|
|
20
|
+
Use it to:
|
|
21
|
+
|
|
22
|
+
- perform the real target function call with unrestricted parameters
|
|
23
|
+
- expose edge-case behavior that clamped variants intentionally avoid
|
|
24
|
+
- apply the correct acting modifier or caller role
|
|
25
|
+
- stay as close as possible to a raw call wrapper
|
|
26
|
+
|
|
27
|
+
These functions are meant to be called both:
|
|
28
|
+
|
|
29
|
+
- directly by the fuzzer, with unrestricted parameters
|
|
30
|
+
- indirectly by the clamped handlers, after those handlers have prepared sensible inputs
|
|
31
|
+
|
|
32
|
+
Unclamped handlers should stay close to the actual protocol surface. They should usually be thin raw calls plus the necessary role modifier and call to internal specific properties, if applicable. "Unclamped" describes their role in the handler structure, not their Solidity visibility.
|
|
33
|
+
|
|
34
|
+
### Caller Context
|
|
35
|
+
|
|
36
|
+
Use the acting context that matches the real role here:
|
|
37
|
+
|
|
38
|
+
- `asActor` for users
|
|
39
|
+
- `asAdmin` for owner or admin operations
|
|
40
|
+
- role-specific modifiers for keepers, operators, reward distributors, or liquidators
|
|
41
|
+
|
|
42
|
+
If the scaffold lacks a needed role modifier, add it.
|
|
43
|
+
|
|
44
|
+
This is required even for raw unclamped handlers. Unrestricted parameters do not mean unrestricted caller identity.
|
|
45
|
+
|
|
46
|
+
## Clamped
|
|
47
|
+
|
|
48
|
+
The `Clamped` section is the restricted-input layer of the handler.
|
|
49
|
+
|
|
50
|
+
Use it to:
|
|
51
|
+
|
|
52
|
+
- expose the small set of high-signal protocol actions that the fuzzer should call
|
|
53
|
+
- normalize arbitrary fuzz inputs into values that can reach meaningful code paths
|
|
54
|
+
- prepare derived values before dispatching into the unclamped implementation
|
|
55
|
+
- prepare preconditions that the target action expects, then forward into the corresponding unclamped function whenever practical
|
|
56
|
+
|
|
57
|
+
### Clamped Design
|
|
58
|
+
|
|
59
|
+
Do not mirror the ABI mechanically if a higher-signal handler shape is better.
|
|
60
|
+
|
|
61
|
+
Good transformations:
|
|
62
|
+
|
|
63
|
+
- merge preparatory steps and the main user action into one handler if the protocol expects them together
|
|
64
|
+
- split one overloaded or ambiguous flow into clearer variants if that improves coverage
|
|
65
|
+
- derive parameters from current state when raw fuzzed values mostly cause trivial reverts
|
|
66
|
+
|
|
67
|
+
### Clamped Input Handling
|
|
68
|
+
|
|
69
|
+
Prefer semantic bounds over arbitrary caps. Clamp toward values that are realistic for the protocol and likely to reach meaningful state transitions.
|
|
70
|
+
|
|
71
|
+
Use the helper functions from `utils/Clamp.sol` for this layer. Those helpers are part of the scaffold specifically so clamped handlers can bound fuzz inputs consistently with functions such as `clampBetween`, `clampLte`, `clampLt`, `clampGte`, and `clampGt`.
|
|
72
|
+
|
|
73
|
+
Examples:
|
|
74
|
+
|
|
75
|
+
- map arbitrary addresses to known actors with `toActor(...)` and `toActorNotCurrent(...)`
|
|
76
|
+
- if a function expects a valid identifier such as an order id, position id, market id, or pool id, pick from known valid values instead of passing arbitrary garbage
|
|
77
|
+
- if a function will pull ERC20s from the caller, bound the amount by the caller's token balance and set the needed approval before calling the unclamped function
|
|
78
|
+
- bound spend amounts by balances or allowances
|
|
79
|
+
- bound share burns by owned shares
|
|
80
|
+
- bound deadlines so the call can reach meaningful code paths
|
|
81
|
+
- use source constants and require guards when they expose real bounds
|
|
82
|
+
|
|
83
|
+
Clamped handlers should usually avoid doing the raw protocol call inline. Prefer to finish argument preparation and then call the unclamped version.
|
|
84
|
+
|
|
85
|
+
If the correct bound is unclear, keep the clamp loose and leave a targeted `// TODO: tighten bound`.
|
|
86
|
+
|
|
87
|
+
### Donation Handlers
|
|
88
|
+
|
|
89
|
+
- If the protocol manages native tokens, include a special `<Contract>_donateETH` handler that accepts an arbitrary amount and sends it to the protocol using `Actor.forceSendETH(...)`.
|
|
90
|
+
- If the protocol manages ERC20 tokens, include a special `<Contract>_donateERC20` handler that accepts an arbitrary amount and (optionally) token address and sends it to the protocol.
|
|
91
|
+
|
|
92
|
+
## Boundary-Value Stress Handlers
|
|
93
|
+
|
|
94
|
+
For every clamped handler, generate **stress variants** that target the extremes of the input domain. Clamped handlers focus on "sensible" ranges to maximize meaningful state transitions, but bugs cluster at the boundaries those clamps filter out. Stress handlers exist to hit those boundaries.
|
|
95
|
+
|
|
96
|
+
The approach is always the same: read the function's code path, identify where the math can degenerate, and write a handler that drives input to that boundary. There are four directions to check.
|
|
97
|
+
|
|
98
|
+
### 1. Near-Zero / Sub-Unit Values
|
|
99
|
+
|
|
100
|
+
When a code path involves division or decimal conversion, values near or below the divisor truncate to zero. This creates free-value bugs (user pays nothing, receives tokens) or division-by-zero reverts.
|
|
101
|
+
|
|
102
|
+
**How to detect**: grep the target contracts for division (`/`), `mulDiv`, decimal scaling (`10**`, `1eN`), or conversion functions. Note the divisor. Any input smaller than that divisor will truncate.
|
|
103
|
+
|
|
104
|
+
```solidity
|
|
105
|
+
// Generic pattern: if the function divides by SCALE_FACTOR, test below it
|
|
106
|
+
function contract_action_smallAmount(uint256 amount) public {
|
|
107
|
+
// Clamp to values near the truncation boundary
|
|
108
|
+
amount = clampBetween(amount, 1, SCALE_FACTOR);
|
|
109
|
+
contract_action(amount);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 2. Full-Amount / Max-State Operations
|
|
114
|
+
|
|
115
|
+
Protocols often work fine for partial operations but break when the entire balance, debt, or supply flows through a single path. Generate handlers that use the maximum available amount from current state:
|
|
116
|
+
|
|
117
|
+
```solidity
|
|
118
|
+
function contract_fullWithdraw() public {
|
|
119
|
+
uint256 fullBalance = contract.balanceOf(actor);
|
|
120
|
+
if (fullBalance == 0) return;
|
|
121
|
+
contract_withdraw(fullBalance);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function contract_fullAction(uint256 auxParam) public {
|
|
125
|
+
uint256 maxAmount = contract.totalAvailable();
|
|
126
|
+
if (maxAmount == 0) return;
|
|
127
|
+
contract_action(maxAmount, auxParam);
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 3. Type-Boundary Values
|
|
132
|
+
|
|
133
|
+
Before writing handlers, grep the target contracts for storage variables that use types narrower than uint256 — `uint8`, `uint80`, `uint96`, `uint128`, `uint160`, or packed struct fields. When a value accumulates via uint256 arithmetic but is stored or cast to a narrower type, the truncation is invisible until the accumulated value exceeds the type's max.
|
|
134
|
+
|
|
135
|
+
For each narrow-typed accumulator, create a handler that pushes values large enough to approach or exceed the type boundary through the accumulation path. Derive the bound from the type max (e.g., `type(uint80).max` is ~1.2e24), not from hardcoded protocol-specific constants.
|
|
136
|
+
|
|
137
|
+
### How to Apply
|
|
138
|
+
|
|
139
|
+
For each clamped handler, ask:
|
|
140
|
+
1. Does this path involve division or scaling? → add a **near-zero** variant
|
|
141
|
+
2. Can this be called with the full available amount? → add a **full-amount** variant
|
|
142
|
+
3. Does this path write to a narrow-typed storage variable? → add a **type-boundary** variant
|
|
143
|
+
|
|
144
|
+
Not every handler needs all three — only add variants where the code path has the relevant pattern.
|
|
145
|
+
|
|
146
|
+
### Admin Handlers
|
|
147
|
+
|
|
148
|
+
For admin/owner functions, always use the correct caller context:
|
|
149
|
+
|
|
150
|
+
```solidity
|
|
151
|
+
function protocol_setFee(uint256 fee) public asAdmin {
|
|
152
|
+
protocol.setFee(fee);
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Admin handlers must use `asAdmin` (or the appropriate role modifier) — not `asActor`. If no `asAdmin` modifier exists in the scaffold, add one that pranks as the contract owner.
|
|
157
|
+
|
|
158
|
+
## Dispatcher for Secondary-Tier Functions
|
|
159
|
+
|
|
160
|
+
Secondary-tier functions appear as `internal` stubs (prefixed `_`) in the Unclamped section, and a single public dispatcher at the end of the Clamped section. The dispatcher is a single clamped entry point that uses a `uint8 selector` parameter to pick which secondary function to call:
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
```solidity
|
|
164
|
+
function vault_secondary(uint8 selector, uint256 arg0, address arg1) public {
|
|
165
|
+
selector = uint8(selector % 3);
|
|
166
|
+
if (selector == 0) _vault_setPaused(arg0 > 0);
|
|
167
|
+
else if (selector == 1) _vault_setFee(arg0);
|
|
168
|
+
else _vault_setAdmin(arg1);
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The unclamped secondary functions are all `internal` and not direct fuzz entry points.
|
|
173
|
+
|
|
174
|
+
This reduces the secondary functions' call frequency naturally — the fuzzer reaches them only when it happens to pick the matching selector value.
|
|
175
|
+
|
|
176
|
+
Primary-tier functions get their own individual clamped + unclamped handlers as normal.
|
|
177
|
+
|
|
178
|
+
## Example
|
|
179
|
+
|
|
180
|
+
```solidity
|
|
181
|
+
// SPDX-License-Identifier: MIT
|
|
182
|
+
pragma solidity >=0.6.2 <0.9.0;
|
|
183
|
+
|
|
184
|
+
import "../Base.sol";
|
|
185
|
+
import {Properties} from "../Properties.sol";
|
|
186
|
+
|
|
187
|
+
/// @notice Handles the interaction with a specific contract
|
|
188
|
+
abstract contract VaultHandler is Properties {
|
|
189
|
+
|
|
190
|
+
// ――――――――――――――――――――――――― Clamped ――――――――――――――――――――――――――
|
|
191
|
+
|
|
192
|
+
function vault_deposit_clamped(uint256 amount) public {
|
|
193
|
+
uint256 balance = token.balanceOf(actor);
|
|
194
|
+
if (balance == 0) return;
|
|
195
|
+
amount = clampBetween(amount, 1, balance);
|
|
196
|
+
|
|
197
|
+
vault_deposit(amount);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function vault_donateETH(uint256 amount) public {
|
|
201
|
+
if (actor.balance == 0) return;
|
|
202
|
+
amount = clampBetween(amount, 1, actor.balance);
|
|
203
|
+
|
|
204
|
+
Actor(actor).forceSendETH{value: amount}(address(vault));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function vault_donateERC20(uint256 amount) public {
|
|
208
|
+
uint256 balance = token.balanceOf(actor);
|
|
209
|
+
if (balance == 0) return;
|
|
210
|
+
amount = clampBetween(amount, 1, balance);
|
|
211
|
+
|
|
212
|
+
vm.prank(actor);
|
|
213
|
+
token.transfer(address(vault), amount);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ―――――――――――――――――――――――― Unclamped ―――――――――――――――――――――――――
|
|
217
|
+
|
|
218
|
+
function vault_deposit(uint256 amount) public asActor {
|
|
219
|
+
vault.deposit(amount);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
```
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Hex invariants and fuzz properties
|
|
2
|
+
|
|
3
|
+
Hex-only reference (not in upstream fizz). Read by `/fuzz` (Steps 3, 9 and 12), its Synthesizer, `/fuzz-sync` and `/fuzz-convert`.
|
|
4
|
+
|
|
5
|
+
Always call the CLI as `npx --no-install hex …`. Never `npx hex …`: an unrelated npm package named `hex` exists, and `npx` would download and run it.
|
|
6
|
+
|
|
7
|
+
## Where the inputs come from
|
|
8
|
+
|
|
9
|
+
| Input | Command / file | Used for |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| Accepted invariants | `npx --no-install hex invariant list --status accepted --json` (saved to `{META_DIR}/hex-invariants.json` in Step 3) | The property list: one property per accepted invariant |
|
|
12
|
+
| All invariants | `.hex/model/invariants.json` (`npx --no-install hex invariant list --json`) | Deduplicating proposals, the next free id |
|
|
13
|
+
| Protocol model | `.hex/model/protocol.json` (`npx --no-install hex model show [section]`) | Actors, assets, privileges, accounting equations, state machines, risky flows |
|
|
14
|
+
| Exact facts | `npx --no-install hex facts query <callers\|callees\|readers\|writers\|layout\|linearization\|entry-points\|reach\|function> [ref]` | Entry points, who writes a variable, storage layout, exact function ids |
|
|
15
|
+
|
|
16
|
+
An invariant entry:
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"id": "INV-003",
|
|
21
|
+
"statement": "The vault's token balance is always at least totalAssets()",
|
|
22
|
+
"kind": "accounting",
|
|
23
|
+
"scope": { "contracts": ["Vault"], "functions": ["Vault.withdraw(uint256,address,address)"] },
|
|
24
|
+
"evidence": [{ "file": "src/Vault.sol", "line_start": 120, "line_end": 134 }],
|
|
25
|
+
"on_chain_enforced": false,
|
|
26
|
+
"status": "accepted",
|
|
27
|
+
"test": { "tool": "fizz", "property_id": "GL-01", "file": "test/fizz/Properties.sol", "status": "passing" },
|
|
28
|
+
"issue_id": "H-012"
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`test` and `issue_id` are optional. `kind` is one of `accounting`, `access`, `bound`, `monotonic`, `state-machine`, `liveness`, `economic`.
|
|
33
|
+
|
|
34
|
+
## The tag in PROPERTIES.md
|
|
35
|
+
|
|
36
|
+
`.hex/fuzz/PROPERTIES.md` keeps upstream's line format, with the invariant's id in parentheses right after the bold Spec ID:
|
|
37
|
+
|
|
38
|
+
```markdown
|
|
39
|
+
- [ ] **GL-01** (INV-003) — Solvency: the vault's token balance is always at least `vault.totalAssets()`. (Category: HIGH_LEVEL; Guarantee: SHOULD-HOLD — …; Priority: HIGH; Sources: CON-01)
|
|
40
|
+
- [x] **SP-02** (INV-007) — After `vault_deposit`, `vault.totalSupply()` strictly increases. (Category: STATE_TRANSITION; Guarantee: EXPLORATORY; After: `vault_deposit`; Priority: HIGH; Sources: ST-01)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Rules:
|
|
44
|
+
|
|
45
|
+
- Each Spec ID maps to exactly one invariant, and each accepted invariant gets one entry.
|
|
46
|
+
- Never put anything between `- [ ] ` and `**GL-NN**`: `fizz_sync.js` and `/fuzz-convert` parse that prefix.
|
|
47
|
+
- Anyone who edits a line (implementers flipping `[ ]` → `[x]`, `/fuzz-sync` flipping `[x]` → `[~]`) keeps the `(INV-NNN)` tag as it is.
|
|
48
|
+
- An entry without a tag is fuzzed but not tracked in Hex. `hex invariant sync-fuzz` lists it as unmapped.
|
|
49
|
+
|
|
50
|
+
Record each mapping when the entry is written:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npx --no-install hex invariant set-test INV-003 --tool fizz --property GL-01 --file test/fizz/Properties.sol --status not_written
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`--file` is the file that holds the property function: `{SUITE_DIR}/Properties.sol` for both `GL-*` and `SP-*`.
|
|
57
|
+
|
|
58
|
+
## Proposing an invariant
|
|
59
|
+
|
|
60
|
+
Discovery agents find properties the auditor did not accept. Those are **proposals**. They are never fuzzed in the current run and never written to `PROPERTIES.md` or `property-plan.md`. They go to the auditor as proposed Hex invariants:
|
|
61
|
+
|
|
62
|
+
1. Read the whole `.hex/model/invariants.json`: `{ "updated_at": "…", "invariants": [ … ] }`. If it does not exist, start from `{ "updated_at": "", "invariants": [] }`.
|
|
63
|
+
2. Skip a candidate that restates an existing invariant of any status, rejected ones included (the auditor already ruled on those).
|
|
64
|
+
3. Give each new entry the next free id: the highest `INV-NNN` number in the file plus one, zero-padded to three digits (`INV-014`), counting up for each further entry.
|
|
65
|
+
4. Fill the entry:
|
|
66
|
+
- `statement`: one sentence, a property of the protocol and not of the harness ("users can always withdraw their full balance when not paused", not "property_x returns true").
|
|
67
|
+
- `kind`: map from fizz's discovery. Conservation and sum-of-parts are `accounting`. Bounds and rounding direction are `bound`. Monotonicity is `monotonic`. State validity and state transitions are `state-machine`. DoS, "can always withdraw" and liveness are `liveness`. Value extraction and profit are `economic`. Who may call what is `access`.
|
|
68
|
+
- `scope.contracts`: contract names. `scope.functions`: exact facts function ids (`Contract.fn(type,…)`, from `npx --no-install hex facts query function <name>`), or `[]` when unsure. A wrong id fails validation.
|
|
69
|
+
- `evidence`: `[{ "file": "src/…", "line_start": N, "line_end": M }]`, project-relative, pointing at the code that makes the property matter.
|
|
70
|
+
- `on_chain_enforced`: `true` only if a `require`/`assert`/`revert` in the code enforces it.
|
|
71
|
+
- `status`: `"proposed"`. Never `accepted`: only the auditor accepts.
|
|
72
|
+
- `rationale`: `"Proposed by /fuzz (<discovery source ids>): <why it should hold, or the doc/identity behind it>"`.
|
|
73
|
+
5. Append the entries and write the whole file back. Keep every existing entry as it was and set `updated_at` to the current ISO time.
|
|
74
|
+
6. Run `npx --no-install hex model validate` and fix what it reports.
|
|
75
|
+
|
|
76
|
+
The auditor reviews proposals with `npx --no-install hex invariant list --status proposed` (or on the dashboard's Model page) and accepts with `npx --no-install hex invariant accept INV-014 …`. `/fuzz-convert` then adds properties for the newly accepted ones.
|
|
77
|
+
|
|
78
|
+
## After every campaign: `hex invariant sync-fuzz`
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
cd {PROJECT_ROOT} && npx --no-install hex invariant sync-fuzz
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
It reads:
|
|
85
|
+
|
|
86
|
+
- `.hex/fuzz/PROPERTIES.md`: Spec IDs, checkboxes and `(INV-NNN)` tags. An invariant whose `test.property_id` names the Spec ID is matched too.
|
|
87
|
+
- The `/// @notice GL-NN:` doctags under the suite (`test/fizz/Properties.sol`, `test/fizz/handlers/*.sol`) to find each property's function. It takes the suite dir from `{META_DIR}/last-run.json` when that file exists.
|
|
88
|
+
- The latest campaign logs: `{META_DIR}/corpus_medusa/medusa-run.log` (`run_medusa.js`), the newest file in `{META_DIR}/logs_medusa/` (a bare `medusa fuzz`), and `{META_DIR}/corpus_echidna/echidna-run.log` (`run_echidna.js`). Newer logs win.
|
|
89
|
+
- `test_repro_<propertyFunction>` tests in `test/fizz/FoundryTester.sol`. A repro whose body still holds the `TODO: manual repro needed` marker does not count.
|
|
90
|
+
|
|
91
|
+
It sets each mapped invariant's `test` (`tool: fizz`, `property_id`, `file`, `status`, `runs`, `last_run_at`, `repro_file`):
|
|
92
|
+
|
|
93
|
+
| Status | When |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `failing` | A repro exists, or the property's own test failed in the latest log that ran it |
|
|
96
|
+
| `broken` | `[~]` (quarantined by `/fuzz-sync`), `[x]` with no tagged function, a quarantined function body, or the fuzzer could not evaluate it |
|
|
97
|
+
| `passing` | `[x]`, it ran (its own test, or for `SP-*` the handlers that call it), and nothing failed |
|
|
98
|
+
| `not_written` | `[ ]` or `[-]` |
|
|
99
|
+
|
|
100
|
+
For each `failing` invariant that has a repro and no `issue_id`, it opens a High card (`Invariant broken: <statement>`, source `invariant`) and links it. It does not do this for rejected invariants. Running it again opens no duplicate cards.
|
|
101
|
+
|
|
102
|
+
When an `SP-*` property's handler failed but no repro names the property, it reports the violation as **unattributed** and leaves the status unchanged, because several assertions can share a handler. Write `test_repro_<property>` to attribute it. Pass `--json` for the full summary.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Property Generation
|
|
2
|
+
|
|
3
|
+
Common instructions for generating properties, ghost variables, snapshot state, and harness contracts after handlers are in place. These rules apply to both global properties and specific properties.
|
|
4
|
+
|
|
5
|
+
This phase runs after handler generation. The agent reads the target contract source files and the generated handlers to produce:
|
|
6
|
+
|
|
7
|
+
**Ghost variables** in `Base.sol` — track cumulative state not directly readable from the contract.
|
|
8
|
+
**Ghost updates** wired into per-contract handler files (`handlers/<Contract>Handler.sol`).
|
|
9
|
+
**Snapshot state** in `Snapshots.sol` — before/after state for delta-based properties.
|
|
10
|
+
**Harness contracts** in `{SUITE_DIR}/harness/` — for accessing private/internal state when necessary.
|
|
11
|
+
**Properties** in `Properties.sol` — global and function-specific invariant checks, called explicitly from handlers or shared helper functions.
|
|
12
|
+
|
|
13
|
+
## 1. Naming convention
|
|
14
|
+
|
|
15
|
+
All property functions must start with `property_` prefix.
|
|
16
|
+
|
|
17
|
+
## 2. Ghost Variables
|
|
18
|
+
|
|
19
|
+
### What they are
|
|
20
|
+
|
|
21
|
+
Ghost variables track state that the contract doesn't expose directly but that is needed to write meaningful invariants. Common examples:
|
|
22
|
+
|
|
23
|
+
- `ghosts.totalDeposited` — sum of all deposits across all actors
|
|
24
|
+
- `ghosts.totalWithdrawn` — sum of all withdrawals
|
|
25
|
+
- `ghosts.totalMinted` — cumulative minted amount
|
|
26
|
+
- `ghosts.lastTimestamp` — timestamp of last state-changing call
|
|
27
|
+
|
|
28
|
+
### Where they go
|
|
29
|
+
|
|
30
|
+
In `Base.sol`, inside the `Ghosts` struct:
|
|
31
|
+
|
|
32
|
+
```solidity
|
|
33
|
+
struct Ghosts {
|
|
34
|
+
uint256 totalDeposited;
|
|
35
|
+
uint256 totalWithdrawn;
|
|
36
|
+
uint256 totalMinted;
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Replace the placeholder `uint256 _placeholder;` with real ghost variables.
|
|
41
|
+
|
|
42
|
+
### How to choose ghosts
|
|
43
|
+
|
|
44
|
+
Read the source contracts and identify:
|
|
45
|
+
- **Accumulative operations**: deposits, withdrawals, mints, burns, transfers — track running totals.
|
|
46
|
+
- **Counter operations**: number of users, number of positions — track counts.
|
|
47
|
+
- **Extreme values**: max/min seen amounts — track with `max()`/`min()` in handlers.
|
|
48
|
+
|
|
49
|
+
Only add ghosts that are needed by at least one property. Don't add speculative ghosts.
|
|
50
|
+
|
|
51
|
+
### Wiring ghost updates into handlers
|
|
52
|
+
|
|
53
|
+
Add ghost updates AFTER the external call in each handler (so they only execute on success).
|
|
54
|
+
|
|
55
|
+
For clamped handlers that forward to unclamped: put ghost updates in the UNCLAMPED handler (since both clamped and direct fuzzer calls go through it).
|
|
56
|
+
|
|
57
|
+
Ghost updates go in the per-contract handler files (`handlers/<Contract>Handler.sol`). Example:
|
|
58
|
+
|
|
59
|
+
```solidity
|
|
60
|
+
function vault_deposit(uint256 assets) public asActor {
|
|
61
|
+
assets = clampBetween(assets, 1, token.balanceOf(address(actor)));
|
|
62
|
+
|
|
63
|
+
vm.prank(address(actor));
|
|
64
|
+
vault.deposit(assets);
|
|
65
|
+
|
|
66
|
+
ghosts.totalDeposited += assets;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 3. Snapshot State
|
|
71
|
+
|
|
72
|
+
### Purpose
|
|
73
|
+
|
|
74
|
+
`Snapshots.sol` captures state before and after a handler call, enabling delta-based properties like "user balance decreased by exactly the deposit amount."
|
|
75
|
+
|
|
76
|
+
### What to track
|
|
77
|
+
|
|
78
|
+
Read the target contracts and populate the `State` struct with:
|
|
79
|
+
- Key balances: `token.balanceOf(address)`, `contract.balanceOf(address)`
|
|
80
|
+
- Protocol state: `totalSupply`, `totalAssets`, `totalShares`
|
|
81
|
+
- Actor state: balances of the current actor
|
|
82
|
+
|
|
83
|
+
Example:
|
|
84
|
+
|
|
85
|
+
```solidity
|
|
86
|
+
struct State {
|
|
87
|
+
uint256 actorTokenBalance;
|
|
88
|
+
uint256 vaultTotalAssets;
|
|
89
|
+
uint256 vaultTotalSupply;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function _takeSnapshot(State storage state) private {
|
|
93
|
+
state.actorTokenBalance = token.balanceOf(actor);
|
|
94
|
+
state.vaultTotalAssets = vault.totalAssets();
|
|
95
|
+
state.vaultTotalSupply = vault.totalSupply();
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Snapshot reads must NOT revert. Use try/catch for any call that could fail.
|
|
100
|
+
|
|
101
|
+
### Wiring snapshots into handlers
|
|
102
|
+
|
|
103
|
+
For handlers that need before/after comparison, call `snapshotBefore()` before the external call and `snapshotAfter()` after it. The full wiring sequence in an unclamped handler is:
|
|
104
|
+
|
|
105
|
+
1. `snapshotBefore()` — capture state before the call
|
|
106
|
+
2. External call — the actual protocol interaction
|
|
107
|
+
3. `snapshotAfter()` — capture state after the call
|
|
108
|
+
4. Ghost updates — track derived state (only executes on success)
|
|
109
|
+
5. Property assertions — call specific properties that check deltas
|
|
110
|
+
|
|
111
|
+
```solidity
|
|
112
|
+
function vault_deposit(uint256 assets) public asActor {
|
|
113
|
+
snapshotBefore();
|
|
114
|
+
|
|
115
|
+
vm.prank(address(actor));
|
|
116
|
+
vault.deposit(assets);
|
|
117
|
+
|
|
118
|
+
snapshotAfter();
|
|
119
|
+
ghosts.totalDeposited += assets;
|
|
120
|
+
property_depositIncreasesShares(assets);
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Do NOT add snapshot calls to every handler — only where delta-based properties exist. They cost gas and slow fuzzing.
|
|
125
|
+
|
|
126
|
+
## 4. Harness Contracts
|
|
127
|
+
|
|
128
|
+
If a property requires access to `private` or `internal` state that is not reachable via the public interface, create a harness contract:
|
|
129
|
+
|
|
130
|
+
- Place it at `{SUITE_DIR}/harness/{TargetContract}Harness.sol`
|
|
131
|
+
- The harness inherits from the target contract and adds only the minimal getter(s) needed
|
|
132
|
+
- Update `Base.sol` to declare and instantiate `{TargetContract}Harness` instead of `{TargetContract}` — the harness is ABI-compatible so handlers and properties continue to work unchanged
|
|
133
|
+
- Only create a harness when strictly necessary — prefer public interface access
|
|
134
|
+
|
|
135
|
+
## 5. Assertion helpers
|
|
136
|
+
|
|
137
|
+
These are the assertion helpers from `utils/PropertiesAsserts.sol`:
|
|
138
|
+
|
|
139
|
+
| Function | Check |
|
|
140
|
+
|---|---|
|
|
141
|
+
| `t(bool, string)` | assert true |
|
|
142
|
+
| `eq(a, b, reason)` | `a == b` |
|
|
143
|
+
| `neq(a, b, reason)` | `a != b` |
|
|
144
|
+
| `gt(a, b, reason)` | `a > b` |
|
|
145
|
+
| `gte(a, b, reason)` | `a >= b` |
|
|
146
|
+
| `lt(a, b, reason)` | `a < b` |
|
|
147
|
+
| `lte(a, b, reason)` | `a <= b` |
|
|
148
|
+
|
|
149
|
+
All have both `uint256` and `int256` overloads. All emit descriptive failure events before `assert(false)`.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Entry-Point Selection Policy
|
|
2
|
+
|
|
3
|
+
Use this policy when creating the initial `entry-point-selection.json`.
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Select the smallest handler surface that still exercises the protocol's real state machine.
|
|
8
|
+
|
|
9
|
+
## Prefer By Default
|
|
10
|
+
|
|
11
|
+
- core user flows such as `deposit`, `withdraw`, `mint`, `redeem`, `borrow`, `repay`, `stake`, `unstake`, `swap`, `claim`
|
|
12
|
+
- recurring permissioned flows such as `harvest`, `liquidate`, `rollover`, `notifyRewardAmount`, `rebalance`, `settle`
|
|
13
|
+
- edge-case actions that plausibly break accounting, mode transitions, or fund safety
|
|
14
|
+
|
|
15
|
+
## Exclude By Default
|
|
16
|
+
|
|
17
|
+
- `view` and `pure` functions
|
|
18
|
+
- one-time migration and bootstrap functions
|
|
19
|
+
- internal plumbing exposed as `external` only for contract-to-contract calls
|
|
20
|
+
- routine parameter setters that mostly tune config without creating meaningful state-machine pressure
|
|
21
|
+
|
|
22
|
+
## Include Carefully
|
|
23
|
+
|
|
24
|
+
Keep a permissioned or config-like action when one of these is true:
|
|
25
|
+
|
|
26
|
+
- it changes fund routing, fee accounting, caps, oracle state, or collateral rules
|
|
27
|
+
- it toggles pause, shutdown, or mode flags
|
|
28
|
+
- sequencing it against user flows is plausibly dangerous
|
|
29
|
+
- it is part of normal operations for keepers, liquidators, or reward distributors
|
|
30
|
+
|
|
31
|
+
## Decision Heuristics
|
|
32
|
+
|
|
33
|
+
For each candidate function, ask:
|
|
34
|
+
|
|
35
|
+
1. Would a real user, admin, keeper, operator, or liquidator call this directly?
|
|
36
|
+
2. Does this function create or unlock important state transitions?
|
|
37
|
+
3. Would omitting it make the fuzz campaign miss an important lifecycle edge?
|
|
38
|
+
4. Is it mostly internal wiring that should instead be exercised indirectly through another entry point?
|
|
39
|
+
|
|
40
|
+
If confidence is low, prefer excluding protocol-internal plumbing and keeping the higher-signal external flows.
|
|
41
|
+
|
|
42
|
+
## Tier Classification
|
|
43
|
+
|
|
44
|
+
After selection, classify each included function as **primary** or **secondary**:
|
|
45
|
+
|
|
46
|
+
- **Primary**: core user flows that the fuzzer should call frequently (deposit, withdraw, mint, redeem, borrow, repay, swap, stake, unstake, claim, liquidate, etc.)
|
|
47
|
+
- **Secondary**: less common functions that are still useful but should be called less often (admin setters, configuration changes, pause/unpause, role grants, parameter tuning, etc.)
|
|
48
|
+
|
|
49
|
+
Secondary functions are grouped into a dispatcher handler in Step 7, reducing their call frequency without excluding them entirely.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Setup Playbook
|
|
2
|
+
|
|
3
|
+
Use this guide during Step 6 when wiring `Base.sol` and `Actor.sol`.
|
|
4
|
+
|
|
5
|
+
## Base.sol FIXMEs
|
|
6
|
+
|
|
7
|
+
The scaffolded `Base.sol` contract contains `FIXME` comments that indicate where protocol-specific setup logic should be implemented.
|
|
8
|
+
|
|
9
|
+
Treat those `FIXME`s as required integration points.
|
|
10
|
+
|
|
11
|
+
## Source Priority
|
|
12
|
+
|
|
13
|
+
Look for existing project setup logic before inventing new deployment code.
|
|
14
|
+
|
|
15
|
+
Read in this order when available:
|
|
16
|
+
|
|
17
|
+
1. integration tests
|
|
18
|
+
2. base test fixtures
|
|
19
|
+
3. deployment scripts
|
|
20
|
+
4. helper contracts used by tests
|
|
21
|
+
|
|
22
|
+
If none of the above exist, scan for initialize() signatures and constructor arguments directly in source files.
|
|
23
|
+
|
|
24
|
+
## Extract From Existing Setup
|
|
25
|
+
|
|
26
|
+
- deployment order
|
|
27
|
+
- constructor argument meaning
|
|
28
|
+
- role grants and ownership transfers
|
|
29
|
+
- initialization or upgrade calls
|
|
30
|
+
- seed state such as approvals, liquidity, balances, oracle values, and reward funding
|
|
31
|
+
|
|
32
|
+
## Good Defaults
|
|
33
|
+
|
|
34
|
+
- reuse real in-protocol dependencies when the protocol already contains them
|
|
35
|
+
- use mocks only for genuinely external systems or missing infrastructure
|
|
36
|
+
- use mock contracts when appropriate for dependencies that are external to the protocol or unnecessarily complex for the harness
|
|
37
|
+
- good mock candidates include external tokens, external oracles, and complex third-party contracts that are not the main subject of the fuzz campaign
|
|
38
|
+
- when the missing dependency is a simple external ERC20 token, prefer the scaffolded `utils/MockERC20.sol` helper unless the project already contains a more faithful token mock
|
|
39
|
+
- grant actors enough balances and approvals to reach meaningful state transitions
|
|
40
|
+
- prefer deterministic constants over random setup branches
|
|
41
|
+
|
|
42
|
+
## Upgradeable Contracts
|
|
43
|
+
|
|
44
|
+
Before writing setup logic, check whether the target contracts use upgradeable proxies.
|
|
45
|
+
|
|
46
|
+
Strong signals:
|
|
47
|
+
|
|
48
|
+
- `_disableInitializers()` in a constructor
|
|
49
|
+
- an `initialize()` function protected by `initializer`
|
|
50
|
+
- versioned initialization functions protected by `reinitializer`
|
|
51
|
+
|
|
52
|
+
If the contract is upgradeable:
|
|
53
|
+
|
|
54
|
+
- use the project's proxy pattern such as `TransparentUpgradeableProxy` or `ERC1967Proxy`
|
|
55
|
+
- deploy the implementation first, then the proxy with initialization calldata
|
|
56
|
+
- use a dedicated proxy admin address that never calls implementation functions directly
|
|
57
|
+
|
|
58
|
+
If the contract is not upgradeable, plain `new Contract(args)` deployment is fine.
|
|
59
|
+
|
|
60
|
+
## Setup Checklist
|
|
61
|
+
|
|
62
|
+
At minimum, wire:
|
|
63
|
+
|
|
64
|
+
- deployment order
|
|
65
|
+
- constructor arguments
|
|
66
|
+
- proxy deployment and initialization when needed
|
|
67
|
+
- registry or service-locator wiring
|
|
68
|
+
- role grants and ownership transfers, including scoped roles when applicable
|
|
69
|
+
- token approvals and seed balances
|
|
70
|
+
- any required initialization calls
|
|
71
|
+
- market, pool, or strategy configuration needed for handlers to reach meaningful states
|
|
72
|
+
|
|
73
|
+
Deploy all in-protocol dependencies needed by the selected entry points, even if those dependencies do not get handlers.
|
|
74
|
+
|
|
75
|
+
## Signature-Dependent Setup
|
|
76
|
+
|
|
77
|
+
If selected entry points require cryptographic signatures such as signed prices, signed orders, or permit signatures:
|
|
78
|
+
|
|
79
|
+
- store a known private key constant in `Base.sol` for the signer or publisher role
|
|
80
|
+
- register the corresponding address as an approved signer during setup
|
|
81
|
+
- expect handlers in Step 7 to use `vm.sign(privateKey, digest)` to construct valid payloads
|
|
82
|
+
- if router-layer signature construction is too complex for the harness, consider targeting the underlying manager functions directly and document that tradeoff
|
|
83
|
+
|
|
84
|
+
## TODO Rule
|
|
85
|
+
|
|
86
|
+
Leave `// TODO` only when:
|
|
87
|
+
|
|
88
|
+
- the dependency is truly external and the correct mock or fork source is project-specific
|
|
89
|
+
- the constructor needs a business value that cannot be inferred safely
|
|
90
|
+
- the protocol needs a privileged operational decision that should come from the user
|
|
91
|
+
|
|
92
|
+
Every TODO should say what is missing and why it blocks a safe default.
|