[VPD-1862]: VIP to Configure Centrifuge YieldGroup to Liquidity Hub - #761
Draft
GitGuru7 wants to merge 4 commits into
Draft
[VPD-1862]: VIP to Configure Centrifuge YieldGroup to Liquidity Hub#761GitGuru7 wants to merge 4 commits into
GitGuru7 wants to merge 4 commits into
Conversation
Grants the ACM roles on CentrifugeSource_USDT, registers a Centrifuge
ERC-7540 fund behind AdapterCentrifuge, and adds the group to Hub_USDT.
Centrifuge is the first asynchronous yield source on the Hub: requests are
escrowed and settled later by the fund manager at a published NAV, so the
group adds request, cancel and claim operations the synchronous
IYieldGroupBase surface cannot express.
The registered fund is a testnet mock controlled by Venus. Centrifuge has no
BSC-testnet deployment, so there is no real ERC-7540 fund on chain 97.
Centrifuge joins the WITHDRAW queue only. Settlement takes days, so routing
an ordinary user deposit there would park that user's capital in a pending
request, unwithdrawable, for a product they never chose; capital enters only
through an Operator reallocation targeted at the vault. It must still appear
in the withdraw queue, because the Hub rejects a queue omitting a registered
group that holds a balance.
The source is granted pauseHub() on the Hub — a grant to a contract, not to a
human role. The drop guard's only reaction is the group calling pauseHub()
with no try/catch, so without it a genuine breach makes the permissionless
enforceDropGuard revert rather than pause: the breaker would be dead, not
degraded.
No price guard is armed. Each needs a sizing decision against observed NAV
behaviour and an over-tight value is a self-inflicted halt; the roles are
granted so arming them later needs no further VIP.
Two constraints found by simulating rather than reasoning:
- granting all three timelocks pushed the proposal to 30,151,896 gas, past
the 30M block limit. Narrowed to the Normal Timelock, matching VIP-650's
testnet proposal; now 9.55M to propose, 3.63M to execute.
- testnet collapses Operator, Keeper and Guardian into one multisig, so
pauseResource(address) was granted twice and produced byte-identical
proposal actions, which GovernorBravo rejects with "identical proposal
action already queued at eta". Grants are now deduplicated by
(account, signature); on mainnet the holders differ and nothing is removed.
Simulation: 58 passing against a bsctestnet fork at block 128,298,000.
…missions the guardian lacks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the Centrifuge YieldGroup to the Liquidity Hub (USDT) on BNB Chain Testnet:
grants the ACM roles on the new source, registers a Centrifuge ERC-7540 fund behind
AdapterCentrifuge, and adds the group to Hub_USDT.
Centrifuge is the first asynchronous source on the Hub — requests are escrowed and
settled later by the fund manager at a published NAV — so the group carries request,
cancel and claim operations that the synchronous
IYieldGroupBasesurface cannotexpress.
Notes
The registered fund is a testnet mock. Centrifuge has no BSC-testnet deployment,
so there is no real ERC-7540 fund on chain 97.
MOCK_CENTRIFUGE_VAULT_USDTisVenus-controlled and has no mainnet counterpart — it must never appear in a mainnet
proposal.
Permissions: two holders, both with the full surface. The Normal Timelock, and the
Guardian multisig, which stands in for the Operator and the Keeper on this network.
Nobody else is granted anything. The FastTrack and Critical timelocks are left out —
granting all three exceeded the 30M block gas limit.
The Guardian is an ACM admin on testnet and granted itself ten signatures against
address(0)on 2026-08-03, which the ACM reads as "on any contract". Those alreadycover the new source, so the proposal grants it only the 13 Centrifuge-specific
signatures the wildcards miss. Verified on chain: the Guardian holds all ten, all
three timelocks hold none, and no wildcard for this surface exists on mainnet.
The source itself gets
pauseHub()on the Hub. A grant to a contract, not a role.The drop guard's only reaction is the group calling
pauseHub()with no try/catch, sowithout it a genuine breach makes the permissionless
enforceDropGuardrevert insteadof pause — the breaker would be dead, not degraded.
No price guard is armed. Each needs a sizing decision against observed NAV
behaviour and an over-tight value is a self-inflicted halt. The roles are granted, so
arming them later needs no further VIP.
Withdraw queue only, Centrifuge first:
[Centrifuge, FRV, Flux, Core]. The Hubdrains front to back, so settled assets earning nothing are spent before a productive
position; Core stays last as the liquid backstop. Centrifuge must be listed because the
Hub rejects a withdraw queue omitting a group that holds a balance. The deposit queue
is not touched — Centrifuge settles over days, so a user deposit routed there would sit
unwithdrawable in a pending request for a product the user never chose.
Testing
npx hardhat test simulations/vip-664/bsctestnet.ts --fork bsctestnet— 64 passing.Covers, beyond the usual state assertions: that the Guardian's wildcards are live and
that the timelock has none (so the skipped grants are justified and its own grants are
load-bearing); that neither the FastTrack nor the Critical timelock holds anything; and
an end-to-end check that the Guardian can pause the new resource through the wildcard
with no per-contract grant of its own.
Follow-up
The mainnet proposal needs its own permission file. Mainnet separates the roles for
real — distinct Operator and Keeper addresses, a containment-only Guardian, price
guards kept with governance — and has no wildcards to lean on, so every signature must
be granted explicitly.