You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Apr 28, 2024. It is now read-only.
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
A burnt position will prevent repayment and liquidation
Summary
A Burnt loan(position) can lead to a scenario where repayment or liquidation is impossible due to the repay(...) function not checking if the loan position is still active.
Vulnerability Detail
The vulnerability is straightforward. To explain this issue in detail, consider the following steps:
Bob borrows a certain amount of loans.
The lender, who is the owner of an active loan position, is compromised or intentionally burns their position. This can be accomplished by calling the Uniswap v3 position manager with the following code:
Now, when Alice attempts to make a repayment, it becomes impossible because the function will revert, indicating that the tokenID does not exist. This occurs when attempting to restore liquidity to the burned position.
As a result, only an emergency "liquidation" is possible for the other loan owners. The entire borrowing cannot be repaid or liquidated anymore.
Proof of Concept
To demonstrate this issue, a Proof of Concept was executed as follows:
it("DOS of repayment if tokenID is burnt",async()=>{letamountWBTC=ethers.utils.parseUnits("0.05",8);//token0constdeadline=(awaittime.latest())+60;constminLeverageDesired=50;constmaxCollateralWBTC=amountWBTC.div(minLeverageDesired);constloans=[{liquidity: nftpos[3].liquidity,tokenId: nftpos[3].tokenId,},];console.log(awaitnonfungiblePositionManager.ownerOf(nftpos[3].tokenId));// alice addressconstswapParams: ApproveSwapAndPay.SwapParamsStruct={swapTarget: constants.AddressZero,swapAmountInDataIndex: 0,maxGasForCall: 0,swapData: swapData,};letparams={internalSwapPoolfee: 500,saleToken: WETH_ADDRESS,holdToken: WBTC_ADDRESS,minHoldTokenOut: amountWBTC,maxCollateral: maxCollateralWBTC,externalSwap: swapParams,loans: loans,};awaitborrowingManager.connect(bob).borrow(params,deadline);constborrowingKey=awaitborrowingManager.userBorrowingKeys(bob.address,0);constswapParamsRep: ApproveSwapAndPay.SwapParamsStruct={swapTarget: constants.AddressZero,swapAmountInDataIndex: 0,maxGasForCall: 0,swapData: swapData,};
let paramsRep: LiquidityBorrowingManager.RepayParamsStruct={isEmergency: false,internalSwapPoolfee: 500,externalSwap: swapParamsRep,borrowingKey: borrowingKey,swapSlippageBP1000: 990,//<=slippage simulated};awaitnonfungiblePositionManager.connect(alice).burn(nftpos[3].tokenId);//@audit simulation of hacked lenderconsole.log("It was burnt");awaitexpect(borrowingManager.connect(bob).repay(paramsRep,deadline)).to.be.reverted// 'Invalid token ID'});
Impact
Disabled repayment for that active borrow of the user. The liquidation bonus is not accessible anymore as the whole liquidation is prevented.
Code Snippet
Here, it will revert as the tokenId does not exist anymore. "Link to Code"
Tool used
Manual Review
Recommendation
To mitigate this vulnerability, it is recommended to implement a check in the _restoreLiquidity(...) function to verify whether the position exists. If it does not exist, necessary actions should be taken to leave the borrowed assets as profit. The following pseudo code outlines this recommendation.
// Pseudo code
function _restoreLiquidity(...){
RestoreLiquidityCache memory cache;
for (uint256 i; i < loans.length; ) {
+ if (!success =underlyingPositionManager.call(ownerOf(loan.tokenID)){
// Do necessary changes
continue;
}
...
}
sherlock-admin2
changed the title
Big Charcoal Cod - A burnt position will prevent repayment and liquidation
talfao - A burnt position will prevent repayment and liquidation
Oct 30, 2023
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
talfao
medium
A burnt position will prevent repayment and liquidation
Summary
A Burnt loan(position) can lead to a scenario where repayment or liquidation is impossible due to the
repay(...)
function not checking if the loan position is still active.Vulnerability Detail
The vulnerability is straightforward. To explain this issue in detail, consider the following steps:
As a result, only an emergency "liquidation" is possible for the other loan owners. The entire borrowing cannot be repaid or liquidated anymore.
Proof of Concept
To demonstrate this issue, a Proof of Concept was executed as follows:
Impact
Disabled repayment for that active borrow of the user. The liquidation bonus is not accessible anymore as the whole liquidation is prevented.
Code Snippet
Here, it will revert as the tokenId does not exist anymore.
"Link to Code"
Tool used
Manual Review
Recommendation
To mitigate this vulnerability, it is recommended to implement a check in the
_restoreLiquidity(...)
function to verify whether the position exists. If it does not exist, necessary actions should be taken to leave the borrowed assets as profit. The following pseudo code outlines this recommendation.// Pseudo code function _restoreLiquidity(...){ RestoreLiquidityCache memory cache; for (uint256 i; i < loans.length; ) { + if (!success =underlyingPositionManager.call(ownerOf(loan.tokenID)){ // Do necessary changes continue; } ... }
Duplicate of #78
The text was updated successfully, but these errors were encountered: