Skip to content

Latest commit

 

History

History
560 lines (454 loc) · 17.1 KB

File metadata and controls

560 lines (454 loc) · 17.1 KB

Position Liquidation System - Implementation Documentation

Overview

This document describes the complete implementation of the position liquidation system for the GateDelay DeFi protocol. The system provides automated monitoring, execution, and management of undercollateralized position liquidations.

Implementation Summary

Files Created

  1. contracts/Liquidation.sol - Main liquidation contract (580+ lines)
  2. test/Liquidation.t.sol - Comprehensive test suite (700+ lines)

Features Implemented

✅ 1. Liquidation Condition Monitoring

  • Health Factor Calculation: Calculates position health as (currentMargin / liquidationMargin) * 1e18
  • Real-time Monitoring: monitorLiquidationCondition() checks if positions are liquidatable
  • Batch Monitoring: batchMonitorConditions() checks multiple accounts simultaneously
  • Integration: Connects with MarginCalculator and CollateralVault for accurate data
  • Events: Emits LiquidationConditionChecked for tracking

Key Functions:

function monitorLiquidationCondition(address account, address market) 
    public view returns (LiquidationCondition memory);

function batchMonitorConditions(address[] calldata accounts, address market) 
    external view returns (LiquidationCondition[] memory);

function isPositionLiquidatable(address account, address market) 
    external view returns (bool);

✅ 2. Liquidation Execution

  • Automated Execution: executeLiquidation() liquidates undercollateralized positions
  • Safety Checks: Validates position health before execution
  • Reentrancy Protection: Uses OpenZeppelin's ReentrancyGuard
  • Pause Mechanism: Admin can pause liquidations in emergencies
  • Event Logging: Comprehensive event emission for transparency

Key Functions:

function executeLiquidation(address account, address market) 
    external nonReentrant whenNotPaused returns (LiquidationExecution memory);

Liquidation Conditions:

  • Health factor < 1.0 (below 1e18)
  • Current margin < liquidation margin threshold
  • Sufficient collateral available

✅ 3. Penalty Calculation

  • Configurable Penalties: Liquidation penalty between 1-20% (100-2000 bps)
  • Liquidator Rewards: Reward between 0.5-10% (50-1000 bps) of penalty
  • Protocol Fees: Remainder of penalty goes to protocol treasury
  • PRBMath Integration: Uses UD60x18 for precise calculations
  • Overflow Protection: Safe math operations throughout

Key Functions:

function calculateLiquidationPenalty(uint256 collateralValue, uint256 debtValue) 
    public view returns (
        uint256 collateralToSeize,
        uint256 penaltyAmount,
        uint256 liquidatorReward,
        uint256 protocolFee
    );

Calculation Formula:

penaltyAmount = (debtValue * liquidationPenaltyBps) / 10000
collateralToSeize = debtValue + penaltyAmount
liquidatorReward = (penaltyAmount * liquidatorRewardBps) / 10000
protocolFee = penaltyAmount - liquidatorReward

✅ 4. Proceeds Handling

  • Automatic Distribution: Rewards distributed during liquidation
  • Protocol Treasury: Accumulates protocol share of penalties
  • Withdrawal Function: Owner can withdraw protocol proceeds
  • Per-Token Tracking: Separate balances for each collateral token
  • Audit Trail: Complete history of all proceeds

Key Functions:

function withdrawProtocolProceeds(address token, address recipient, uint256 amount) 
    external onlyOwner nonReentrant;

function getProtocolProceeds(address token) 
    external view returns (uint256);

function getMarketProceeds(address market) 
    external view returns (LiquidationProceeds memory);

Proceeds Structure:

struct LiquidationProceeds {
    uint256 totalSeized;        // Total collateral seized
    uint256 totalPenalties;     // Total penalties collected
    uint256 totalRewards;       // Total rewards paid to liquidators
    uint256 protocolBalance;    // Protocol's share
    uint256 liquidationCount;   // Number of liquidations
}

✅ 5. Query Functions

  • Position Health: getHealthFactor() returns current health factor
  • Liquidation History: getLiquidationHistory() returns all liquidations for an account
  • Market Statistics: getMarketProceeds() returns aggregated market data
  • Batch Queries: Efficient multi-account monitoring

Available Queries:

function getHealthFactor(address account, address market) external view returns (uint256);
function getLiquidationHistory(address account, address market) external view returns (LiquidationExecution[] memory);
function getMarketProceeds(address market) external view returns (LiquidationProceeds memory);
function getProtocolProceeds(address token) external view returns (uint256);
function isPositionLiquidatable(address account, address market) external view returns (bool);

Architecture

Contract Integration

┌─────────────────────────────────────────────────────────────┐
│                     Liquidation.sol                          │
│  - Monitor positions                                         │
│  - Execute liquidations                                      │
│  - Calculate penalties                                       │
│  - Distribute proceeds                                       │
└────────────┬────────────────────────────┬───────────────────┘
             │                            │
             ▼                            ▼
┌────────────────────────┐   ┌──────────────────────────┐
│  MarginCalculator.sol  │   │  CollateralVault.sol     │
│  - Margin requirements │   │  - Collateral storage    │
│  - Health checks       │   │  - Liquidation execution │
└────────────────────────┘   └──────────────────────────┘
             │
             ▼
┌────────────────────────┐
│   PriceOracle.sol      │
│   - Price feeds        │
│   - Staleness checks   │
└────────────────────────┘

Data Structures

LiquidationCondition

Represents the current state of a position:

struct LiquidationCondition {
    uint256 healthFactor;       // < 1e18 = liquidatable
    uint256 collateralValue;    // Total collateral in USD
    uint256 positionValue;      // Total position value
    uint256 requiredMargin;     // Maintenance margin required
    uint256 currentMargin;      // Current margin deposited
    bool isLiquidatable;        // Liquidation eligibility
}

LiquidationExecution

Records details of executed liquidations:

struct LiquidationExecution {
    address account;            // Liquidated account
    address market;             // Market address
    address liquidator;         // Executor address
    uint256 collateralSeized;   // Amount seized
    uint256 penaltyAmount;      // Total penalty
    uint256 liquidatorReward;   // Reward paid
    uint256 protocolFee;        // Protocol share
    uint256 timestamp;          // Execution time
    uint256 healthFactorBefore; // Pre-liquidation health
}

Security Features

1. Access Control

  • Ownable: Admin functions restricted to contract owner
  • Market Registration: Only registered markets can be liquidated
  • Pause Mechanism: Emergency stop functionality

2. Reentrancy Protection

  • ReentrancyGuard: Applied to all state-changing functions
  • Checks-Effects-Interactions: Proper ordering of operations
  • External Call Safety: Careful handling of vault interactions

3. Input Validation

  • Zero Address Checks: Prevents invalid addresses
  • Parameter Bounds: Enforces min/max for penalties and rewards
  • Collateral Verification: Ensures sufficient collateral exists

4. Safe Math

  • PRBMath Library: Precise 18-decimal fixed-point arithmetic
  • Overflow Protection: Solidity 0.8.20 built-in checks
  • Division Safety: Checks for zero denominators

Testing

Test Coverage

The test suite (test/Liquidation.t.sol) includes:

Constructor Tests (4 tests)

  • ✅ Parameters set correctly
  • ✅ Revert on zero addresses
  • ✅ Revert on invalid penalty
  • ✅ Revert on invalid reward

Admin Tests (6 tests)

  • ✅ Market registration
  • ✅ Penalty parameter updates
  • ✅ Pause functionality
  • ✅ Access control enforcement

Monitoring Tests (3 tests)

  • ✅ Healthy position detection
  • ✅ Liquidatable position detection
  • ✅ Zero margin handling

Penalty Calculation Tests (3 tests)

  • ✅ Standard penalty calculation
  • ✅ Insufficient collateral handling
  • ✅ Fuzz testing for edge cases

Execution Tests (6 tests)

  • ✅ Successful liquidation
  • ✅ Revert on healthy position
  • ✅ Revert on insufficient collateral
  • ✅ Revert when paused
  • ✅ History tracking
  • ✅ Proceeds accumulation

Proceeds Tests (3 tests)

  • ✅ Protocol proceeds withdrawal
  • ✅ Insufficient balance handling
  • ✅ Access control

Query Tests (5 tests)

  • ✅ Position liquidatability check
  • ✅ Health factor retrieval
  • ✅ Batch monitoring
  • ✅ Empty history handling
  • ✅ Initial proceeds state

Integration Tests (1 test)

  • ✅ Multiple liquidations

Total: 31 comprehensive tests

Running Tests

cd Contracts
forge test --match-path test/Liquidation.t.sol -vv

Fuzz Testing

The test suite includes fuzz tests for penalty calculations:

function testFuzz_calculateLiquidationPenalty(uint128 collateral, uint128 debt) public view {
    // Tests with random inputs to find edge cases
}

Configuration

Default Parameters

// Penalty Configuration
uint256 public constant MIN_LIQUIDATION_PENALTY_BPS = 100;   // 1%
uint256 public constant MAX_LIQUIDATION_PENALTY_BPS = 2000;  // 20%
uint256 public constant MIN_LIQUIDATOR_REWARD_BPS = 50;      // 0.5%
uint256 public constant MAX_LIQUIDATOR_REWARD_BPS = 1000;    // 10%

// Health Factor
uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1e18; // 1.0

// Basis Points
uint256 public constant BPS_DENOMINATOR = 10000;

Deployment Parameters

constructor(
    address _collateralVault,      // CollateralVault contract
    address _marginCalculator,     // MarginCalculator contract
    uint256 _liquidationPenaltyBps, // e.g., 1000 = 10%
    uint256 _liquidatorRewardBps    // e.g., 500 = 5%
)

Usage Examples

1. Deploy Liquidation Contract

Liquidation liquidation = new Liquidation(
    address(collateralVault),
    address(marginCalculator),
    1000,  // 10% liquidation penalty
    500    // 5% liquidator reward
);

2. Register a Market

liquidation.registerMarket(
    marketAddress,
    collateralTokenAddress,
    priceOracleAddress
);

3. Monitor Position Health

LiquidationCondition memory condition = liquidation.monitorLiquidationCondition(
    userAddress,
    marketAddress
);

if (condition.isLiquidatable) {
    // Position can be liquidated
    console.log("Health Factor:", condition.healthFactor);
}

4. Execute Liquidation

if (liquidation.isPositionLiquidatable(userAddress, marketAddress)) {
    LiquidationExecution memory execution = liquidation.executeLiquidation(
        userAddress,
        marketAddress
    );
    
    // Liquidator receives execution.liquidatorReward
    // Protocol receives execution.protocolFee
}

5. Query Liquidation History

LiquidationExecution[] memory history = liquidation.getLiquidationHistory(
    userAddress,
    marketAddress
);

for (uint i = 0; i < history.length; i++) {
    console.log("Liquidation", i);
    console.log("  Seized:", history[i].collateralSeized);
    console.log("  Penalty:", history[i].penaltyAmount);
    console.log("  Timestamp:", history[i].timestamp);
}

6. Withdraw Protocol Proceeds

uint256 proceeds = liquidation.getProtocolProceeds(collateralTokenAddress);
liquidation.withdrawProtocolProceeds(
    collateralTokenAddress,
    treasuryAddress,
    proceeds
);

Events

LiquidationExecuted

event LiquidationExecuted(
    address indexed account,
    address indexed market,
    address indexed liquidator,
    uint256 collateralSeized,
    uint256 penaltyAmount,
    uint256 liquidatorReward,
    uint256 healthFactor
);

LiquidationConditionChecked

event LiquidationConditionChecked(
    address indexed account,
    address indexed market,
    uint256 healthFactor,
    bool isLiquidatable
);

PenaltyParametersUpdated

event PenaltyParametersUpdated(
    uint256 liquidationPenaltyBps,
    uint256 liquidatorRewardBps
);

ProceedsWithdrawn

event ProceedsWithdrawn(
    address indexed recipient,
    uint256 amount
);

MarketRegistered

event MarketRegistered(
    address indexed market,
    address indexed collateralToken,
    address indexed priceOracle
);

Gas Optimization

Efficient Storage

  • Uses immutable for contract references
  • Packs struct fields efficiently
  • Minimizes storage writes

Batch Operations

  • batchMonitorConditions() for multiple accounts
  • Single transaction for liquidation + distribution

View Functions

  • Most queries are view or pure (no gas cost)
  • Efficient memory usage in loops

Error Handling

Custom Errors (Gas Efficient)

error ZeroAddress();
error PositionHealthy();
error PositionNotLiquidatable();
error InvalidLiquidationPenalty();
error InvalidLiquidatorReward();
error NoLiquidationProceeds();
error MarketNotRegistered();
error OracleStale();
error InsufficientCollateral();

Integration Checklist

  • Liquidation condition monitoring
  • Liquidation execution
  • Penalty calculation
  • Proceeds distribution
  • Query functions
  • Event emission
  • Access control
  • Reentrancy protection
  • Pause mechanism
  • Comprehensive testing
  • Documentation

Acceptance Criteria Status

Conditions are monitored

  • monitorLiquidationCondition() provides real-time health checks
  • batchMonitorConditions() for efficient multi-account monitoring
  • Health factor calculation with 18-decimal precision

Liquidations execute

  • executeLiquidation() handles complete liquidation flow
  • Integrates with CollateralVault for collateral seizure
  • Reentrancy protected and pausable

Penalties are calculated

  • calculateLiquidationPenalty() with configurable parameters
  • PRBMath for precise calculations
  • Bounds checking for safety

Proceeds are handled

  • Automatic distribution to liquidators
  • Protocol treasury accumulation
  • Withdrawal function for admin
  • Per-token tracking

Queries work

  • getHealthFactor() - position health
  • getLiquidationHistory() - historical data
  • getMarketProceeds() - market statistics
  • isPositionLiquidatable() - quick check
  • batchMonitorConditions() - bulk queries

Dependencies

External Libraries

  • OpenZeppelin Contracts v5.x

    • Ownable.sol - Access control
    • ReentrancyGuard.sol - Reentrancy protection
    • IERC20.sol - Token interface
    • SafeERC20.sol - Safe token transfers
  • PRBMath v4.x

    • UD60x18.sol - Fixed-point arithmetic
    • Used for precise penalty calculations

Internal Contracts

  • CollateralVault.sol - Collateral management
  • MarginCalculator.sol - Margin requirements
  • PriceOracle.sol - Price feeds (optional)

Future Enhancements

Potential Improvements

  1. Partial Liquidations: Allow liquidating only portion of position
  2. Dutch Auction: Decreasing penalty over time for competitive liquidations
  3. Liquidation Incentives: Additional rewards for quick liquidations
  4. Multi-Collateral: Support multiple collateral types per position
  5. Oracle Integration: Direct price oracle integration for valuation
  6. Liquidation Queue: Priority queue for liquidation execution
  7. Insurance Fund: Protocol insurance for bad debt
  8. Liquidation Bots: Off-chain monitoring and execution bots

Conclusion

The Position Liquidation System is a production-ready implementation that provides:

  • Complete Functionality: All acceptance criteria met
  • Security: Multiple layers of protection
  • Efficiency: Gas-optimized operations
  • Flexibility: Configurable parameters
  • Transparency: Comprehensive event logging
  • Testability: 31 comprehensive tests
  • Documentation: Complete technical documentation

The system is ready for deployment and integration with the GateDelay protocol.

Support

For questions or issues:

  1. Review this documentation
  2. Check the inline code comments
  3. Run the test suite
  4. Review the test cases for usage examples

Implementation Date: June 1, 2026 Solidity Version: 0.8.20 License: MIT