Assessment reports>Resonate>Low findings>Inconsistent interest calculations in Resonate
Category: Business Logic

Inconsistent interest calculations in Resonate

Low Severity
Low Impact
Low Likelihood

Description

In order to convert from the amount of underlying assets to shares, claimInterest uses previewWithdraw(...):

function previewWithdraw(uint256 assets)
    public
    view
    override
    returns (uint256)
{
    return convertToShares(assets);
}
[...]
function convertToShares(uint256 assets)
    public
    view
    override
    returns (uint256)
{
    return (assets * yVault.totalSupply()) / getFreeFunds();
}

However, batchClaimInterest uses the following to convert from assets to shares:

uint shareNormalization = vault.totalSupply() * PRECISION / vault.totalAssets();
[...]
uint totalSharesUnderlying = shareNormalization * amountUnderlying / PRECISION;

When interacting with the yearn vault, this results in a difference in interest calculations between the two functions - claimInterest(...) uses getFreeFunds() in the divisor while batchClaimInterest uses vault.totalAssets();.

Impact

The interest calculation of batchClaimInterest would be inflated over claimInterest by the difference in denominator in the asset-to-share conversion.

Recommendations

The difference is probably not intended by developers. It would be better to leverage composability and to use previewWithdraw(...) in batchClaimInterest. This would ensure batchClaimInterest is consistent with claimInterest across the different adapter implementations.

Remediation

Revest has followed the recommendation and is using previewWithdraw(...) in commit da89259c00235fdab7edbcb638ec04f3e360ef48.

Zellic © 2024Back to top ↑