Skip to content

Latest commit

 

History

History
149 lines (118 loc) · 6 KB

File metadata and controls

149 lines (118 loc) · 6 KB

Original Lace Sheep

High

Price manipulation in LenderCommitmentGroup_Smart lending pools remains a critical vulnerability despite acknowledged risk

Summary

Despite protocol's acknowledged risk, the use of Uniswap's current slot0 price (when twapInterval = 0) presents an unacceptable vulnerability that can lead to large scale losses and is just an overall unacceptable risk to have within the Teller protocol. Economic assumptions about pool size ratios fail to protect against sophisticated MEV and flash loan attacks, making this an urgent security concern requiring immediate mitigation.

Critical Call Flow:

acceptFundsForAcceptBid
└── calculateCollateralRequiredToBorrowPrincipal
    └── calculateCollateralTokensAmountEquivalentToPrincipalTokens
        └── UniswapPricingLibrary.getUniswapPriceRatioForPoolRoutes
            └── getSqrtTwapX96 (vulnerable point)

Root Cause

In UniswapPricingLibrary.sol:60 the getSqrtTwapX96() function allows twapInterval = 0 which defaults to using current Uniswap slot0 price. While acknowledged, real-world attack scenarios demonstrate this "accepted risk" is based on flawed economic assumptions:

https://github.com/sherlock-audit/2024-11-teller-finance-update/blob/main/teller-protocol-v2-audit-2024/packages/contracts/contracts/libraries/UniswapPricingLibrary.sol#L103

function getSqrtTwapX96(address uniswapV3Pool, uint32 twapInterval) internal view {
    if (twapInterval == 0) {
        // return the current price if twapInterval == 0
        (sqrtPriceX96, , , , , , ) = IUniswapV3Pool(uniswapV3Pool).slot0();
    }
}

Affected Contracts and Functions:

  1. UniswapPricingLibrary.sol
  • getSqrtTwapX96() - Core vulnerability point
  • getUniswapPriceRatioForPoolRoutes()
  • getUniswapPriceRatioForPool()
  1. LenderCommitmentGroup_Smart.sol
  • acceptFundsForAcceptBid()
  • calculateCollateralRequiredToBorrowPrincipal()
  • calculateCollateralTokensAmountEquivalentToPrincipalTokens()
  • getUniswapPriceRatioForPoolRoutes()
  • getPrincipalForCollateralForPoolRoutes()
  • initialize()
  1. LenderCommitmentGroupFactory.sol
  • deployLenderCommitmentGroupPool()

Proof of Flawed Risk Assessment

Example Profitable Attack (Even Within Protocol's Safety Parameters):

  1. LenderCommitmentGroup_Smart pool: $1M lending capacity
  2. Uniswap pool: $10M TVL (adhering to protocol's "10x larger" safety assumption)
  3. Attack using $5M flash loan (0.09% fee = $4,500)
  4. Price manipulation potential:
    • 30-40% temporary price movement achievable
    • Original collateral requirement: $1M collateral → $666K borrowing
    • Manipulated price (1.4x): Same $1M collateral → $933K borrowing
  5. Profit Calculation:
    Costs:
    - Flash loan fee: $4,500
    - Gas + MEV: ~$500
    - Slippage (~1%): $50,000
    Total costs: ~$55,000
    
    Revenue:
    - Borrowed amount: $933K
    - True collateral value: $666K
    Net profit: $212,000 per attack

Internal pre-conditions

  1. A LenderCommitmentGroup_Smart pool must be deployed with twapInterval = 0 in its oracle configuration
  2. The pool must have sufficient principal tokens available (determined by getPrincipalAmountAvailableToBorrow())
  3. The pool must be unpaused and active (whenNotPaused modifier satisfied)
  4. The collateral ratio must be set (typically >100% via collateralRatio)

External pre-conditions

  1. Sufficient liquidity in relevant Uniswap V3 pools to execute flash loans and achieve meaningful price manipulation
  2. The targeted token pair must have enough price impact potential relative to pool depth to make the attack profitable after gas costs
  3. No external circuit breakers or price deviation checks that would prevent the price manipulatio

Attack Path

  1. Attacker identifies a LenderCommitmentGroup_Smart pool using vulnerable price feeds
  2. Attacker takes a flash loan of collateral token from any lending protocol
  3. Attacker executes a large swap in the Uniswap pool to manipulate the slot0 price, artificially increasing collateral token value
  4. Attacker calls acceptFundsForAcceptBid() with manipulated prices allowing them to:
    function acceptFundsForAcceptBid(
        address _borrower,
        uint256 _bidId,
        uint256 _principalAmount,
        uint256 _collateralAmount,
        ...
    ) external {
        uint256 requiredCollateral = calculateCollateralRequiredToBorrowPrincipal(_principalAmount);
        require(_collateralAmount >= requiredCollateral, "Insufficient Borrower Collateral");
        ...
    }
    • Provide less collateral than normally required due to manipulated price ratio
    • Borrow maximum principal amount based on inflated collateral value
  5. Attacker repays flash loan, allowing price to return to normal
  6. Loan remains active but severely under-collateralized based on true market price

Impact

This vulnerability must be addressed because:

  1. Protocol's economic assumptions fail:

    • Flash loans eliminate capital requirements
    • MEV strategies can optimize profit beyond basic calculations
    • Real profit potential exists even within "safe" parameters
    • $200K+ profit per attack proves economic deterrence insufficient
  2. Systemic risks:

    • Multiple pools can be attacked sequentially
    • MEV bots can automate and optimize attacks
    • No technical barriers prevent exploitation
  3. Market Impact:

    • Protocol reputation damage
    • Lender confidence erosion
    • Potential cascade effect across integrated protocols

PoC

No response

Mitigation

  1. Remove twapInterval = 0 option entirely
  2. Implement mandatory minimum TWAP period (suggest 30 minutes)
  3. Add price deviation circuit breakers
  4. Consider multiple oracle sources for validation

The protocol's current stance of "make it unprofitable" is demonstrably insufficient given:

  • Proven profit potential even within safety parameters
  • Evolving MEV strategies
  • Flash loan accessibility
  • Automation potential

This issue requires immediate attention as economic deterrence has been proven inadequate for modern DeFi security.