Omniscia Euler Finance Audit
Cache Manual Review Findings
Cache Manual Review Findings
CEH-01M: Inexistent Upward-Rounding Operation of Total Borrows
Type | Severity | Location |
---|---|---|
Mathematical Operations | Cache.sol:L99 |
Description:
The share-based fee captured as part of a borrow interest update will calculate the shares to mint based on a newTotalAssets
evaluation that does not round the borrows upwards, resulting in an under-evaluation of the newTotalAssets
and thus an over-evaluation of the fees captured.
Impact:
Although the fees captured will be over-evaluated, the error by which this overvaluation will occur is small rendering this exhibit to be of minor severity.
Example:
98if (feeAssets != 0) {99 uint256 newTotalAssets = vaultCache.cash.toUint() + (newTotalBorrows >> INTERNAL_DEBT_PRECISION);100 newTotalShares = newTotalAssets * newTotalShares / (newTotalAssets - feeAssets);101 newAccumulatedFees += newTotalShares - vaultCache.totalShares.toUint();102 }103
104 // Store new values in vaultCache, only if no overflows will occur. Fees are not larger than total shares, since they are included in them.105
106 if (newTotalShares <= MAX_SANE_AMOUNT && newTotalBorrows <= MAX_SANE_DEBT_AMOUNT) {107 vaultCache.totalBorrows = newTotalBorrows.toOwed();108 vaultCache.interestAccumulator = newInterestAccumulator;109 vaultCache.lastInterestAccumulatorUpdate = uint48(block.timestamp);110
111 if (newTotalShares != Shares.unwrap(vaultCache.totalShares)) {112 vaultCache.accumulatedFees = newAccumulatedFees.toShares();113 vaultCache.totalShares = newTotalShares.toShares();114 }115 }116 }117}118
119function totalAssetsInternal(VaultCache memory vaultCache) internal pure returns (uint256) {120 // total assets can exceed Assets max amount (MAX_SANE_AMOUNT)121 return vaultCache.cash.toUint() + vaultCache.totalBorrows.toAssetsUp().toUint();122}
Recommendation:
We advise the newTotalAssets
calculation to properly use the Cache::totalAssetsInternal
function, ensuring that the total assets calculated properly represent the expected total assets after the interest rate update is reflected in the contract's storage.
Alleviation (fb2dd77a6ff9b7f710edb48e7eb5437e0db4fc1a):
The calculation will properly round upwards by using the newly introduced OwedLib::toAssetsUpUint256
function, alleviating this exhibit and ensuring consistency in the total asset evaluation across the system.
CEH-02M: Improper Interest Rate Update
Type | Severity | Location |
---|---|---|
Logical Fault | Cache.sol:L106-L115 |
Description:
In the current system, whether the interest rate update succeeds in the Cache::initVaultCache
function relies on whether the newTotalShares
and newTotalBorrows
variables can be represented in their respective types.
Impact:
In the low-likelihood scenario whereby the vaultCache.totalShares
value is very close to the MAX_SANE_AMOUNT
but the vaultCache.totalBorrows
value is relatively low, an interest rate update will be forfeited incorrectly. As the impact is high, we consider a medium-severity assessment as appropriate for this finding.
Example:
106if (newTotalShares <= MAX_SANE_AMOUNT && newTotalBorrows <= MAX_SANE_DEBT_AMOUNT) {107 vaultCache.totalBorrows = newTotalBorrows.toOwed();108 vaultCache.interestAccumulator = newInterestAccumulator;109 vaultCache.lastInterestAccumulatorUpdate = uint48(block.timestamp);110
111 if (newTotalShares != Shares.unwrap(vaultCache.totalShares)) {112 vaultCache.accumulatedFees = newAccumulatedFees.toShares();113 vaultCache.totalShares = newTotalShares.toShares();114 }115}
Recommendation:
We consider the current approach incorrect, as the total borrows and interest rate of the system should be updated distinctly from the fees permitting the system to accumulate interest on underlying borrows even if fees cannot be captured to increase the total share supply.
Alleviation (fb2dd77a6ff9b7f710edb48e7eb5437e0db4fc1a):
The code was updated to evaluate the borrow interest and accumulated fees updates distinctly, validating that the borrow interest rate can be applied at first and consequently evaluating whether fees can be safely accumulated.
As such, we consider this exhibit fully alleviated as a total borrow update taking precedence over a fee update is what we consider best practice.