Documentation

Protocol
Intelligence

Mevryx monitors liquidation opportunities across four DeFi lending protocols simultaneously. Each protocol has its own discovery mechanism, health accounting system, and liquidation mechanics — yet the platform surfaces all of them through a single normalized interface, ranked by real profitability.

This page documents exactly how Mevryx connects to each protocol: what data is fetched, how health is interpreted, and what makes each one different from a liquidator's perspective.

Protocols Covered
4
On-chain Scan
Every block
Euler + Morpho
Every 5 min
Oracle Check
Every 60s
Positions Tracked
5,000+
Priority Metric
Net USD profit

Normalization Layer

The core challenge of monitoring multiple protocols is that each one speaks a different language. Aave returns aggregated USD values directly from the contract. Compound computes health from per-asset Chainlink feeds. Euler denominates everything in a per-vault "unit of account" that can be either a stablecoin or ETH. Morpho uses an LLTV ratio instead of a health factor entirely.

Mevryx resolves this through a shared NormalizedPosition type. Every adapter, regardless of protocol, outputs the same structure — USD values, a health score, distance to threshold, and a net profit figure after gas costs. This means the ranking engine, the frontend, and the alert system never need to know which protocol a position came from.

Shared Type Fields

NormalizedPosition {
  protocol:               'aave_v3' | 'compound_v3' | 'euler_v2' | 'morpho'
  owner:                  string           // wallet address
  collateralAsset:        string           // e.g. "WETH", "MULTI", "wstETH"
  borrowAsset:            string           // e.g. "USDC", "MULTI"

  collateralValueUSD:     number           // always in USD
  debtValueUSD:           number           // always in USD

  healthScore:            number           // protocol-normalized — see below
  distanceToThreshold:    number           // % price drop to liquidation
  liquidationBonusPct:    number           // e.g. 0.05 = 5%
  liquidationProfitNetUSD: number          // gross profit minus gas cost
  isProfitable:           boolean

  isHidden:               boolean          // true if oracle lag detected
  needsFlashLoan:         boolean          // Aave only
  isVerifiedCollateral:   boolean          // curated asset lists
}
Health Score Convention
Every protocol maps its internal health metric to the same convention: a value above 1.0 means the position is safe; below 1.0 means it is liquidatable. For Morpho, which uses LLTV rather than a health factor, this is computed as (collateral × LLTV) / debt — making the 1.0 crossing point universal across all four protocols.

Aave V3

Per-BlockWatchlist

Aave V3 is the most data-efficient protocol to monitor. The contract's getUserAccountData() function returns a pre-computed health factor and aggregated USD values in a single call, meaning Mevryx doesn't need to calculate health independently — it comes straight from the protocol.

Position Discovery

Aave positions are tracked via a watchlist — a database of wallet addresses seeded from The Graph subgraph, refreshed every 6 hours. Every new Ethereum block triggers a multicall batch across all watched wallets, fetching their account data simultaneously.

Contract
0x87870B...4fA4E2
Function
getUserAccountData()
Batch Size
500 wallets / call
Scan
Every block
Flash Loan
Required (0.09% fee)
Debt Coverage
50% max per tx

Health Factor

Aave returns the health factor as a raw uint256 with 18 decimal places. Mevryx divides by 1e18 to get the decimal value. No recalculation is needed — the protocol does this internally using its own weighted liquidation thresholds per asset.

// From contract (18 decimals)
healthScore = healthFactor / 1e18

// USD values (8 decimals, already in USD base currency)
collateralValueUSD = totalCollateralBase / 1e8
debtValueUSD       = totalDebtBase / 1e8

Liquidation Mechanics

Aave V3 caps each liquidation at 50% of the outstanding debt. This is a protocol rule to prevent full single-step liquidations. Combined with the mandatory flash loan (to source the repayment capital), the profit calculation accounts for both the 0.09% flash loan fee and gas costs.

grossProfit     = (debtUSD × 0.5) × 0.05      // 5% bonus on half the debt
flashLoanFee    = (debtUSD × 0.5) × 0.0009   // 0.09% fee
netProfit       = grossProfit - flashLoanFee - gasCostUSD
Mevryx Perspective
Aave's multi-asset collateral model means the collateral and borrow assets are normalized to "MULTI" — the protocol aggregates them internally. This simplifies monitoring but means Mevryx cannot isolate which specific collateral token drives the health factor. Oracle lag detection maps ETH-correlated assets (WETH, wstETH, cbETH, rETH) to the ETH price feed for hidden position tracking.

Compound V3

Per-BlockWatchlist

Compound V3 (Comet) operates a single-asset borrow market — all debt is in USDC. This makes debt accounting trivial, but health calculation is more involved: Mevryx must fetch each collateral asset's balance, its Chainlink price, and its per-asset liquidation factor on-chain to compute health from scratch.

Position Discovery

Like Aave, Compound positions are seeded from The Graph and stored in a watchlist. Every block triggers a multicall to the Comet contract — but the call structure is more complex because each position requires multiple sub-calls: borrow balance, liquidatability flag, and one balance call per supported collateral asset.

Contract
0xc3d688...84cdc3
Borrow Asset
USDC only
Collaterals
Multiple (per-asset)
Flash Loan
Not required
Debt Coverage
100%
Bonus
5% (fixed)

Health Factor Calculation

Compound doesn't return a health factor directly. Mevryx recomputes it from raw data: for each collateral asset, it fetches the USD price via the asset's Chainlink feed, multiplies by the asset's liquidateCollateralFactor, and sums across all assets. The result is divided by the USDC debt balance.

// Per-asset
assetUSD    = (balance / scale) × getPrice(priceFeed) / 1e8
liquidValue = assetUSD × liquidateCollateralFactor / 1e18

// Aggregate
healthScore = Σ(liquidValue_i) / debtUSD

The contract also exposes an isLiquidatable() boolean. If this returns true while the computed health factor is still above 1.0, Mevryx overrides health to 0.99 — the protocol's own assessment takes precedence.

Mevryx Perspective
Compound is the only protocol where debt is always USDC and flash loans are unnecessary — the liquidator can repay with capital on hand. This changes the profit model: no flash loan fee, and 100% debt coverage is allowed. Per-asset liquidation factors (which vary) mean health is more granular than Aave's aggregated threshold.

Euler V2

5-Min ScanSubgraph

Euler V2 is a permissionless vault system — anyone can create a lending market for any asset. This means Mevryx cannot rely on a fixed contract address or a known set of assets. Instead, it enumerates all active positions from the Goldsky subgraph every five minutes, then queries each vault contract directly for health data.

Position Discovery

The Goldsky subgraph tracks all accounts that have active borrows across Euler's vault ecosystem. Each entry contains the subaccount address and the vault address — Mevryx parses these from packed binary data in the subgraph response, then batches on-chain health queries against each vault.

Source
Goldsky Subgraph
Method
accountLiquidityFull()
Batch Size
50 vaults / multicall
Vault Concurrency
5 parallel
Flash Loan
Not required
Bonus
Variable (per vault)

Health Factor Calculation

Euler's accountLiquidityFull(account, liquidation=true) returns all collateral values and the total liability value, already denominated in the vault's "unit of account" (which can be USDC, USDT, DAI, or WETH depending on the vault). Mevryx converts to USD as a final step.

// From vault contract
(collaterals[], collateralValues[], liabilityValue) = accountLiquidityFull(account, true)

// Health score
totalCollateralValue = Σ(collateralValues)
healthScore          = totalCollateralValue / liabilityValue

// Convert to USD (unit of account dependent)
if (unitOfAccount == WETH):
    valueUSD = rawValue / 1e18 × ethPrice
else:
    valueUSD = rawValue / 1e18   // stablecoin UOA

Liquidation Bonus

Unlike Aave and Compound where the bonus is a fixed 5%, Euler's liquidation discount is set per vault via the maxLiquidationDiscount() function. Mevryx fetches this on-chain alongside health data and uses it in the profit calculation.

liquidationBonusPct     = maxLiquidationDiscount / 10_000
liquidationProfitUSD    = min(collateralUSD, debtUSD) × liquidationBonusPct
liquidationProfitNetUSD = liquidationProfitUSD - gasCostUSD

Collateral Asset Identification

Because a single account can use multiple vaults as collateral simultaneously, Mevryx identifies the primary collateral as the vault with the largest USD value. The asset symbol is fetched from the ERC-20 contract and cached to avoid redundant RPC calls on subsequent scans.

Mevryx Perspective
Euler's permissionless model is its defining characteristic. Variable liquidation bonuses, per-vault units of account, and multi-vault collateral stacking all make normalization non-trivial. Real-time health monitoring (between 5-min scans) uses the block watcher to re-query accountLiquidity() on all watched positions every block — giving Euler positions near-real-time health updates despite the longer scan cycle.

Morpho

5-Min ScanGraphQL API

Morpho is architecturally the most minimal of the four protocols — the core contract is intentionally simple, with no oracle logic or interest rate models inside the protocol itself. Health is defined purely by LLTV (liquidation loan-to-value), which is set per market at creation time and never changes.

Position Discovery

Morpho provides an official GraphQL API that exposes all positions with borrow shares greater than zero. Mevryx queries this for the top 5,000 positions by borrow size, then verifies each one on-chain via multicall to confirm the position is still open and adjust for any share drift since the API snapshot.

Source
Morpho GraphQL API
On-chain Verify
position() + market()
Batch Size
50 per multicall
LLTV
Fixed per market
Flash Loan
Not required
Bonus
LLTV-based curve

Health Factor Calculation

Morpho doesn't have a health factor — it uses LLTV. Mevryx maps this to the universal convention by computing health as the ratio of LLTV-adjusted collateral to outstanding debt. When this value crosses 1.0, the position is liquidatable.

lltvFloat   = market.lltv / 1e18   // e.g. 0.77 for a 77% LLTV market
healthScore = (collateralValueUSD × lltvFloat) / debtValueUSD

// On-chain adjustment for share drift
ratio       = onChainBorrowAssets / apiBorrowAssets
debtValueUSD = apiBorrowAssetsUsd × ratio

Liquidation Incentive Curve

Morpho's liquidation incentive is not a fixed percentage. It follows a curve based on the market's LLTV — lower LLTV markets (safer collateral) have higher incentives to attract liquidators for the rarer events. The formula implements Morpho's published liquidation cursor mechanism.

LIQUIDATION_CURSOR       = 0.3
MAX_LIQUIDATION_INCENTIVE = 0.15

denominator          = 1 - CURSOR × (1 - lltvFloat)
incentive            = min(MAX_INCENTIVE, 1 / denominator - 1)

// Example: 77% LLTV → ~4.5% incentive
// Example: 91.5% LLTV → ~3% incentive

Block-Level Health Monitoring

Between 5-minute scans, Mevryx tracks Morpho position health using borrow share changes as a proxy — if a position's borrow shares increase by more than 0.5% in a single block, it's flagged for priority refresh on the next scan cycle. This avoids fetching oracle prices every block while still catching fast-moving positions.

Mevryx Perspective
Morpho's market-specific LLTV is the most important concept to understand. Each market (collateral/loan asset pair) has a different threshold, so comparing health scores across markets requires normalizing to the same 1.0 convention. The variable incentive curve also means the profit from liquidating the same-sized position differs significantly between a 77% LLTV market and a 91.5% LLTV market — Mevryx accounts for this in per-position profit calculations.

Profitability Scoring

With normalized positions from all four protocols, Mevryx ranks them using a composite priority score that balances two factors: how much profit is available right now, and how close the position is to the liquidation threshold.

// Priority score (stored in Redis sorted set)
hfScore       = 1_000_000 / healthScore   // lower HF → higher score
priorityScore = netProfitUSD × 0.6 + hfScore × 0.4

The 60/40 weighting intentionally prioritizes profit over urgency. A highly profitable position with HF 1.05 ranks above a marginal position at HF 1.001. This reflects real liquidation economics — gas costs and execution risk make marginal opportunities less attractive even if they're technically closer to the threshold.

Oracle Lag and Hidden Positions

Every 60 seconds, Mevryx compares live CoinGecko prices against on-chain Chainlink values for ETH, BTC, LINK, and USDC. If the divergence exceeds 0.5%, positions collateralized by affected assets are marked isHidden: true.

Hidden positions are those that would appear liquidatable using real market prices, but are not yet liquidatable on-chain because the Chainlink oracle hasn't updated. This is the core insight behind Mevryx: the oracle lag window is the early-warning signal that lets operators prepare before the liquidation is technically executable.

Oracle Feeds
ETH, BTC, LINK, USDC
Lag Threshold
> 0.5% divergence
Check Frequency
Every 60s
Data Source
CoinGecko vs Chainlink
Effect
isHidden = true
Stale Cutoff
15 min without update
Why This Matters
Chainlink price feeds update on a heartbeat or deviation threshold — typically when the price moves more than 0.5% or after a fixed time interval (e.g. 1 hour for some feeds). During rapid market moves, the on-chain price can lag the real market by minutes. Mevryx detects this gap and surfaces positions that are about to become liquidatable, not just those that already are.