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

Reentrancy in _close() #337

Closed
code423n4 opened this issue Nov 10, 2022 · 3 comments
Closed

Reentrancy in _close() #337

code423n4 opened this issue Nov 10, 2022 · 3 comments
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 downgraded by judge Judge downgraded the risk level of this issue duplicate-176 satisfactory Finding meets requirement

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/debtdao/Line-of-Credit/blob/e8aa08b44f6132a5ed901f8daa231700c5afeb3a/contracts/modules/credit/LineOfCredit.sol#L483-L507

Vulnerability details

Impact

The contract fund could be drained due to reentrancy possibility in _close().

Proof of Concept

In _close() the token transfer happens before the storage state change of ids. Hence, reentrancy is possible, as long as the token has the callback hook. For example, some ERC777 token, or even existing token could have this feature after upgrade.

// Line-of-Credit/contracts/modules/credit/LineOfCredit.sol
    function _close(Credit memory credit, bytes32 id) internal virtual returns (bool) {
        if(credit.principal > 0) { revert CloseFailedWithPrincipal(); }

        // return the Lender's funds that are being repaid
        if (credit.deposit + credit.interestRepaid > 0) {
            LineLib.sendOutTokenOrETH(
                credit.token,
                credit.lender,
                credit.deposit + credit.interestRepaid
            );
        }

        delete credits[id]; // gas refunds

        // remove from active list
        ids.removePosition(id);
        unchecked { --count; }

        // ...
    }

A malicious lender can call close(id) and reenter to drain the fund, or can use another address as the borrower to call depositAndClose() to do similar thing.

Tools Used

Manual analysis.

Recommended Mitigation Steps

For the _close() function:

  • add nonReentrant modifier
  • follow check-effects-interaction pattern
@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Nov 10, 2022
code423n4 added a commit that referenced this issue Nov 10, 2022
@c4-judge
Copy link
Contributor

dmvt marked the issue as duplicate of #176

@c4-judge
Copy link
Contributor

dmvt changed the severity to 2 (Med Risk)

@c4-judge c4-judge added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value downgraded by judge Judge downgraded the risk level of this issue and removed 3 (High Risk) Assets can be stolen/lost/compromised directly labels Nov 17, 2022
@c4-judge
Copy link
Contributor

c4-judge commented Dec 6, 2022

dmvt marked the issue as satisfactory

@c4-judge c4-judge added the satisfactory Finding meets requirement label Dec 6, 2022
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 downgraded by judge Judge downgraded the risk level of this issue duplicate-176 satisfactory Finding meets requirement
Projects
None yet
Development

No branches or pull requests

2 participants