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
graph TD
User[Risk Manager Bot] -->|Repay Debt| Safe[Smart Account]
Safe -->|Check Policy| Matador[Matador Interpreter]
Matador -->|Decode Calldata| Check{Policy Rules}
Check -- Pass --> Pool[Aave Pool]
Check -- Fail --> Revert[Revert Transaction]Permission Patterns
1. Safe Lending (Supply & Withdraw)
The primary risk in lending is fund diversion: an attacker withdrawing your collateral to their own wallet.
import "abis/AavePool.json" as Aave;
permission SafeLending -> 1.0.0 {
parameters: {
pool: address
}
when: {
all {
context.target == parameters.pool,
any {
// Allow supplying assets
Aave.supply,
// Allow withdrawing ONLY to self
all {
Aave.withdraw,
context.args.to == context.account
}
}
}
}
}2. Health Factor Guardian
Allow a bot to borrow assets, but only if the account remains healthy after the transaction.
State Verification
This policy uses STATE_VARIABLE_CHECK to query the Aave Pool for the user's health factor after the operation would theoretically occur (in simulation) or as a pre-condition check.
import "abis/AavePool.json" as Aave;
permission ControlledBorrow -> 1.0.0 {
parameters: {
pool: address,
minHealthFactor: uint256 // e.g. 1.5e18
}
when: {
all {
context.target == parameters.pool,
Aave.borrow,
// Check health factor of the account
// Note: In a real tx, this checks the state BEFORE execution.
// Ideally, this is used in simulation/validation phase.
Aave.getUserAccountData(user: context.account).healthFactor >= parameters.minHealthFactor
}
}
}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.
import "abis/AavePool.json" as Aave;
permission EmergencyRepay -> 1.0.0 {
parameters: {
pool: address,
dangerThreshold: uint256 // e.g. 1.1e18
}
when: {
all {
context.target == parameters.pool,
Aave.repay,
// Only allow if health is CRITICAL
Aave.getUserAccountData(user: context.account).healthFactor < parameters.dangerThreshold
}
}
}Integration Tutorial
Setup Project
Install the CLI and download the Aave V3 ABI.
npm install -D matador-policy-cli
mkdir abis
# Download Aave Pool ABI to ./abis/AavePool.jsonWrite the Policy
Create policies/aave-supply.matador.
import "abis/AavePool.json" as Aave;
permission AaveSupply -> 1.0.0 {
parameters: {
pool: address
}
when: {
all {
context.target == parameters.pool,
// Check calldata for supply() signature
Aave.supply,
// Ensure onBehalfOf is the account itself
context.args.onBehalfOf == context.account
}
}
}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:
- Checking Selectors First:
Aave.supplycheck is cheap (4 bytes comparison). Do this before complex logic. - Avoid Redundant State Checks: If you trust the bot, you might skip the on-chain
getUserAccountDatacheck for every single supply transaction, reserving it only for borrows.
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
PermissionViolation | onBehalfOf mismatch. | Ensure the bot is supplying on behalf of the smart account, not itself. |
Call Reverted | Aave Pool paused or frozen. | Check Aave protocol status. Matador cannot bypass protocol-level pauses. |
Invalid ABI | Mismatch between V2 and V3 ABIs. | Ensure you are using the V3 Pool ABI. V2 uses LendingPool. |