Matador Docs
Integrations

Aave V3 Integration

Comprehensive guide to securing Aave V3 positions with Matador.

Matador is highly effective for managing delegated access to Aave V3 positions. By defining granular policies, you can allow automated bots to manage health factors or rebalance portfolios without risking the principal collateral.

Security Architecture

Permission Patterns

1. Safe Lending (Supply & Withdraw)

The primary risk in lending is fund diversion: an attacker withdrawing your collateral to their own wallet.

policies/aave-supply.matador
import "abis/AavePool.json" as Aave;

permission SafeLending -> 1.0.0 {
    parameters: {
        authorizer: address,
        pool: address,
        account: address
    }

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

    fn main() -> bool {
        if (context.target != parameters.pool) {
            return false;
        }

        if (context.selector == Aave.supply) {
            return Aave.supply.onBehalfOf == parameters.account;
        } else if (context.selector == Aave.withdraw) {
            return Aave.withdraw.to == parameters.account;
        }

        return false;
    }
}

2. Health Factor Guardian

Allow a bot to borrow assets, but only if the account is healthy when the policy is evaluated.

Aave health read

The policy reads Aave V3 getUserAccountData(...).healthFactor directly from the Pool ABI. It does not rely on a caller-supplied health-factor value.

policies/aave-borrow.matador
import "abis/AavePool.json" as Aave;

permission ControlledBorrow -> 1.0.0 {
    parameters: {
        authorizer: address,
        pool: Aave,
        account: address,
        borrowAmount: uint256,
        minHealthFactor: uint256
    }

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

    fn main() -> bool {
        if (context.target != parameters.pool) {
            return false;
        }

        if (context.selector == Aave.borrow) {
            if (Aave.borrow.onBehalfOf != parameters.account) {
                return false;
            }

            if (Aave.borrow.amount != parameters.borrowAmount) {
                return false;
            }

            let healthFactor = parameters.pool.getUserAccountData(parameters.account).healthFactor;
            return healthFactor >= parameters.minHealthFactor;
        }

        return false;
    }
}

3. Emergency Repay (Panic Mode)

Create a "Panic Mode" policy that allows ANYONE (or a specific keeper) to repay debt if the health factor drops dangerously low, bypassing other restrictions.

policies/aave-panic.matador
import "abis/AavePool.json" as Aave;

permission EmergencyRepay -> 1.0.0 {
    parameters: {
        authorizer: address,
        pool: address,
        account: address
    }

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

    fn main() -> bool {
        if (context.target != parameters.pool) {
            return false;
        }

        if (context.selector == Aave.repay) {
            return Aave.repay.onBehalfOf == parameters.account;
        }

        return false;
    }
}

Integration Tutorial

Setup Project

Install the CLI and download the Aave V3 ABI.

npm install -D @steerprotocol/matador-cli
mkdir abis
# Download Aave Pool ABI to ./abis/AavePool.json

Write the Policy

Create policies/aave-supply.matador.

import "abis/AavePool.json" as Aave;

permission AaveSupply -> 1.0.0 {
    parameters: {
        pool: address,
        account: address
    }

    fn main() -> bool {
        if (context.target != parameters.pool) {
            return false;
        }

        if (context.selector == Aave.supply) {
            return Aave.supply.onBehalfOf == parameters.account;
        }

        return false;
    }
}

Compile

Compile the policy to bytecode.

npx --package @steerprotocol/matador-cli matador-policy-cli compile policies/aave-supply.matador

Deploy

Grant the permission to your smart account.

const policy = require('./policies/aave-supply.json');
// Grant permission on-chain...

Gas Optimization

Aave interactions are gas-intensive. Minimize overhead by:

  1. Checking Selectors First: context.selector == Aave.supply is cheap (4 bytes comparison). Do this before complex logic.
  2. Avoid Redundant State Checks: If you trust the bot, you might skip the on-chain getUserAccountData check for every single supply transaction, reserving it only for borrows.

Troubleshooting

IssueCauseFix
PermissionViolationonBehalfOf mismatch.Ensure the bot is supplying on behalf of the smart account, not itself.
Call RevertedAave Pool paused or frozen.Check Aave protocol status. Matador cannot bypass protocol-level pauses.
Invalid ABIMismatch between V2 and V3 ABIs.Ensure you are using the V3 Pool ABI. V2 uses LendingPool.

On this page