312 lines
5.0 KiB
Markdown
312 lines
5.0 KiB
Markdown
# Strategy Authoring Guide
|
|
|
|
## Overview
|
|
|
|
This guide explains how to create and author DeFi strategies using the Strategic executor system.
|
|
|
|
## Strategy Structure
|
|
|
|
A strategy is a JSON file that defines a sequence of DeFi operations to execute atomically.
|
|
|
|
### Basic Structure
|
|
|
|
```json
|
|
{
|
|
"name": "Strategy Name",
|
|
"description": "What this strategy does",
|
|
"chain": "mainnet",
|
|
"executor": "0x...",
|
|
"blinds": [],
|
|
"guards": [],
|
|
"steps": []
|
|
}
|
|
```
|
|
|
|
## Components
|
|
|
|
### 1. Strategy Metadata
|
|
|
|
- **name**: Unique identifier for the strategy
|
|
- **description**: Human-readable description
|
|
- **chain**: Target blockchain (mainnet, arbitrum, optimism, base)
|
|
- **executor**: Optional executor contract address (can be set via env)
|
|
|
|
### 2. Blinds (Sealed Runtime Parameters)
|
|
|
|
Blinds are values that are substituted at runtime, not stored in the strategy file.
|
|
|
|
```json
|
|
{
|
|
"blinds": [
|
|
{
|
|
"name": "amount",
|
|
"type": "uint256",
|
|
"description": "Amount to supply"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
Use blinds in steps:
|
|
```json
|
|
{
|
|
"amount": { "blind": "amount" }
|
|
}
|
|
```
|
|
|
|
### 3. Guards (Safety Checks)
|
|
|
|
Guards prevent unsafe execution:
|
|
|
|
```json
|
|
{
|
|
"guards": [
|
|
{
|
|
"type": "minHealthFactor",
|
|
"params": {
|
|
"minHF": 1.2,
|
|
"user": "0x..."
|
|
},
|
|
"onFailure": "revert"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Guard Types**:
|
|
- `oracleSanity`: Price validation
|
|
- `twapSanity`: TWAP price checks
|
|
- `maxGas`: Gas limits
|
|
- `minHealthFactor`: Aave health factor
|
|
- `slippage`: Slippage protection
|
|
- `positionDeltaLimit`: Position size limits
|
|
|
|
**onFailure Options**:
|
|
- `revert`: Stop execution (default)
|
|
- `warn`: Log warning but continue
|
|
- `skip`: Skip the step
|
|
|
|
### 4. Steps (Operations)
|
|
|
|
Steps define the actual DeFi operations:
|
|
|
|
```json
|
|
{
|
|
"steps": [
|
|
{
|
|
"id": "step1",
|
|
"description": "Supply to Aave",
|
|
"guards": [],
|
|
"action": {
|
|
"type": "aaveV3.supply",
|
|
"asset": "0x...",
|
|
"amount": "1000000"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Action Types
|
|
|
|
### Aave v3
|
|
|
|
```json
|
|
{
|
|
"type": "aaveV3.supply",
|
|
"asset": "0x...",
|
|
"amount": "1000000",
|
|
"onBehalfOf": "0x..." // optional
|
|
}
|
|
```
|
|
|
|
```json
|
|
{
|
|
"type": "aaveV3.withdraw",
|
|
"asset": "0x...",
|
|
"amount": "1000000",
|
|
"to": "0x..." // optional
|
|
}
|
|
```
|
|
|
|
```json
|
|
{
|
|
"type": "aaveV3.borrow",
|
|
"asset": "0x...",
|
|
"amount": "1000000",
|
|
"interestRateMode": "variable", // or "stable"
|
|
"onBehalfOf": "0x..." // optional
|
|
}
|
|
```
|
|
|
|
```json
|
|
{
|
|
"type": "aaveV3.repay",
|
|
"asset": "0x...",
|
|
"amount": "1000000",
|
|
"rateMode": "variable",
|
|
"onBehalfOf": "0x..." // optional
|
|
}
|
|
```
|
|
|
|
```json
|
|
{
|
|
"type": "aaveV3.flashLoan",
|
|
"assets": ["0x..."],
|
|
"amounts": ["1000000"],
|
|
"modes": [0] // optional
|
|
}
|
|
```
|
|
|
|
### Uniswap v3
|
|
|
|
```json
|
|
{
|
|
"type": "uniswapV3.swap",
|
|
"tokenIn": "0x...",
|
|
"tokenOut": "0x...",
|
|
"fee": 3000,
|
|
"amountIn": "1000000",
|
|
"amountOutMinimum": "990000", // optional
|
|
"exactInput": true
|
|
}
|
|
```
|
|
|
|
### Compound v3
|
|
|
|
```json
|
|
{
|
|
"type": "compoundV3.supply",
|
|
"asset": "0x...",
|
|
"amount": "1000000",
|
|
"dst": "0x..." // optional
|
|
}
|
|
```
|
|
|
|
### MakerDAO
|
|
|
|
```json
|
|
{
|
|
"type": "maker.openVault",
|
|
"ilk": "ETH-A"
|
|
}
|
|
```
|
|
|
|
```json
|
|
{
|
|
"type": "maker.frob",
|
|
"cdpId": "123",
|
|
"dink": "1000000000000000000", // optional
|
|
"dart": "1000" // optional
|
|
}
|
|
```
|
|
|
|
### Balancer
|
|
|
|
```json
|
|
{
|
|
"type": "balancer.swap",
|
|
"poolId": "0x...",
|
|
"kind": "givenIn",
|
|
"assetIn": "0x...",
|
|
"assetOut": "0x...",
|
|
"amount": "1000000"
|
|
}
|
|
```
|
|
|
|
### Curve
|
|
|
|
```json
|
|
{
|
|
"type": "curve.exchange",
|
|
"pool": "0x...",
|
|
"i": 0,
|
|
"j": 1,
|
|
"dx": "1000000",
|
|
"minDy": "990000" // optional
|
|
}
|
|
```
|
|
|
|
### Aggregators
|
|
|
|
```json
|
|
{
|
|
"type": "aggregators.swap1Inch",
|
|
"tokenIn": "0x...",
|
|
"tokenOut": "0x...",
|
|
"amountIn": "1000000",
|
|
"minReturn": "990000", // optional
|
|
"slippageBps": 50 // optional, default 50
|
|
}
|
|
```
|
|
|
|
## Flash Loan Strategies
|
|
|
|
Flash loans require special handling. Steps after a flash loan are executed in the callback:
|
|
|
|
```json
|
|
{
|
|
"steps": [
|
|
{
|
|
"id": "flashLoan",
|
|
"action": {
|
|
"type": "aaveV3.flashLoan",
|
|
"assets": ["0x..."],
|
|
"amounts": ["1000000"]
|
|
}
|
|
},
|
|
{
|
|
"id": "swap",
|
|
"action": {
|
|
"type": "uniswapV3.swap",
|
|
// This executes in the flash loan callback
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Always use guards** for safety checks
|
|
2. **Use blinds** for sensitive values
|
|
3. **Test on fork** before live execution
|
|
4. **Start small** and increase gradually
|
|
5. **Monitor gas usage**
|
|
6. **Validate addresses** before execution
|
|
7. **Use slippage protection** for swaps
|
|
8. **Check health factors** for lending operations
|
|
|
|
## Examples
|
|
|
|
See `strategies/` directory for complete examples:
|
|
- `sample.recursive.json`: Recursive leverage
|
|
- `sample.hedge.json`: Hedging strategy
|
|
- `sample.liquidation.json`: Liquidation helper
|
|
- `sample.stablecoin-hedge.json`: Stablecoin arbitrage
|
|
|
|
## Validation
|
|
|
|
Validate your strategy before execution:
|
|
|
|
```bash
|
|
strategic validate strategy.json
|
|
```
|
|
|
|
## Execution
|
|
|
|
```bash
|
|
# Simulate
|
|
strategic run strategy.json --simulate
|
|
|
|
# Dry run
|
|
strategic run strategy.json --dry
|
|
|
|
# Explain
|
|
strategic run strategy.json --explain
|
|
|
|
# Live execution
|
|
strategic run strategy.json
|
|
```
|
|
|