This guide helps managers understand and mitigate risks when borrowing from Flux vaults. Learn how to monitor your positions, avoid liquidation, and operate safely with leverage.
As a manager, you need to monitor these critical metrics:
Health Ratio = Total Position Value / True Debt
Liquidation Threshold = 1 + minBondRatio - liquidationBuffer
Liquidatable When: Health Ratio < Liquidation Threshold
Example:
Bond: 20K USDC
Borrowed: 80K USDC (4x leverage)
Wrapper collateral: 50K USDC worth of WETH
Total position value: 70K USDC (20K bond + 50K WETH)
True debt: 85K USDC (with accrued interest)
Health ratio: 70K / 85K = 0.823 (82.3%)
Liquidation threshold: 110%
Status: LIQUIDATABLE ⚠️
Your Risk Parameters
Different vaults have different risk parameters. Check your vault's strategy:
Health Monitoring
Real-Time Monitoring
Set up continuous monitoring to avoid surprises:
Alert Thresholds
Set up alerts at different safety levels:
Health Ratio
Status
Action Required
> 140%
Safe
Monitor normally
125-140%
Caution
Increase monitoring frequency
115-125%
Warning
Consider reducing leverage or adding collateral
110-115%
Danger
Urgent action needed - reduce position immediately
< 110%
Liquidatable
Position will be liquidated
Monitoring Tools
Option 1: Simple Script
Option 2: Monitoring Service
Set up alerts via PagerDuty, Telegram, Discord
Use Tenderly alerts for on-chain monitoring
Subscribe to Flux SDK event notifications (if available)
Option 3: Dashboard
Build custom dashboard with health metrics
Display real-time collateral values
Show time-until-liquidation estimates
Liquidation Prevention
Strategy 1: Maintain Safety Buffer
Never operate at minimum health ratio. Always maintain a buffer above the liquidation threshold:
Why?
Asset prices can drop suddenly
Interest accrues continuously
Slippage when adding collateral
Network congestion can delay transactions
Strategy 2: Add Collateral Proactively
Don't wait until liquidation is imminent:
Strategy 3: Reduce Debt
Pay down debt to improve health ratio:
Strategy 4: Rebalance Collateral
If some collateral assets are falling, rebalance to stronger assets:
Strategy 5: Emergency Exit
If market conditions deteriorate rapidly, close your position:
import { ethers } from 'ethers';
async function monitorHealth(vaultAddress: string, managerAddress: string) {
const vault = new ethers.Contract(vaultAddress, VAULT_ABI, provider);
const strategy = await vault.STRATEGY();
// Get position data
const [principalDebt, bondValue] = await vault.getManagerPosition(managerAddress);
const trueDebt = await vault.getManagerTrueDebt(managerAddress);
const totalValue = await vault.getManagerTotalValue(managerAddress);
// Calculate health ratio
const healthRatio = totalValue.mul(1e18).div(trueDebt);
// Get liquidation threshold
const liquidationThreshold = await strategy.liquidationThreshold();
// Calculate safety margin
const safetyMargin = healthRatio.sub(liquidationThreshold).mul(100).div(1e18);
console.log('━━━ Position Health ━━━');
console.log('Total Value:', ethers.utils.formatUnits(totalValue, 6), 'USDC');
console.log('True Debt:', ethers.utils.formatUnits(trueDebt, 6), 'USDC');
console.log('Health Ratio:', ethers.utils.formatUnits(healthRatio, 18));
console.log('Liquidation Threshold:', ethers.utils.formatUnits(liquidationThreshold, 18));
console.log('Safety Margin:', safetyMargin.toString(), '%');
// Alert levels
if (healthRatio.lt(liquidationThreshold)) {
console.error('🚨 CRITICAL: Position is LIQUIDATABLE');
} else if (healthRatio.sub(liquidationThreshold).lt(ethers.utils.parseUnits('0.05', 18))) {
console.warn('⚠️ WARNING: Within 5% of liquidation');
} else if (healthRatio.sub(liquidationThreshold).lt(ethers.utils.parseUnits('0.15', 18))) {
console.warn('⚡ CAUTION: Within 15% of liquidation');
} else {
console.log('✅ SAFE: Position healthy');
}
}
// Run every 30 seconds
setInterval(() => monitorHealth(VAULT_ADDRESS, MANAGER_ADDRESS), 30_000);
# monitor.sh
while true; do
cast call $VAULT "getManagerTotalValue(address)(uint256)" $MANAGER
cast call $VAULT "getManagerTrueDebt(address)(uint256)" $MANAGER
sleep 30
done
Recommended Minimum Health Ratio = Liquidation Threshold + 20%
Example:
Liquidation threshold: 110%
Your minimum: 130%
// Add more bond when health drops below 130%
function addBondProactively(uint256 amount) external {
bytes memory data = abi.encodeCall(
this.addBondCallback,
(amount)
);
vault.unlock(data);
}
function addBondCallback(uint256 amount) external {
// Transfer from manager's wallet to executor first
asset.transferFrom(msg.sender, address(this), amount);
// Approve vault
asset.approve(address(vault), amount);
// Deposit bond
vault.locked_depositBond(amount);
}
function partialRepayment(uint256 repayAmount) external {
bytes memory data = abi.encodeCall(
this.repayCallback,
(repayAmount)
);
vault.unlock(data);
}
function repayCallback(uint256 repayAmount) external {
// Transfer repayment funds to executor
asset.transferFrom(msg.sender, address(this), repayAmount);
// Approve vault
asset.approve(address(vault), repayAmount);
// Deposit to working capital
vault.locked_depositToWrapper(
vault.BASE_ASSET_WRAPPER(),
bytes32(0), // WORKING_CAPITAL_POS_ID
repayAmount
);
// Repay debt (vault automatically uses working capital)
vault.locked_repay(repayAmount);
}
function rebalanceToStablecoin() external {
bytes memory data = abi.encodeCall(
this.rebalanceCallback,
()
);
vault.unlock(data);
}
function rebalanceCallback() external {
// 1. Withdraw declining asset (e.g., WETH dropping)
vault.locked_withdrawFromWrapper(
wethWrapper,
positionId,
wethAmount
);
// 2. Swap to stablecoin on Uniswap
weth.approve(UNISWAP_ROUTER, wethAmount);
uniswap.swapExactTokensForTokens(
wethAmount,
minUsdcOut,
[WETH, USDC],
address(this),
deadline
);
// 3. Deposit stablecoin back to vault
usdc.approve(address(vault), usdcReceived);
vault.locked_depositToWrapper(
vault.BASE_ASSET_WRAPPER(),
bytes32(0),
usdcReceived
);
}
function emergencyExit() external {
bytes memory data = abi.encodeCall(
this.exitCallback,
()
);
vault.unlock(data);
}
function exitCallback() external {
// 1. Withdraw all wrapper collateral
uint256[] memory balances = getAllWrapperBalances();
for (uint256 i = 0; i < wrappers.length; i++) {
vault.locked_withdrawFromWrapper(
wrappers[i],
positionIds[i],
balances[i]
);
}
// 2. Liquidate all to base asset
swapAllToBaseAsset();
// 3. Deposit to working capital
uint256 baseBalance = asset.balanceOf(address(this));
asset.approve(address(vault), baseBalance);
vault.locked_depositToWrapper(
vault.BASE_ASSET_WRAPPER(),
bytes32(0),
baseBalance
);
// 4. Repay all debt
vault.locked_repay(0); // 0 = repay all
// 5. Withdraw bond
vault.locked_withdrawBond(type(uint256).max);
}
async function checkADLRisk(vaultAddress: string, managerAddress: string) {
const vault = new ethers.Contract(vaultAddress, VAULT_ABI, provider);
const strategy = await vault.STRATEGY();
// Check vault utilization
const totalAssets = await vault.totalAssets();
const totalBorrowed = await vault.totalBorrowed();
const utilization = totalBorrowed.mul(1e18).div(totalAssets);
// Check ADA threshold
const adlUtilizationThreshold = await strategy.adlUtilizationThreshold();
const adlThreshold = await strategy.adlThreshold();
// Check your health
const totalValue = await vault.getManagerTotalValue(managerAddress);
const trueDebt = await vault.getManagerTrueDebt(managerAddress);
const healthRatio = totalValue.mul(1e18).div(trueDebt);
// Evaluate ADA
const { canADL, managerNetEquityUSD } = await strategy.evaluateADL(
vaultAddress,
managerAddress
);
console.log('━━━ ADL Risk Analysis ━━━');
console.log('Vault Utilization:', ethers.utils.formatUnits(utilization, 16), '%');
console.log('ADL Utilization Threshold:', ethers.utils.formatUnits(adlUtilizationThreshold, 16), '%');
console.log('Your Health Ratio:', ethers.utils.formatUnits(healthRatio, 18));
console.log('ADL Health Threshold:', ethers.utils.formatUnits(adlThreshold, 18));
console.log('Can be ADL\'d:', canADL);
if (canADL) {
console.error('🚨 CRITICAL: Position subject to ADL');
console.log('Your net equity:', ethers.utils.formatUnits(managerNetEquityUSD, 6), 'USD');
}
}
Normal times: 130% health ratio minimum
High utilization (>90%): 140% health ratio minimum
Max Leverage = 1 / minBondRatio
Examples:
minBondRatio = 0.2 (20%) → Max leverage = 5x
minBondRatio = 0.3 (30%) → Max leverage = 3.3x
minBondRatio = 0.4 (40%) → Max leverage = 2.5x
// Reduce leverage during volatility
function reduceLeverage(uint256 targetHealthRatio) external {
uint256 currentHealth = getCurrentHealthRatio();
if (currentHealth < targetHealthRatio) {
// Calculate how much to repay
uint256 repayAmount = calculateRepaymentForHealth(targetHealthRatio);
// Execute repayment
repayDebt(repayAmount);
}
}
// Increase leverage during calm markets (cautiously!)
function increasePosition(uint256 additionalBorrowAmount) external {
// Only if health is very good
require(getCurrentHealthRatio() > 1.5e18, "Health too low");
// Execute borrow
borrowAndDeploy(additionalBorrowAmount);
}