# Sovryn Rootstock contract-control registry methodology

## What this record is

`sovryn-contract-control.json` is a fail-closed inventory of Rootstock contracts and control paths relevant to Sovryn. It supplies both an engine-native `inventory` for live reads and a dated `reviewedSnapshot` for the no-JavaScript public record. A missing probe, partial family review, unfamiliar controller, or uncertain lifecycle remains unresolved; it is never interpreted as safe. When one verified owner or administrator reaches Bitocracy but another powerful role remains unreviewed, the page shows both facts instead of replacing the verified path with a generic failure label.

The reviewed snapshot is pinned to Rootstock block **9,197,120**, hash `0x4b425988b24350d8e75f5a476fcf7f38f3719c6a2890bf5770612df190ab728e`, timestamp **2026-08-30T20:25:22.000Z**. The inventory version is `2026-08-31.2` and its canonical manifest hash is `sha256:c4eb3e9be1a64cc9bbf278f3473b884171adb22b0f63de70fe8ad34e1b8576c4`.

## Coverage

The registry contains **338 unique Rootstock addresses** after case-insensitive address deduplication. It includes 266 active, 9 legacy, 59 external/implementation-topology, and 4 unclassified rows. The engine-native inventory types these as 256 runtime contracts, 69 implementation-only records, and 13 genuine outside dependencies. Sixty high-value rows are marked as the priority reviewed cohort, while all 338 rows retain source and pinned-block probe evidence.

The unique union of the five official deployment trees is 158 addresses. It includes Sovryn core and external deployment files, Zero, Perimeter, and Mynt. Mynt coverage specifically includes all 18 checked-in Rootstock mainnet deployment files, representing 13 unique Mynt mainnet addresses. Current config sources extend that tree union with lending, AMM, bridge, BabelFish/XUSD, rUSDT/USDT0, and Rune records.

The pinned git sources are:

| Source | Commit | Hashed paths | Tree-manifest SHA-256 |
| --- | --- | ---: | --- |
| `sovryn-smart-contracts` | `7d07782e7d765c6221ea5e6104d38404b0be7ef5` | 161 | `edf747da114c4d846e55baacaeb2344a63533e8fc57984ed40d612ed0c762b81` |
| `sovryn-frontend` | `4c2cbe81aaba39a15c71e7393441b46141f10306` | 5 | `90c7bc2d5cd99705cffc007ade1f10e15a8ced7f87cc546a062faaac8db270a8` |
| `zero` | `a387382261a098b1b7e2dd2b531ef339d22dfcf7` | 35 | `b674d9efc7c87c6a7574d20f753826e351bc51d52873320bd69e4959da797138` |
| `sovryn-perimeter` | `1c8586259864b479cd86b1f907c4de8e14f3e880` | 3 | `8702d89559c9946d32805ad70ba4a741d06b17e0eaa1f19570da36717e76f018` |
| `mynt` | `488d55981b409163075d63de1083e5cdb2bdfa7d` | 31 | `fef411d166f6e376970d65d27d22224fe650bc25747a7fa795a90b9fe2433c84` |
| `oracle-based-amm` | `c0cda95ad24e966c75782f94d5551c19620d6ab5` | 6 | `95d9c644cb6cbfd64f21400ba24e92ba29c5061fed1d321d6b214c7924911524` |
| `Bridge-SC` | `c5a6f607481277a69dd86364976b078501e10c4e` | 8 | `a9d763bfd66aa85881fe58c86b8ebb7645cfada1b457f6032273a11e2e7c34ff` |
| `nbte-bridge` | `b8e40313ab5f91b40120346c8316a62f693d27b2` | 3 | `272ee623766c2119c6ae6fd5a2d74e4b47c67ca504e2736517573ceb39dce2fe` |
| `babelfish-sc` | `57654a815c66ab43f4d826d58ce0dd8872c1a3f4` | 8 | `2beee540a44b9b37ae1a19d73a75fd829906ed7bb1d3bcec563f326179227a6c` |

Each record's source reference uses the repository's single pinned commit URL and separately records the exact path and file SHA-256. This keeps provenance exact without creating hundreds of distinct public links.

## Collection and classification

The generator unions addresses from the pinned deployment trees, current frontend/interaction registries, the original AMM mainnet configs, current Rootstock sides of the ETH and BSC bridge configs, BabelFish mainnet state/token maps, the Rootstock USDT swap broadcast, and the Rune chain-30 OpenZeppelin manifest. At the pinned block it records runtime-code hashes, ERC-1967 implementation and administrator slots, and ABI-derived address-valued controller reads. `probeEvidence` preserves each successful read method, calldata or slot evidence, block number, and block hash.

Only the owner and administrator timelocks at `0x967c…f69f` and `0x6c94…fb13` are Bitocracy terminals. Governors and the Sovryn proxy-administrator contract are topology nodes, so resolution must continue through their critical owner/administrator edge. Guardian, pauser, and pending-owner edges are not used to manufacture a critical topology continuation. The system pauser at `0xdd8e…88b7` remains visibly classified as an outside address, not as a timelock. Its narrow emergency-stop role does not create a warning when it is the only outside path and the contract's reviewed ownership or upgrade path ends at a Bitocracy timelock.

Capabilities use these tiers:

- **Critical:** owner, administrator, proxy upgrade, mint/burn, sweep/rescue/withdraw, and fund-routing authority.
- **Limited:** pauser, guardian, pending owner, and narrowly scoped configuration authority. Pending-owner paths also carry `pending: true`.
- **Informational:** implementation, logic, target, and beacon pointers. An implementation-only contract's local owner is informational and is never treated as proxy upgrade authority.

Status precedence is outside-Bitocracy critical, then outside-Bitocracy limited, then unresolved. A row enters the fully resolved Bitocracy count only after its contract-specific privileged surface is reviewed and its consequential ownership and upgrade paths end at one of the two timelocks or an empty address. The sole narrow exception is the named system pauser described above: the address and role remain visible, but pausing alone does not imply ownership or upgrade control. Twenty-eight rows have source-level review. Twenty-seven resolve through Bitocracy under this policy, while `StakingRewardsProxy` is a critical outside-Bitocracy finding because its separate proxy-upgrade owner is Exchequer. Other rows can still display **Bitocracy path verified — other controls unresolved**. That wording confirms the listed path without claiming that unreviewed roles are safe.

The Zero review distinguishes proxy ownership from the roles inside the delegated logic. The custom proxy source makes both `setOwner()` and `setImplementation()` callable only by `getOwner()`. The pinned logic source likewise restricts administrative dependency and configuration setters to that owner for BorrowerOperations, StabilityPool, TroveManager, ZUSD, PriceFeed, SortedTroves, CommunityIssuance, and HintHelpers. Their checked `getOwner()` paths reach the Bitocracy owner timelock, so these proxy control checks resolve through Bitocracy. ZEROToken remains unresolved because its distinct staking and mint/burn role configuration is not silently treated as owner control. The two standalone TroveManagerRedeemOps addresses are delegatecall implementation code, so their local owners are informational rather than proxy-control findings.

Active totals count active lifecycle rows only. Legacy contracts remain in a separate ledger with their actual control finding visible. Third-party assets and issuer/oracle dependencies—rather than Sovryn-owned tooling or bridge control contracts—are external dependency rows and excluded from active totals. Per-user vesting contracts are likewise excluded from the primary score.

## Live browser check, request limits, and privacy

The interactive page performs its current check directly from the visitor's browser. Read-only Rootstock JSON-RPC calls go to `https://public-node.rsk.co`; Blockscout is not used as the live chain RPC. The reader verifies chain ID 30, selects one current block, discovers lending and AMM members from their on-chain registries, reads contract code, declared proxy storage and control getters at that block, and checks the same block hash again before accepting a result. It never requests a wallet connection, signs a message, or submits a transaction.

Independent JSON-RPC operations are grouped into bounded requests of no more than 50 calls and a 256 KB serialized request body. A missing, rejected, malformed, or inconsistent reply remains unresolved. The whole refresh is also time-bounded and coordinated across tabs so one browser does not start duplicate checks.

Blockscout's API is limited to six reviewed deployer-history feeds: normal and internal-transaction history for each of the three pinned deployer addresses. A current scan normally needs one request per feed; if a feed grows beyond one page, pagination is capped at ten pages per feed and 100 pages across the watch. Those histories begin at the reviewed checkpoint and are used only to surface candidate deployments. A candidate remains unclassified until another record confirms that it belongs to Sovryn. Blockscout also supplies the explorer pages opened when a reader follows a contract, controller, block, or transaction link; merely rendering the register does not open those explorer pages.

The page sends neither login credentials nor an HTTP referrer to either data service. Rootstock's public node and Blockscout still receive ordinary connection information, including the visitor's IP address, browser request headers, and the `sovryn.org` origin. The public node also receives the read-only methods and contract addresses being checked; Blockscout receives the three reviewed deployer addresses in its history URLs. The page does not send these results to the dossier's intake service.

A completed validated result is treated as current for 30 minutes and is reused across tabs in the same browser. An incomplete discovery result is reused for no more than five minutes so a temporary failure can recover sooner. After a request failure, the browser waits through a shared cooldown and then makes a bounded retry; open tabs coordinate so they do not duplicate it. The last verified result can remain in browser storage after its freshness window so it stays visible if an update fails; it remains until it is replaced or the visitor clears the site's stored data. The page does not make rapid or overlapping polling requests.

## Dated findings and limits

The active snapshot totals are **37 outside-Bitocracy critical**, **2 outside-Bitocracy limited**, **179 unresolved**, **26 fully resolved through Bitocracy**, **0 no-mutable-control**, and **22 informational**. These six counts cover all 266 active rows.

Notable pinned findings include:

- The BOS AMM converter at `0xf1de…a27f` reports Exchequer as owner. Its owner can change converter settings, fees, and ownership, so the path is critical and outside Bitocracy.
- The BOS–RBTC pool token at `0xfd83…087b` reports the BOS converter as owner; following the converter's owner reaches Exchequer. The complete static path is therefore also critical and outside Bitocracy.
- osSOV's ERC-1967 administrator is the Sovryn proxy-administrator contract at `0x0389…5780`; that contract's pinned `owner()` resolves to Exchequer. The upgrade path continues through the topology node and ends outside Bitocracy.
- `GenericTokenSender` is active Sovryn tooling, and its pinned `owner()` resolves to Exchequer; it is a runtime outside-critical record, not an external token dependency.
- `RootstockUsdtSwap.rescuer()` resolves to Contracts Guardian. Rescue/sweep authority can move contract funds and is therefore critical.
- The two loan-token logic beacons and six reviewed lending tokens trace ownership or upgrade control to Bitocracy. Their separate `0xdd8e…88b7` system-pauser path remains visible as a narrow emergency-stop role and does not create an outside-control warning by itself.
- `StakingRewardsProxy` has two distinct authority domains. Its delegated reward-logic `owner()` reaches the Bitocracy admin timelock, but `getProxyOwner()` reaches Exchequer, which can replace the implementation. The proxy is therefore a critical outside-Bitocracy finding.

Discovery is intentionally incomplete. The live engine must enumerate registered lending pools, AMM anchors/converters, and watched deployer candidates and compare them with this baseline. The Rune chain-30 manifest establishes a proxy and implementation, but it does not establish current service activation, complete access-control/federation topology, or Bitcoin custody controls. Cross-chain counterpart contracts, off-chain federation operations, Perimeter activation, and issuer-level reserve-token controls also remain explicit gaps. Unknown or partial evidence is not a safety finding.

## Verify

From the repository root, run:

```sh
node evidence/public/verify-sovryn-contract-control.mjs
```

The offline verifier parses the JSON, reproduces the canonical inventory and per-source tree hashes, validates all record and control-path shapes, checks active-only totals, enforces capability and implementation rules, confirms bounded pinned source URLs, and asserts the BOS, proxy-administrator, SOV/XUSD, bridge, Rune, and Mynt fixtures. It does not query a network.
