feat(psr): support multiple pool registries - #168
Debugger022 wants to merge 5 commits into
Conversation
Hub-funded spoke pools ship their own PoolRegistry so indexers and tooling can tell them apart from the isolated pools. Repointing `poolRegistry` at the spoke registry would make every existing isolated pool fail `updateAssetsState`, which vTokens call both when reducing reserves and when seizing the protocol's share of liquidated collateral. Those pools would stop taking income and their liquidations would revert on-chain. `poolRegistry` now stays the primary registry and the spoke registry is added alongside it, so pools that resolve today keep resolving on the same single external call. - add owner gated `addPoolRegistry` / `removePoolRegistry`, bounded by maxLoopsLimit - resolve a market through the primary registry first, then the additional set - add `getPoolRegistries`, `totalAdditionalPoolRegistries` and `isMarketRegistered` views - reject promoting a registry that is already in the additional set, so no registry is probed twice - append new state after `distributionTargets`, so the upgrade needs no reinitializer and no migration - pin the deployed storage slots in a test, and cover the upgrade against the live proxy in a bscmainnet fork suite
Greptile SummaryThe PR extends ProtocolShareReserve market resolution to support a bounded set of additional pool registries while preserving the existing primary registry and deployed storage layout.
Confidence Score: 5/5The PR appears safe to merge, with no concrete blocking or independently actionable non-blocking issue identified. The existing primary-registry behavior and ABI remain intact, additional registry management is bounded and owner-controlled, and deployed storage evidence confirms the new variables occupy previously unused slots.
|
| Filename | Overview |
|---|---|
| contracts/ProtocolReserve/ProtocolShareReserve.sol | Adds bounded multi-registry storage, governance controls, views, and primary-first market resolution without changing existing accounting slots or the updateAssetsState ABI. |
| tests/ProtocolReserve/ProtocolShareReserve.ts | Covers access control, duplicate and limit guards, swap-and-pop removal, views, primary and additional registry resolution, removal behavior, and fund distribution. |
| tests/ProtocolReserve/storageLayout.ts | Pins inherited and deployed storage through slot 304 and verifies the new registry state is appended at slots 305 and 306. |
| tests/fork/ProtocolShareReserve.ts | Upgrades the live BSC proxy in a fork and verifies preserved configuration and accounting alongside simultaneous primary and additional registry resolution. |
Reviews (1): Last reviewed commit: "feat(psr): support multiple pool registr..." | Re-trigger Greptile
|
Note: If it is added as a distribution target in the future, it would need to support the Spoke registry as well. However, there is also an existing compatibility issue: So the registry change alone would not be sufficient. This should be addressed as a follow-up if cc: @fred-venus |
I dont think we will ever use reuse RiskFundConverter, its relatively low efficient, so i am ok to skip |
Summary
Hub-funded spoke pools ship their own
PoolRegistryso indexers and tooling can tell them apart from the isolated pools. PSR stores a singlepoolRegistryand rejects any non-core pool that registry does not know, so pointing it at the spoke registry would break every live isolated pool:updateAssetsStateis called by vTokens both onreduceReservesand on the protocol-seize path, which means those pools stop taking income and their liquidations revert on-chain.This PR lets PSR resolve markets through more than one registry.
poolRegistrystays the primary and is probed first; extra registries are added alongside it.Changes
addPoolRegistry/removePoolRegistry, owner gated, bounded bymaxLoopsLimitupdateAssetsStateresolves through the primary registry, then the additional setgetPoolRegistries,totalAdditionalPoolRegistries,isMarketRegisteredsetPoolRegistrykeeps its behaviour and ABI, plus a guard against promoting a registry that is already in the additional setWhy keep
poolRegistryinstead of only the array + mappingpoolRegistrysits at slot 301 andassetsReservesat 302. Removing the declaration shiftsassetsReservesonto 301 and corrupts live accounting, so a dead placeholder slot would have to stay anyway, holding the same address the array would then duplicate. Storage ends up less clean, not more.poolRegistry()andsetPoolRegistry(address)stay on the deployed ABI, so off-chain consumers are unaffected.addPoolRegistrycall or that chain's isolated-pool liquidations revert until it lands.Storage safety
PSR is a leaf contract with no trailing gap. New state is appended at slots 305/306; 301-304 are untouched, so the upgrade needs no reinitializer and no migration. Pinned by
tests/ProtocolReserve/storageLayout.ts.Rollout
Upgrade and
addPoolRegistry(<spoke registry>)must go in the same VIP proposal, per chain.setPoolRegistryis never called.Testing
DefaultProxyAdmin, assertpoolRegistry, all 18 distribution targets and the income ledger survive, and prove a live isolated pool and a second-registry pool both resolve at the same timeOut of scope
distributionTargetsis global, not per-pool, so spoke income will split across the same destinations as core income. Routing it to the treasury is a separate product decision.RiskFundConverterholds its ownpoolRegistryand is untouched; nothing in this change or its rollout repoints it.