Initial commit
This commit is contained in:
181
docs/ARCHITECTURE.md
Normal file
181
docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,181 @@
|
||||
# DBIS System Architecture
|
||||
|
||||
## Overview
|
||||
|
||||
The DBIS (Debt-Based Institutional Strategy) system is a comprehensive DeFi leverage management platform that implements atomic amortizing cycles to improve position health while maintaining strict invariants.
|
||||
|
||||
## Core Principles
|
||||
|
||||
### 1. Amortization Rule
|
||||
Every atomic transaction MUST end with:
|
||||
- **Debt ↓** (decreased)
|
||||
- **Collateral ↑** (increased)
|
||||
- **LTV ↓** (decreased loan-to-value ratio)
|
||||
- **HF ↑** (improved health factor)
|
||||
|
||||
If any of these conditions fail, the transaction reverts.
|
||||
|
||||
### 2. Policy Controls Over Bot Intelligence
|
||||
- Bots suggest actions
|
||||
- **Contracts enforce invariants**
|
||||
- If invariant fails → revert → no risk
|
||||
|
||||
### 3. Single Identity
|
||||
- One vault address
|
||||
- One router
|
||||
- One kernel
|
||||
- Multisig/MPC owner
|
||||
- Zero opacity
|
||||
- Maximum governance safety
|
||||
|
||||
### 4. Modular & Upgradeable
|
||||
All components are swappable:
|
||||
- Router
|
||||
- Kernel
|
||||
- Policy modules
|
||||
- Providers
|
||||
- Oracle adapters
|
||||
|
||||
## System Components
|
||||
|
||||
### Core Contracts
|
||||
|
||||
1. **DBISInstitutionalVault.sol**
|
||||
- Tracks collateral and debt across multiple assets
|
||||
- Integrates with Aave v3 for position data
|
||||
- Enforces position invariants
|
||||
|
||||
2. **FlashLoanRouter.sol**
|
||||
- Aggregates flash loans from multiple providers:
|
||||
- Aave v3
|
||||
- Balancer Vault
|
||||
- Uniswap V3
|
||||
- DAI Flash Mint
|
||||
- Liquidity-weighted provider selection
|
||||
|
||||
3. **RecursiveLeverageKernel.sol**
|
||||
- Implements atomic amortizing cycle pipeline:
|
||||
1. Harvest yield
|
||||
2. Swap to stable/collateral
|
||||
3. Split: repay debt + add collateral
|
||||
4. Enforce invariants
|
||||
5. Revert if LTV worsens
|
||||
|
||||
4. **CollateralToggleManager.sol**
|
||||
- Manages Aave v3 collateral enable/disable
|
||||
- Batch operations for efficiency
|
||||
|
||||
### Governance Contracts
|
||||
|
||||
5. **ConfigRegistry.sol**
|
||||
- Stores all system parameters:
|
||||
- Max loops
|
||||
- Max flash size per asset
|
||||
- Min/Target health factor
|
||||
- Allowed assets
|
||||
- Provider caps
|
||||
|
||||
6. **PolicyEngine.sol**
|
||||
- Plugin architecture for policy modules
|
||||
- Aggregates policy decisions
|
||||
- All modules must approve
|
||||
|
||||
7. **GovernanceGuard.sol**
|
||||
- Final gatekeeper for all actions
|
||||
- Invariant validation
|
||||
- Strategy throttling
|
||||
|
||||
8. **Policy Modules**
|
||||
- **PolicyHFTrend**: Monitors health factor trends
|
||||
- **PolicyFlashVolume**: Limits flash loan volume per period
|
||||
- **PolicyLiquiditySpread**: Validates liquidity spreads
|
||||
- **PolicyProviderConcentration**: Prevents over-concentration
|
||||
|
||||
### Oracle Layer
|
||||
|
||||
9. **DBISOracleAdapter.sol**
|
||||
- Standardizes pricing from multiple sources:
|
||||
- Aave oracles
|
||||
- Chainlink price feeds
|
||||
- Uniswap TWAPs
|
||||
- Aggregates with confidence scoring
|
||||
|
||||
## Execution Flow
|
||||
|
||||
### Atomic Amortizing Cycle
|
||||
|
||||
```
|
||||
1. Kernel.executeAmortizingCycle()
|
||||
↓
|
||||
2. GovernanceGuard.enforceInvariants()
|
||||
↓
|
||||
3. Vault.snapshotPosition()
|
||||
↓
|
||||
4. FlashRouter.flashLoan()
|
||||
↓
|
||||
5. Kernel.onFlashLoan() callback:
|
||||
- Harvest yield
|
||||
- Swap to target asset
|
||||
- Repay debt
|
||||
- Add collateral
|
||||
↓
|
||||
6. Vault.verifyPositionImproved()
|
||||
↓
|
||||
7. If invariant fails → revert
|
||||
If invariant passes → emit events
|
||||
```
|
||||
|
||||
## Security Model
|
||||
|
||||
### Invariant Enforcement
|
||||
|
||||
All position changes must satisfy:
|
||||
- `debtAfter <= debtBefore`
|
||||
- `collateralAfter >= collateralBefore`
|
||||
- `healthFactorAfter >= healthFactorBefore`
|
||||
|
||||
### Access Control
|
||||
|
||||
- **Owner**: Full administrative control
|
||||
- **Operator**: Can execute amortization cycles
|
||||
- **Kernel Role**: Can record position changes
|
||||
- **Policy Modules**: Evaluated by PolicyEngine
|
||||
|
||||
### Upgradeability
|
||||
|
||||
- All core contracts support UUPS upgradeability
|
||||
- Policy modules are plugin-based
|
||||
- Provider addresses are configurable
|
||||
|
||||
## Integration Points
|
||||
|
||||
### Aave v3
|
||||
- Position data
|
||||
- Collateral management
|
||||
- Borrowing/repayment
|
||||
|
||||
### Flash Loan Providers
|
||||
- Aave v3 Pool
|
||||
- Balancer Vault
|
||||
- Uniswap V3 Pools
|
||||
- DAI Flash Mint
|
||||
|
||||
### DEXs
|
||||
- Uniswap V3 Router (swaps)
|
||||
|
||||
### Oracles
|
||||
- Chainlink Price Feeds
|
||||
- Aave Oracle
|
||||
- Uniswap TWAPs
|
||||
|
||||
## Multi-Chain Support
|
||||
|
||||
The system is designed for multi-chain deployment:
|
||||
- Primary: Ethereum Mainnet
|
||||
- Secondary: Arbitrum, Polygon, Base, Optimism
|
||||
|
||||
Each chain requires:
|
||||
- Chain-specific protocol addresses
|
||||
- Chain-specific oracle feeds
|
||||
- Chain-specific RPC endpoints
|
||||
|
||||
186
docs/ATOMIC_CYCLE.md
Normal file
186
docs/ATOMIC_CYCLE.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# Atomic Amortizing Cycle
|
||||
|
||||
## Overview
|
||||
|
||||
The atomic amortizing cycle is the core mechanism of the DBIS system. It guarantees that every execution improves the position (debt↓, collateral↑, LTV↓, HF↑) in a single atomic transaction.
|
||||
|
||||
## Cycle Phases
|
||||
|
||||
### Phase 1: Pre-Execution Validation
|
||||
```
|
||||
GovernanceGuard.enforceInvariants()
|
||||
↓
|
||||
PolicyEngine.evaluateAll()
|
||||
↓
|
||||
ConfigRegistry.getMaxLoops()
|
||||
↓
|
||||
Vault.snapshotPosition()
|
||||
```
|
||||
|
||||
**Checks:**
|
||||
- Policy modules approve action
|
||||
- Max loops not exceeded
|
||||
- Position snapshot taken
|
||||
|
||||
### Phase 2: Flash Loan Execution
|
||||
```
|
||||
FlashLoanRouter.flashLoan()
|
||||
↓
|
||||
Provider-specific flash loan (Aave/Balancer/Uniswap/DAI)
|
||||
↓
|
||||
Kernel.onFlashLoan() callback
|
||||
```
|
||||
|
||||
**Actions:**
|
||||
- Borrow flash loan amount
|
||||
- Execute callback with borrowed funds
|
||||
|
||||
### Phase 3: Amortization Operations
|
||||
```
|
||||
onFlashLoan() callback:
|
||||
1. Harvest yield (if available)
|
||||
2. Swap to target asset
|
||||
3. Split funds:
|
||||
- 50% repay debt
|
||||
- 50% add collateral
|
||||
4. Repay flash loan (principal + fee)
|
||||
```
|
||||
|
||||
**Math:**
|
||||
```
|
||||
yieldAmount = harvestYield()
|
||||
totalAmount = flashAmount + yieldAmount
|
||||
swapAmount = swapToTargetAsset(totalAmount)
|
||||
debtRepayment = swapAmount / 2
|
||||
collateralAddition = swapAmount - debtRepayment
|
||||
```
|
||||
|
||||
### Phase 4: Invariant Verification
|
||||
```
|
||||
Vault.verifyPositionImproved(
|
||||
collateralBefore,
|
||||
debtBefore,
|
||||
healthFactorBefore
|
||||
)
|
||||
```
|
||||
|
||||
**Checks:**
|
||||
- `debtAfter < debtBefore` ✓
|
||||
- `collateralAfter > collateralBefore` ✓
|
||||
- `healthFactorAfter > healthFactorBefore` ✓
|
||||
|
||||
### Phase 5: Completion
|
||||
```
|
||||
If invariants pass:
|
||||
- Emit AmortizationExecuted event
|
||||
- Return success
|
||||
If invariants fail:
|
||||
- Emit InvariantFail event
|
||||
- Revert transaction
|
||||
```
|
||||
|
||||
## Recursive Cycles
|
||||
|
||||
The kernel can execute multiple cycles in sequence:
|
||||
|
||||
```solidity
|
||||
for (uint256 i = 0; i < maxLoops; i++) {
|
||||
executeSingleStep();
|
||||
|
||||
// Early exit if target achieved
|
||||
if (currentHF >= targetHF) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Early exit if no improvement
|
||||
if (noImprovement) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Each cycle must improve the position independently.
|
||||
|
||||
## Example Flow
|
||||
|
||||
### Input
|
||||
- Current Position:
|
||||
- Collateral: $1,000,000
|
||||
- Debt: $800,000
|
||||
- HF: 1.05
|
||||
- LTV: 80%
|
||||
|
||||
### Cycle Execution
|
||||
1. Flash loan: $100,000 USDC
|
||||
2. Swap: $100,000 → $100,000 USDC (no swap needed)
|
||||
3. Repay debt: $50,000
|
||||
4. Add collateral: $50,000
|
||||
|
||||
### Output
|
||||
- New Position:
|
||||
- Collateral: $1,050,000 (+$50,000)
|
||||
- Debt: $750,000 (-$50,000)
|
||||
- HF: 1.12 (+0.07)
|
||||
- LTV: 71.4% (-8.6%)
|
||||
|
||||
### Invariant Check
|
||||
- ✓ Debt decreased
|
||||
- ✓ Collateral increased
|
||||
- ✓ HF improved
|
||||
- ✓ LTV decreased
|
||||
|
||||
**Result: SUCCESS**
|
||||
|
||||
## Gas Optimization
|
||||
|
||||
### Batch Operations
|
||||
- Multiple cycles in one transaction
|
||||
- Batch collateral toggles
|
||||
- Batch policy evaluations
|
||||
|
||||
### Flash Loan Optimization
|
||||
- Use cheapest provider (DAI flash mint = 0% fee)
|
||||
- Split across providers for large amounts
|
||||
- Optimal provider selection
|
||||
|
||||
### Early Exits
|
||||
- Exit if target HF achieved
|
||||
- Exit if no improvement possible
|
||||
- Exit if max loops reached
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Revert Conditions
|
||||
1. Policy check fails
|
||||
2. Flash loan unavailable
|
||||
3. Swap fails (slippage too high)
|
||||
4. Debt repayment fails
|
||||
5. Invariant check fails
|
||||
|
||||
### Recovery
|
||||
All state changes are atomic. On revert:
|
||||
- Flash loan not borrowed (or automatically repaid)
|
||||
- Position unchanged
|
||||
- Can retry with different parameters
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Events Emitted
|
||||
- `AmortizationExecuted(cyclesExecuted, collateralIncrease, debtDecrease, hfImprovement)`
|
||||
- `InvariantFail(reason)`
|
||||
- `SingleStepCompleted(collateralAdded, debtRepaid)`
|
||||
|
||||
### Metrics Tracked
|
||||
- Cycles executed per transaction
|
||||
- Average HF improvement per cycle
|
||||
- Gas cost per cycle
|
||||
- Success rate
|
||||
|
||||
## Safety Guarantees
|
||||
|
||||
1. **Atomicity**: All-or-nothing execution
|
||||
2. **Invariant Preservation**: Position always improves
|
||||
3. **Reversibility**: Can revert at any point
|
||||
4. **Policy Compliance**: All policies must approve
|
||||
5. **Access Control**: Only authorized operators
|
||||
|
||||
232
docs/DEPLOYMENT.md
Normal file
232
docs/DEPLOYMENT.md
Normal file
@@ -0,0 +1,232 @@
|
||||
# Deployment Guide
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Node.js** >= 18.0.0
|
||||
2. **Foundry** (Forge) installed
|
||||
3. **Environment variables** configured
|
||||
4. **Testnet tokens** for testing
|
||||
|
||||
## Environment Setup
|
||||
|
||||
### 1. Install Dependencies
|
||||
|
||||
```bash
|
||||
# Install Node.js dependencies
|
||||
npm install
|
||||
|
||||
# Install Foundry dependencies
|
||||
forge install
|
||||
```
|
||||
|
||||
### 2. Configure Environment
|
||||
|
||||
Create `.env` file:
|
||||
|
||||
```env
|
||||
# RPC URLs
|
||||
RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY
|
||||
TESTNET_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY
|
||||
|
||||
# Private Keys
|
||||
PRIVATE_KEY=your_private_key_here
|
||||
MULTISIG_ADDRESS=your_multisig_address
|
||||
|
||||
# Contract Addresses (will be filled after deployment)
|
||||
VAULT_ADDRESS=
|
||||
KERNEL_ADDRESS=
|
||||
FLASH_ROUTER_ADDRESS=
|
||||
CONFIG_REGISTRY_ADDRESS=
|
||||
POLICY_ENGINE_ADDRESS=
|
||||
GOVERNANCE_GUARD_ADDRESS=
|
||||
ORACLE_ADAPTER_ADDRESS=
|
||||
COLLATERAL_MANAGER_ADDRESS=
|
||||
|
||||
# Protocol Addresses (Mainnet)
|
||||
AAVE_POOL_ADDRESS=0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2
|
||||
UNISWAP_ROUTER_ADDRESS=0xE592427A0AEce92De3Edee1F18E0157C05861564
|
||||
BALANCER_VAULT_ADDRESS=0xBA12222222228d8Ba445958a75a0704d566BF2C8
|
||||
DAI_FLASH_MINT_ADDRESS=0x1EB4CF3A948E7D72A198fe073cCb8C7a948cD853
|
||||
|
||||
# Chainlink Feeds
|
||||
CHAINLINK_WETH_USD=0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
|
||||
CHAINLINK_WBTC_USD=0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c
|
||||
```
|
||||
|
||||
## Deployment Order
|
||||
|
||||
Deploy contracts in this order (respects dependencies):
|
||||
|
||||
### Step 1: Oracle Adapter
|
||||
|
||||
```bash
|
||||
forge script scripts/deploy.ts:DeployOracleAdapter --rpc-url $TESTNET_RPC_URL --broadcast
|
||||
```
|
||||
|
||||
### Step 2: Config Registry
|
||||
|
||||
```bash
|
||||
forge script scripts/deploy.ts:DeployConfigRegistry --rpc-url $TESTNET_RPC_URL --broadcast
|
||||
```
|
||||
|
||||
### Step 3: Policy Modules
|
||||
|
||||
Deploy all 4 policy modules:
|
||||
|
||||
```bash
|
||||
forge script scripts/deploy.ts:DeployPolicyHFTrend --rpc-url $TESTNET_RPC_URL --broadcast
|
||||
forge script scripts/deploy.ts:DeployPolicyFlashVolume --rpc-url $TESTNET_RPC_URL --broadcast
|
||||
forge script scripts/deploy.ts:DeployPolicyLiquiditySpread --rpc-url $TESTNET_RPC_URL --broadcast
|
||||
forge script scripts/deploy.ts:DeployPolicyProviderConcentration --rpc-url $TESTNET_RPC_URL --broadcast
|
||||
```
|
||||
|
||||
### Step 4: Policy Engine
|
||||
|
||||
```bash
|
||||
forge script scripts/deploy.ts:DeployPolicyEngine --rpc-url $TESTNET_RPC_URL --broadcast
|
||||
```
|
||||
|
||||
### Step 5: Vault
|
||||
|
||||
```bash
|
||||
forge script scripts/deploy.ts:DeployVault --rpc-url $TESTNET_RPC_URL --broadcast
|
||||
```
|
||||
|
||||
### Step 6: Flash Router
|
||||
|
||||
```bash
|
||||
forge script scripts/deploy.ts:DeployFlashRouter --rpc-url $TESTNET_RPC_URL --broadcast
|
||||
```
|
||||
|
||||
### Step 7: Collateral Manager
|
||||
|
||||
```bash
|
||||
forge script scripts/deploy.ts:DeployCollateralManager --rpc-url $TESTNET_RPC_URL --broadcast
|
||||
```
|
||||
|
||||
### Step 8: Governance Guard
|
||||
|
||||
```bash
|
||||
forge script scripts/deploy.ts:DeployGovernanceGuard --rpc-url $TESTNET_RPC_URL --broadcast
|
||||
```
|
||||
|
||||
### Step 9: Kernel
|
||||
|
||||
```bash
|
||||
forge script scripts/deploy.ts:DeployKernel --rpc-url $TESTNET_RPC_URL --broadcast
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
After deployment, configure all contracts:
|
||||
|
||||
```bash
|
||||
tsx scripts/configure.ts
|
||||
```
|
||||
|
||||
This script will:
|
||||
1. Set Config Registry parameters
|
||||
2. Register policy modules with Policy Engine
|
||||
3. Configure Oracle Adapter with price feeds
|
||||
4. Grant roles (Kernel, Operator)
|
||||
5. Set allowed assets
|
||||
6. Configure provider caps
|
||||
|
||||
## Verification
|
||||
|
||||
### 1. Verify Contracts on Etherscan
|
||||
|
||||
```bash
|
||||
forge verify-contract --chain-id 1 --num-of-optimizations 200 \
|
||||
--compiler-version v0.8.24 \
|
||||
CONTRACT_ADDRESS CONTRACT_NAME \
|
||||
--constructor-args $(cast abi-encode "constructor(...)" ARG1 ARG2 ...)
|
||||
```
|
||||
|
||||
### 2. Run Tests
|
||||
|
||||
```bash
|
||||
# Unit tests
|
||||
forge test
|
||||
|
||||
# Fork tests (on mainnet fork)
|
||||
forge test --fork-url $RPC_URL
|
||||
|
||||
# Coverage
|
||||
forge coverage
|
||||
```
|
||||
|
||||
### 3. Run Simulations
|
||||
|
||||
```bash
|
||||
tsx scripts/simulate.ts
|
||||
```
|
||||
|
||||
## Multi-Chain Deployment
|
||||
|
||||
### Arbitrum
|
||||
|
||||
```bash
|
||||
export ARBITRUM_RPC_URL=https://arb1.arbitrum.io/rpc
|
||||
forge script scripts/deploy.ts --rpc-url $ARBITRUM_RPC_URL --broadcast
|
||||
```
|
||||
|
||||
### Polygon
|
||||
|
||||
```bash
|
||||
export POLYGON_RPC_URL=https://polygon-rpc.com
|
||||
forge script scripts/deploy.ts --rpc-url $POLYGON_RPC_URL --broadcast
|
||||
```
|
||||
|
||||
Update protocol addresses for each chain in `.env`.
|
||||
|
||||
## Mainnet Deployment Checklist
|
||||
|
||||
- [ ] All contracts tested on testnet
|
||||
- [ ] All parameters verified
|
||||
- [ ] Multi-sig wallet configured
|
||||
- [ ] Emergency pause mechanism ready
|
||||
- [ ] Monitoring dashboard setup
|
||||
- [ ] Alert system configured
|
||||
- [ ] Documentation reviewed
|
||||
- [ ] Security audit completed (if applicable)
|
||||
- [ ] Gas optimization verified
|
||||
- [ ] Backup deployment scripts ready
|
||||
|
||||
## Post-Deployment
|
||||
|
||||
1. **Monitor closely** for first 24-48 hours
|
||||
2. **Start with conservative parameters**
|
||||
3. **Gradually increase limits** after stability
|
||||
4. **Enable MEV bot** after verification
|
||||
5. **Set up alerts** for all critical metrics
|
||||
|
||||
## Emergency Procedures
|
||||
|
||||
### Pause System
|
||||
```bash
|
||||
# Call pause on all contracts
|
||||
cast send $VAULT_ADDRESS "pause()" --private-key $PRIVATE_KEY
|
||||
```
|
||||
|
||||
### Upgrade Contracts
|
||||
```bash
|
||||
# Upgrade via UUPS proxy
|
||||
cast send $PROXY_ADDRESS "upgradeTo(address)" $NEW_IMPL_ADDRESS --private-key $PRIVATE_KEY
|
||||
```
|
||||
|
||||
### Update Parameters
|
||||
```bash
|
||||
# Reduce limits immediately
|
||||
cast send $CONFIG_REGISTRY_ADDRESS "setMaxLoops(uint256)" 1 --private-key $PRIVATE_KEY
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
Set up monitoring for:
|
||||
- Position health factors
|
||||
- Flash loan execution rates
|
||||
- Policy denial rates
|
||||
- Gas costs
|
||||
- Contract events
|
||||
|
||||
110
docs/INVARIANTS.md
Normal file
110
docs/INVARIANTS.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# System Invariants
|
||||
|
||||
## Core Invariants
|
||||
|
||||
The DBIS system enforces strict invariants that **must** be maintained at all times. These invariants are checked on-chain and any violation causes transaction reversion.
|
||||
|
||||
## Position Invariants
|
||||
|
||||
### 1. Debt Never Increases
|
||||
```
|
||||
debtAfter <= debtBefore
|
||||
```
|
||||
After any amortization cycle, total debt value must never increase.
|
||||
|
||||
### 2. Collateral Never Decreases
|
||||
```
|
||||
collateralAfter >= collateralBefore
|
||||
```
|
||||
After any amortization cycle, total collateral value must never decrease.
|
||||
|
||||
### 3. Health Factor Never Worsens
|
||||
```
|
||||
healthFactorAfter >= healthFactorBefore
|
||||
```
|
||||
Health factor must always improve or stay the same.
|
||||
|
||||
### 4. LTV Never Worsens
|
||||
```
|
||||
LTV_after <= LTV_before
|
||||
```
|
||||
Loan-to-value ratio must never increase.
|
||||
|
||||
## Combined Invariant Check
|
||||
|
||||
All position invariants are checked together in `Vault.verifyPositionImproved()`:
|
||||
|
||||
```solidity
|
||||
bool debtDecreased = debtAfter < debtBefore;
|
||||
bool collateralIncreased = collateralAfter > collateralBefore;
|
||||
bool hfImproved = healthFactorAfter > healthFactorBefore;
|
||||
|
||||
// All three must improve for strict amortization
|
||||
return debtDecreased && collateralIncreased && hfImproved;
|
||||
```
|
||||
|
||||
## Policy Invariants
|
||||
|
||||
### Flash Volume Limits
|
||||
- Flash loan volume per asset per period ≤ configured limit
|
||||
- Global flash loan volume per period ≤ configured limit
|
||||
|
||||
### Health Factor Thresholds
|
||||
- Current HF ≥ minimum HF (from ConfigRegistry)
|
||||
- HF improvement ≥ minimum improvement (for amortization)
|
||||
|
||||
### Provider Concentration
|
||||
- No single provider can exceed maximum concentration percentage
|
||||
- Diversification across providers enforced
|
||||
|
||||
### Liquidity Spreads
|
||||
- Swap spreads ≤ maximum acceptable spread
|
||||
- Liquidity depth ≥ minimum required depth
|
||||
|
||||
## Invariant Enforcement Points
|
||||
|
||||
1. **Pre-Execution**: GovernanceGuard verifies policy invariants
|
||||
2. **During Execution**: Kernel enforces position changes
|
||||
3. **Post-Execution**: Vault verifies position improvement
|
||||
4. **On Revert**: All state changes rolled back
|
||||
|
||||
## Testing Invariants
|
||||
|
||||
### Unit Tests
|
||||
- Test each invariant in isolation
|
||||
- Test invariant violations cause reversion
|
||||
|
||||
### Integration Tests
|
||||
- Test full cycles maintain invariants
|
||||
- Test edge cases
|
||||
|
||||
### Fuzz Tests
|
||||
- Random inputs verify invariants hold
|
||||
- Stress test boundary conditions
|
||||
|
||||
### Invariant Tests (Foundry)
|
||||
- Continuous invariant checking
|
||||
- Property-based testing
|
||||
|
||||
## Failure Modes
|
||||
|
||||
### Invariant Violation Detection
|
||||
When an invariant is violated:
|
||||
1. Transaction reverts
|
||||
2. Event emitted: `InvariantFail(reason)`
|
||||
3. State unchanged (all changes rolled back)
|
||||
4. MEV bot alerted
|
||||
|
||||
### Recovery Procedures
|
||||
1. Analyze reason for failure
|
||||
2. Adjust parameters if needed
|
||||
3. Re-run with corrected parameters
|
||||
4. Verify invariants before next cycle
|
||||
|
||||
## Formal Verification
|
||||
|
||||
Future work:
|
||||
- Formal verification of invariant preservation
|
||||
- Mathematical proofs of correctness
|
||||
- Certified invariant checks
|
||||
|
||||
271
docs/MEV_BOT.md
Normal file
271
docs/MEV_BOT.md
Normal file
@@ -0,0 +1,271 @@
|
||||
# MEV Bot Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The DBIS MEV Bot is a TypeScript application that monitors positions and executes profitable atomic amortization cycles, arbitrage opportunities, and protective deleveraging.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Core Components
|
||||
|
||||
1. **Bot Engine** (`bot.ts`)
|
||||
- Main event loop
|
||||
- Strategy coordination
|
||||
- Opportunity detection
|
||||
|
||||
2. **Strategies**
|
||||
- **Amortization**: Executes amortization cycles
|
||||
- **Arbitrage**: Finds arbitrage opportunities
|
||||
- **Deleverage**: Protects positions with low HF
|
||||
|
||||
3. **Utilities**
|
||||
- **Invariant Checker**: Verifies invariants before execution
|
||||
- **Position Calculator**: Calculates position metrics
|
||||
- **Bundle Builder**: Builds Flashbots bundles
|
||||
|
||||
4. **Providers**
|
||||
- **Flash Router Client**: Interacts with FlashLoanRouter
|
||||
- **Aave Client**: Reads Aave position data
|
||||
- **Uniswap Client**: Executes swaps
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Install Dependencies
|
||||
|
||||
```bash
|
||||
cd mev-bot
|
||||
npm install
|
||||
```
|
||||
|
||||
### 2. Configure Environment
|
||||
|
||||
Create `.env` in `mev-bot/`:
|
||||
|
||||
```env
|
||||
RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY
|
||||
PRIVATE_KEY=your_bot_private_key
|
||||
FLASH_ROUTER_ADDRESS=0x...
|
||||
VAULT_ADDRESS=0x...
|
||||
KERNEL_ADDRESS=0x...
|
||||
AAVE_POOL_ADDRESS=0x...
|
||||
UNISWAP_ROUTER_ADDRESS=0x...
|
||||
```
|
||||
|
||||
### 3. Build
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
### 4. Run
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
## Strategies
|
||||
|
||||
### Amortization Strategy
|
||||
|
||||
**Purpose**: Execute profitable amortization cycles
|
||||
|
||||
**Detection**:
|
||||
1. Check current position
|
||||
2. Calculate potential improvement
|
||||
3. Estimate gas costs
|
||||
4. Determine profitability
|
||||
|
||||
**Execution**:
|
||||
1. Verify invariants
|
||||
2. Build transaction
|
||||
3. Submit via Flashbots (if enabled)
|
||||
4. Monitor execution
|
||||
|
||||
### Arbitrage Strategy
|
||||
|
||||
**Purpose**: Find arbitrage opportunities
|
||||
|
||||
**Detection**:
|
||||
1. Compare prices across DEXs
|
||||
2. Calculate potential profit
|
||||
3. Account for gas and fees
|
||||
4. Determine if profitable
|
||||
|
||||
**Execution**:
|
||||
1. Execute arbitrage trade
|
||||
2. Capture profit
|
||||
3. Update position
|
||||
|
||||
### Deleverage Strategy
|
||||
|
||||
**Purpose**: Protect position when HF is low
|
||||
|
||||
**Trigger**: Health factor < 1.10
|
||||
|
||||
**Action**:
|
||||
1. Reduce leverage
|
||||
2. Improve health factor
|
||||
3. Prevent liquidation risk
|
||||
|
||||
## Bundle Building
|
||||
|
||||
### Flashbots Integration
|
||||
|
||||
For private transaction submission:
|
||||
|
||||
```typescript
|
||||
import { FlashbotsBundleProvider } from "@flashbots/ethers-provider-bundle";
|
||||
|
||||
const bundle = await bundleBuilder.buildBundle(transactions);
|
||||
await flashbotsProvider.sendBundle(bundle, targetBlockNumber);
|
||||
```
|
||||
|
||||
### Benefits
|
||||
- No front-running
|
||||
- Atomic execution
|
||||
- Priority inclusion
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Position Monitoring
|
||||
|
||||
```typescript
|
||||
const position = await positionCalculator.getPosition();
|
||||
console.log(`HF: ${position.healthFactor}`);
|
||||
console.log(`LTV: ${position.ltv}`);
|
||||
console.log(`Collateral: ${position.collateral}`);
|
||||
console.log(`Debt: ${position.debt}`);
|
||||
```
|
||||
|
||||
### Alert Conditions
|
||||
|
||||
- Health factor < 1.10
|
||||
- Position at risk
|
||||
- Policy denial
|
||||
- Transaction failure
|
||||
- Bot downtime
|
||||
|
||||
## Multi-Region Deployment
|
||||
|
||||
Deploy in multiple regions for redundancy:
|
||||
- US East
|
||||
- EU
|
||||
- Singapore
|
||||
|
||||
Use leader election or load balancing.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Poll Interval
|
||||
Adjust how often bot checks for opportunities:
|
||||
```typescript
|
||||
private pollInterval = 5000; // 5 seconds
|
||||
```
|
||||
|
||||
### Profitability Thresholds
|
||||
Minimum profit to execute:
|
||||
```typescript
|
||||
const minProfit = ethers.parseEther("0.01"); // 0.01 ETH
|
||||
```
|
||||
|
||||
### Gas Price Management
|
||||
Set max gas price:
|
||||
```typescript
|
||||
const maxGasPrice = ethers.parseUnits("100", "gwei");
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Retry Logic
|
||||
```typescript
|
||||
async executeWithRetry(operation, maxRetries = 3) {
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
try {
|
||||
return await operation();
|
||||
} catch (error) {
|
||||
if (i === maxRetries - 1) throw error;
|
||||
await sleep(1000 * (i + 1)); // Exponential backoff
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Failure Notifications
|
||||
Send alerts on:
|
||||
- Transaction failures
|
||||
- Invariant violations
|
||||
- Policy denials
|
||||
- Bot crashes
|
||||
|
||||
## Logging
|
||||
|
||||
Use Winston for structured logging:
|
||||
|
||||
```typescript
|
||||
import winston from "winston";
|
||||
|
||||
const logger = winston.createLogger({
|
||||
level: "info",
|
||||
format: winston.format.json(),
|
||||
transports: [
|
||||
new winston.transports.File({ filename: "error.log", level: "error" }),
|
||||
new winston.transports.File({ filename: "combined.log" })
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
1. **Batch Operations**: Group multiple checks
|
||||
2. **Caching**: Cache position data
|
||||
3. **Async Processing**: Parallel opportunity detection
|
||||
4. **Connection Pooling**: Reuse RPC connections
|
||||
|
||||
## Security
|
||||
|
||||
1. **Private Key Management**: Use secure key storage
|
||||
2. **Access Control**: Limit bot permissions
|
||||
3. **Rate Limiting**: Prevent spam
|
||||
4. **Monitoring**: Track all bot actions
|
||||
|
||||
## Deployment
|
||||
|
||||
### Docker
|
||||
|
||||
```dockerfile
|
||||
FROM node:18
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
COPY . .
|
||||
CMD ["npm", "start"]
|
||||
```
|
||||
|
||||
### Systemd Service
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=DBIS MEV Bot
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=dbis
|
||||
WorkingDirectory=/opt/dbis-mev-bot
|
||||
ExecStart=/usr/bin/npm start
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
## Metrics
|
||||
|
||||
Track:
|
||||
- Opportunities detected
|
||||
- Cycles executed
|
||||
- Profit generated
|
||||
- Gas costs
|
||||
- Success rate
|
||||
- Average HF improvement
|
||||
|
||||
185
docs/POLICY.md
Normal file
185
docs/POLICY.md
Normal file
@@ -0,0 +1,185 @@
|
||||
# Policy System
|
||||
|
||||
## Overview
|
||||
|
||||
The policy system provides modular, plugin-based governance controls. Policy modules evaluate proposed actions and can approve or deny them.
|
||||
|
||||
## Policy Architecture
|
||||
|
||||
### PolicyEngine
|
||||
Central coordinator that:
|
||||
- Registers policy modules
|
||||
- Aggregates decisions from all modules
|
||||
- Returns allow/deny with reason
|
||||
|
||||
### Policy Modules
|
||||
|
||||
#### 1. PolicyHFTrend
|
||||
Monitors health factor trends and ensures:
|
||||
- HF never decreases
|
||||
- HF improvements meet minimum threshold
|
||||
- Trend is always improving
|
||||
|
||||
**Configuration:**
|
||||
- `minHFThreshold`: Minimum acceptable HF (default: 1.05)
|
||||
- `minHFImprovement`: Minimum improvement per cycle (default: 1%)
|
||||
|
||||
#### 2. PolicyFlashVolume
|
||||
Limits flash loan volume per time period:
|
||||
- Per-asset volume limits
|
||||
- Global volume limits
|
||||
- Time-based tracking windows
|
||||
|
||||
**Configuration:**
|
||||
- `periodDuration`: Tracking window (default: 1 day)
|
||||
- `assetVolumeLimit[asset]`: Per-asset limit
|
||||
- `globalVolumeLimit`: Global limit
|
||||
|
||||
#### 3. PolicyLiquiditySpread
|
||||
Validates liquidity and spreads:
|
||||
- Maximum acceptable spread
|
||||
- Minimum liquidity depth
|
||||
- Liquidity-to-operation ratio checks
|
||||
|
||||
**Configuration:**
|
||||
- `maxSpreadBps`: Maximum spread in basis points (default: 50 = 0.5%)
|
||||
- `minLiquidityDepth[asset]`: Minimum liquidity required
|
||||
|
||||
#### 4. PolicyProviderConcentration
|
||||
Prevents over-concentration in single providers:
|
||||
- Maximum percentage from single provider
|
||||
- Diversification enforcement
|
||||
- Time-window tracking
|
||||
|
||||
**Configuration:**
|
||||
- `maxProviderConcentrationBps`: Maximum concentration (default: 5000 = 50%)
|
||||
- `trackingWindow`: Tracking period (default: 7 days)
|
||||
|
||||
## Policy Evaluation Flow
|
||||
|
||||
```
|
||||
Action Proposed
|
||||
↓
|
||||
PolicyEngine.evaluateAll(actionType, actionData)
|
||||
↓
|
||||
For each registered module:
|
||||
1. Check if enabled
|
||||
2. Call module.evaluate()
|
||||
3. Get decision
|
||||
4. If deny → return deny immediately
|
||||
↓
|
||||
If all modules approve → return allow
|
||||
```
|
||||
|
||||
## Policy Decision Structure
|
||||
|
||||
```solidity
|
||||
struct PolicyDecision {
|
||||
bool allowed;
|
||||
string reason; // Empty if allowed, explanation if denied
|
||||
}
|
||||
```
|
||||
|
||||
## Adding New Policy Modules
|
||||
|
||||
### Step 1: Implement IPolicyModule
|
||||
|
||||
```solidity
|
||||
contract MyPolicyModule is IPolicyModule {
|
||||
function evaluate(
|
||||
bytes32 actionType,
|
||||
bytes memory actionData
|
||||
) external view returns (PolicyDecision memory) {
|
||||
// Policy logic
|
||||
return PolicyDecision({
|
||||
allowed: true,
|
||||
reason: ""
|
||||
});
|
||||
}
|
||||
|
||||
function name() external pure returns (string memory) {
|
||||
return "MyPolicy";
|
||||
}
|
||||
|
||||
function isEnabled() external view returns (bool) {
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
function setEnabled(bool enabled) external onlyOwner {
|
||||
_enabled = enabled;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 2: Register with PolicyEngine
|
||||
|
||||
```solidity
|
||||
policyEngine.registerPolicyModule(address(myPolicyModule));
|
||||
```
|
||||
|
||||
### Step 3: Configure Parameters
|
||||
|
||||
```solidity
|
||||
myPolicyModule.setParameter(value);
|
||||
```
|
||||
|
||||
## Policy Enforcement
|
||||
|
||||
### Pre-Execution
|
||||
- GovernanceGuard calls `PolicyEngine.evaluateAll()`
|
||||
- If denied, transaction reverts before execution
|
||||
|
||||
### During Execution
|
||||
- Some policies monitor state during execution
|
||||
- Can emit warnings or deny mid-execution
|
||||
|
||||
### Post-Execution
|
||||
- Policies can verify outcomes
|
||||
- Can trigger alerts if thresholds exceeded
|
||||
|
||||
## Configuration Management
|
||||
|
||||
### Owner-Only Updates
|
||||
- Register/unregister modules
|
||||
- Configure policy parameters
|
||||
- Enable/disable modules
|
||||
|
||||
### Multi-Sig Requirements
|
||||
Critical policy changes should require multi-sig:
|
||||
- Adding new policy modules
|
||||
- Changing volume limits
|
||||
- Changing HF thresholds
|
||||
|
||||
## Testing Policies
|
||||
|
||||
### Unit Tests
|
||||
- Test each policy module independently
|
||||
- Test allow/deny scenarios
|
||||
- Test configuration updates
|
||||
|
||||
### Integration Tests
|
||||
- Test policy aggregation
|
||||
- Test policy conflicts
|
||||
- Test policy order independence
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Fail-Safe Defaults**: Deny by default if policy unavailable
|
||||
2. **Clear Reasons**: Provide detailed denial reasons
|
||||
3. **Modular Design**: Keep policies independent
|
||||
4. **Upgradeable**: Support parameter updates
|
||||
5. **Documented**: Document all policy logic
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Policy Metrics
|
||||
- Approval/denial rates
|
||||
- Most common denial reasons
|
||||
- Policy evaluation latency
|
||||
- Module usage statistics
|
||||
|
||||
### Alerts
|
||||
- High denial rate
|
||||
- Policy module failures
|
||||
- Unusual policy patterns
|
||||
|
||||
257
docs/TESTING.md
Normal file
257
docs/TESTING.md
Normal file
@@ -0,0 +1,257 @@
|
||||
# Testing Guide
|
||||
|
||||
## Overview
|
||||
|
||||
The DBIS system includes comprehensive test coverage across multiple test types:
|
||||
- Unit tests
|
||||
- Integration tests
|
||||
- Invariant tests
|
||||
- Fuzz tests
|
||||
- Fork tests
|
||||
|
||||
## Running Tests
|
||||
|
||||
### All Tests
|
||||
```bash
|
||||
forge test
|
||||
```
|
||||
|
||||
### Specific Test File
|
||||
```bash
|
||||
forge test --match-path test/vault/DBISInstitutionalVault.t.sol
|
||||
```
|
||||
|
||||
### Verbose Output
|
||||
```bash
|
||||
forge test -vvv
|
||||
```
|
||||
|
||||
### Gas Report
|
||||
```bash
|
||||
forge test --gas-report
|
||||
```
|
||||
|
||||
## Test Structure
|
||||
|
||||
### Unit Tests
|
||||
Located in `test/{contract}/`:
|
||||
- `test/vault/DBISInstitutionalVault.t.sol`
|
||||
- `test/router/FlashLoanRouter.t.sol`
|
||||
- `test/kernel/RecursiveLeverageKernel.t.sol`
|
||||
|
||||
### Integration Tests
|
||||
Located in `test/integration/`:
|
||||
- `test/integration/FullCycle.t.sol`
|
||||
- `test/integration/AmortizationInvariant.t.sol`
|
||||
|
||||
### Fuzz Tests
|
||||
Located in `test/fuzz/`:
|
||||
- `test/fuzz/KernelFuzz.t.sol`
|
||||
|
||||
## Test Categories
|
||||
|
||||
### 1. Core Functionality Tests
|
||||
|
||||
#### Vault Tests
|
||||
```solidity
|
||||
function test_RecordCollateralAdded() public {
|
||||
// Test collateral recording
|
||||
}
|
||||
|
||||
function test_RecordDebtRepaid() public {
|
||||
// Test debt repayment recording
|
||||
}
|
||||
|
||||
function test_VerifyPositionImproved() public {
|
||||
// Test invariant verification
|
||||
}
|
||||
```
|
||||
|
||||
#### Kernel Tests
|
||||
```solidity
|
||||
function test_ExecuteAmortizingCycle() public {
|
||||
// Test full amortization cycle
|
||||
}
|
||||
|
||||
function test_ExecuteAmortizingCycleRevertsIfInvariantFails() public {
|
||||
// Test invariant enforcement
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Invariant Tests
|
||||
|
||||
Foundry invariant tests ensure invariants hold:
|
||||
|
||||
```solidity
|
||||
function invariant_HealthFactorNeverDecreases() public {
|
||||
// HF must never decrease
|
||||
}
|
||||
|
||||
function invariant_DebtNeverIncreases() public {
|
||||
// Debt must never increase
|
||||
}
|
||||
|
||||
function invariant_CollateralNeverDecreases() public {
|
||||
// Collateral must never decrease
|
||||
}
|
||||
```
|
||||
|
||||
Run invariant tests:
|
||||
```bash
|
||||
forge test --match-test invariant
|
||||
```
|
||||
|
||||
### 3. Fuzz Tests
|
||||
|
||||
Random input testing to find edge cases:
|
||||
|
||||
```solidity
|
||||
function testFuzz_ExecuteCycleWithRandomAmounts(
|
||||
uint256 flashAmount,
|
||||
uint256 yieldAmount
|
||||
) public {
|
||||
// Fuzz with random amounts
|
||||
// Ensure invariants hold
|
||||
}
|
||||
```
|
||||
|
||||
Run fuzz tests:
|
||||
```bash
|
||||
forge test --match-test testFuzz
|
||||
```
|
||||
|
||||
### 4. Fork Tests
|
||||
|
||||
Test against mainnet state:
|
||||
|
||||
```bash
|
||||
forge test --fork-url $RPC_URL
|
||||
```
|
||||
|
||||
## Test Utilities
|
||||
|
||||
### Helpers
|
||||
|
||||
Create test helpers in `test/helpers/`:
|
||||
|
||||
```solidity
|
||||
contract TestHelpers {
|
||||
function deployMockAavePool() internal returns (address) {
|
||||
// Deploy mock
|
||||
}
|
||||
|
||||
function createPosition(uint256 collateral, uint256 debt) internal {
|
||||
// Setup test position
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Mocks
|
||||
|
||||
Mock external contracts:
|
||||
- Mock Aave Pool
|
||||
- Mock Oracle
|
||||
- Mock Uniswap Router
|
||||
|
||||
## Test Scenarios
|
||||
|
||||
### Happy Path
|
||||
1. Successful amortization cycle
|
||||
2. Position improvement
|
||||
3. Invariant preservation
|
||||
|
||||
### Edge Cases
|
||||
1. Maximum loops reached
|
||||
2. Flash loan fee exceeds profit
|
||||
3. Swap slippage too high
|
||||
4. Health factor at threshold
|
||||
|
||||
### Failure Modes
|
||||
1. Policy denial
|
||||
2. Invariant violation
|
||||
3. Flash loan unavailable
|
||||
4. Insufficient gas
|
||||
|
||||
### Stress Tests
|
||||
1. Large positions
|
||||
2. High leverage
|
||||
3. Multiple concurrent cycles
|
||||
4. Rapid price changes
|
||||
|
||||
## Coverage Goals
|
||||
|
||||
Target coverage:
|
||||
- Core contracts: >90%
|
||||
- Governance: >85%
|
||||
- Utilities: >80%
|
||||
- Overall: >85%
|
||||
|
||||
Generate coverage report:
|
||||
```bash
|
||||
forge coverage
|
||||
```
|
||||
|
||||
## Continuous Integration
|
||||
|
||||
### GitHub Actions Example
|
||||
|
||||
```yaml
|
||||
name: Tests
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install Foundry
|
||||
uses: foundry-rs/foundry-toolchain@v1
|
||||
- name: Run tests
|
||||
run: forge test
|
||||
- name: Generate coverage
|
||||
run: forge coverage
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Test All Edge Cases**: Include boundary conditions
|
||||
2. **Use Descriptive Names**: Clear test function names
|
||||
3. **Test Invariants**: Always verify invariants
|
||||
4. **Mock External Dependencies**: Use mocks for external calls
|
||||
5. **Test Both Success and Failure**: Cover all paths
|
||||
6. **Use Fuzz Testing**: Find unexpected edge cases
|
||||
7. **Fork Tests for Integration**: Test with real protocols
|
||||
8. **Gas Optimization Tests**: Ensure gas efficiency
|
||||
|
||||
## Debugging Tests
|
||||
|
||||
### Verbose Output
|
||||
```bash
|
||||
forge test -vvvv # Maximum verbosity
|
||||
```
|
||||
|
||||
### Debug Specific Test
|
||||
```bash
|
||||
forge test --match-test test_ExecuteCycle -vvv
|
||||
```
|
||||
|
||||
### Trace Transactions
|
||||
```bash
|
||||
forge test --debug test_ExecuteCycle
|
||||
```
|
||||
|
||||
## Test Data
|
||||
|
||||
### Fixtures
|
||||
Store test data in `test/fixtures/`:
|
||||
- Sample positions
|
||||
- Test transaction data
|
||||
- Expected outcomes
|
||||
|
||||
### Constants
|
||||
Define test constants:
|
||||
```solidity
|
||||
uint256 constant TEST_COLLATERAL = 1000e18;
|
||||
uint256 constant TEST_DEBT = 800e18;
|
||||
address constant TEST_ASSET = 0x...
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user