Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Borrower is not able to compensate his lenders if he is underwater #107

Open
c4-bot-8 opened this issue Jul 2, 2024 · 6 comments
Open
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working edited-by-warden M-09 primary issue Highest quality submission among a set of duplicates 🤖_primary AI based primary recommendation 🤖_65_group AI based duplicate group recommendation satisfactory satisfies C4 submission criteria; eligible for awards selected for report This submission will be included/highlighted in the audit report sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") sufficient quality report This report is of sufficient quality

Comments

@c4-bot-8
Copy link
Contributor

c4-bot-8 commented Jul 2, 2024

Lines of code

https://github.com/code-423n4/2024-06-size/blob/8850e25fb088898e9cf86f9be1c401ad155bea86/src/Size.sol#L250

Vulnerability details

Impact

A borrower of a loan could have other credit positions with borrowers that have healthy CRs which he could use to compensate his lenders to avoid liquidations and improve his CR. However he is not able to do this via compensate() and he is forced to sell his credit positions via sellCreditMarket() or sellCreditLimit(). The complications of this are described in the example below.

Proof of Concept

Before we start just to have context, repay() repays the whole debt amount of the loan in full and can be called even when the borrower is underwater or past due date.

compensate() is used to either split a loan in smaller parts in order to be more easily repaid with repay() or to repay certain lenders and reduce the debt of the loan by the borrower giving specific lenders some of his own healthy credit positions that he owns.

Here is an example of the issue:
Bob has collateral X in place and has 10 different debt positions (he borrowed).
With the newly acquired borrow tokens he buys 10 different credit positions.

Some time passes and his collateral value drops significantly (volatile market), his CR is below the healthy threshold. At the moment Bob does not have any more borrow tokens available but he has 10 healthy credit positions that he can use to improve his CR by compensating some of his lenders.

Here comes the important part.

He can successfully compensate 1 of his lenders if at the end of the compensate() tx his CR becomes healthy. The problem appears when he must compensate for 3 out of all 10 debt positions (more than 1 position) in order to become with healthy CR.

He will call compensate for the first time and the end of this tx he will face a revert due to this check because he needs to compensate 2 more times to become healthy.

Link to code: link

    function compensate(CompensateParams calldata params) external payable override(ISize) whenNotPaused {
        state.validateCompensate(params);
        state.executeCompensate(params);
@>      state.validateUserIsNotUnderwater(msg.sender);
    }

Link to code: link

    function isUserUnderwater(State storage state, address account) public view returns (bool) {
@>      return collateralRatio(state, account) < state.riskConfig.crLiquidation;
    }

    function validateUserIsNotUnderwater(State storage state, address account) external view {
@>      if (isUserUnderwater(state, account)) {
            revert Errors.USER_IS_UNDERWATER(account, collateralRatio(state, account));
        }
    }

The only option Bob has currently is to sell some of his credit positions via sellCreditMarket or sellCreditLimit. There might not be any buyers at the moment or he might be forced to take a very bad deal for his credit positions because he will be in a rush in order to repay part of his loans on time to not get liquidated.

Tools Used

Manual Review

Recommended Mitigation Steps

The CR check at the end of compensate is important because fragmentation fees could occur and lower the CR and make it under the healthy threshold in some specific situations.

What I propose as a solution is measuring the CR before and after the compensate() logic and it should revert if the CR is becoming worse.

This way Bob will be able to improve his CR by using his credit positions even if he has to compensate multiple times before becoming healthy again.

Assessed type

Other

@c4-bot-8 c4-bot-8 added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels Jul 2, 2024
c4-bot-6 added a commit that referenced this issue Jul 2, 2024
@c4-bot-12 c4-bot-12 added the 🤖_65_group AI based duplicate group recommendation label Jul 2, 2024
@c4-bot-13 c4-bot-13 added the 🤖_primary AI based primary recommendation label Jul 2, 2024
@howlbot-integration howlbot-integration bot added primary issue Highest quality submission among a set of duplicates sufficient quality report This report is of sufficient quality labels Jul 4, 2024
@aviggiano aviggiano added the sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") label Jul 4, 2024
@aviggiano
Copy link

Fixed in SizeCredit/size-solidity#129

@hansfriese
Copy link

Nice recommendation!

@c4-judge c4-judge added the satisfactory satisfies C4 submission criteria; eligible for awards label Jul 10, 2024
@c4-judge
Copy link
Contributor

hansfriese marked the issue as satisfactory

@c4-judge c4-judge added the selected for report This submission will be included/highlighted in the audit report label Jul 10, 2024
@c4-judge
Copy link
Contributor

hansfriese marked the issue as selected for report

@hansfriese
Copy link

Hi @aviggiano
I want to hear your feedback on this one of the validation repo.

@aviggiano
Copy link

Responded there

@C4-Staff C4-Staff added the M-09 label Jul 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working edited-by-warden M-09 primary issue Highest quality submission among a set of duplicates 🤖_primary AI based primary recommendation 🤖_65_group AI based duplicate group recommendation satisfactory satisfies C4 submission criteria; eligible for awards selected for report This submission will be included/highlighted in the audit report sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") sufficient quality report This report is of sufficient quality
Projects
None yet
Development

No branches or pull requests

8 participants