Summary
The signature in withDraw can be reused and this will cause users can choose one improper odosAssembledData and convert less collateral than expected.
Root Cause
In borrowing.sol:withDraw, borrowers can withdraw their collateral. If the current Ether price is larger than deposited Ether price, borrowers will not withdraw all collaterals. There will be some remaining collateral. These remaining collaterals will be swapped to USDT via odos router.
In one normal scenario, the protocol backend server will generate odos assembled data got from odos api, and sign the signature. The borrower will use this signed signature and odosAssembledData to trigger this withDraw function.
But the problem is that malicious users can choose one improper odosAssembledData and signature. Although we can not manipulate the odosAssembledData to any value we want, the backend servers will generate all kinds of odosAssembledData for different borrower's withdrawal. The malicious borrower can choose any odosAssembledData from all of these odosAssembledData.
For example:
- Alice deposits WrsETH via depositTokens.
- The Ether price increases, Alice wants to withdraw her collateral. Her borrow position's remaining collateral is 0.05 ether. Normally, Alice's
odosAssembledDatawill swap 0.05 ether wrsETH to USDT. But Alice searches the valid usedodosAssembledData, and find oneodosAssembledDatawhich input token amt is 0.01 ether. Alice uses usedodosAssembledDatato trigger her withdraw. - We will swap 0.01 ether wrsETH to USDT. This will cause some wrsETH locked in the contract.
function _withdraw(
address toAddress,
uint64 index,
bytes memory odosAssembledData,
uint64 ethPrice, // current ether price
uint128 exchangeRate,
uint64 withdrawTime
) internal {
...
uint256 amountToSwap = result.collateralRemainingInWithdraw -
collateralRemainingInWithdraw;
if (amountToSwap > 0) {
amountToSwap = (amountToSwap * 1 ether) / exchangeRate;
treasury.swapCollateralForUSDT(depositDetail.assetName, amountToSwap, odosAssembledData);
}
...
}Internal pre-conditions
N/A
External pre-conditions
N/A
Attack Path
- Alice deposits WrsETH via depositTokens.
- The Ether price increases, Alice wants to withdraw her collateral. Her borrow position's remaining collateral is 0.05 ether. Normally, Alice's
odosAssembledDatawill swap 0.05 ether wrsETH to USDT. But Alice searches the valid usedodosAssembledData, and find oneodosAssembledDatawhich input token amt is 0.01 ether. Alice uses usedodosAssembledDatato trigger her withdraw. - We will swap 0.01 ether wrsETH to USDT. This will cause some wrsETH locked in the contract.
Impact
When we swap the remaining collateral to USDT, we may swap only one part of remaining collateral to USDT. This will break our intent. Some remaining collateral will be locked in the contract, and the output USDT is less than expected.
PoC
N/A
Mitigation
odosAssembledData and signature should only be valid for one borrower's specific borrowing index.