Skip to content

InstitutionalLoanVault

Inherits: BaseVault

Title: InstitutionalLoanVault

ERC-4626 vault for institutional fixed-term lending with on-chain collateral, borrowing, and liquidation support. Deployed as EIP-1167 minimal proxy clones.

Inherits BaseVault for shared ERC-4626 mechanics, fundraising, interest, settlement, and core state machine. Adds: collateral deposit/withdraw, borrowing, risk checks, liquidation entry points, and pre-fundraising states (WaitingForMargin, MarginDeposited). No ACM — all governance calls are proxied through VaultController. Position-holder gated functions (collateral ops, claimRaisedFunds) are restricted to the current owner of the vault’s PositionToken — not the original institution address. The institution can transfer vault ownership by transferring the token to another address. Fee-on-transfer tokens are NOT supported for either the underlying asset or collateral.

Institutional-specific configuration — collateral, sizing, position identity.

InstitutionalConfig internal _instConfig

Institutional-specific runtime — collateral accounting, margin confiscation.

InstitutionalRuntime internal _instRuntime

Risk parameters — LT/LI/latePenaltyRate mutable via controller.

RiskConfig internal _riskConfig

InstitutionPositionToken contract — from controller storage.

IInstitutionPositionToken public positionToken

Restricts to the current owner of the vault’s PositionToken. Ownership is transferable — if the institution transfers the token, the new holder gains access to position-holder gated functions.

modifier onlyPositionHolder();

Restricts to the LiquidationAdapter contract stored on the controller.

modifier onlyLiquidationAdapter();

Note: oz-upgrades-unsafe-allow: constructor

constructor();

Initializes the vault clone. Called once by VaultController.

function initialize(
VaultConfig calldata config_,
InstitutionalConfig calldata instConfig_,
RiskConfig calldata riskConfig_,
IInstitutionPositionToken positionToken_,
string calldata name_,
string calldata symbol_
) external initializer;

Parameters

NameTypeDescription
config_VaultConfigShared vault configuration (asset, rates, caps, timing).
instConfig_InstitutionalConfigInstitutional-specific configuration (collateral, sizing, position identity).
riskConfig_RiskConfigRisk parameters.
positionToken_IInstitutionPositionTokenInstitutionPositionToken contract reference.
name_stringERC-20 share token name.
symbol_stringERC-20 share token symbol.

Transitions MarginDeposited -> Fundraising. Controller only.

Notes:

  • error: InvalidState If vault is not in MarginDeposited state.
  • event: VaultOpened Emitted with the open end time.
  • event: StateTransition Emitted for MarginDeposited -> Fundraising.
function openVault() external onlyController;

Cancels a vault that has not yet launched and refunds any deposited collateral to the NFT position holder. Restricted to the two pre-launch states: WaitingForMargin (no collateral yet) or MarginDeposited (margin in escrow). Uses positionToken.ownerOf so any approved NFT transfer is honoured.

Notes:

  • error: InvalidState If vault is not in WaitingForMargin or MarginDeposited.
  • event: VaultCancelled Emitted with the position-holder recipient and refunded collateral amount.
  • event: StateTransition Emitted by _stateTransition for WaitingForMargin/MarginDeposited -> Failed.
function cancelVault() external onlyController nonReentrant;

Permissionless bad-debt rescue. Anyone may repay to settle a vault where collateral < debt.

Notes:

  • error: InvalidState If vault is not in Lock, PendingSettlement, or SettlementDeadlineExceeded.
  • error: ZeroRepayAmount If repayAmount is zero.
  • error: NoOutstandingDebt If there is no debt to repay.
  • error: NotBadDebt If collateral value >= debt value.
  • error: InsufficientRepayment If outstanding debt after repay still exceeds total interest (principal not fully returned).
function repayBadDebt(uint256 repayAmount) external nonReentrant whenNotCompletelyPaused;

Parameters

NameTypeDescription
repayAmountuint256Amount of supply asset to pull from caller.

Updates liquidation threshold. Controller only.

Note: event: LiquidationThresholdUpdated

function setLiquidationThreshold(uint256 newLT) external onlyController;

Parameters

NameTypeDescription
newLTuint256New liquidation threshold (mantissa).

Updates liquidation incentive. Controller only.

Note: event: LiquidationIncentiveUpdated

function setLiquidationIncentive(uint256 newLI) external onlyController;

Parameters

NameTypeDescription
newLIuint256New liquidation incentive (mantissa).

Updates late penalty rate. Controller only.

Note: event: LatePenaltyRateUpdated

function setLatePenaltyRate(uint256 newRate) external onlyController;

Parameters

NameTypeDescription
newRateuint256New late penalty rate (mantissa).

HF-based liquidation. LiquidationAdapter only.

Notes:

  • error: ZeroRepayAmount If repayAmount is zero.
  • error: InvalidState If vault is not in Lock, PendingSettlement, or SettlementDeadlineExceeded.
  • error: NoOutstandingDebt If there is no debt to repay.
  • error: NotLiquidatable If vault has no LT shortfall.
  • event: LiquidationExecuted Emitted with liquidator, repay amount, and collateral seized.
function liquidate(
uint256 repayAmount
) external onlyLiquidationAdapter nonReentrant whenNotCompletelyPaused returns (uint256 actualRepay);

Parameters

NameTypeDescription
repayAmountuint256Amount of supply asset to repay.

Returns

NameTypeDescription
actualRepayuint256Actual amount repaid after clamping to outstanding debt.

Deadline-based liquidation. LiquidationAdapter only.

Notes:

  • error: ZeroRepayAmount If repayAmount is zero.
  • error: InvalidStateForOverdueLiquidation If not in SettlementDeadlineExceeded.
  • error: NoOutstandingDebt If there is no debt to repay.
  • error: ExceedsCloseFactor If actualRepay exceeds the close factor limit (via _executeLiquidation).
  • error: InsufficientCollateralForSeize If seize amount exceeds collateral balance (via _executeLiquidation).
  • event: OverdueLiquidationExecuted Emitted with settler, repay amount, and collateral seized.
function liquidateOverdueVault(
uint256 repayAmount
) external onlyLiquidationAdapter nonReentrant whenNotCompletelyPaused returns (uint256 actualRepay);

Parameters

NameTypeDescription
repayAmountuint256Amount of supply asset to repay.

Returns

NameTypeDescription
actualRepayuint256Actual amount repaid after clamping to outstanding debt.

Deposits collateral into the vault. Fee-on-transfer / rebasing collateral tokens are NOT supported.

  • WaitingForMargin: the full margin amount must be deposited in a single transaction to transition to MarginDeposited; partial deposits revert.
  • Fundraising: institution deposits remaining collateral alongside lender fundraising.
  • Lock: top-up collateral.

Notes:

  • error: InvalidState If vault is not in WaitingForMargin, Fundraising, or Lock.
  • error: InsufficientCollateral If deposit in WaitingForMargin does not meet margin threshold.
  • event: CollateralDeposited Emitted with actual deposited amount and total collateral.
function depositCollateral(uint256 amount) external onlyPositionHolder nonReentrant whenNotPaused;

Parameters

NameTypeDescription
amountuint256Amount of collateral tokens to deposit.

Withdraws collateral.

  • Lock: floor-checked (minimumCollateralRequired) + LT-checked.
  • Failed (Scenario A — raised < minCap): withdraw all deposited collateral.
  • Failed (Scenario B — institution default): withdraw deposited minus confiscated margin.
  • Matured: capped at totalCollateralDeposited, unrestricted.
  • Liquidated: blocked — collateral is recoverable by governance via sweep().

Notes:

  • error: InvalidState If vault is not in Lock, Matured, or Failed.
  • error: InsufficientCollateral If withdrawal would breach floor or exceed available amount.
  • error: WithdrawalWouldBreachLT If withdrawal would cause LT shortfall during Lock.
  • event: CollateralWithdrawn Emitted with position holder, amount, and remaining collateral.
function withdrawCollateral(uint256 amount) external onlyPositionHolder nonReentrant whenNotPaused;

Parameters

NameTypeDescription
amountuint256Amount of collateral tokens to withdraw.

One-time fund withdrawal. Transfers all raised supply assets to institution.

Notes:

  • error: AlreadyWithdrawn if funds already claimed.
  • error: ClaimWouldBreachLT if post-claim debt would exceed LT cap.
  • event: RaisedFundsClaimed
function claimRaisedFunds() external onlyPositionHolder nonReentrant whenNotPaused;

Repays outstanding debt. Anyone may call. Clamped to outstandingDebt.

Notes:

  • error: InvalidState If vault is not in Lock, PendingSettlement, or SettlementDeadlineExceeded.
  • error: ZeroRepayAmount if amount is zero.
  • error: NoOutstandingDebt if there is no debt to repay.
  • event: Repaid
function repay(uint256 amount) external nonReentrant whenNotCompletelyPaused;

Parameters

NameTypeDescription
amountuint256Amount of supply asset to repay.

Current collateral value in USD via oracle.

function getCollateralValueUSD() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256Collateral value in 18-decimal USD.

Current outstanding debt value in USD via oracle.

function getDebtValueUSD() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256Debt value in 18-decimal USD.

Returns the institutional-specific configuration.

function institutionalConfig() external view returns (InstitutionalConfig memory);

Returns

NameTypeDescription
<none>InstitutionalConfigInstitutional config struct.

Returns the risk configuration.

function riskConfig() external view returns (RiskConfig memory);

Returns

NameTypeDescription
<none>RiskConfigRisk parameters struct.

Returns the institutional-specific runtime state.

function institutionalRuntime() external view returns (InstitutionalRuntime memory);

Returns

NameTypeDescription
<none>InstitutionalRuntimeInstitutional runtime struct.

Returns current liquidity and shortfall for the vault.

function getVaultLiquidity() external view returns (uint256 liquidity, uint256 shortfall);

Returns

NameTypeDescription
liquidityuint256Excess liquidity (0 if shortfall).
shortfalluint256LT shortfall (0 if healthy).

Returns hypothetical liquidity/shortfall after a simulated withdrawal and/or debt increase.

function getHypotheticalVaultLiquidity(
uint256 withdrawAmount,
uint256 additionalDebt
) external view returns (uint256 liquidity, uint256 shortfall);

Parameters

NameTypeDescription
withdrawAmountuint256Simulated collateral withdrawal amount.
additionalDebtuint256Simulated additional debt on top of outstanding.

Returns

NameTypeDescription
liquidityuint256Excess liquidity (0 if shortfall).
shortfalluint256LT shortfall (0 if healthy).

Preview seize amount for a given repay and liquidation type.

function calculateSeizeAmount(
uint256 repayAmount,
LiquidationType liquidationType
) external view returns (uint256);

Parameters

NameTypeDescription
repayAmountuint256Amount being repaid.
liquidationTypeLiquidationTypeHF_BASED or DEADLINE.

Returns

NameTypeDescription
<none>uint256Collateral seize amount.
event VaultOpened(uint256 openEndTime);
event VaultLocked(uint256 totalRaised, uint256 lockEndTime);
event VaultFailed(uint256 totalRaised, uint256 minBorrowCap);
event VaultLiquidated(uint256 available);
event CollateralDeposited(uint256 amount, uint256 totalCollateral);
event CollateralWithdrawn(address indexed positionHolder, uint256 amount, uint256 remaining);
event LiquidationExecuted(address indexed liquidator, uint256 repayAmount, uint256 collateralSeized);
event OverdueLiquidationExecuted(address indexed settler, uint256 repayAmount, uint256 collateralSeized);
event MarginConfiscated(uint256 marginAmount);
event MarginCompensationClaimed(address indexed receiver, uint256 amount);
event VaultCancelled(address indexed recipient, uint256 collateralAmount);
event LiquidationThresholdUpdated(uint256 oldLT, uint256 newLT);
event LiquidationIncentiveUpdated(uint256 oldLI, uint256 newLI);
event LatePenaltyRateUpdated(uint256 oldRate, uint256 newRate);
error InsufficientCollateral();
error NotPositionHolder();
error InvalidStateForOverdueLiquidation();
error NotBadDebt();
error InsufficientRepayment();
error NotLiquidatable();
error ExceedsCloseFactor();
error InsufficientCollateralForSeize(uint256 seizeAmount, uint256 availableCollateral);
error WithdrawalWouldBreachLT();
error WithdrawExceedsCollateral();
error ClaimWouldBreachLT();
error InvalidOraclePrice();