Assessment reports>Voyage>High findings>Buyers make first interest payment twice
Category: Business Logic

Buyers make first interest payment twice

High Severity
High Impact
High Likelihood

Description

Callers of buyNow(...) will always pay the first interest payment twice.

The first time happens when they pay the down payment—they can pay it in either ETH or WETH.

The down payment is equal to params.downpayment = params.pmt.pmt where pmt is given by

function calculatePMT(Loan storage loan)
    internal
    view
    returns (PMT memory)
{
    PMT memory pmt;
    pmt.principal = loan.principal / loan.nper;
    pmt.interest = loan.interest / loan.nper;
    pmt.pmt = pmt.principal + pmt.interest;
    return pmt;
}

The second time happens when distributeInterest(...) is called:

LibLoan.distributeInterest(
    reserveData,
    params.pmt.interest,
    _msgSender()
);

This pulls the same amount, but only WETH, directly from the buyer.

Impact

Users will be discouraged from using the protocol due to the extra large payment arising from high interest rates.

Recommendations

Remove the interest component from the down payment.

Remediation

Commit 3320ba3c was indicated as containing the remediation for this issue. The params.downpayment variable is now set to params.pmt.principal instead of params.pmt.pmt, meaning it will contain the value corresponding to the principal (without interest) of a single installment.

We note that a total of 29 commits exist between the commit under review and 3320ba3c; the diff between the two commits amounts to 24 solidity files changed, with 324 insertions and 525 deletions, containing other potentially relevant changes.

Zellic © 2024Back to top ↑