Submitted by peakbolt, also found by rvierdiiev and adeolu
src/periphery/LendgineRouter.sol#L142
src/periphery/LendgineRouter.sol#L87-L124
src/periphery/LendgineRouter.sol#L119-L123
src/periphery/Payment.sol#L44-L46
When the collateral/speculative token (Token1) is WETH, a borrower could mint Power Tokens and deposit the collateral tokens by sending ETH while calling the payable mint() function in LendgineRouter.sol.
The exact collateral amount required to be deposited by the borrower is only calculated during minting (due to external swap), which could be lesser than what the borrower has sent for the mint. This means that there will be excess ETH left in LengineRouter contract and they are not automatically refunded to the borrower.
Anyone that sees this opportunity can call refundETH() to retrieve the excess ETH.
The borrower could retrieve the remaining ETH with a separate call to refundETH(). However, as the calls are not atomic, it is possible for a MEV bot to frontrun the borrower and steal the ETH too.
Furthermore, there are no documentation and test cases that advise or handle this issue.
First, call payable mint() in LendgineRouter contract with the required ETH amount for collateral.
src/periphery/LendgineRouter.sol#L142
LendgineRouter.mintCallback() will be triggered, which will perform the external swap of the borrowed token0 to token1 on uniswap. The collateralSwap value (token1) is only calculated and known after the successful swap. Both swapped token1 and borrowed token1 are then sent to Lendgine contract (msg.sender).
src/periphery/LendgineRouter.sol#L87-L124
After that, mintCallback() will continue to calculate the remaining token1 required to be paid by the borrower (collateralIn value).
Depending on the external swap, the collateralSwap (token1) value could be higher than expected, resulting in a lower collateralIn value. A small collateralIn value means that less ETH is required to be paid by the borrower (via the pay function), resulting in excess ETH left in the LengineRouter contract. However, the excess ETH is not automatically refunded by the mint() call.
Note: For WETH, the pay() uses the ETH balance deposited and wrap it before transferring to Lendgine contract.
src/periphery/LendgineRouter.sol#L119-L123
A MEV bot or anyone that see this opportunity can call refundETH() to retrieve the excess ETH.
src/periphery/Payment.sol#L44-L46
Automatically refund any excess ETH to the borrower.
kyscott18 (Numoen) acknowledged and commented:
berndartmueller (judge) decreased severity to Medium and commented:
