DocumentationOpen App

Credit Manager

The CreditManagerV3 is the core accounting engine of the Gearbox Protocol. It manages Credit Account lifecycle, tracks debt and collateral, calculates health factors, and enforces risk parameters. All Credit Account state is stored and managed through this contract.

Core State: CreditAccountInfo

Every Credit Account's state is tracked in a CreditAccountInfo struct:

FieldTypeDescription
debtuint256Principal amount borrowed from the pool
cumulativeIndexLastUpdateuint256Pool's interest index at last debt update
cumulativeQuotaInterestuint128Accrued quota interest not yet added to debt
quotaFeesuint128Quota fees owed
enabledTokensMaskuint256Bitmask of currently enabled collateral tokens
flagsuint16Account state flags (e.g., BOT_PERMISSIONS_SET_FLAG)
lastDebtUpdateuint64Timestamp of last debt change (flash-loan protection)
borroweraddressCurrent account owner

Debt Tracking Architecture

Indexed Interest Accrual

The Credit Manager uses an indexed interest model rather than storing accrued interest directly. This approach is gas-efficient because it doesn't require per-block updates.

Formula:

accruedInterest = debt * (currentIndex - lastIndex) / lastIndex
totalDebt = principal + accruedInterest + quotaInterest + fees

The cumulativeIndexLastUpdate is snapshotted whenever debt changes, allowing the contract to calculate exact interest at any time by comparing against the Pool's current baseInterestIndex().

Flash-Loan Protection

The lastDebtUpdate timestamp prevents multiple debt changes in the same block. This protects against flash-loan attacks where an attacker could:

  1. Borrow heavily
  2. Manipulate prices
  3. Close position profitably

Any second debt change in the same block will revert.


Collateral Management

Token Masking System

Every collateral token has a unique uint256 mask (power of 2). An account's enabledTokensMask is the bitwise OR of all enabled token masks.

Benefits:

  • O(enabled_tokens) iteration: Health checks only iterate over enabled tokens, not all possible collateral
  • Gas efficiency: Single storage slot tracks all enabled/disabled states
  • Atomic updates: Enable/disable multiple tokens in one operation
TypeScript
// TypeScript: Checking enabled tokens const enabledMask = await creditManager.read.enabledTokensMaskOf([creditAccount]); // Get all enabled token addresses const collateralTokens = []; for (let i = 0; i < 256; i++) { if (enabledMask & (1n << BigInt(i))) { const tokenData = await creditManager.read.getTokenByMask([1n << BigInt(i)]); collateralTokens.push(tokenData); } }

Liquidation Thresholds (LT)

Each collateral token has a Liquidation Threshold determining how much of its value counts toward collateralization:

ParameterDescription
ltInitialStarting LT value (e.g., 8500 = 85%)
ltFinalFinal LT after ramping
timestampRampStartWhen LT ramping begins
rampDurationDuration of linear interpolation

LT Ramping allows gradual changes to risk parameters without sudden liquidation cascades. The current LT is linearly interpolated between ltInitial and ltFinal over the ramp period.

Phantom Tokens

Phantom tokens are virtual representations of staked/LP positions (e.g., staked Curve LP tokens). They implement IPhantomToken.getPhantomTokenInfo() which returns the underlying deposited token.

During health factor calculations, phantom tokens are resolved to their underlying value, ensuring proper collateral accounting for wrapped positions.


Health Factor Calculation

TWV Formula

The Health Factor determines whether an account is solvent:

TWV (Threshold Weighted Value) = Sum(Balance_i * Price_i * LT_i)
TotalDebt = principal + baseInterest + quotaInterest + fees
HealthFactor = TWV / TotalDebt

An account is:

  • Healthy: HF >= 1.0 (10000 in basis points)
  • Liquidatable: HF < 1.0

Collateral Calculation Modes

The Credit Manager supports different calculation modes for gas optimization:

ModeUse Case
DEBT_ONLYCalculate debt + interest without collateral
DEBT_COLLATERALFull TWV + HF calculation
FULL_COLLATERAL_CHECK_LAZYOptimized: stops early when HF exceeds threshold

The lazy mode is used during multicalls where we only need to verify HF > 1, not calculate the exact value.

TypeScript
// TypeScript: Reading account health import { getContract } from 'viem'; const creditManager = getContract({ address: creditManagerAddress, abi: creditManagerV3Abi, client: publicClient, }); // Get full debt breakdown const debtData = await creditManager.read.calcDebtAndCollateral([ creditAccount, 2 // CollateralCalcTask.DEBT_COLLATERAL ]); // debtData returns: { debt, accruedInterest, accruedFees, totalDebtUSD, // totalValue, twvUSD, enabledTokensMask, ... } const healthFactor = debtData.twvUSD * 10000n / debtData.totalDebtUSD; console.log(`Health Factor: ${Number(healthFactor) / 100}%`);

Pool and Oracle Coordination

Pool Interaction

The Credit Manager coordinates with PoolV3 for all debt operations:

OperationPool Function
Borrowpool.lendCreditAccount(debt, creditAccount)
Repaypool.repayCreditAccount(debt, profit, loss)
Interest trackingpool.baseInterestIndex()

On liquidation with loss, the Credit Manager reports the loss to the Pool, which may burn Treasury shares or incur "uncovered loss" that's socialized across LPs.

Oracle Interaction

Price data comes from PriceOracleV3:

FunctionDescription
convertToUSD(amount, token)Convert token amount to USD value
getPrice(token)Get token price (respects USE_SAFE_PRICES_FLAG)

Dual Price Safety: When USE_SAFE_PRICES_FLAG is set (for forbidden tokens), the oracle returns min(primaryPrice, reservePrice) to protect against price manipulation.


Access Control

The Credit Manager restricts sensitive operations:

CallerAllowed Operations
CreditFacadeV3All account operations (open, close, multicall)
CreditConfiguratorV3Parameter updates (tokens, adapters, fees)
Credit Account (via execute)Adapter calls during multicall

External contracts cannot directly manipulate Credit Account state - all operations must flow through the Facade.

Sources