Skip to content

feat: add hub funded spoke pool testnet VIP - #762

Open
Debugger022 wants to merge 3 commits into
mainfrom
feat/hub-spoke-pool-testnet-vip
Open

feat: add hub funded spoke pool testnet VIP#762
Debugger022 wants to merge 3 commits into
mainfrom
feat/hub-spoke-pool-testnet-vip

Conversation

@Debugger022

@Debugger022 Debugger022 commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

What this VIP does

Phase 1 of the Hub-Funded Spoke pool on BNB Chain testnet. Covers the spoke pool side only (isolated-pools#559). Hub integration and bStock liquidation are Phase 2.

  1. Accept ownership of the spoke Comptroller and the spoke pool registry
  2. Grant 24 ACM roles (details below)
  3. Set the ResilientOracle and the DeviationBoundedOracle on the Comptroller
  4. Upgrade ProtocolShareReserve and register the spoke registry as an additional registry
  5. Move the risk fund's 20% income share from RiskFundConverter to RiskFundBuyback
  6. Register the pool and list 4 markets: USDT (liquidity), TSLAB / NVDAB / SPCXB (collateral)
  7. Set per-market liquidation incentives, and arm the USDT supply allowlist with no members

62 commands. Addresses are placeholders until deployment, so this cannot be simulated yet.

Permissions

Grantee Roles
SpokePoolRegistry the 6 Comptroller setters it drives inside addPool / addMarket
Normal, FastTrack, Critical timelocks the 5 spoke-only roles plus setForcedLiquidation
Guardian none

Everything else is already covered by wildcard grants on this chain, verified on chain rather than assumed. The registry grants are the easy miss: the identical wildcards exist but name the isolated-pools registry as the account, so the spoke registry inherits none and addPool reverts without them.

Notes

  • The spoke pool is listed through a PoolRegistry of its own, so it stays out of the directory the indexer, frontend and risk tooling iterate. The Comptroller takes that registry as a constructor immutable with no setter.
  • Step 4 depends on protocol-reserve#168 being merged and deployed. The upgrade and addPoolRegistry stay in the same proposal, per that PR. Without it every liquidation in the pool reverts, since vTokens call updateAssetsState on both the reserve and the seize path.
  • Step 5 fixes config drift. RiskFundConverter is still a 20% income destination on testnet but was retired on mainnet in VIP-618, and it is the one destination that cannot resolve a pool outside its own registry. The share is unchanged, only the destination.
  • The USDT market ships closed to supply until Phase 2 authorises the Hub source. Seed liquidity minted at listing is unaffected, and redeeming is never gated.
  • Risk parameters are TODO. CF and LT come from PRD section 6, which conflicts with the lower values VIP-633 used for the same assets in the testnet Core pool. Caps are copied from VIP-633, IRM curves are unspecified, and protocolSeizeShare is left at the 5% deploy default.
  • PRD section 6 also names MUB and SNDKB, which have no testnet token, so they are out of scope.

Known follow-up, not blocking

RiskFundConverter still resolves through a single registry. It stops being a PSR destination after step 5, so it does not affect this launch, but it needs the same multi-registry treatment before any spoke pool reaches mainnet. Noted on protocol-reserve#168.

- Foundation draft only. The spoke comptroller, markets, adapter and
  yield source are unbuilt, so their addresses are zero placeholders
  and the proposal cannot be simulated until they land.
- Command order is load-bearing in four places: acceptOwnership before
  any owner-gated setter, setPriceOracle before addPool, the bounded
  oracle before the pool serves a borrow or redeem, and addMarket
  before the supply allowlist is armed.
- Grants only the six ACM roles this chain does not already cover.
  The rest are held by the timelock or the registry as wildcards,
  checked on chain
- Risk parameters the PRD does not specify are left as TODO, as are the bStock liquidation calls, which have no testnet target yet.
@Debugger022 Debugger022 self-assigned this Sep 2, 2026
…ase 1

- Refined comments and descriptions in config.ts for clarity and accuracy regarding pool mechanics and risk factors.
- Adjusted liquidation incentive and collateral factor definitions to align with updated PRD references.
- Enhanced the permissions.ts file to include necessary role strings for the new Spoke pool, ensuring proper access control.
- Added comments to clarify the implications of wildcard grants and the necessity of specific role grants for the new registry.
- Introduced new roles for governance and registry-driven actions, ensuring smooth operation of the Spoke pool.
@Debugger022
Debugger022 marked this pull request as ready for review September 8, 2026 12:26
@greptile-apps

greptile-apps Bot commented Sep 8, 2026

Copy link
Copy Markdown

Greptile Summary

This PR introduces the BNB Chain testnet Phase 1 VIP for a Hub-Funded Spoke pool.

  • Adds a network-specific address book and four-market configuration.
  • Encodes ownership acceptance, ACM grants, oracle configuration, and pool/market registration.
  • Upgrades ProtocolShareReserve for an additional registry and migrates the risk-fund distribution destination.
  • Enables an empty supply allowlist for the USDT liquidity market.
  • The proposal remains non-executable because deployment addresses, risk approval, and simulation coverage are outstanding.

Confidence Score: 4/5

The PR is not safe to use or merge as an executable VIP until proposal-consumed zero addresses are replaced; the unresolved risk configuration and missing simulation should also be addressed.

The proposal deterministically attempts to configure zero-address spoke contracts and upgrade ProtocolShareReserve to a zero implementation, so governance execution cannot complete in its current form. The remaining findings concern risk sign-off, unused IRM configuration, and absent regression coverage.

Files Needing Attention: vips/vip-671/addresses/bsctestnet.ts, vips/vip-671/bsctestnet.ts, vips/vip-671/config.ts

Important Files Changed

Filename Overview
vips/vip-671/addresses/bsctestnet.ts Adds the testnet address book, but proposal-critical spoke and implementation addresses remain zero placeholders.
vips/vip-671/bsctestnet.ts Builds the ordered governance payload, but lacks fork simulation and does not apply or verify configured market IRMs.
vips/vip-671/config.ts Defines four markets and reserve distribution constants, with several materially consequential risk values still awaiting approval.
vips/vip-671/permissions.ts Defines registry and governance ACM roles using a command-builder pattern consistent with existing VIPs.

Reviews (1): Last reviewed commit: "feat(: update Hub-Funded Spoke pool para..." | Re-trigger Greptile

Comment on lines +96 to +104
export const PROTOCOL_SHARE_RESERVE_IMPL = "0x0000000000000000000000000000000000000000";

/// TODO(deploy): isolated-pools `deploy/024-deploy-spoke-pool-registry.ts` -> `SpokePoolRegistry`.
/// A SECOND `PoolRegistry` instance, behind the chain's existing DefaultProxyAdmin. The spoke pool is
/// deliberately kept out of the isolated-pools directory that the indexer, the frontend pool list and
/// the risk tooling all iterate.
/// `Ownable2Step`: the deploy script only NOMINATES the Normal Timelock, so this VIP must call
/// `acceptOwnership()` before `addPool`.
export const SPOKE_POOL_REGISTRY = "0x0000000000000000000000000000000000000000";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Proposal targets zero addresses

The executable proposal still uses zero-address placeholders for the spoke registry, comptroller, markets, and new reserve implementation. If vip671 is submitted in this state, its calls cannot configure the spoke contracts, and the ProxyAdmin upgrade to the zero implementation will revert, preventing proposal execution. Replace every address consumed by the proposal before merging the executable VIP.

Comment thread vips/vip-671/config.ts
Comment on lines +136 to +157
collateralFactor: parseUnits("0.75", 18), // PRD §6
liquidationThreshold: parseUnits("0.8", 18), // PRD §6
supplyCap: parseUnits("236", 18), // TODO(risk): copied from VIP-633's Core listing.
};

export const MARKET_NVDAB: SpokeMarket = {
...collateralDefaults,
symbol: "vNVDAB_HubSpoke",
vToken: VNVDAB_SPOKE,
underlying: NVDAB,
collateralFactor: parseUnits("0.75", 18), // PRD §6
liquidationThreshold: parseUnits("0.8", 18), // PRD §6
supplyCap: parseUnits("450", 18), // TODO(risk): copied from VIP-633's Core listing.
};

export const MARKET_SPCXB: SpokeMarket = {
...collateralDefaults,
symbol: "vSPCXB_HubSpoke",
vToken: VSPCXB_SPOKE,
underlying: SPCXB,
collateralFactor: parseUnits("0.7", 18), // PRD §6
liquidationThreshold: parseUnits("0.75", 18), // PRD §6

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Risk values remain unapproved

These collateral factors and liquidation thresholds are explicitly unresolved risk placeholders, but proposal tooling does not prevent them from entering the governance payload. Compared with VIP-633 for the same assets, these factors allow 25% more borrowing for TSLAB and NVDAB and 40% more for SPCXB. Obtain risk approval and replace or explicitly validate these values before making the proposal executable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant