Skip to content

[VPD-778] Configure Fixed Rate Vaults on Mainnet#705

Open
GitGuru7 wants to merge 10 commits into
feat/VIP-664from
feat/vpd-778-fixed-rate-vault-mainnet
Open

[VPD-778] Configure Fixed Rate Vaults on Mainnet#705
GitGuru7 wants to merge 10 commits into
feat/VIP-664from
feat/vpd-778-fixed-rate-vault-mainnet

Conversation

@GitGuru7
Copy link
Copy Markdown
Contributor

@GitGuru7 GitGuru7 commented May 8, 2026

VIP-627: Activate Institutional Fixed Rate Vault System

Summary

If passed, this VIP activates the Institutional Fixed Rate Vault system on BNB Chain and upgrades the Protocol Share Reserve to support it. The new system introduces fixed-rate, time-bound vaults intended for whitelisted institutional borrowers, with a dedicated liquidation flow separate from the existing core pool.

Description

The proposal performs the following on-chain actions:

1. Grant ACM permissions via the ACMCommandsAggregator

Permissions for the new InstitutionalVaultController and LiquidationAdapter contracts have been pre-loaded off-chain into the ACMCommandsAggregator (index 3). The VIP temporarily grants the aggregator the DEFAULT_ADMIN_ROLE on the AccessControlManager, executes the batch, and revokes the role in the same proposal. This grants role-based access (33 permissions in total) over all administrative functions of both contracts to the Normal / Fast-track / Critical timelocks and, where appropriate, the Critical Guardian.

  • Vault lifecycle and operations (createVault, openVault, cancelVault, partialPauseVault, completePauseVault, unpauseVault, closeVault, sweep, approvePositionTransfer, revokePositionTransfer) — granted to all three timelocks and the Critical Guardian.
  • Risk parameter setters (setLiquidationThreshold, setLiquidationIncentive, setLatePenaltyRate, setVaultImplementation) — granted to the three timelocks only.
  • Plumbing setters (setLiquidationAdapter, setOracle, setProtocolShareReserve, setComptroller, setTreasury) — granted to the Normal Timelock and Critical Guardian.
  • LiquidationAdapter controls (setLiquidatorWhitelist, setSettlerWhitelist, setProtocolLiquidationShare, setCloseFactor, sweepProtocolShareToReserve) — granted to the timelocks, with the whitelist and sweep functions also granted to the Critical Guardian.

2. Complete two-step ownership transfers

The InstitutionalVaultController, the LiquidationAdapter, and the InstitutionPositionToken were deployed with their Ownable2Step pending owner set to the Normal Timelock. The VIP calls acceptOwnership() on the controller and adapter, and acceptPositionTokenOwnership() on the controller (which in turn accepts ownership of the position-token NFT).

3. Wire the LiquidationAdapter into the controller

Call setLiquidationAdapter on the InstitutionalVaultController, pointing it at the newly deployed LiquidationAdapter.

4. Whitelist the Critical Guardian as the initial liquidator and settler

Whitelist the Critical Guardian on the LiquidationAdapter as both an authorized liquidator and an authorized settler, so that the dedicated liquidation flow can run under operational control while remaining governance-bounded.

5. Upgrade the ProtocolShareReserve implementation

Upgrade the ProtocolShareReserve proxy to a new implementation that recognises an additional income type produced by institutional-vault liquidations, so that protocol-share income flowing in from the LiquidationAdapter is routed and accounted for correctly.

Security and additional considerations

  • The DEFAULT_ADMIN_ROLE grant to the ACMCommandsAggregator is scoped to this proposal: it is granted, used once to apply a pre-loaded permission batch, and revoked in the same transaction sequence.
  • All sensitive risk-parameter changes (liquidation threshold, liquidation incentive, late-penalty rate, vault implementation) are restricted to timelock callers only and are not exposed to the Critical Guardian.
  • The Critical Guardian initially fills the liquidator and settler roles on the LiquidationAdapter; additional whitelisted parties can be added later via subsequent VIPs.

Deployed contracts (BNB Chain)

  • InstitutionalVaultController (proxy): 0x6D9e91cB766259af42619c14c994E694E57e6E85
  • LiquidationAdapter (proxy): 0x17A6222fB8b4b6D852cA54f5bc376a6A2c6224Bd
  • InstitutionPositionToken: 0x3Ed56f6937fc8549f9325405d1e8E650739647Fa
  • ProtocolShareReserve (proxy): 0xCa01D5A9A248a830E9D93231e791B1afFed7c446
  • New ProtocolShareReserve implementation: 0x4eC6D748a2647000895b455c408f85602A144Ed6
  • ACMCommandsAggregator: 0x8b443Ea6726E56DF4C4F62f80F0556bB9B2a7c64 (batch index 3)

@GitGuru7 GitGuru7 self-assigned this May 8, 2026
@GitGuru7 GitGuru7 marked this pull request as ready for review May 26, 2026 11:45
Comment thread vips/vip-627/bsctestnet-addendum.ts
Comment thread vips/vip-664/bscmainnet.ts Outdated
{
target: ACM_AGGREGATOR,
signature: "addGrantPermissions((address,string,address)[])",
params: [PERMISSIONS],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be done ahead of the vip. I saw addGrantPermissions itself is permissionless

  1. if attacker calls addGrantPermissions ahead of us, its gonna take the index=2
  2. then in the follow up cmd we have executeGrantPermissions(2) and we are fucked

@fred-venus
Copy link
Copy Markdown
Contributor

also i guess we will need to update the implementation of PSR

context: VenusProtocol/protocol-reserve#165 (comment)

Comment thread vips/vip-664/bscmainnet.ts Outdated
{
target: INSTITUTIONAL_VAULT_CONTROLLER,
fn: "approvePositionTransfer(address)",
callers: [NORMAL, FAST_TRACK, CRITICAL],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pls add CRITICAL_GUARDIAN as well for easier operation

Copy link
Copy Markdown
Contributor

@fred-venus fred-venus May 27, 2026

Choose a reason for hiding this comment

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

also seems the signature is wrong

Image

target: INSTITUTIONAL_VAULT_CONTROLLER,
fn: "openVault(address)",
callers: [NORMAL, FAST_TRACK, CRITICAL, CRITICAL_GUARDIAN],
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

where is cancelVault ?

import ACM_AGGREGATOR_ABI from "./abi/ACMAggregator.json";
import ACCESS_CONTROL_MANAGER_ABI from "./abi/AccessControlManager.json";
import INSTITUTION_POSITION_TOKEN_ABI from "./abi/InstitutionPositionToken.json";
import INSTITUTIONAL_VAULT_CONTROLLER_ABI from "./abi/InstitutionalVaultController.json";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ABI is stale — has approvePositionTransfer(address) (1 param, should be 2) and missing cancelVault(address). VIP permission strings are correct (verified against on-chain source at 0x9e1ECb...). ABI needs regeneration from build artifacts.

GitGuru7 and others added 2 commits May 27, 2026 20:31
Existing 'CriticalGuardian should be able to create vault' test only asserts
that the call doesn't revert with Unauthorized — but the test config has
marginRate=1.5e18 and fixedAPY=5e16, both of which violate _validateVaultConfig
invariants, so the call always reverts with InvalidConfig and the success
path is never exercised.

Add a parallel test that:
- uses valid config (marginRate=0.5e18, fixedAPY=500 bps)
- deploys a stub oracle returning 1e18 and swaps it in via NT (since the
  forked ResilientOracle's chainlink feeds go stale after testVip advances
  time past the timelock delay)
- asserts VaultCreated is emitted, allVaultsLength increments, and the new
  vault is registered
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.

3 participants