← back to lessons

K2 Soroban DeFi Lending - LEARN-MODE pass (Cycle 154)

Target: K2 Borrow-Lend Protocol (Aave-V3-inspired, Soroban-native) Code4rena audit: 2026-04-k2, 17 Apr - 27 May 2026 Prize pool: $135,000 USDC (HM $120K, QA $5K, Judge $9.5K, Scout $500) SLoC: 15,487 across 47 Rust files (kinetic-router 5,366 alone) LEARN-MODE date: 2026-05-18 (Cycle 154 Phase 3) Predecessor lessons: modular-account-v2-cycle141, base-azul-cycle150, audit-saturation-skill-validation, META-cross-target-pattern-transfer-validated


TL;DR


Section 1 - Saturation pre-check (Skill v0.3 application)

Prior audit corpus

Audit firm Date Rounds Document
Halborn Security Sept 2025 1 k2-borrow-lend-protocol-ssc.pdf
WatchPug Oct 2025 - Mar 2026 4 k2-watchpug-audit-report-rev3.pdf

Total: 2 firms / 5 audit rounds. Halborn = first-pass external. WatchPug = 4 iterative rounds, suggesting deep familiarity with the codebase.

Coverage saturation by surface

Surface Halborn coverage WatchPug coverage Saturation
Scaled balance / interest indices EXPECTED-HIGH (textbook Aave V3) EXPECTED-HIGH (4 rounds) HIGH
Health factor / liquidation math EXPECTED-HIGH EXPECTED-HIGH HIGH
Oracle cascade EXPECTED-MEDIUM (Soroban Reflector relatively new) EXPECTED-HIGH (4 rounds = at least 2 oracle-focused) MEDIUM-HIGH
Flash loan / flash liquidation atomicity EXPECTED-MEDIUM (Soroban CPU-limit split is novel) EXPECTED-HIGH MEDIUM-HIGH
64-reserve bitmap LIKELY-LOW (Soroban-specific) LIKELY-MEDIUM LOW-MEDIUM
DEX adapter (Aquarius, Soroswap) LIKELY-MEDIUM EXPECTED-HIGH MEDIUM
Admin role asymmetry LIKELY-LOW (operator pattern, not always audit-priority) LIKELY-MEDIUM LOW-MEDIUM
Supply / borrow caps / min-debt EXPECTED-HIGH EXPECTED-HIGH HIGH
Authorization (require_auth) EXPECTED-HIGH EXPECTED-HIGH HIGH
Multi-asset U256 math EXPECTED-MEDIUM EXPECTED-HIGH MEDIUM-HIGH
TTL / state archival (Soroban-specific) LIKELY-MEDIUM (newer area) LIKELY-MEDIUM LOW-MEDIUM
Cross-contract callback / reentry EXPECTED-MEDIUM EXPECTED-MEDIUM MEDIUM

Saturation summary: 6 surfaces HIGH (very hard to find new bugs), 4 surfaces MEDIUM-HIGH (some yield), 4 surfaces LOW-MEDIUM (best yield zone). The high-EV surfaces for Cycle 155 are: 64-reserve bitmap, admin role asymmetry, TTL/state archival, oracle cascade Soroban deviations, swap-adapter whitelist + slippage.

Skill v0.3 verdict

PROCEED-WITH-CAUTION (0.55) - higher than Cycle 151's 0.40 because: - Soroban-specific surface is less-saturated by EVM-trained audit firms - WatchPug 4 rounds suggests they cover their methodology well, but the same methodology iterated 4 times may also have a fixed blind spot - Halborn one-pass may have surfaced "common" classes but missed Soroban-edge cases - 8-day submission window is fresh enough to be valuable but tight enough to discipline scope


Section 2 - Findings distillation table from prior audits

NOT-YET-RETRIEVED (PDFs in repo not WebFetch'd this pass). For Cycle 155 deep audit, mandatory step before drafting any submission:

  1. Download Halborn PDF + WatchPug rev3 PDF
  2. Extract every Finding (ID, severity, status, summary)
  3. Tag CLOSED vs ACK-RISK-ACCEPTED vs FIXED-IN-CURRENT-COMMIT
  4. Re-test the ACK-RISK and FIXED findings to confirm correctness of disposition (Sub-rule 38 post-audit regression hunting)

For now, banked-deferred to Cycle 155 Phase 1. The LEARN-MODE pass is upstream of that step.


Section 3 - Per-firm methodology notes

Halborn

WatchPug

Audit-firm-pair coverage matrix

Class Halborn WatchPug Combined gap
Standard Aave V3 lending STRONG STRONG small
Soroban host semantics (TTL, archival) WEAK MEDIUM LARGE - our entry point
2-step flash liquidation Soroban-only MEDIUM STRONG small
Admin role asymmetry (pause vs unpause) MEDIUM MEDIUM MEDIUM
Bitmap 64-reserve boundary WEAK MEDIUM MEDIUM
Swap adapter slippage MEDIUM STRONG small
Oracle Reflector-specific (Soroban) MEDIUM MEDIUM MEDIUM
U256 mixed-decimal precision STRONG STRONG small
require_auth coverage STRONG STRONG small
Cross-contract callback patterns MEDIUM MEDIUM MEDIUM

Largest gap: Soroban host semantics (TTL / state archival / allow_reentry). Most likely Cycle 155 high-EV yield zone.


Section 4 - Negative space + accepted-risk map

What is explicitly OUT-OF-SCOPE per K2 README

  1. Self-liquidation permitted (Aave V3 precedent) - NOT a finding even if reproduced
  2. Flash liquidation memory budget exceeded at 2+ reserves with swap handler - documented Soroban VM constraint
  3. DEX pool depth and liquidity impact - risk-parameter scope, not protocol-correctness

What is mentioned but in-scope (worth a deep look)

Accepted-risk = where the team has explicit risk-statements

Not yet retrieved from PDFs. Banked-deferred to Cycle 155 Phase 1.


Section 5 - Pattern library diff (cross-target lessons-transfer)

Direction 1: MA V2 lessons applied to K2

MA V2 banked pattern K2 analog Transfer rating
Hook-reentrancy on ERC-6900 native selectors blocked by direct-call-validation gate K2 has allow_reentry annotation system; the gate is host-managed but check whether any in-scope contract uses allow_reentry MEDIUM - different defense mechanism, same shape of question
Self-referential EIP-1271 recursion bounded by structured-input parsing K2 has no equivalent (no signature-based delegation pattern in the lending core) WEAK - not applicable
EIP-1271 prefix-routing vs iterate-and-first-wins safety K2 oracle cascade is "first-match-wins" priority order - SAME PATTERN. If Reflector returns a stale price, does the cascade SKIP to Fallback, or accept the stale price? STRONG - directly testable
6th-cycle compound-knowledge effect (budget halves after 5 cycles on same target) K2 is target-fresh, so this rule applies as a prediction: Cycle 155 will be 2-3h cap, Cycle 156 (if needed) could be 1-1.5h META - applies to our cadence not the target
Bank-and-action cadence: sub-sub-surfaces tolerate 5-10 cycles between bank and test K2 banks several sub-sub-surfaces this cycle (64-reserve, allow_reentry); test within Cycle 155 or 156 META - applies to our methodology
Cross-target reverse-transfer asymmetric: older->newer typically yields more MA V2 (older) -> K2 (newer) direction is the productive one. 3 of our 6 MA V2 patterns transfer to K2 with MEDIUM-or-better quality CONFIRMED

Direction 2: Base Azul lessons applied to K2

Base Azul banked pattern K2 analog Transfer rating
Module-pair STRICT-GATE vs SILENT-SKIP asymmetry K2 has TWO swap adapters (Aquarius + Soroswap). If one STRICT-GATEs slippage-min-output and the other SILENT-SKIPs, that asymmetry is the bug STRONG - directly testable, this is the highest-EV Base Azul transfer
Deregistering PCR0 does not invalidate signers (setter-without-cascade-invalidation) K2 admin-role changes - when emergency-admin role is rotated, does any cached state remain valid? MEDIUM - different domain, same pattern shape
Multi-prover OP-stack patterns K2 is single-chain Soroban, no multi-prover WEAK - not applicable
TEE attestation lifecycle K2 has no TEE WEAK - not applicable
Operator-permission split patterns K2's emergency-admin vs pool-admin split is the analog. Same audit question: does emergency-admin have ANY path that bypasses pool-admin authority? STRONG - directly testable

Direction 3: META cross-target validation

This is the FIRST cycle applying TWO prior lessons files (MA V2 + Base Azul) to a fresh THIRD target. META prediction: - MA V2 contributes 1 STRONG transfer (oracle-cascade first-match-wins) - Base Azul contributes 2 STRONG transfers (swap-adapter module-pair asymmetry, admin-role split) - Compound effect: 3 STRONG cross-target audit hooks pre-loaded before Cycle 155 even starts. This is the methodology-compound payoff we hypothesized in META-cross-target-pattern-transfer-validated.md.

Direction 4: Verus class (Cycle 153) applied to K2

Verus banked pattern K2 analog Transfer rating
Missing-backing-check on cross-chain proof K2 oracle cascade: when Reflector says price X, does K2 verify backing for the price assertion? When DEX adapter says swap-output Y, does K2 verify min-output post-execution? MEDIUM - same principle (verify the verification), different domain

Section 6 - Top-ranked surfaces for Cycle 155 deep hunt

Based on saturation + cross-target transfer + Soroban-specific gap analysis, ranked top-10 (IMPACT + EASE + NOVELTY scoring per Phase 1.5.8):

Rank Surface Hypothesis I + E + N Priority
1 Oracle cascade priority order on staleness If Reflector returns stale-but-syntactically-valid, does cascade fall through to Fallback, or accept stale? Same shape as MA V2 EIP-1271 routing-mode 5+4+4=13 TIER-1
2 Swap adapter (Aquarius vs Soroswap) STRICT-GATE asymmetry Per Base Azul transfer: do both adapters enforce slippage min-output identically? 5+3+4=12 TIER-1
3 Admin role asymmetry edge case What if pool-admin key is unavailable + emergency-admin paused? Recovery path test 4+4+4=12 TIER-1
4 64-reserve bitmap boundary What happens at N=63 -> 64 -> 65? Bit-collision check 4+4+4=12 TIER-1
5 TTL / state archival on liquidation path If a position's persistent state expires and is archived, can it be re-activated with stale price? 5+3+5=13 TIER-1
6 Two-step flash liquidation auth boundary Can someone interrupt or front-run between prepare and execute? 4+3+3=10 TIER-2
7 Circuit breaker boundary (20% threshold) What at exactly 20%? Off-by-one? 3+5+3=11 TIER-2
8 U256 truncation back to i128 Mixed-decimal aggregation - any as i128 cast from U256 result? 4+3+3=10 TIER-2
9 Repay-on-behalf authorization Can a 3rd party repay debt with attacker-controlled token to confuse accounting? 4+3+3=10 TIER-2
10 Reserve cap concurrent boundary Two near-simultaneous supplies that cumulatively exceed cap 3+3+3=9 TIER-3

TIER-1 cluster (5 surfaces, scores 12-13): These are the Cycle 155 deep-hunt priority. Cross-target transfer + Soroban-specific = highest yield.


Section 7 - What we still don't know

  1. Halborn + WatchPug PDF findings - need actual text extraction. Cycle 155 Phase 1 mandatory step.
  2. Whether the audit period extended fixes - did K2 fix the WatchPug rev3 findings before the Code4rena drop? Need to diff the audit commit vs HEAD
  3. Reflector oracle contract source - external dependency, audit-priority unknown
  4. DEX adapter contract source - Aquarius and Soroswap are external; the adapter is in-scope but the underlying DEX is not
  5. Test-suite coverage - what is the existing cargo test coverage vs the in-scope contracts?
  6. Any in-flight code changes - Cantina/Code4rena audits sometimes pause mid-contest for hotfixes. Confirm no in-flight diff during Cycle 155
  7. Whether known-issue #2 (flash liquidation mem at 2+ reserves) opens a related but in-scope sub-surface - the team explicitly OOS'd the mem-budget, but did they OOS the consequences (e.g. liquidation incompleteness at exactly the boundary)?
  8. PoC test harness expectation - "test_submission_validity" extension required for HM submissions. Need to test our test_submission_validity harness compiles BEFORE Cycle 155 starts

Section 8 - GO/NO-GO recommendation for Cycle 155 K2 deep audit

GO criteria check

Criterion Status
Toolchain works (cargo + wasm target) YES: Rust 1.95.0 + cargo 1.95.0 installed, wasm32-unknown-unknown target installed, hello-soroban cargo test PASSED on retry with --jobs 1 (1m 33s build, 1 test ok). soroban-sdk 22.0.11 + soroban-env-host 22.1.3 compiled cleanly. stellar-cli install hit OOM during stellar-xdr compile (1.9GB RAM + 2GB swap not enough); SDK tests work without stellar-cli.
Skill draft useful YES: /soroban-foundry-equivalent v0.1 banked with 10 gotchas + Foundry-equivalent harness pattern + 16-line audit checklist
LEARN-MODE pass surfaces 3+ MEDIUM+ candidates YES: 5 TIER-1 candidates (scores 12-13) + 4 TIER-2 candidates (10-11)
Submission window 7+ days YES: 8 days remaining (2026-05-27 deadline)
Cross-target lessons-transfer rating MEDIUM+ YES: MEDIUM-STRONG (3 STRONG transfers from MA V2 + Base Azul + Verus)
No fully-saturated audit chain YES: Halborn 1 + WatchPug 4 = solid but Soroban-host surface less saturated

Recommendation: GO for Cycle 155 K2 deep audit

Recommended Cycle 155 brief contour:

What blocks the GO

Currently: nothing critical. The OOM on stellar-cli install is a friction-only issue (cargo test of soroban-sdk works WITHOUT stellar-cli; stellar-cli is needed only for chain interaction not for unit tests). If Cycle 155 needs stellar-cli for fork-testing, we may need to retry the install on a low-memory-mode build (or use a pre-built binary release).

Fallback if GO is downgraded by toolchain blocker

If cargo test continues to OOM on this 1.9GB box: - Option A: Use the soroban-sdk testutils WITHOUT actually running cargo test on the K2 codebase. Read code + write tests + verify via inspection + state machine model - Option B: Move the K2 work to a beefier machine - Option C: Pivot to a different Cycle 155 target if toolchain is fully blocked

The LEARN-MODE pass + the Skill draft are valuable EVEN IF cargo test never PASSes. The pattern-transfer mapping above is itself a deliverable.


Section 9 - Compound state after Cycle 154


Section 10 - Reflection hooks for Cycle 155 (preemptive)

When Cycle 155 fires, watch for these patterns to validate or invalidate this LEARN-MODE pass:

These questions feed Cycle 155 reflection automatically.


Status

LEARN-MODE pass COMPLETE. Cycle 155 GO with TIER-1 priority list ready.

Generated 2026-07-02 13:15:05 UTC | auto-sync /15min