Euler Finance Integration
Comprehensive guide to securing Euler Finance vaults with Matador.
Euler Finance offers modular lending vaults where permission management is crucial for protecting capital efficiency and preventing unauthorized withdrawals. This guide details how to implement robust security policies for Euler integrations.
Security Architecture
graph TD
User[Lending Bot] -->|Deposit/Withdraw| Safe[Smart Account]
Safe -->|Check Policy| Matador[Matador Interpreter]
Matador -->|Verify Calldata| Check{Policy Rules}
Check -- Pass --> Vault[Euler Vault]
Check -- Fail --> Revert[Revert Transaction]Permission Patterns
1. Secure Deposits
When automating deposits, the critical invariant is ensuring the shares are minted to the smart account, not an attacker.
import "abis/EulerVault.json" as Euler;
permission SafeEulerDeposit -> 1.0.0 {
parameters: {
vault: address,
account: address
}
fn main() -> bool {
if (context.target != parameters.vault) {
return false;
}
if (context.selector == Euler.deposit) {
return Euler.deposit.receiver == parameters.account;
}
return false;
}
}2. Operational Limits (Capped Exposure)
Prevent a bot from deploying too much capital into a single vault, limiting exposure to protocol risks.
import "abis/EulerVault.json" as Euler;
permission CappedDeposit -> 1.0.0 {
parameters: {
vault: address,
maxDepositAmount: uint256
}
fn main() -> bool {
if (context.target != parameters.vault) {
return false;
}
if (context.selector == Euler.deposit) {
return Euler.deposit.assets == parameters.maxDepositAmount;
}
return false;
}
}3. Flash Loan Protection (Self-Originated)
Euler vaults support flash loans. You may want to allow flash loans ONLY if the borrower is your own account (e.g., for liquidation or rebalancing strategies), preventing external actors from using your credit.
import "abis/EulerVault.json" as Euler;
permission SafeFlashLoan -> 1.0.0 {
parameters: {
vault: address,
receiver: address
}
fn main() -> bool {
if (context.target != parameters.vault) {
return false;
}
if (context.selector == Euler.flashLoan) {
return Euler.flashLoan.receiver == parameters.receiver;
}
return false;
}
}Integration Tutorial
Setup Project
Install the CLI and download the Euler Vault ABI.
npm install -D matador-policy-cli
mkdir abis
# Download Euler Vault ABI to ./abis/EulerVault.jsonWrite the Policy
Create policies/euler-guard.matador.
import "abis/EulerVault.json" as Euler;
permission EulerGuard -> 1.0.0 {
parameters: {
vault: address,
account: address
}
fn main() -> bool {
if (context.target != parameters.vault) {
return false;
}
if (context.selector == Euler.deposit) {
return Euler.deposit.receiver == parameters.account;
} else if (context.selector == Euler.withdraw) {
return Euler.withdraw.receiver == parameters.account;
}
return false;
}
}Compile & Deploy
Compile the policy and provision it to your smart account.
npx matador-policy-cli compile policies/euler-guard.matadorGas Optimization
- Selector First: Always check
context.selector == Euler.depositorcontext.selector == Euler.withdrawbefore checking arguments. This fails fast if the function is wrong. - Batching: If you are performing multiple operations (e.g.
approve+deposit), consider wrapping them in a MultiCall and using a policy that inspects the MultiCall data (advanced).
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
PermissionViolation | receiver mismatch. | Ensure your bot sends receiver as the smart account address, not msg.sender (which might be the bot EOA). |
Invalid Target | Wrong vault address. | Euler has many vaults (one per asset). Ensure the policy parameter matches the specific vault you are interacting with. |