Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: low
Invalid

GMXManager.calcSwapForRepay() should check if the amount of token B > the balance of token B before swap, when the repay TokenAAmt > the balance of token A, and vice versa.

Summary

The GMXManager.calcSwapForRepay() function should ensure there is enough tokenB before conducting a swap, especially when repaying with tokenA, and vice versa. Failing to do so may lead to a breakdown in the capital chain, where liabilities exceed assets. In such cases, please avoid using one asset to cover another's shortfall. Instead, please trigger events and consider alternative funding sources or seek professional advice.

Vulnerability Details

From a risk management perspective, engaging in a robbing-Peter-to-pay-Paul behavior can lead to a situation where liabilities exceed assets, potentially resulting in a breakdown of the capital chain if not flagged by the asset management institution.

Impact

In such a scenario, it is advisable to refrain from simply using one asset to fill the gap in another. Instead, it should trigger corresponding events to alert management. Simultaneously, a series of professional risk management solutions should be implemented, for example:

1)Seek alternative sources of funds:

Please attempt to acquire funds from alternative channels, such as personal savings, loans, or extracting funds from other investments.

2)Temporarily delay repayment:

If it is possible, please postpone repayment until the financial situation improves.

Tools Used

VS Code

Recommendations

event FundsShortage(address account, uint256 amount);

function calcSwapForRepay(
GMXTypes.Store storage self,
GMXTypes.RepayParams memory rp
) external view returns (bool, address, address, uint256) {
address _tokenFrom;
address _tokenTo;
uint256 _tokenToAmt;

uint256 tokenABalance = self.tokenA.balanceOf(address(this));
uint256 tokenBBalance = self.tokenB.balanceOf(address(this));

// Check if swapping tokenB to tokenA is enough to repay
if (rp.repayTokenAAmt <= tokenABalance && rp.repayTokenBAmt <= tokenBBalance) {
    return (false, address(0), address(0), 0); // No swap needed
}

// Check if swapping tokenB to tokenA could cover the shortfall in tokenA
if (rp.repayTokenAAmt > tokenABalance) {
    uint256 swapAmountBtoA = rp.repayTokenAAmt - tokenABalance;
    uint256 swapAmountAtoB = swapAmountBtoA * self.tokenAtoBPrice() / self.tokenBtoAPrice();

    if (swapAmountAtoB <= tokenBBalance) {
        return (true, address(self.tokenB), address(self.tokenA), swapAmountBtoA);
    } else {
        emit FundsShortage(address(this), swapAmountAtoB);
    }
}

// Check if swapping tokenA to tokenB could cover the shortfall in tokenB
if (rp.repayTokenBAmt > tokenBBalance) {
    uint256 swapAmountAtoB = rp.repayTokenBAmt - tokenBBalance;
    uint256 swapAmountBtoA = swapAmountAtoB * self.tokenBtoAPrice() / self.tokenAtoBPrice();

    if (swapAmountBtoA <= tokenABalance) {
        return (true, address(self.tokenA), address(self.tokenB), swapAmountAtoB);
    } else {
        emit FundsShortage(address(this), swapAmountBtoA);
    }
}
Updates

Lead Judging Commences

hans Lead Judge almost 2 years ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

INFO: Ensure repayment is feasible

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.