Matador Docs
Protocol Security

Tutorial - Real-World Integration

Hardening a lending protocol.

Tutorial: Hardening a Lending Protocol

In this tutorial, we will add a Solvency Check to a lending market.

Goal: Ensure that no transaction can leave the protocol with TotalDebt > TotalCollateral.

Prerequisites

  • A deployed Lending Market contract (we'll use a mock address).
  • Matador CLI.

Solvency checks protect the whole market

This guard applies to every user action, so solvency remains enforced even if core logic changes.

Step 1: Write the Solvency Policy

solvency.matador:

Demo helper ABI

MarketLens.json is a local helper ABI for this tutorial, not a public protocol ABI.

    import "abis/MarketLens.json" as Market;

    permission SolvencyGuard -> 1.0.0 {
        parameters: {
            authorizer: address,
            market: address,
            minCollateralRatioBps: uint256
        }

        pub fn solvencyOk(collateralRatioBps: uint256, totalDebt: uint256) -> bool {
            if (totalDebt == 0) {
                return true;
            }

            return collateralRatioBps >= parameters.minCollateralRatioBps;
        }

        pub fn authorize() -> bool {
            return authorizedBy(parameters.authorizer);
        }

        fn main() -> bool {
            return context.target == parameters.market;
        }
    }

Step 2: Compile

    npx --package @steerprotocol/matador-cli matador-policy-cli compile solvency.matador -d ./out

Step 3: Install

We attach this policy to the User Role and configure the protocol integration to call solvencyOk(...) with reviewed market values at the relevant enforcement phase. The main() entry scopes which market target the role can touch; the callable helper performs the solvency decision.

Step 4: Verification

  1. Scenario A (Safe Borrow): User borrows 50 USDC against 100 ETH.
    • Post-state: Collateral >> Debt.
    • Result: Approved.
  2. Scenario B (Exploit Attempt): User finds a bug that lets them withdraw all collateral without repaying debt.
    • The protocol integration evaluates solvencyOk(...) with the relevant market values.
    • TotalCollateral is 0. TotalDebt is > 0.
    • The guard fails.
    • Result: REVERT.

The protocol is saved from the exploit, even though the exploit existed in the Solidity code.

On this page