📄 README.md
D-OPEN SOVEREIGN
1# Ꭰ-Library Smart Contracts
2
3The on-chain engine of [DataPond.Earth](https://datapond.earth) — a sovereign digital library. These are the Solidity contracts that gate access, record activity, and anchor permanence for a library built to outlast any single company, server, or founder.
4
5Everything here is public by design. The contracts hold no user files and no private data — content lives permanently on [Arweave](https://arweave.org); these contracts are the access-control and bookkeeping layer sitting in front of it. Auditors, integrators, and the merely curious are equally welcome to read, deploy, and question this code.
6
7---
8
9## Design in one sentence
10
11**A registry of immutable, upgradeable-by-redeploy contracts, gated by a single access-control layer, writing append-only activity records that nothing — including the library's own operators — can quietly rewrite.**
12
13No contract here is proxy-upgradeable. There is no admin key that can silently swap out logic behind a fixed address. When the contracts change, a new version is deployed and the [`AddressRegistry`](#addressregistry--the-front-door) is updated to point at it — a visible, on-chain event, not an invisible one.
14
15---
16
17## How a write happens
18
19Every state-changing action — registering an account, logging a download, recording a donation — flows through the same choke point:
20
21```
22 caller (wallet or dApp)
23 │
24 ▼
25 Factory orchestrates the write; the only contract
26 │ most external calls actually target
27 ▼
28 Bouncer ──────────────▶ BouncerStorage
29 (access check) the source of truth for accounts, usernames,
30 │ membership levels, and authorized callers
31 ▼
32 ScientistStorage content activity: visits, downloads, ratings,
33 shares, edits — batched and stored by month
34 │
35 ▼
36 BackupStorage per-user patch history + Arweave sidecar links
37```
38
39A request that fails the `Bouncer` check never reaches storage. This is enforced in Solidity, not in application code — no frontend, admin panel, or API server can bypass it, because none of them hold write authorization on the storage contracts directly.
40
41---
42
43## Contracts
44
45### Core write pipeline
46
47| Contract | Role |
48|---|---|
49| **`Factory`** | The public entry point. Inherits `Bouncer`, `Backup`, `Accountant`, `Scientist`, and `Subscription` — one address exposes registration, content-activity logging, donations, and subscriptions as a single coherent ABI. |
50| **`Bouncer`** / **`BouncerStorage`** | Access control. `BouncerStorage` is the canonical account registry — address ↔ user ID ↔ username, referral graph, membership level — and the only contract that can authorize new writers. `Bouncer` is the facade other contracts call through. |
51| **`Scientist`** / **`ScientistStorage`** | Content-activity ledger. Records visits, downloads, ratings, shares, and edits, batched by month and by content object, without storing any personally identifying data alongside the activity itself. |
52| **`Backup`** / **`BackupStorage`** | Per-user backup trail — patch history and pointers to permanent Arweave-hosted content, keyed by user level rather than by name. |
53| **`Accountant`** | Donation and funding logic. Uses a [Pyth Network](https://pyth.network) price oracle to accept native-token donations denominated in USD, and splits funds across project, maintenance, and marketing treasuries. |
54| **`Subscription`** / **`SubscriptionManager`** | The subscription graph between accounts — who follows whom, with a bounded traversal (`MAX_BFS_NODES`) so on-chain graph reads stay gas-safe. |
55| **`UserBackup`** | Compact per-user append log of binary-encoded actions (`storeBatchActions` / `loadActions`), the lowest-level storage primitive `Backup` builds on. |
56
57### Registry & identity
58
59| Contract | Role |
60|---|---|
61| **`AddressRegistry`** | An immutable, append-only record of every contract this library has ever deployed, per network — the mechanism that lets a client resolve "where is `Factory` today?" without hard-coding an address that a hard fork or redeploy could orphan. See [below](#addressregistry--the-front-door). |
62| **`Identity`** | Generates human-readable, procedurally-assigned usernames (adjective + verb pairs) at registration time — no email, no phone number, no personal identifier required to hold an account. |
63| **`Ownable`** | Minimal single-owner access-control base (OpenZeppelin-style), used by contracts that need one clearly accountable admin key rather than the full `Bouncer` authorization graph. |
64
65### Project funding
66
67| Contract | Role |
68|---|---|
69| **`ProjectManager`** / **`ProjectManagerStorage`** | Tracks funding proposals ("projects"), their multilingual version history, per-address donation totals, and allocated vs. remaining budget. |
70
71### Shared utilities
72
73| Contract | Role |
74|---|---|
75| **`ErrorLibrary`** | Every custom revert error used across the codebase, in one place — so a failed transaction always reverts with a name you can look up, not a bare string or a silent `require`. See [`README_ErrorParser.md`](../README_ErrorParser.md) for a JS utility that decodes these client-side. |
76| **`DateUtils`** | Gas-conscious date and integer-to-string formatting helpers shared by the storage contracts. |
77| **`Migrations`** | Standard Truffle/Hardhat migration bookkeeping contract; not part of the library's data model. |
78
79### Interfaces
80
81`IBackup`, `IBouncerStorage`, `IProjectManagerStorage`, `IScientistStorage`, `ISubscriptionManager` define the storage-contract ABIs consumed by their matching facade contracts above. Reading an interface is the fastest way to see exactly what a storage contract promises to callers, independent of its implementation.
82
83### In development
84
85`LibraryRegistry` — a registry for community-proposed content collections, gated by member level — exists in this directory but is not yet part of the deploy pipeline below. Treat it as a preview, not a deployed dependency.
86
87---
88
89## `AddressRegistry` — the front door
90
91Traditional dApps hard-code contract addresses at build time. If a contract is redeployed — a bug fix, a chain migration, a hard fork — every client needs a new build. `AddressRegistry` exists so they don't:
92
93```solidity
94contract AddressRegistry {
95 struct ContractRecord {
96 address contractAddress;
97 string abiUrl;
98 // ...
99 }
100}
101```
102
103Any client — this project's own frontend, a third-party integrator, an auditor's script — can query `AddressRegistry` for the current address of any core contract, on any deployed network, and get back a value that was itself written on-chain by an accountable admin action. It is the one contract every other deployment script (`05-sync-registry.js`) writes into last, after everything else exists.
104
105---
106
107## Access control model
108
109Every write-capable storage contract (`BouncerStorage`, `ScientistStorage`, `BackupStorage`, `ProjectManagerStorage`) follows the same three-tier pattern:
110
111- **`admin`** — a single address (an EOA or a multisig, at the deployer's discretion) that can authorize or revoke writers. Changing `admin` is itself an on-chain, logged action.
112- **`_isAuthorized[address]`** — the set of contracts (never end users directly) permitted to call write methods. In production this is exactly `Factory`, and nothing else.
113- **Everything else is a public view function.** Read access to activity stats, account records, and backup history is unrestricted — the ledger is public by construction, not by a permission you have to request.
114
115This means a compromised frontend can, at worst, submit transactions on behalf of whoever signed them — it can never grant itself write access it wasn't already authorized for, and it can never alter historical records.
116
117---
118
119## Networks
120
121| Name | Chain ID | Role |
122|---|---|---|
123| CORE | 1116 | Production |
124| tCORE2 | 1114 | Testnet |
125| Base Sepolia | 84532 | Test |
126
127Deployed addresses, ABIs, and network RPC details are published per-chain and consumed by [`@the_library/web3-contracts`](../packages/web3-contracts) — see the root [`config/networks.js`](../config/networks.js) for the canonical source.
128
129---
130
131## Compiler configuration
132
133- Solidity `0.8.24`
134- `viaIR: true`, optimizer enabled at `500` runs — tuned for contracts that are deployed once and called often, not deployed often.
135
136---
137
138## Deploy order
139
140Deployment is scripted, sequential, and idempotent — see [`deploy/core/`](../deploy/core):
141
142```
14300-deploy-registry.js AddressRegistry
14401-deploy-bouncer.js BouncerStorage
14501-deploy-project-manager.js ProjectManagerStorage
14602-deploy-scientist.js ScientistStorage
14703-deploy-backup.js BackupStorage
14803b-deploy-subscription-manager.js SubscriptionManager
14904-deploy-factory.js Factory (wires Bouncer + Accountant + Scientist + Subscription together)
15005-sync-registry.js writes every address above into AddressRegistry
151```
152
153```sh
154pnpm run build # compile (Hardhat, force)
155pnpm test # run the Mocha/Chai test suite against a local network
156pnpm run test:coverage # solidity-coverage report
157pnpm run evm:deploy # deploy to every configured network
158pnpm run sync:abis # copy fresh ABIs into packages/web3-contracts
159pnpm run sync:config # regenerate the public-safe deployed-address config
160```
161
162---
163
164## Verifying this yourself
165
166Nothing above is a claim you need to take on trust:
167
1681. **Read the storage contracts directly** — `BouncerStorage.sol`, `ScientistStorage.sol`, `BackupStorage.sol` — and confirm that only `admin` can call `addAuthorized`, and only addresses in `_isAuthorized` can call any write method.
1692. **Read `Factory.sol`** and confirm it is the only contract the deployment scripts add to each storage contract's authorized-caller set.
1703. **Query `AddressRegistry`** on-chain for any network above and compare its record against what a client claims to be using.
1714. **Run the test suite** in [`../test/`](../test) — it exercises the access-control boundary directly (`Bouncer.spec.js`, `BouncerStorage.spec.js`), not just the happy path.
172
173---
174
175## Licence
176
177Published under the **D-Open Code Sovereign Licence v1.0**. See the licence header in each source file, or [`packages/canonical-schemas/README.md`](../packages/canonical-schemas/README.md#the-d-open-code-sovereign-licence--source-code) for the full licence architecture — including the "Technical Guardian" accountability structure that stands behind this code.
178