Thanks to visit codestin.com
Credit goes to github.com

Skip to content

lastdotnet/hypurrfi-deployments

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Leverage System Functions - Mathematical Overview

Table of Contents

  1. LeverageCloneFactory Functions
  2. LeverageProxyImpl Functions
  3. PositionLogic Library Functions
  4. PositionUtils Library Functions
  5. Mathematical Formulas
  6. Key Data Structures

LeverageCloneFactory Functions

1. createPosition() - Position Creation Entry Point

Purpose: Main entry point for creating leveraged positions

Steps:

  1. Salt Generation: Create deterministic salt for proxy deployment
  2. Proxy Prediction: Predict the proxy address using deterministic deployment
  3. Token Transfer: Transfer collateral from user to factory
  4. Proxy Creation: Deploy deterministic proxy contract
  5. Position Creation: Call proxy's createPosition function
  6. Counter Update: Increment user's position counter

Mathematical Operations:

salt = keccak256(abi.encodePacked(msg.sender, positionCounter[msg.sender], address(this)))
predictedProxy = Clones.predictDeterministicAddress(implementation, salt, address(this))
proxyAddress = Clones.cloneDeterministic(implementation, salt)
positionCounter[msg.sender]++

2. createPositionPreview() - Position Preview

Purpose: Calculates preview for position creation

Steps:

  1. Parameter Validation: Ensure implementation is initialized
  2. Preview Calculation: Delegate to PositionUtils.windPositionPreview
  3. Return Preview: Return calculated leverage preview

Mathematical Operations:

  • Delegates to PositionUtils.windPositionPreview()
  • Creates temporary Position struct for calculation

3. getMaxMultiplier() - Maximum Leverage Query

Purpose: Returns maximum safe leverage for given parameters

Steps:

  1. Parameter Validation: Ensure implementation is initialized
  2. Calculation: Delegate to PositionUtils.getMaxMultiplier
  3. Return Result: Return maximum multiplier result

Mathematical Operations:

  • Delegates to PositionUtils.getMaxMultiplier()

4. createPositionSwapCallback() - Swap Callback

Purpose: Handles swap operations during position creation

Steps:

  1. Access Control: Ensure caller is a valid child proxy
  2. Swap Execution: Delegate to PositionLogic.createSwapCallback
  3. Return Results: Return swap amounts

Mathematical Operations:

  • Delegates to PositionLogic.createSwapCallback()

5. reinitialize() - Proxy Reinitialization

Purpose: Reinitializes proxy after implementation upgrade

Steps:

  1. Access Control: Ensure caller is proxy owner
  2. Proxy Call: Call initialize function on proxy
  3. Success Check: Verify reinitialization succeeded

Mathematical Operations:

  • No direct calculations (administrative function)

6. rescueTokens() - Emergency Token Recovery

Purpose: Emergency function to recover stuck tokens

Steps:

  1. Access Control: Only owner can call
  2. Token Transfer: Transfer all tokens to owner
  3. Balance Check: Get current token balance

Mathematical Operations:

balance = token.balanceOf(address(this))
token.safeTransfer(owner(), balance)

LeverageProxyImpl Functions

1. initialize() - Proxy Initialization

Purpose: Initializes the proxy contract

Steps:

  1. Owner Validation: Ensure owner is not zero address
  2. Factory Setup: Set factory address to caller
  3. Ownership Transfer: Transfer ownership to specified owner
  4. Event Emission: Emit initialization event

Mathematical Operations:

  • No direct calculations (initialization function)

2. createPosition() - Position Creation

Purpose: Creates a leveraged position (called by factory)

Steps:

  1. Access Control: Ensure caller is factory
  2. Logic Delegation: Delegate to PositionLogic.create
  3. Constants Retrieval: Get constants from factory

Mathematical Operations:

  • Delegates to PositionLogic.create()

3. closePosition() - Position Closure

Purpose: Closes a leveraged position completely

Steps:

  1. Access Control: Ensure caller is owner
  2. Logic Delegation: Delegate to PositionLogic.close
  3. Constants Retrieval: Get constants from factory

Mathematical Operations:

  • Delegates to PositionLogic.close()

4. closePositionManual() - Manual Position Closure

Purpose: Allows manual/partial closure of positions

Steps:

  1. Access Control: Ensure caller is owner
  2. Logic Delegation: Delegate to PositionLogic.closeManual
  3. Constants Retrieval: Get constants from factory

Mathematical Operations:

  • Delegates to PositionLogic.closeManual()

5. windPosition() - Increase Leverage

Purpose: Increases leverage of existing position

Steps:

  1. Access Control: Ensure caller is owner
  2. Logic Delegation: Delegate to PositionLogic.wind
  3. Constants Retrieval: Get constants from factory

Mathematical Operations:

  • Delegates to PositionLogic.wind()

6. unwindPosition() - Decrease Leverage

Purpose: Decreases leverage of existing position

Steps:

  1. Access Control: Ensure caller is owner
  2. Logic Delegation: Delegate to PositionLogic.unwind
  3. Constants Retrieval: Get constants from factory

Mathematical Operations:

  • Delegates to PositionLogic.unwind()

7. closePositionPreview() - Close Preview

Purpose: Calculates preview for position closure

Steps:

  1. Logic Delegation: Delegate to PositionLogic.closePreview
  2. Constants Retrieval: Get constants from factory
  3. Return Preview: Return calculated preview

Mathematical Operations:

  • Delegates to PositionLogic.closePreview()

8. closePositionManualPreview() - Manual Close Preview

Purpose: Calculates preview for manual position closure

Steps:

  1. Logic Delegation: Delegate to PositionLogic.closeManualPreview
  2. Constants Retrieval: Get constants from factory
  3. Return Preview: Return calculated preview

Mathematical Operations:

  • Delegates to PositionLogic.closeManualPreview()

9. windPositionPreview() - Wind Preview

Purpose: Calculates preview for increasing leverage

Steps:

  1. Logic Delegation: Delegate to PositionLogic.windPreview
  2. Constants Retrieval: Get constants from factory
  3. Return Preview: Return calculated preview

Mathematical Operations:

  • Delegates to PositionLogic.windPreview()

10. unwindPositionPreview() - Unwind Preview

Purpose: Calculates preview for decreasing leverage

Steps:

  1. Logic Delegation: Delegate to PositionLogic.unwindPreview
  2. Constants Retrieval: Get constants from factory
  3. Return Preview: Return calculated preview

Mathematical Operations:

  • Delegates to PositionLogic.unwindPreview()

11. executeOperation() - Flash Loan Callback

Purpose: Handles Aave flash loan callbacks

Steps:

  1. Parameter Construction: Build PositionCallbackParams
  2. Logic Delegation: Delegate to PositionLogic.handleCallback
  3. Constants Retrieval: Get constants from factory
  4. Return Success: Return true for successful execution

Mathematical Operations:

  • Delegates to PositionLogic.handleCallback()

12. onFlashLoan() - ERC3156 Flash Loan Callback

Purpose: Handles ERC3156 flash loan callbacks

Steps:

  1. Parameter Construction: Build PositionCallbackParams
  2. Logic Delegation: Delegate to PositionLogic.handleCallback
  3. Constants Retrieval: Get constants from factory
  4. Return Hash: Return keccak256('ERC3156FlashBorrower.onFlashLoan')

Mathematical Operations:

  • Delegates to PositionLogic.handleCallback()

13. getPositionDetails() - Position Information

Purpose: Returns current position details

Steps:

  1. Logic Delegation: Delegate to PositionLogic.getPositionDetails
  2. Constants Retrieval: Get constants from factory
  3. Return Details: Return position details

Mathematical Operations:

  • Delegates to PositionLogic.getPositionDetails()

14. executeMultiCall() - Multi-Call Execution

Purpose: Executes multiple calls atomically

Steps:

  1. Access Control: Ensure caller is owner
  2. Loop Execution: Execute each call in sequence
  3. Error Handling: Handle reverts based on allowRevert flag
  4. Result Processing: Process call results

Mathematical Operations:

for (uint256 i = 0; i < calls.length; i++) {
    (bool success, bytes memory result) = calls[i].target.call{value: calls[i].value}(calls[i].data);
    if (!success && !calls[i].allowRevert) {
        revert(string(result));
    }
}

15. rescueTokens() - Emergency Token Recovery

Purpose: Emergency function to recover stuck tokens

Steps:

  1. Access Control: Ensure caller is owner
  2. Address Validation: Ensure recipient is not zero
  3. Balance Check: Get current token balance
  4. Token Transfer: Transfer tokens to recipient

Mathematical Operations:

balance = IERC20(token).balanceOf(address(this))
if (balance > 0) {
    IERC20(token).safeTransfer(to, balance);
}

16. rescueETH() - Emergency ETH Recovery

Purpose: Emergency function to recover stuck ETH

Steps:

  1. Access Control: Ensure caller is owner
  2. Address Validation: Ensure recipient is not zero
  3. ETH Transfer: Transfer ETH to recipient

Mathematical Operations:

balance = address(this).balance
if (balance > 0) {
    payable(to).transfer(balance);
}

PositionLogic Library Functions

1. create() - Position Creation

Purpose: Creates a new leveraged position using flash loans

Steps:

  1. Parameter Validation: Check collateral/debt assets, amounts, and health factors
  2. EMode Check: Enable eMode if available for the asset pairing
  3. Flash Loan: Borrow collateral asset from Aave pool
  4. Callback Execution: Execute position creation logic in callback

Mathematical Operations:

  • No direct calculations (delegates to preview functions)

2. close() - Position Closure

Purpose: Closes a leveraged position completely

Steps:

  1. Preview Calculation: Calculate close preview using _closePreview()
  2. Flash Loan: Borrow debt asset to repay position
  3. Swap Execution: Swap collateral for debt tokens via Gluex
  4. Position Cleanup: Reset position state to zero

Mathematical Operations:

  • Uses _calculateClosePreview() for USD-based calculations
  • Handles decimal conversions between collateral and debt tokens

3. closeManual() - Manual Position Closure

Purpose: Allows partial or full manual closure of positions

Steps:

  1. Repay Calculation: Calculate repayment amount based on percentage
  2. Withdrawal Calculation: Calculate collateral withdrawal amount
  3. Position Update: Update position state without calling unwind functions
  4. Health Factor Check: Ensure position remains healthy

Mathematical Operations:

repayAmount = (currentDebt * repayPercent) / 1e18
withdrawAmount = (currentCollateral * repayPercent) / 1e18
newLeverageMultiplier = (remainingCollateral * 1e18) / remainingUserCollateral

4. wind() - Increase Leverage

Purpose: Increases leverage of existing position

Steps:

  1. Preview Calculation: Calculate wind preview
  2. Flash Loan: Borrow additional collateral
  3. Swap Execution: Swap debt for more collateral
  4. Position Update: Update leverage multiplier

Mathematical Operations:

  • Delegates to windPositionPreview() for calculations

5. unwind() - Decrease Leverage

Purpose: Decreases leverage of existing position

Steps:

  1. Preview Calculation: Calculate unwind preview
  2. Flash Loan: Borrow debt tokens
  3. Swap Execution: Swap collateral for debt tokens
  4. Position Update: Update leverage multiplier

Mathematical Operations:

  • Delegates to unwindPositionPreview() for calculations

PositionUtils Library Functions

1. previewLeverage() - Core Leverage Calculation

Purpose: Calculates the preview for creating a new leveraged position

Mathematical Steps:

Step 1: Price and Decimal Setup

collateralPrice = getAssetPrice(collateralAsset)
debtPrice = getAssetPrice(debtAsset)
collateralDecimals = IERC20Metadata(collateralAsset).decimals()
debtDecimals = IERC20Metadata(debtAsset).decimals()
priceDecimals = getPriceDecimals(constants)

Step 2: Initial Collateral Calculation

initialCollateralAmountUSD = (collateralAmount * collateralPrice) * (10^(18 - collateralDecimals)) / (10^priceDecimals)
initialCollateralAmountTokens = collateralAmount

Step 3: Leveraged Collateral Calculation

collateralAmountTokens = initialCollateralAmountTokens * leverageMultiplier / 1e18
collateralAmountUSD = initialCollateralAmountUSD * leverageMultiplier / 1e18

Step 4: Debt Calculation

debtAmountUSD = collateralAmountUSD - initialCollateralAmountUSD
flashLoanFee = (collateralAmountUSD * flashLoanFeeBps) / 10000
totalDebtUSD = debtAmountUSD + flashLoanFee
debtAmountTokens = (totalDebtUSD * (10^priceDecimals)) / debtPrice
debtAmountTokens = scaleDecimals(debtAmountTokens, debtDecimals)

Step 5: Health Factor Calculation

totalCollateralUSD = existingCollateral + newCollateralUSD/1e10
totalDebtUSD = existingDebt + newDebtUSD/1e10
healthFactor = (totalCollateralUSD * liquidationThresholdWad) / totalDebtUSD

2. windPositionPreview() - Wind Preview Calculation

Purpose: Calculates preview for increasing leverage on existing position

Mathematical Steps:

Step 1: Additional Debt Calculation

additionalDebt18 = (newCollateralAmount * leverageMultiplier) / 1e18
additionalDebt = scaleDecimals(additionalDebt18, debtDecimals)

Step 2: New Position Values

newTotalCollateral = oldCollateral + newCollateralAmount
newTotalDebt = oldDebt + additionalDebt
newTotalCollateralUSD = oldCollateralUSD + newCollateralUSD
newTotalDebtUSD = oldDebtUSD + newDebtUSD

Step 3: Health Factor Calculation

newHealthFactor = (newTotalCollateralUSD * liquidationThresholdWad) / newTotalDebtUSD

3. unwindPositionPreview() - Unwind Preview Calculation

Purpose: Calculates preview for decreasing leverage on existing position

Mathematical Steps:

Step 1: New Collateral Calculation

userCollateral = newParams.collateralAmount
newCollateralAmount = userCollateral * leverageMultiplier / 1e18

Step 2: Collateral to Remove

collateralToRemove = max(0, oldCollateral - newCollateralAmount)

Step 3: Preview Calculation

// Uses previewLeverage() with new parameters
newPreview = previewLeverage(totalParams, constants)

// Calculate differences
debtReduction = oldDebt - newDebt
collateralReduction = oldCollateral - newCollateral

4. _getMaxMultiplier() - Maximum Leverage Calculation

Purpose: Calculates the maximum safe leverage multiplier for given parameters

Mathematical Steps:

Step 1: Liquidity Calculation

// For USDXL
usdxlLiquidity = usdxlFlashMinter.reserveCapacity - usdxlFlashMinter.reserveLevel
aTokenLiquidity = aToken.reserveCapacity - aToken.reserveLevel
borrowLiquidity = min(usdxlLiquidity, aTokenLiquidity)

// For other assets
borrowLiquidity = IERC20(debtAsset).balanceOf(aTokenAddress)

Step 2: LTV and Liquidation Threshold

// EMode or regular reserve data
ltv = reserveConfiguration.getLtv()
liquidationThreshold = reserveConfiguration.getLiquidationThreshold()
ltvWad = ltv * 1e14
liqThresholdWad = liquidationThreshold * 1e14

Step 3: Required Collateral-Debt Ratio

(requiredCollateralDebtRatio, totalCollateralDebtRatio) = _calculateRequiredCollateralUSD(
    targetHealthFactor,
    1e18,
    ltvWad
)

Step 4: Required Collateral Tokens

requiredCollateralTokens = requiredCollateralDebtRatio * (10^priceDecimals) / collateralPrice
requiredCollateralTokens = scaleDecimals(requiredCollateralTokens, collateralDecimals)

Step 5: Maximum Multiplier

maxMultiplier = totalCollateralDebtRatio * 1e18 / requiredCollateralDebtRatio
maxBorrow = borrowLiquidity
maxBorrowUSD = maxBorrow * debtPrice / (10^priceDecimals)
maxCollateralAmountUSD = requiredCollateralDebtRatio * maxBorrowUSD / 1e18
maxCollateralAmountTokens = maxCollateralAmountUSD * (10^priceDecimals) / collateralPrice

Step 6: Supply Cap Check

if (supplyCap > 0) {
    availableSupply = supplyCap - currentSupply
    if (availableSupply < maxCollateralWithMultiplier) {
        maxCollateralAmountTokens = availableSupply * 1e18 / maxMultiplier
        // Recalculate maxBorrow based on supply cap limit
    }
}

5. _calculateClosePreview() - Close Preview Calculation

Purpose: Calculates preview for completely closing a position

Mathematical Steps:

Step 1: Current Position Values

currentDebt = getCurrentDebt(constants, position.debtAsset)
currentCollateral = getCurrentCollateral(constants, position)

Step 2: USD Conversion

debtPrice = getAssetPrice(debtAsset)
collateralPrice = getCollateralPrice(collateralAsset)
debtUSD = currentDebt * debtPrice / (10^debtDecimals)
collateralUSD = currentCollateral * collateralPrice / (10^collateralDecimals)

Step 3: Collateral to Sell

totalDebtWithFee = debtUSD + flashLoanFee
collateralToSellUSD = totalDebtWithFee
collateralToSell = collateralToSellUSD * (10^collateralDecimals) / collateralPrice

Step 4: Preview Setup

remainingCollateral = currentCollateral - collateralToSell
expectedDebtTokens = totalDebtWithFee

LeverageCloneFactory Functions

1. createPosition() - Position Creation Entry Point

Purpose: Main entry point for creating leveraged positions

Steps:

  1. Salt Generation: Create deterministic salt for proxy deployment
  2. Proxy Prediction: Predict the proxy address using deterministic deployment
  3. Token Transfer: Transfer collateral from user to factory
  4. Proxy Creation: Deploy deterministic proxy contract
  5. Position Creation: Call proxy's createPosition function
  6. Counter Update: Increment user's position counter

Mathematical Operations:

salt = keccak256(abi.encodePacked(msg.sender, positionCounter[msg.sender], address(this)))
predictedProxy = Clones.predictDeterministicAddress(implementation, salt, address(this))
proxyAddress = Clones.cloneDeterministic(implementation, salt)
positionCounter[msg.sender]++

2. createPositionPreview() - Position Preview

Purpose: Calculates preview for position creation

Steps:

  1. Parameter Validation: Ensure implementation is initialized
  2. Preview Calculation: Delegate to PositionUtils.windPositionPreview
  3. Return Preview: Return calculated leverage preview

Mathematical Operations:

  • Delegates to PositionUtils.windPositionPreview()
  • Creates temporary Position struct for calculation

3. getMaxMultiplier() - Maximum Leverage Query

Purpose: Returns maximum safe leverage for given parameters

Steps:

  1. Parameter Validation: Ensure implementation is initialized
  2. Calculation: Delegate to PositionUtils.getMaxMultiplier
  3. Return Result: Return maximum multiplier result

Mathematical Operations:

  • Delegates to PositionUtils.getMaxMultiplier()

4. createPositionSwapCallback() - Swap Callback

Purpose: Handles swap operations during position creation

Steps:

  1. Access Control: Ensure caller is a valid child proxy
  2. Swap Execution: Delegate to PositionLogic.createSwapCallback
  3. Return Results: Return swap amounts

Mathematical Operations:

  • Delegates to PositionLogic.createSwapCallback()

5. reinitialize() - Proxy Reinitialization

Purpose: Reinitializes proxy after implementation upgrade

Steps:

  1. Access Control: Ensure caller is proxy owner
  2. Proxy Call: Call initialize function on proxy
  3. Success Check: Verify reinitialization succeeded

Mathematical Operations:

  • No direct calculations (administrative function)

6. rescueTokens() - Emergency Token Recovery

Purpose: Emergency function to recover stuck tokens

Steps:

  1. Access Control: Only owner can call
  2. Token Transfer: Transfer all tokens to owner
  3. Balance Check: Get current token balance

Mathematical Operations:

balance = token.balanceOf(address(this))
token.safeTransfer(owner(), balance)

LeverageProxyImpl Functions

1. initialize() - Proxy Initialization

Purpose: Initializes the proxy contract

Steps:

  1. Owner Validation: Ensure owner is not zero address
  2. Factory Setup: Set factory address to caller
  3. Ownership Transfer: Transfer ownership to specified owner
  4. Event Emission: Emit initialization event

Mathematical Operations:

  • No direct calculations (initialization function)

2. createPosition() - Position Creation

Purpose: Creates a leveraged position (called by factory)

Steps:

  1. Access Control: Ensure caller is factory
  2. Logic Delegation: Delegate to PositionLogic.create
  3. Constants Retrieval: Get constants from factory

Mathematical Operations:

  • Delegates to PositionLogic.create()

3. closePosition() - Position Closure

Purpose: Closes a leveraged position completely

Steps:

  1. Access Control: Ensure caller is owner
  2. Logic Delegation: Delegate to PositionLogic.close
  3. Constants Retrieval: Get constants from factory

Mathematical Operations:

  • Delegates to PositionLogic.close()

4. closePositionManual() - Manual Position Closure

Purpose: Allows manual/partial closure of positions

Steps:

  1. Access Control: Ensure caller is owner
  2. Logic Delegation: Delegate to PositionLogic.closeManual
  3. Constants Retrieval: Get constants from factory

Mathematical Operations:

  • Delegates to PositionLogic.closeManual()

5. windPosition() - Increase Leverage

Purpose: Increases leverage of existing position

Steps:

  1. Access Control: Ensure caller is owner
  2. Logic Delegation: Delegate to PositionLogic.wind
  3. Constants Retrieval: Get constants from factory

Mathematical Operations:

  • Delegates to PositionLogic.wind()

6. unwindPosition() - Decrease Leverage

Purpose: Decreases leverage of existing position

Steps:

  1. Access Control: Ensure caller is owner
  2. Logic Delegation: Delegate to PositionLogic.unwind
  3. Constants Retrieval: Get constants from factory

Mathematical Operations:

  • Delegates to PositionLogic.unwind()

7. closePositionPreview() - Close Preview

Purpose: Calculates preview for position closure

Steps:

  1. Logic Delegation: Delegate to PositionLogic.closePreview
  2. Constants Retrieval: Get constants from factory
  3. Return Preview: Return calculated preview

Mathematical Operations:

  • Delegates to PositionLogic.closePreview()

8. closePositionManualPreview() - Manual Close Preview

Purpose: Calculates preview for manual position closure

Steps:

  1. Logic Delegation: Delegate to PositionLogic.closeManualPreview
  2. Constants Retrieval: Get constants from factory
  3. Return Preview: Return calculated preview

Mathematical Operations:

  • Delegates to PositionLogic.closeManualPreview()

9. windPositionPreview() - Wind Preview

Purpose: Calculates preview for increasing leverage

Steps:

  1. Logic Delegation: Delegate to PositionLogic.windPreview
  2. Constants Retrieval: Get constants from factory
  3. Return Preview: Return calculated preview

Mathematical Operations:

  • Delegates to PositionLogic.windPreview()

10. unwindPositionPreview() - Unwind Preview

Purpose: Calculates preview for decreasing leverage

Steps:

  1. Logic Delegation: Delegate to PositionLogic.unwindPreview
  2. Constants Retrieval: Get constants from factory
  3. Return Preview: Return calculated preview

Mathematical Operations:

  • Delegates to PositionLogic.unwindPreview()

11. executeOperation() - Flash Loan Callback

Purpose: Handles Aave flash loan callbacks

Steps:

  1. Parameter Construction: Build PositionCallbackParams
  2. Logic Delegation: Delegate to PositionLogic.handleCallback
  3. Constants Retrieval: Get constants from factory
  4. Return Success: Return true for successful execution

Mathematical Operations:

  • Delegates to PositionLogic.handleCallback()

12. onFlashLoan() - ERC3156 Flash Loan Callback

Purpose: Handles ERC3156 flash loan callbacks

Steps:

  1. Parameter Construction: Build PositionCallbackParams
  2. Logic Delegation: Delegate to PositionLogic.handleCallback
  3. Constants Retrieval: Get constants from factory
  4. Return Hash: Return keccak256('ERC3156FlashBorrower.onFlashLoan')

Mathematical Operations:

  • Delegates to PositionLogic.handleCallback()

13. getPositionDetails() - Position Information

Purpose: Returns current position details

Steps:

  1. Logic Delegation: Delegate to PositionLogic.getPositionDetails
  2. Constants Retrieval: Get constants from factory
  3. Return Details: Return position details

Mathematical Operations:

  • Delegates to PositionLogic.getPositionDetails()

14. executeMultiCall() - Multi-Call Execution

Purpose: Executes multiple calls atomically

Steps:

  1. Access Control: Ensure caller is owner
  2. Loop Execution: Execute each call in sequence
  3. Error Handling: Handle reverts based on allowRevert flag
  4. Result Processing: Process call results

Mathematical Operations:

for (uint256 i = 0; i < calls.length; i++) {
    (bool success, bytes memory result) = calls[i].target.call{value: calls[i].value}(calls[i].data);
    if (!success && !calls[i].allowRevert) {
        revert(string(result));
    }
}

15. rescueTokens() - Emergency Token Recovery

Purpose: Emergency function to recover stuck tokens

Steps:

  1. Access Control: Ensure caller is owner
  2. Address Validation: Ensure recipient is not zero
  3. Balance Check: Get current token balance
  4. Token Transfer: Transfer tokens to recipient

Mathematical Operations:

balance = IERC20(token).balanceOf(address(this))
if (balance > 0) {
    IERC20(token).safeTransfer(to, balance);
}

16. rescueETH() - Emergency ETH Recovery

Purpose: Emergency function to recover stuck ETH

Steps:

  1. Access Control: Ensure caller is owner
  2. Address Validation: Ensure recipient is not zero
  3. ETH Transfer: Transfer ETH to recipient

Mathematical Operations:

balance = address(this).balance
if (balance > 0) {
    payable(to).transfer(balance);
}

Mathematical Formulas

Health Factor Formula

healthFactor = (totalCollateralUSD * liquidationThreshold) / totalDebtUSD

Leverage Multiplier Formula

leverageMultiplier = totalCollateral / userCollateral

Required Collateral-Debt Ratio

requiredRatio = (targetHealthFactor * 1e18) / liquidationThreshold

Decimal Scaling

// Scale up (add decimals)
scaledAmount = amount * (10^decimals)

// Scale down (remove decimals)
scaledAmount = amount / (10^decimals)

Price Conversion

usdValue = tokenAmount * price / (10^tokenDecimals)
tokenAmount = usdValue * (10^tokenDecimals) / price

Deterministic Address Generation

salt = keccak256(abi.encodePacked(owner, positionCounter, factory))
proxyAddress = Clones.predictDeterministicAddress(implementation, salt, factory)

Key Data Structures

LeveragePreview

struct LeveragePreview {
    uint256 initialCollateralAmountUSD;    // User's initial collateral in USD
    uint256 initialCollateralAmountTokens; // User's initial collateral in tokens
    uint256 collateralAmountUSD;           // Total collateral in USD
    uint256 collateralAmountTokens;        // Total collateral in tokens
    uint256 debtAmountUSD;                 // Total debt in USD
    uint256 debtAmountTokens;              // Total debt in tokens
    uint256 resultingHealthFactor;         // Calculated health factor
}

GetMaxMultiplierResult

struct GetMaxMultiplierResult {
    uint256 requiredCollateralDebtRatio;   // Required ratio for target health factor
    uint256 totalCollateralDebtRatio;      // Total ratio available
    uint256 requiredCollateralTokens;      // Required collateral in tokens
    uint256 maxMultiplier;                 // Maximum safe leverage multiplier
    uint256 maxBorrow;                     // Maximum borrow amount
    uint256 maxBorrowUSD;                  // Maximum borrow in USD
    uint256 maxCollateralAmountUSD;        // Maximum collateral in USD
    uint256 maxCollateralAmountTokens;     // Maximum collateral in tokens
}

Position

struct Position {
    address collateralAsset;               // Collateral asset address
    address debtAsset;                     // Debt asset address
    uint256 leverageMultiplier;            // Current leverage multiplier
    uint256 userCollateral;                // User's collateral amount
}

PositionParams

struct PositionParams {
    LeverageParams input;                  // Leverage parameters
    uint256 debtAmount;                    // Debt amount
    string gluexData;                      // Gluex swap data
}

Call

struct Call {
    address target;                        // Target contract address
    uint256 value;                         // ETH value to send
    bytes data;                            // Call data
    bool allowRevert;                      // Whether to allow reverts
}

Key Constants and Thresholds

  • Minimum Multiplier: 1e18 (1x leverage)
  • Minimum Health Factor: 1500000000000000000 (1.5x)
  • Flash Loan Fee: Typically 9 basis points (0.09%)
  • Price Decimals: 8 or 18 depending on oracle
  • LTV WAD: LTV * 1e14 (for precision)
  • Liquidation Threshold WAD: Liquidation threshold * 1e14

Error Handling

Common Error Conditions

  • MULTIPLIER_TOO_LOW: Leverage below minimum
  • MULTIPLIER_TOO_HIGH: Leverage exceeds maximum safe level
  • HEALTH_FACTOR_TOO_LOW: Health factor below minimum threshold
  • COLLATERAL_AMOUNT_TOO_LOW: Insufficient collateral
  • BORROW_CAP_EXCEEDED: Borrowing exceeds pool limits
  • SUPPLY_CAP_EXCEEDED: Collateral supply exceeds limits
  • DEBT_CEILING_EXCEEDED: Total debt exceeds ceiling
  • ONLY_FACTORY: Function called by non-factory address
  • ONLY_OWNER: Function called by non-owner
  • INVALID_IMPLEMENTATION: Invalid implementation address
  • IMPLEMENTATION_NOT_INITIALIZED: Implementation not set

Safety Checks

  • Division by zero prevention
  • Underflow/overflow protection
  • Price validation (non-zero prices)
  • Cap and ceiling enforcement
  • Health factor validation
  • Access control enforcement
  • Address validation

Architecture Overview

Factory Pattern

  • LeverageCloneFactory: Creates and manages proxy instances
  • Deterministic Deployment: Uses CREATE2 for predictable addresses
  • Position Counter: Tracks positions per user for deterministic salts

Proxy Pattern

  • LeverageProxyImpl: Implementation contract for all proxies
  • Beacon Proxy: Single implementation for all user positions
  • Upgradeable: Implementation can be upgraded without affecting user positions

Flash Loan Integration

  • Aave V3: Primary flash loan provider
  • USDXL Flash Minter: Alternative flash loan provider
  • ERC3156: Standard flash loan interface

Swap Integration

  • Gluex Router: DEX for token swaps
  • Callback Pattern: Handles swap operations during flash loans

This document provides a comprehensive overview of all the mathematical operations and functions in the leverage system, including the factory and proxy implementation layers, suitable for technical presentations and documentation.

Packages

No packages published

Languages

  • Solidity 87.1%
  • Shell 12.3%
  • Other 0.6%