Releases: coinlive-apyee/apyee-protocol
Release list
v2.1.3 — Soken remediation-review residuals (APY-2026-06-002 follow-up)
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.
Audit Reports
v2.1.2 — Soken round-2 remediation (APY-2026-06-002)
Round-2 audit response for Soken APY-2026-06-002 (V2.1.1 review, verdict REVIEW 78/100 with 25 new findings + 8 pre-release recommendations). All 8 recommendations addressed plus one self-identified post-submission fix (fix #9). Round-1 findings (16 total) remain fully mitigated.
What's fixed
Soken 8 pre-release recommendations
- On-chain Chainlink
minOutfloor (F-04-MEV.1, N-03) —_computeMinOutFloorderives a fair-price minimum from Chainlink (preferred) or Owner-set fallback (long-tail tokens), reduced by per-token slippage (default 5%,MAX_SLIPPAGE_BPS_CAP = 10%). - Intermediate-hop whitelist (F-04-MEV.2, N-01, N-SP-01) — Owner-managed
allowedHopToken;_validateSwapPathiterates middle hops and revertsHopTokenNotWhitelisted. - Pause propagation (N-02) —
whenVaultNotPausedmodifier on all 5 concreteclaimAndCompound. Userwithdrawremains pause-free (invariant unchanged). rewardToken == underlyingAssetskip-swap branch — replaces the priorAssetMismatchrevert with a direct_depositpath when the distributor pays yield in USDC.- Owner rescue helper —
sweepIdleAssetToVault(). Moves onlyunderlyingAsset; destination hardcoded tovault; reward / receipt tokens untouchable. via_ir = true(M-BUILD-1) —foundry.toml.- TRUST_MODEL documentation (F-04-MEV.4) —
docs/TRUST_MODEL.md§9 appended. Existing §1–§8 (V2.1 F-16 response) unchanged. - Constructor guards (R-01, R-02) —
dexRouterextcodesize > 0check;DEPLOY_CHAIN_IDimmutable +onlyDeployChainon every fund-moving external;DexRouterConfiguredevent.
Self-identified post-submission (informational)
- Accrue-aware view math (fix #9) — Vault.sol
_convertToAssets/_convertToSharesoverridden to include_pendingFeeShares()in the divisor. Fixes the observedERC4626ExceededMaxWithdrawrevert on frontend "MAX" buttons in the V2.1.1-dev vault (Arbitrum). Not part of Soken's original 8; natural extension of Soken F-01 (accrue-BEFORE-preview) from the transactional path to the view path. Transactional-path correctness preserved (no-op there). Seedocs/SOKEN_AUDIT.md§11.3.9.
Tests
- 40 new specs (36 for the 8 recommendations, 4 for fix #9).
npx hardhat teston this repo atv2.1.2: 143 passing / 9 pending / 0 regression.
Docs
docs/SOKEN_AUDIT.md§11 — V2.1.2 remediation full section including §11.3.9 fix #9.docs/TRUST_MODEL.md§9 — V2.1.2 additions.CHANGELOG.md— full V2.1.2 changelog entry with new Vault layer section.
Deployment status
V2.1.2 dev vault redeployment: pending (separate release track).
Verification
Reproduce with:
```
git clone https://github.com/coinlive-apyee/apyee-protocol.git
cd apyee-protocol
git checkout v2.1.2
npm install
npx hardhat test
```
Expected output: 143 passing, 9 pending, 0 failing.
V2.1.1 — F-04 follow-up: multi-hop swap path
V2.1.1 — Soken F-04 follow-up
Previous tag: v2.1.0 — initial Soken APY-2026-06-001 remediation (16 findings)
Why V2.1.1
V2.1.0 의 F-04 fix (reward claim + auto-compound) 가 single-hop UniV3 swap (exactInputSingle) 만 지원했습니다. Compound mainnet fork probe (2026-06-25) 에서 COMP/USDC direct pool 유동성 부족으로 swap revert 발생. 다른 reward 토큰 (MORPHO 등) 도 비슷한 한계 예상.
V2.1.1 에서 multi-hop path 지원으로 fix.
Change Summary
| 영역 | 변경 |
|---|---|
BaseStrategy._swapAndReinvest |
uint24 poolFee → bytes calldata swapPath. exactInput(path) 사용 |
_validateSwapPath (신규) |
length + endpoint binding (rewardToken → USDC) |
Errors.InvalidPath (신규) |
잘못된 path layout / endpoint 거부 |
5 strategy claimAndCompound |
poolFee → swapPath 시그니쳐 변경 |
hardhat.config.ts |
viaIR: true (FluidStrategy stack 회피) |
Test coverage
test/v2/Strategy.claim.fork.spec.ts— Compound real Ethereum fork, 3 cases (multi-hop COMP→WETH→USDC e2e)test/v2/Strategy.claim.spec.ts— 5 strategy mock unit, 11 cases (claim path + onlyKeeper + InvalidPath)- Full mapping:
docs/SOKEN_AUDIT.md§F-04 follow-up
Verification at this tag
npx hardhat compile— 47 Solidity files OKnpx hardhat test— 103 passingFORK=true npx hardhat test test/v2/Strategy.claim.fork.spec.ts— 3 passing
Migration
V2.1.0 으로 배포된 vault 는 함수 시그니쳐 변경으로 호출 불가 → 폐기. V2.1.1 의 prod 배포 사이클은 Soken remediation review 통과 후 별도 진행.
Status
Awaiting Soken remediation review against this tag. PR #3.
V2.1 — Soken Audit Remediation
V2.1 — Soken Audit Remediation
Audited V2.0: tag v2.0.0 · Audit report: Soken APY-2026-06-001 (2026-06-23)
Findings summary
| Severity | Count | Status |
|---|---|---|
| Critical | 1 | ✅ Fixed (F-17) |
| High | 0 | — |
| Medium | 2 | ✅ Fixed (F-01, F-02) |
| Low | 4 | ✅ Fixed (F-03, F-04, F-06, F-07) |
| Informational (code-change) | 5 | ✅ Fixed (F-05, F-15, F-16 docs, +X-listed) |
| Informational (acknowledged) | 4 | Documented as design tradeoffs |
| Total | 16 | 12 fixed + 4 acknowledged |
Full per-finding mapping (root cause → V2.1 fix → regression test): docs/SOKEN_AUDIT.md
Critical highlight — F-17
Soken's Foundry PoC reproduced a permanent vault brick: once totalSupply() returns to zero, the never-reset lastSharePrice baseline detonated the FeeTooHigh defensive guard on the next deposit and froze every entrypoint. Fixed in _accrue() + _withdraw(); the next deposit re-takes the lazy-init path and re-snaps the baseline cleanly.
Reproduced post-fix in test/v2/Vault.v21.spec.ts — test_f17_freshDepositAfterEmptyVault_doesNotBrick.
Verification at this tag
npx hardhat compile— 16 Solidity files OKnpx hardhat test— 92 passing (4 fork specs pending withoutFORK=true)npx hardhat test test/v2/Vault.v21.spec.ts— 14 V2.1-specific specs passingforge test --fuzz-runs 10000— 10 streaming-fee invariants × 10 000 iterations, zero failures
Status
Awaiting Soken remediation review against this tag. Production V2.0 contracts remain on-chain (immutable); V2.1 redeploy + voluntary V2.0 → V2.1 migration begins after the remediation review completes.
Commits
7f34422feat(v2.1): contracts — Soken APY-2026-06-001 remediation (9 findings)eacb892chore(v2.1): scripts — F-04g chain × strategy reward matrix + plumbinga30190atest(v2.1): hardhat V2.1 spec + sync existing V2 specs to new constructor sigs5e3bb50docs(v2.1): V2_DESIGN + TRUST_MODEL + SECURITY + new SOKEN_AUDIT — Soken remediation
Merged via PR #2.