docs: finish UUPS bank demo guide
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# UUPS Bank V1 Demo
|
||||
# UUPS Bank V1 → V2 Demo
|
||||
|
||||
> Educational demo — mock token — never use real funds.
|
||||
|
||||
This repository is the prepared starting point for a live upgradeability lesson. It deploys a local V1 bank that custodies a six-decimal mock ERC-20, records customer balances behind an ERC-1967 proxy, and presents the result in a read-only operations console.
|
||||
This repository is a local-first upgradeability lesson. It deploys a six-decimal mock ERC-20 and a V1 custody ledger behind an ERC-1967 proxy, upgrades the proxy to V2 without losing state, performs a customer-to-customer ledger transfer, and presents the result in a read-only operations console.
|
||||
|
||||
> **Trust boundary:** MockUSDC has no value. These contracts are educational and unaudited; real deposits must never be sent here. The owner can pause customer actions and install arbitrary future logic. UUPS mistakes can corrupt state or permanently brick upgradeability. A real custody product requires professional audits, operational key controls, multisig or timelocked governance, incident procedures, legal advice, and jurisdiction-specific compliance work.
|
||||
|
||||
@@ -19,46 +19,63 @@ make doctor
|
||||
|
||||
## Ten-minute local quick start
|
||||
|
||||
This complete path is local. It needs no Base Sepolia service, browser wallet, faucet, explorer, public RPC, keystore, secret, or real funds.
|
||||
|
||||
In the first terminal:
|
||||
|
||||
```bash
|
||||
make demo-local
|
||||
```
|
||||
|
||||
The command performs a scoped reset, starts a deterministic Anvil chain at `http://127.0.0.1:8545`, deploys and seeds V1, checks its exact state, exports public artifacts, and starts the console at `http://127.0.0.1:5173/`. It remains attached so Ctrl-C safely stops only the recorded project process groups.
|
||||
The command performs a scoped reset, starts deterministic Anvil at `http://127.0.0.1:8545`, deploys and seeds V1, checks its exact state, exports public artifacts, and starts the console at `http://127.0.0.1:5173/`. It remains attached so Ctrl-C safely stops only the recorded project process groups.
|
||||
|
||||
In a second terminal:
|
||||
|
||||
```bash
|
||||
DEMO_EXPECTED_STAGE=v1 make check-state
|
||||
make upgrade-v2
|
||||
make demo-transfer
|
||||
DEMO_EXPECTED_STAGE=v2 make check-state
|
||||
curl --fail http://127.0.0.1:5173/
|
||||
```
|
||||
|
||||
The state check proves Alice has `900 mUSDC`, Bob has `500 mUSDC`, liabilities and reserves are both `1,400 mUSDC`, and the contract version is `1`. After Ctrl-C in the first terminal, run `make reset-local` to remove reproducible local state.
|
||||
Act 1 proves Alice has `900 mUSDC`, Bob has `500 mUSDC`, liabilities and reserves are both `1,400 mUSDC`, and version is `1`. The upgrade keeps the proxy, owner, asset, pause state, customer balances, liabilities, reserves, surplus, and deployment block unchanged while changing the implementation and version to `2`. The internal `250 mUSDC` transfer then leaves Alice with `650 mUSDC` and Bob with `750 mUSDC`; liabilities and reserves remain `1,400 mUSDC`, and the console decodes `BalanceTransferred` without an ERC-20 reserve transfer.
|
||||
|
||||
## Architecture
|
||||
Stop the attached first terminal with Ctrl-C, then remove only reproducible local state:
|
||||
|
||||
Foundry scripts are the state-changing control plane; the browser never signs. `MockUSDC` holds no value. An ERC-1967 proxy keeps the bank address and storage stable while delegating calls to `BankV1`. The proxy itself holds token reserves and the internal ledger records liabilities. A confirmed public deployment manifest and generated ABI connect that on-chain system to a React/Vite console using viem and wagmi for read-only, block-consistent state and event display.
|
||||
```bash
|
||||
make reset-local
|
||||
```
|
||||
|
||||
## Architecture and guarantees
|
||||
|
||||
Foundry scripts are the state-changing control plane; the browser has no connector, signer, transaction client, or write control. `MockUSDC` holds no value. An ERC-1967 proxy keeps the bank address and storage stable while delegating calls to `BankV1` or `BankV2`. The proxy holds token reserves and the internal ledger records liabilities. Confirmed public manifests and generated ABIs connect that system to the React/Vite console through viem and wagmi.
|
||||
|
||||
OpenZeppelin supplies the UUPS and access-control primitives plus storage/upgrade validation. Foundry supplies compilation, tests, scripts, and the local chain. The project supplies the application logic, tests, manifests, lifecycle tooling, and UI. Passing those checks does not make the demo audited, decentralized, or suitable for custody.
|
||||
|
||||
## Command reference
|
||||
|
||||
- `make doctor` — read-only prerequisite, dependency, directory, and port checks.
|
||||
- `make doctor` — check prerequisites, dependencies, runtime locations, configuration, and local ports without changing chain state.
|
||||
- `make setup` — initialize pinned submodules and npm dependencies.
|
||||
- `make demo-local` — run the complete attached V1 experience.
|
||||
- `make verify` — run formatting, clean build, artifact checks, upgrade CLI check, Solidity tests, script tests, process tests, project scan, web lint/typecheck/tests, and production build.
|
||||
- `make check-state` — validate and print the active local V1 state at `http://127.0.0.1:8545`.
|
||||
- `make demo-local` — run the attached local V1 experience.
|
||||
- `make verify` — run Solidity format/build/unit/fuzz/invariant/upgrade gates, artifact and shell-safety tests, the project scanner, and web lint/type/tests/build.
|
||||
- `make check-state` — print and validate the selected stage; use `DEMO_EXPECTED_STAGE=v1` or `v2` for the exact local acts.
|
||||
- `make upgrade-v2` — validate and perform the owner-authorized local V1-to-V2 upgrade, finalize its manifest, and refresh exported artifacts.
|
||||
- `make demo-transfer` — perform Alice's local `250 mUSDC` internal transfer to Bob and validate Act 3.
|
||||
- `make reset-local` — validate recorded process identity, stop only owned groups, and remove only known local artifacts.
|
||||
- `make deploy-v1` — lower-level guarded V1 deployment and manifest finalization.
|
||||
- `make seed-v1` — lower-level deterministic Act 1 deposits and withdrawal.
|
||||
- `make sync-artifacts` — regenerate the ABI module and publish the confirmed active manifest.
|
||||
- `make sync-artifacts-check` — test generation and prove generated ABIs are current.
|
||||
- `make deploy-v1` and `make seed-v1` — run the lower-level guarded V1 deployment and deterministic Act 1 setup used by `make demo-local`.
|
||||
- `make sync-artifacts`, `make sync-artifacts-check`, `make sync-abis`, and `make publish-web-manifest` — regenerate or validate the ABI bridge and publish only the confirmed active manifest.
|
||||
- `make test-finalize-manifest` — exercise manifest finalization in isolation.
|
||||
- `make select-anvil` and `make select-base-sepolia` — explicitly select and republish an existing confirmed manifest.
|
||||
- `make archive-base-manifest` — safely archive the Base canonical manifest before an intentional redeployment.
|
||||
- `make deploy-base-sepolia`, `make upgrade-base-sepolia`, and `make transfer-base-sepolia` — explicit optional-testnet commands with chain, actor, account, and RPC guards.
|
||||
|
||||
## Optional Base Sepolia encore
|
||||
|
||||
The local lesson is complete without a wallet, faucet, explorer, or public RPC. An optional Base Sepolia encore is available only after the local V1→V2 demo and `make verify` succeed. It uses a named encrypted Foundry keystore through `--account` plus the same public address through `--sender`; there is no private-key or mnemonic fallback.
|
||||
The local lesson above is complete without a wallet, faucet, explorer, or public RPC. The optional Base Sepolia encore is separate and runs only after the local V1→V2 demo and `make verify` succeed. It uses a named encrypted Foundry keystore through `--account` and the same public address through `--sender`; no supported command accepts a raw private key or mnemonic.
|
||||
|
||||
Copy `.env.example` to `.env` and fill only its public configuration. `BASE_SEPOLIA_RPC_URL` is the terminal endpoint and may be credentialed; `BASE_SEPOLIA_PUBLIC_RPC_URL` is intentionally public and is the only RPC serialized for the browser. Foundry requests the keystore password interactively, and the password never belongs in `.env`.
|
||||
Copy `.env.example` to `.env` and fill only its public configuration. `BASE_SEPOLIA_RPC_URL` is the terminal endpoint and may be credentialed; `BASE_SEPOLIA_PUBLIC_RPC_URL` is intentionally public and is the only RPC serialized for the browser. Foundry requests the keystore password interactively, and that password never belongs in `.env`.
|
||||
|
||||
Use `make archive-base-manifest` before an intentional Base redeployment. The command moves only the Base canonical manifest to a timestamped sibling; it preserves the active browser fallback and all Anvil state. `make select-anvil` and `make select-base-sepolia` explicitly switch the active manifest and republish the browser copy. See the presenter runbook for the exact wallet onboarding, funding boundary, deploy/upgrade/transfer sequence, and recovery rules.
|
||||
Use `make archive-base-manifest` before an intentional Base redeployment. It moves only the Base canonical manifest to a timestamped sibling while preserving the active browser fallback and Anvil state. See the [presenter runbook](docs/PRESENTER_RUNBOOK.md) for the exact optional onboarding, funding boundary, execution sequence, and recovery rules.
|
||||
|
||||
Continue with the [learning guide](docs/LEARNING_GUIDE.md) or rehearse from the [presenter runbook](docs/PRESENTER_RUNBOOK.md).
|
||||
|
||||
Reference in New Issue
Block a user