sherlock-2023-08-cooler-m02

[M-02] Lender is able to steal borrowers collateral by calling rollLoan with unfavourable terms on behalf of the borrower

보고서

Summary

채무자가 아닌 누구나 rollLoan를 호출해 새로 제안된 대출 요건으로 수정할 수 있다. 대여자가 원하는 조건으로 provideNewTermsForRoll 를 호출한 뒤 rollLoan를 호출시켜 강제로 대출 조건을 변경할 수 있다. 갚을 수 없는 조건을 제시하여 채무 불이행 상태를 유도, 담보를 강제 몰수할 수 있다.

Keyword

access control

Vulnerability

rollLoan 함수는 호출자를 제한하지 않는다. 따라서 대여자(공격자)가 원하는 조건으로 provideNewTermsForRoll를 호출한 뒤, 채무자를 대신하여 rollLoan를 호출하여 대여자가 제공한 조건으로 대출을 연장하도록 강제할 수 있다.

    function rollLoan(uint256 loanID_) external {
        Loan memory loan = loans[loanID_];
 
        if (block.timestamp > loan.expiry) revert Default();
        if (!loan.request.active) revert NotRollable();
 
        ...
    }

provideNewTermsForRoll 함수에서는 이율, 담보 토큰의 가격, 기한 등을 변경할 수 있으므로 이를 조작해 대여자가 유리한 상황을 만들 수 있다. 이를 악용하여 채무자가 상환하기 매우 불리한 조건으로 대출 조건을 수정해 채무 불이행 상태를 유도하고, 담보를 몰수할 수 있다.

    function provideNewTermsForRoll(
        uint256 loanID_,
        uint256 interest_,
        uint256 loanToCollateral_,
        uint256 duration_
    ) external {
        Loan storage loan = loans[loanID_];
 
        if (msg.sender != loan.lender) revert OnlyApproved();
 
        loan.request =
            Request(
                loan.amount,
                interest_,
                loanToCollateral_,
                duration_,
                true
            );
    }

Impact

채무자가 불리한 조건으로 대출금을 상환하도록 강제되거나, 상환에 실패하여 담보를 몰수당할 수 있다.

Mitigation

채무자만 rollLoan를 호출하도록 제한한다.

function rollLoan(uint256 loanID_) external {
    Loan memory loan = loans[loanID_];
    
    if (msg.sender != owner()) revert OnlyApproved();

tags: bughunting, olympus dao, smart contract, solidity, lending protocol, access control vulnerability, severity medium