Ethereum Credit Guild - glorySec's results

A trust minimized pooled lending protocol.

General Information

Platform: Code4rena

Start Date: 11/12/2023

Pot Size: $90,500 USDC

Total HM: 29

Participants: 127

Period: 17 days

Judge: TrungOre

Total Solo HM: 4

Id: 310

League: ETH

Ethereum Credit Guild

Findings Distribution

Researcher Performance

Rank: 63/127

Findings: 1

Award: $196.26

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: sl1

Also found by: 0x70C9, 0xDemon, Aymen0909, Beepidibop, Tendency, carrotsmuggler, glorySec

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
sufficient quality report
duplicate-1057

Awards

196.2606 USDC - $196.26

External Links

Lines of code

https://github.com/volt-protocol/ethereum-credit-guild/blob/main/src/loan/LendingTerm.sol#L634-L675

Vulnerability details

Impact

There is no way to liquidate the loan for terms with no partial repayment (maxDelayBetweenPartialRepay = 0).

Hence, it results in either of two things:

  1. Bad debt is collected
  2. The term is offboarded resulting in healthy loans to get liquidated.

Proof of Concept

https://github.com/volt-protocol/ethereum-credit-guild/blob/main/src/loan/LendingTerm.sol#L634-L675

require( GuildToken(refs.guildToken).isDeprecatedGauge(address(this)) || partialRepayDelayPassed(loanId), "LendingTerm: cannot call" );

The call function only allows calling loans based on two conditions:

  1. The gauge has been deprecated (generally the case with off-boarding term)
  2. The delay after the last re-payment has passed maxDelayBetweenPartialRepay

But if the maxDelayBetweenPartialRepay is set to 0, the partialRepayDelayPassed function always returns false, which results in the call function getting reverted as well. https://github.com/volt-protocol/ethereum-credit-guild/blob/main/src/loan/LendingTerm.sol#L240-L241

function partialRepayDelayPassed( bytes32 loanId ) public view returns (bool) { // if no periodic partial repays are expected, always return false if (params.maxDelayBetweenPartialRepay == 0) return false; // if loan doesn't exist, return false if (loans[loanId].borrowTime == 0) return false; // if loan is closed, return false if (loans[loanId].closeTime != 0) return false; // return true if delay is passed return lastPartialRepay[loanId] < block.timestamp - params.maxDelayBetweenPartialRepay; }

Hence liquidation never happens for the loans in terms with maxDelayBetweenPartialRepay set to 0.

Tools Used

Manual

There should be a way to liquidate specific loans in terms where maxDelayBetweenPartialRepay is set to 0.

Assessed type

Other

#0 - c4-pre-sort

2024-01-02T12:11:10Z

0xSorryNotSorry marked the issue as sufficient quality report

#1 - c4-pre-sort

2024-01-02T12:11:20Z

0xSorryNotSorry marked the issue as duplicate of #1174

#2 - c4-pre-sort

2024-01-05T13:06:03Z

0xSorryNotSorry marked the issue as duplicate of #1057

#3 - c4-judge

2024-01-26T12:50:42Z

Trumpero marked the issue as satisfactory

#4 - c4-judge

2024-01-31T13:42:22Z

Trumpero changed the severity to 2 (Med Risk)

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter