Follow-up on Soken APY-2026-06-002 (V2.1.2 review, verdict PASS 88/100 with 2 Low + 5 Informational residuals). This tag applies the two actionable one-line fixes Soken recommended (§5.1 F-901 pre-existing hardening + §5.2 F-902 fix-#9 invariant restore), corrects two in-source comments (F-i04, F-i02), tightens TRUST_MODEL.md §9.2 (F-i01), and adds an ops runbook item for URD-expiry / chain-gated setters (F-903, F-i03).
Prod deployment posture: addendum received — Soken APY-2026-06-002-B (V2.1.3 residual-review, 2026-07-09, PASS 91/100, 0 new findings) extends APY-2026-06-002 to cover this tag. Prod deployed 2026-07-13 across 4 chains (5 vaults); Owner transferred to Gnosis Safe multi-sig 0xEC4d3B6a...A98e (2/3 threshold). Prior v2.0.0 vaults retired.
What's fixed
Code (2 items)
- Vault.sol F-902 —
_convertToAssets/_convertToSharesoverrides now gate the pending term onlastAccruedAt == block.timestamp. Restores the bit-identical invariant on the transactional path stated in v2.1.2 §11.3.9: inside the same-block window (accrue → donate → previewDeposit) the pending term is forced to 0, so the override yields base-OZ math exactly. Outside the same-block window the override remains accrue-aware — fix #9's original frontendmaxWithdrawMAX behaviour is unchanged. - Vault.sol F-901 —
whenNotPausedadded toinvestToStrategy(single chokepoint). Guardian pause now closes the last principal-in path.divestFromStrategy,emergencyWithdraw, and userwithdrawintentionally remain pause-free (§6 core invariant unchanged).
Comments / docs (5 items)
- BaseStrategy.sol F-i04 —
setRewardFallbackPricedoc-comment now correctly states deflation disables the floor (theft vector). Inflation only raises the floor (liveness DoS). - BaseStrategy.sol F-i02 —
_computeMinOutFloordoc notes (i) dust-amountIntruncation for high-decimal rewards vs. 6-dp USDC, and (ii) implicit USDC = $1 pricing assumption. - docs/TRUST_MODEL.md §9.2 F-i01 — floor framing tightened: Chainlink-strong for feed-backed reward tokens, Owner-trust for feed-less (FLUID / KINZA / SPK) with explicit deflate-direction attack path.
- apyee-docs SERVER_KEEPER_CLAIM.md §11.2 F-903 — new ops runbook: Morpho URD campaign expiry monitoring + fallback-price freshness for feed-less tokens (stale price near URD deadline can hard-DoS the claim).
- apyee-docs SERVER_KEEPER_CLAIM.md §11.2 F-i03 — reminder that Owner config setters (
setRewardPriceFeed/setRewardFallbackPrice/setRewardMaxSlippage/setAllowedHopToken) are intentionally notonlyDeployChain; multi-sig signers must confirm chainId in the UI.
Tests
test/v2/Vault.v213.spec.ts— 6 new specs, all pass:test_f902_sameBlockAccrueLatch_pendingIsZeroInsidePreview(reproduces Soken's PoC viaevm_setAutomine, assertsconvertToShares == baseOZinside the latch window)test_f902_multiBlock_pendingContinuesToBeReflectedInViews(regression guard)test_f901_investToStrategy_whenPaused_revertstest_f901_investToStrategy_whenUnpaused_succeedstest_f901_divestFromStrategy_whenPaused_stillSucceeds(invariant)test_f901_userWithdraw_whenPaused_stillSucceeds(invariant)
npx hardhat teston this repo atv2.1.3: 149 passing / 9 pending / 0 failing (was 143 → +6).
No change to
- External interfaces / ABI shape / storage layout / cap parameters / audited-scope file set
- Round-1 (16) and round-2 (25) findings remain fully mitigated
- Zero regressions
Verification
git clone https://github.com/coinlive-apyee/apyee-protocol.git
cd apyee-protocol
git checkout v2.1.3
npm install
npx hardhat test
Expected: 149 passing / 9 pending / 0 failing.