Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Developer/BACK_LOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@
| BL-30 | Solidity/foundry (task contracts) | No recovery from a stalled GI | If a T1/T2 batch never reaches the reveal quorum, `finalizeT1Aggregation`/`finalizeT2Aggregation` revert forever (`TC_NoSubmissions`/`TC_InsufficientSubmissions`), and there is no owner path to skip the batch or abort the GI. `endGI` needs `AggregatorsSlashed` and `startGI` needs `GIended`, so the model is stuck: its reward pool and its validators' registration slots stay locked. This is also why BL-26's contract-side re-anchor cap was deferred. Needs a GI-abort design: who may abort, when, and where the reward pool goes. | P3/P4 | PR No. 191 review (BL-26); PR No. 204 review (`DINTaskCoordinator.md` §10 No. 6) | 🆕 Decided, unimplemented — Abraham's GI-abort policy (Oct 26, [#222](https://github.com/InfiniteZeroFoundation/DevNet/issues/222)): anyone may abort after a stall timeout, locked rewards go back to their funders, slots are released, non-revealers are still penalised; the timeout value is set with the other testnet parameters in [#155](https://github.com/InfiniteZeroFoundation/DevNet/issues/155). Adds code to `DINTaskCoordinator`, which has 55 B above the size gate ([#201](https://github.com/InfiniteZeroFoundation/DevNet/issues/201)) |
| BL-31 | Solidity/foundry (slashing) | S6 no-participation slashing is implemented but not wired | `DinValidatorStake.recordNoParticipation` (escalating 10%-per-breach slash past `s6NoParticipationThreshold`) exists and is tested, but no task contract calls it. They deliberately skip it where `slashPartial` (S1/S2, with S5 escalation) already penalises the same missed work, to avoid stacking past `MIN_STAKE`. So S6 never fires. Decide whether S6 should cover something S1/S2 don't (e.g. registered but never assigned or never active), or whether to remove it and its parameters. | P3 | PR No. 204 review (`DinValidatorStake.md` §14 No. 1), Sep 30, 2026; slashing taxonomy S6 (issue #38) | ⏸️ Parked for testnet — Abraham (Oct 26, [#224](https://github.com/InfiniteZeroFoundation/DevNet/issues/224)): S1/S2 plus S5 already cover missed work; leave S6 unwired (or remove it and its parameters) and revisit after testnet. Needs a removal PR or a "parked" note in the docs |
| BL-32 | Tooling / onboarding | Contributor environment preflight check | No single command checks a dev machine before work starts. Each of these has already cost time: (1) Python ≥ 3.12; (2) `forge`/`anvil` installed and solc 0.8.28 available; (3) `foundry/node_modules` present — without `npm ci`, `forge test`'s parallel tests race to fetch `@openzeppelin/upgrades-core` over npx (see [CLAUDE.md](../CLAUDE.md)); (4) `eth-account` and `py-multibase` import; (5) `torch` imports in the active venv (full `pytest` run); (6) `.env`/`.env.<network>` exist, the RPC endpoint answers, and `resolve_ipfs_config()` resolves. | P3/P4 (onboarding; small, ~half a day) | `preflight.sh` pattern from [Osomudeya/devops-scripting-labs](https://github.com/Osomudeya/devops-scripting-labs) (reviewed 2026-10-02); no existing equivalent (note: the only "preflight" in `dincli/cli/system.py` is the bridge's tx preflight — unrelated) | 🟡 Mostly fixed — [PR #255](https://github.com/InfiniteZeroFoundation/DevNet/pull/255) added `scripts/preflight.py` (Python/forge/anvil/node_modules/package checks, `--network` RPC/IPFS checks, 13 tests in `tests/test_preflight.py`, a preflight section in `Documentation/public/getting-started.md`). Remaining (exit non-zero on `node_modules`, eth-account/py-multibase, `--network` RPC/IPFS failures) tracked in [#245](https://github.com/InfiniteZeroFoundation/DevNet/issues/245) |
| BL-33 | Tooling / deploy | On-chain deployment drift check | Nothing verifies that `foundry/deployments/<network>.json` (and the `din_info` that `dincli system import-deployments` writes) still matches the chain. Proposal: a read-only check, either a forge script or `dincli system verify-deployment`, that for each recorded contract compares (1) the proxy's EIP-1967 implementation and admin slots against the recorded implementation/`proxyAdmin*` addresses; (2) the deployed runtime code hash against the current `forge build` artifact (immutables masked); (3) owner / DIN-Representative addresses; (4) wiring: `DinCoordinator` ↔ `DinToken`/`DinValidatorStake`/`DinModelRegistry`/fee router/treasury links and slasher authorizations on `DinValidatorStake`. Report per-item `OK` / `DRIFT` with expected vs. actual. Caveat: it only covers what the deployments JSON records, so a clean run doesn't prove nothing else was deployed or authorized. | P3 (before the DevNet 3.0 deploy; re-run after every `UpgradePlatform.s.sol` run) | Terraform state-vs-live drift pattern from [Osomudeya/devops-scripting-labs](https://github.com/Osomudeya/devops-scripting-labs) `03-drift-detection` (reviewed 2026-10-02); no existing code reads EIP-1967 slots or code hashes in `dincli/` or `foundry/script/` | 💭 Idea |
| BL-33 | Tooling / deploy | On-chain deployment drift check | Nothing verifies that `foundry/deployments/<network>.json` (and the `din_info` that `dincli system import-deployments` writes) still matches the chain. Proposal: a read-only check, either a forge script or `dincli system verify-deployment`, that for each recorded contract compares (1) the proxy's EIP-1967 implementation and admin slots against the recorded implementation/`proxyAdmin*` addresses; (2) the deployed runtime code hash against the current `forge build` artifact (immutables masked); (3) owner / DIN-Representative addresses; (4) wiring: `DinCoordinator` ↔ `DinToken`/`DinValidatorStake`/`DinModelRegistry`/fee router/treasury links and slasher authorizations on `DinValidatorStake`. Report per-item `OK` / `DRIFT` with expected vs. actual. Caveat: it only covers what the deployments JSON records, so a clean run doesn't prove nothing else was deployed or authorized. | P3 (before the DevNet 3.0 deploy; re-run after every `UpgradePlatform.s.sol` run) | Terraform state-vs-live drift pattern from [Osomudeya/devops-scripting-labs](https://github.com/Osomudeya/devops-scripting-labs) `03-drift-detection` (reviewed 2026-10-02); no existing code reads EIP-1967 slots or code hashes in `dincli/` or `foundry/script/` | ✅ Fixed — PR [#254](https://github.com/InfiniteZeroFoundation/DevNet/pull/254) (issue [#244](https://github.com/InfiniteZeroFoundation/DevNet/issues/244)). `dincli system verify-deployment` added: reads the deployments JSON, checks EIP-1967 impl/admin slots, extcodehash, ProxyAdmin owner(), DinCoordinator wiring, and slasher authorizations. `DeployPlatform.s.sol` and `UpgradePlatform.s.sol` extended to write impl addresses, codehashes, deployer, and git commit. 16 tests in `tests/test_verify_deployment.py`. |
| BL-34 | Solidity/foundry (task contracts) | `DINModelRegistry.disableModel()` kill-switch doesn't reach the live task contracts | `modelDisabled[modelId]` only gates `requestModelRegistration`/`requestManifestUpdate` inside the registry itself. `DINTaskCoordinator`/`DINTaskAuditor` have no dependency on, or awareness of, the registry (confirmed: zero functional references; the auditor has two doc comments naming `DINModelRegistry` by name (L31, L434) plus two more referencing "model registry" generically without naming the type (L393, L405) — none are functional checks). A model the DIN-Representative has disabled — e.g. because its task contracts are wrongfully slashing honest validators — keeps running full GIs completely unaffected. The task contracts' own doc table calls this a "kill-switch," which it isn't. Needs a decision: wire the task contracts to check `modelDisabled` before state-changing calls (requires threading the model ID + registry address into contracts that don't know about the registry today), or document `disableModel` as registry-metadata-only. | P3/P4 | 2026-07 security review M-2 (`Documentation/technical/audits/foundry-src-security-review.md`) | 🆕 Decided, unimplemented — Abraham (Oct 26, [#224](https://github.com/InfiniteZeroFoundation/DevNet/issues/224)): make the kill-switch real before the public testnet (at minimum stop new GIs on a disabled model's task contracts), preferably in `DINTaskAuditor` or a small external guard given `DINTaskCoordinator`'s size headroom |
| BL-35 | Solidity/foundry (registry) | `rejectModel()`'s non-refund of the registration fee was never confirmed as intentional | `feePaid` (set at `requestModelRegistration`) is never refunded on `rejectModel()`, but it's also never refunded on `approveModel()` either — the fee appears to be a deliberate pay-to-apply cost regardless of outcome (anti-spam), not an oversight specific to rejection. Never written down as a deliberate choice anywhere. Needs confirmation and a doc note in `DINModelRegistry.md` / the dinrep role docs, so a future reader doesn't "fix" it into an inconsistent partial-refund state. | P4 (doc-only once confirmed) | 2026-07 security review L-4 (`Documentation/technical/audits/foundry-src-security-review.md`) | ✅ Decided — keep as intended (Abraham, Oct 26, [#224](https://github.com/InfiniteZeroFoundation/DevNet/issues/224)): the registration fee is a pay-to-apply anti-spam cost, refunded on neither approval nor rejection. Docs pending (`DINModelRegistry.md`, dinrep role docs) |
77 changes: 77 additions & 0 deletions Documentation/public/guides/verify-deployment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Verifying a Platform Deployment

`dincli system verify-deployment` is a read-only drift check that compares
`foundry/deployments/<network>.json` against the live chain and reports
`[OK]` / `[DRIFT]` / `[ERROR]` per item.

Run it after every `DeployPlatform.s.sol` or `UpgradePlatform.s.sol` invocation,
and before each Global Iteration if you want to rule out a stale deployment file.

## Prerequisites

- `dincli` installed and a network configured (`dincli system configure-network`).
- `foundry/deployments/<network>.json` present (written by the deploy scripts).
- An RPC endpoint reachable for the active network.

No wallet or signing key is required — the command never sends transactions.

## Quick start

```bash
# Check the active network (default: local → foundry/deployments/localhost.json)
dincli system verify-deployment

# Explicit file
dincli system verify-deployment --file foundry/deployments/sepolia_op_devnet.json

# CI / no color
dincli system verify-deployment --no-color

# Also verify expected task-coordinator slashers
dincli system verify-deployment --slashers 0xTaskCoord1,0xTaskCoord2
```

## What is checked

| # | Check | DRIFT condition |
|---|-------|-----------------|
| 1 | EIP-1967 implementation slot | Slot value ≠ `dinXxxImpl` in the JSON |
| 2 | EIP-1967 admin slot | Slot value ≠ `proxyAdminXxx` in the JSON |
| 3 | Implementation extcodehash | `keccak256(eth_getCode(impl))` ≠ `dinXxxImplCodehash` in the JSON |
| 4 | ProxyAdmin `owner()` | On-chain owner ≠ `owner` in the JSON |
| 5 | `DinCoordinator` wiring | `dinToken` / `dinValidatorStakeContract` / `feeRouter` addresses mismatch |
| 5b | `DinFeeRouter.treasury()` wiring | Return value ≠ `dinTreasury` in the JSON (checked independently of `dinCoordinator`) |
| 5c | `DINModelRegistry.dinValidatorStake()` wiring | Return value ≠ `dinValidatorStake` in the JSON |
| 6 | Slasher authorizations | Expected slasher not authorized (only when `--slashers` is given) |

Checks 1–4 require that `DeployPlatform.s.sol` / `UpgradePlatform.s.sol` was run
at the correct version (issue #244 or later), which writes `dinXxxImpl`,
`dinXxxImplCodehash`, and `owner` into the JSON. Files written by an older
deploy script are missing these keys — affected items are reported as `[INFO]`
rather than `[DRIFT]`, and the command still exits 0.

## Recording metadata at deploy time

The deploy scripts record the implementation address and its extcodehash
automatically. To also record the deploying git commit, set `GIT_COMMIT_HASH`
before running the script:

```bash
GIT_COMMIT_HASH=$(git rev-parse HEAD) \
forge script foundry/script/DeployPlatform.s.sol \
--rpc-url "$RPC_URL" --broadcast ...
```

The same variable works for `UpgradePlatform.s.sol`.

## Exit codes

| Code | Meaning |
|------|---------|
| 0 | All checks passed (or reported as `[INFO]` due to missing recorded values) |
| 1 | At least one `[DRIFT]` or `[ERROR]` item |

## Limitations

A clean run does not prove that nothing else was deployed or authorized outside
the deployments file. Only the contracts recorded in the file are checked.
Loading
Loading