Skip to documentation
AnyLend docs
Browse documentation

Docs / How AnyLend works

How AnyLend works

AnyLend is a permissionless registry of isolated lending pools. A pool pairs one collateral token with one borrow token and carries its own oracle, interest-rate model, limits, accounting, and administrative state.

Network scope. The app supports Ethereum, Sepolia, Base, OP Mainnet, Arbitrum, Robinhood Chain, Polygon, Avalanche, BNB Smart Chain, ZKsync Era, Linea, and Scroll. Production deployments use a reviewed chain configuration; Sepolia remains the supported rehearsal network. Pool parameters are visible on-chain, but visibility is not a safety guarantee.

A pool has its own ledger

Pool A and Pool B may use the same token contract, but they do not share deposits, debt, collateral, reserves, or risk parameters. The factory stores the registry and creates a dedicated LendingPool for each configuration.

Pool componentPurposeWhy it matters
Collateral tokenAsset a borrower locks before borrowing.Price, decimals, custody, and transfer behavior affect health and recovery.
Borrow tokenLiquidity supplied by lenders and transferred to borrowers.Exact transfer deltas and aggregate custody checks protect the ledger.
OracleReturns normalized prices and feed-health checks.A stale, invalid, or misgoverned feed can change liquidation outcomes.
Interest-rate modelQuotes utilization-sensitive borrow and supply rates.Rates affect debt growth and lender accounting; the model is pool-specific.
LimitsLTV, liquidation threshold, bonus, supply cap, and borrow cap.Parameters bound exposure but do not promise a return or prevent every loss.

Lender path

  1. Approve the borrow token. The wallet grants the pool permission to transfer the exact amount.
  2. Deposit liquidity. deposit(amount, minSharesOut) transfers the token and mints lender shares.
  3. Track the ledger. Deposits, shares, borrows, interest, and protocol reserves are accounted for separately.
  4. Withdraw after reviewing liquidity. withdraw(shares, minAssetsOut) burns shares and returns available assets when the pool is healthy.

Shares represent a proportional claim on the pool's tracked lender assets. A write can fail closed when actual token custody is below the represented ledger, when debt is active, or when a requested minimum output cannot be met.

Borrower path

  1. Approve and deposit collateral. depositCollateral(amount) moves the collateral token into the pool.
  2. Preview the debt. previewBorrow(borrower, amount) returns the expected borrow shares and debt increase.
  3. Borrow within the pool limits. borrow(amount, maxDebtIncrease) checks health, custody, pause state, caps, and the caller's debt bound before transferring the borrow token.
  4. Monitor the position. Price, interest, collateral, and pause changes can alter the position after the transaction.

The final write preflight in the app repeats factory identity, runtime bytecode, pool state, oracle, and wallet-network checks immediately before a wallet prompt. Direct contract callers must perform equivalent checks themselves.

Repayment and liquidation

repay(amount, minDebtReduction) removes debt shares based on the pool's current accounting and requires the exact transfer delta. Repayment is the normal way to reduce a borrower's position and unlock collateral.

A position can become liquidatable when its health falls below the configured boundary. A liquidator supplies borrow tokens through liquidate(borrower, repayAmount, minSeizeAmount). The contract calculates a bounded collateral seizure and preserves the pool's custody invariants.

When no collateral remains, the risk-reducing resolveBadDebt path can clear an uncollectible position under stricter conditions. Recovery paths do not turn an unhealthy pool into a healthy lending market; the verifier and normal risk-increasing writes remain fail-closed.

Read before write

Every wallet prompt is a boundary. Read the current pool configuration, token metadata, oracle health, pause state, custody health, and factory identity immediately before simulation and again before the transaction is submitted. A UI snapshot is context, not authorization.
// Illustrative calls; use the connected pool address and current state.
previewDeposit(amount)
previewBorrow(borrower, amount)
previewRepay(borrower, maxAmount)
collateralLedgerHealthy()
borrowTokenLedgerHealthy()

Continue reading