code4rena-2024-03-dittoeth-h06

[H-06] Closing a SR during a wrong redemption proposal leads to loss of funds

보고서

Summary

청산 요청중인 숏이 다른 인터렉션으로 인해 닫힐 수 있다. 청산이 취소되고 빼앗긴 담보를 돌려받더라도 이미 숏이 닫혀있어 돌려받은 담보를 핸들링할 수 없다. 결과적으로 유저는 담보 토큰을 잃는다.

Keyword

business logic vul, defi, asset lock

Vulnerability

청산 요청 중 담보율이 낮지만 청산 요청되지 않은 숏이 있다면 disputeRedemption 를 호출하여 청산을 취소시킬 수 있다. 청산을 요청하는 시점에 청산 대상 숏의 담보를 압수하고, 청산이 취소되면 이를 각 숏에게 돌려준다.

function disputeRedemption(address asset, address redeemer, uint8 incorrectIndex, address disputeShorter, uint8 disputeShortId)
    external
    isNotFrozen(asset)
    nonReentrant
{
    ...
    MTypes.ProposalData[] memory decodedProposalData =
        LibBytes.readProposalData(redeemerAssetUser.SSTORE2Pointer, redeemerAssetUser.slateLength);
 
    ...
 
    if (disputeCR < incorrectProposal.CR && disputeSR.updatedAt + C.DISPUTE_REDEMPTION_BUFFER <= redeemerAssetUser.timeProposed)
    {
        // @dev All proposals from the incorrectIndex onward will be removed
        // @dev Thus the proposer can only redeem a portion of their original slate
        for (uint256 i = incorrectIndex; i < decodedProposalData.length; i++) {
@>          currentProposal = decodedProposalData[i];
 
@>          STypes.ShortRecord storage currentSR = s.shortRecords[d.asset][currentProposal.shorter][currentProposal.shortId]; // The currentSR might be closed
@>          currentSR.collateral += currentProposal.colRedeemed;
@>          currentSR.ercDebt += currentProposal.ercDebtRedeemed;
 
            d.incorrectCollateral += currentProposal.colRedeemed;
            d.incorrectErcDebt += currentProposal.ercDebtRedeemed;
        }
 
        ...
    } ...
}

만약 청산 요청된 숏이 여러 가지 이유(숏 청산, 종료, 이동)로 닫히면, 이후 disputeRedemption 로 청산을 취소하여도 빼앗긴 담보를 돌려받을 수 없다. 이미 숏이 닫혀있기 때문이다.

예를 들어 다음과 같다.

  1. Alice 의 숏 3번이 proposesRedemption 로 청산 요청되었다. redemptionAmount 로 인해 이 숏에는 ercDebt 와 담보 dETH가 남아있다.
  2. Alice 가 exitShortWallet 를 호출하여 숏 3번을 닫았다.
  3. Bob이 disputeRedemption 를 호출하여 숏 청산을 취소시켰다. Alice의 숏 3번에 ercDebt 와 가져갔던 담보 수를 원상복구 한다.
  4. Alice는 이미 숏 3번을 닫았기 때문에 돌려받은 ercDebt 와 담보 dETH를 핸들링할 수 없다.

숏 3번이 의도치 않게 닫히는 시나리오는 여러가지 있다. 예를 들어 동일한 숏이 2번 proposeRedemption 로 청산 요청 된다면, 이후 첫번째 청산 요청에 대한 claim 을 할 때 숏이 닫힌다. 두번쨰 청산 요청에 분쟁이 발생하더라도 Alice는 반환된 자금을 핸들링할 수 없다.

Impact

유저가 돌려받은 담보 토큰에 대한 핸들링이 불가하여 담보를 잃는다.

Mitigation

청산이 진행중인 숏은 닫힐 수 없도록 한다. 청산 요청중이라면 숏이 닫힐 수 있는 작업이 불가하도록 막아야 한다.


tags: bughunting, dittoeth, smart contract, solidity, business-logic-vul, defi, asset lock, severity high