58703 sc insight cached interest rate calculation in peapodseth strategy leads to inaccurate apr apy estimates
Submitted on Nov 4th 2025 at 06:37:48 UTC by @dobrevaleri for Audit Comp | Alchemix V3
Report ID: #58703
Report Type: Smart Contract
Report severity: Insight
Target: https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/strategies/mainnet/PeapodsETH.sol
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
Brief/Intro
The PeapodsETHStrategy uses Peapods vault's convertToAssets() function to calculate base rates per second for APR/APY estimation. However, this function relies on cached total assets values, while previewRedeem() provides more accurate estimates by simulating interest accrual. This discrepancy leads to consistently inaccurate yield calculations.
Vulnerability Details
The root cause lies in the PeapodsETHStrategy::_computeBaseRatePerSecond() function's reliance on cached interest rate data. The strategy calculates the price per share (PPS) using:
function _computeBaseRatePerSecond() internal override returns (uint256 ratePerSec, uint256 newIndex) {
uint256 dt = lastSnapshotTime == 0 ? 0 : block.timestamp - lastSnapshotTime;
@> uint256 currentPPS = vault.convertToAssets(1e18);
newIndex = currentPPS;
if (lastIndex == 0 || dt == 0 || currentPPS <= lastIndex) return (0, newIndex);
uint256 growth = (currentPPS - lastIndex) * FIXED_POINT_SCALAR / lastIndex;
ratePerSec = growth / dt;
return (ratePerSec, newIndex);
}According to the Peapods vault implementation, convertToAssets() uses a cached conversion rate (_cbr()) with cached _totalAssets, while previewRedeem() uses _previewCbr() which simulates interest accrual to provide current, accurate conversion rates.
The issue affects the entire yield calculation chain:
_computeBaseRatePerSecond()returns inaccurate rates due to stale datasnapshotYield()uses these rates to calculate APR:uint256 apr = totalRatePerSec * SECONDS_PER_YEARAPY calculations via
_approxAPY()compound the inaccuracyThese estimates are smoothed and stored in
estAprandestApystate variables
The same issue affects the realAssets() function:
Impact Details
The strategy's estApr and estApy values will not reflect the actual current yield performance.
References
https://github.com/peapodsfinance/contracts/blob/main/contracts/LendingAssetVault.sol
Proof of Concept
Proof of Concept
Was this helpful?