Skip to content

Latest commit

 

History

History
93 lines (65 loc) · 3.61 KB

File metadata and controls

93 lines (65 loc) · 3.61 KB

Cheesy Fossilized Snail

Medium

Front-Running Vulnerability in repayBorrow FunctionAn attacker can front-run the _repayBorrow transaction to manipulate the exchange rate between assets and shares, potentially causing a loss of funds for the SetToken

Summary

The _repayBorrow function in MorphoLeverageModule.sol allows repayment using either asset amounts or share amounts, but not both simultaneously. This design can be exploited by a malicious actor to front-run the transaction and manipulate the exchange rate between assets and shares, potentially causing the SetToken to repay more than necessary or receive fewer shares than expected.

Root Cause

the _repayBorrow function uses an if-else statement to decide whether to repay based on shares or assets. This mutually exclusive approach creates a window of opportunity for front-running attacks.

check code snippet https://github.com/sherlock-audit/2024-10-morpho-x-index/blob/main/index-protocol/contracts/protocol/modules/v1/MorphoLeverageModule.sol#L742-L760

Internal pre-conditions

The SetToken must have an outstanding borrow position on Morpho. The _repayBorrow function must be called as part of a larger transaction (e.g., within the delever function).

External pre-conditions

The attacker must have the ability to monitor the mempool and quickly submit transactions. The Morpho protocol must allow for rapid changes in the asset-to-share ratio.

Attack Path

The SetToken initiates a delever transaction that includes a call to _repayBorrow. An attacker observes this pending transaction in the mempool. The attacker quickly submits a transaction to manipulate the asset-to-share ratio on Morpho (e.g., by making a large deposit or withdrawal). The attacker's transaction is mined before the SetToken's transaction. The SetToken's _repayBorrow transaction is executed with the manipulated asset-to-share ratio.

Impact

The SetToken could suffer a loss of funds due to overpayment or undervaluation of its repayment. The exact impact would depend on the size of the borrow position and the degree of manipulation in the asset-to-share ratio.

PoC

sample test case

function simulateFrontRunningAttack() public {
    // Assume SetToken is about to call delever which includes _repayBorrow
    uint256 initialRatio = morpho.getAssetToShareRatio(marketId);
    
    // Attacker manipulates the ratio
    attacker.manipulateRatio(marketId);
    
    uint256 manipulatedRatio = morpho.getAssetToShareRatio(marketId);
    
    // SetToken's _repayBorrow executes with manipulated ratio
    setToken.delever(...);
    
    // Check the difference in repayment amount or received shares
    // This difference represents the potential loss to the SetToken
}

Mitigation

Implement a slippage protection mechanism in the _repayBorrow function. Consider using both assets and shares in the repayment to ensure a fair exchange rate. Implement a commit-reveal scheme for repayments to prevent front-running.

Example mitigation:

function _repayBorrow(
    ISetToken _setToken,
    MarketParams memory _marketParams,
    uint256 _notionalQuantity,
    uint256 _shares,
    uint256 _maxSlippage
)
    internal
{
    uint256 initialRatio = morpho.getAssetToShareRatio(_marketParams.id());
    
    _setToken.invokeApprove(_marketParams.loanToken, address(morpho), _notionalQuantity);
    _setToken.invokeRepay(
        morpho,
        _marketParams,
        _notionalQuantity,
        _shares
    );
    
    uint256 finalRatio = morpho.getAssetToShareRatio(_marketParams.id());
    require(finalRatio <= initialRatio * (1 + _maxSlippage), "Slippage too high");
}