Skip to content

Add incident exposure reviews for Rhea and SWEAT exploits#424

Open
royalf00l wants to merge 2 commits into
devfrom
claude/audit-notes-exploits-2026-04
Open

Add incident exposure reviews for Rhea and SWEAT exploits#424
royalf00l wants to merge 2 commits into
devfrom
claude/audit-notes-exploits-2026-04

Conversation

@royalf00l

@royalf00l royalf00l commented Apr 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add two audit documents analyzing recent protocol exploits (Rhea Finance margin-trading and SWEAT lockup drains) and confirming that Templar's architecture and implementation are not vulnerable to the same attack classes.

Changes

  • audits/2026-04-29/rhea-exploit-analysis.md — Analysis of the Rhea Finance (Burrow) $18.4M margin-trading exploit

    • Documents the root cause: slippage validation that incorrectly aggregates min_amount_out across multi-hop swaps when tokens are reused in the route
    • Maps the attack surface (margin trading, multi-step swap routing, shared pool architecture) to Templar's design
    • Confirms Templar is safe via isolated markets, no margin/swap-routing surface, single-step slippage checks, and fixed asset whitelists on FT receivers
  • audits/2026-04-29/sweat-exploit-analysis.md — Analysis of the SWEAT lockup drain (~13.71B SWEAT, ~65% of supply)

    • Identifies the likely root cause as a privileged hot-key compromise exploited via unprotected update_contract
    • Documents secondary issues: hardcoded editable accounts, untimelocked admin paths, and an unprotected callback surface
    • Confirms Templar is safe via #[private] on all callbacks, predecessor validation on FT receivers, no admin paths that move user funds, and timelocked governance for sensitive operations

Notable Details

Both analyses are marked "review only — no code change required" and serve as incident exposure documentation rather than bug reports. They establish that Templar's isolated-market design, lack of leverage/swap-routing features, and timelocked governance structurally prevent the attack classes that affected Rhea and SWEAT.

https://claude.ai/code/session_01WWkR2nd7eL9PsjhsjgdNte


This change is Reviewable

claude added 2 commits April 29, 2026 16:13
Adds two notes under audits/2026-04-29/:

- sweat-exploit-analysis.md: reviews the 2026-04-29 hodl-lockup.sweat drain
  (~13.71B SWEAT). The on-disk sweatco/hodl-lockup source has several
  privileged paths (edit, terminate, update_contract) gated by a single hot
  key with no timelock — most likely root cause is a manager / deposit
  whitelist key compromise. Templar's analogous surfaces are protected by
  #[private] callbacks, predecessor-checked FT receivers, role-based auth
  with a timelocked governance state machine, no admin path that can move
  user funds, and registry-based code deploys.

- rhea-exploit-analysis.md: reviews the 2026-04-16 Rhea/Burrow margin
  exploit (~\$18.4M). Buggy code is in
  burrowland/contracts/contract/src/margin_trading.rs:86-113
  (RefV1TokenReceiverMessage::get_token_in/get_token_out) — slippage check
  sums amount_in / min_amount_out across every action whose token name
  matches, ignoring intermediate token reuse, so multi-hop routes through
  attacker-controlled fake Ref pools bypass slippage. Templar has no margin
  trading, no multi-hop swap routing, no DEX integration that consumes
  user-supplied action chains; slippage checks are single-step against
  convert_to_shares / convert_to_assets in the vault kernel.

Notes only — no code change.
Adds a section to the Rhea exploit note explaining that the Burrow contract
co-mingles every asset and every user (and every margin position) in shared
maps inside a single Contract, so a slippage-validation bug in the margin
subsystem drained the protocol's shared reserve pool.

Templar is structured the opposite way: each lending market is its own
deployed contract (registry creates a fresh subaccount) with exactly one
borrow asset and one collateral asset (rejected if equal). The vault is a
separate contract on top with a single underlying, and exposes user
deposits to markets only via per-market caps set through timelocked
governance. A hypothetical comparable bug in one market is bounded to that
market's TVL.

Includes a new conclusion bullet for isolated markets and another for the
vault's capped, curator-set market exposure.

Notes only — no code change.
@coderabbitai

coderabbitai Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Incident Exposure Reviews: Rhea and SWEAT Exploits

This PR adds two audit-only documents (no code changes) analyzing recent protocol incidents on NEAR and confirming Templar's resilience to these attack classes.

Rhea Finance Exploit Analysis (rhea-exploit-analysis.md)

Documents a ~$18.4M margin-trading exploit targeting Burrow's slippage validation, which incorrectly aggregated min_amount_out across multi-hop swaps when tokens were reused in routes. The analysis maps Burrow's shared-pool architecture (all users/assets in one contract) against Templar's isolated-market design, concluding Templar is safe via:

  • Per-market isolated contracts (each with its own borrow/collateral pair)
  • No margin trading or user-supplied swap routing surfaces
  • Single-step slippage checks (not aggregating across actions)
  • Fixed FT receiver asset whitelists via predecessor validation

SWEAT Lockup Exploit Analysis (sweat-exploit-analysis.md)

Documents a ~13.71B SWEAT drain (~65% of supply) via likely privileged key compromise, exploited through unprotected admin paths (update_contract, edit, terminate) lacking timelocks or multisig gates. The analysis concludes Templar is safe via:

  • All callbacks marked #[private]
  • Strict predecessor validation on FT receivers
  • No admin paths that redirect user funds (skim explicitly excludes underlying/share tokens)
  • Timelocked governance with role-based auth for sensitive operations

Critical aspects for human review:

  1. Timelock configuration weakness: Both audits claim "timelocked governance prevents admin abuse," but MIN_TIMELOCK_NS = 0 (defined in common/src/vault/params.rs:6) allows timelock duration to be set to zero nanoseconds, rendering timelocking ineffective if misconfigured in deployment. The audit should explicitly state the required minimum timelock duration expected in production and verify that governance initialization enforces a non-zero value.

  2. Exposed callback entrypoint: The audit claims update_idle_balance is "not exposed as a contract entrypoint" because it's in a non-#[near] impl block. However, verification shows it is in the #[near] impl Contract block (verified via sed output showing it's within the block that starts with #[near]). This function is a public entrypoint, though it only accepts IdleBalanceDelta and appears to be called internally. The audit's claim is inaccurate; either the function should be #[private] or the analysis should explain why it's safe for external callers.

  3. Slippage aggregation claim needs refinement: The audit correctly identifies that Templar avoids the Rhea vulnerability through single-step checks. However, the kernel's apply_action abstraction should be audited to confirm it doesn't introduce similar token-reuse pitfalls in its action composition logic.

  4. Market isolation verification: The analysis correctly notes market isolation via format!("{name}.{registry_account}") subaccounts. However, confirm that is_sub_account_of() validation in registry deployment prevents attackers from creating markets at sibling accounts (e.g., market.attacker.registry under a shared parent).

  5. Governance role enforcement: Nine require_* checks exist in governance.rs, but spot-check that every privileged function (set_fees, set_sentinel, set_curator, etc.) invokes the appropriate one before state mutations.

Walkthrough

Two new audit analysis documents are added to the repository for the Rhea and Sweat exploit incidents dated 2026-04-29. Both documents map identified vulnerabilities from external protocols to Templar's architecture and conclude that no code changes are required based on existing security measures.

Changes

Cohort / File(s) Summary
Audit Analysis Documents
audits/2026-04-29/rhea-exploit-analysis.md, audits/2026-04-29/sweat-exploit-analysis.md
New incident documentation analyzing Rhea token slippage aggregation bug and Sweat admin entrypoint authorization vulnerabilities, mapping each to Templar's architecture and confirming existing protections address identified attack surfaces. No code changes required.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding incident exposure reviews for Rhea and SWEAT exploits.
Description check ✅ Passed The description provides comprehensive context about both audit documents, their findings, and how Templar's architecture mitigates the identified risks.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/audit-notes-exploits-2026-04

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • LINEAR integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.

Review rate limit: 4/5 reviews remaining, refill in 12 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

@royalf00l

Copy link
Copy Markdown
Collaborator Author

for posterity. No need to actually merge

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@audits/2026-04-29/rhea-exploit-analysis.md`:
- Line 13: The document currently cites mutable repo paths and path:line
references; update every external/internal code citation in
audits/2026-04-29/rhea-exploit-analysis.md to use commit-pinned permalinks
(exact SHA commit URLs) for github.com/rhea-finance/burrowland and
github.com/ref-finance/burrowland and any other repo cited, replacing path:line
links with the corresponding blob/commit SHA permalinks; follow a consistent
pattern (e.g.,
https://github.com/<org>/<repo>/blob/<commit-sha>/<path>#Lstart-Lend), add a
short "Sources / SHAs" section enumerating each repo + commit SHA used, and
ensure every existing inline code reference and quoted snippet links to the
exact commit so future line drift cannot invalidate the analysis.

In `@audits/2026-04-29/sweat-exploit-analysis.md`:
- Around line 15-16: Replace any mutable "path:line" references with
commit-pinned permalinks to the exact commits for both the SWEAT repo
(github.com/sweatco/hodl-lockup — reference the commit that matches Cargo.toml:
name "hodl-lockup", version "1.1.0") and the Templar source; update every
instance where you currently cite file:line (including the places around the
Cargo.toml mention and the two later citations) so each link points to the
specific commit SHA permalink on GitHub and include the file path within that
commit to preserve forensic reliability.
- Around line 26-31: Add blank lines immediately before the opening ```rust
fence and after the closing ``` fence surrounding the EDITABLE_ACCOUNTS const
block so the fenced code block has a blank line above and below (fixing MD031);
locate the block containing the symbol EDITABLE_ACCOUNTS and insert a single
empty line above the ```rust line and a single empty line after the closing ```
to satisfy markdownlint.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f9e4a7d2-3c14-4de4-9f4c-5a576bdf09e5

📥 Commits

Reviewing files that changed from the base of the PR and between 32206c0 and 06e9c5f.

📒 Files selected for processing (2)
  • audits/2026-04-29/rhea-exploit-analysis.md
  • audits/2026-04-29/sweat-exploit-analysis.md


## Investigation constraints

External writeups (Halborn, Phemex, AMBCrypto, TechFlowPost, Rhea's own X post) all return 403 from this sandbox's egress proxy; I could only fetch GitHub. The analysis below is therefore based on direct review of the deployed Burrow source at `github.com/rhea-finance/burrowland` (mirrored at `github.com/ref-finance/burrowland`) cross-referenced against the publicly reported root cause: "the slippage protection algorithm summed all `min_amount_out` values across swap actions and did not account for swap actions where the output token of one step is reused as the input of the next."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Use immutable evidence links for audit-grade reproducibility.

This note cites mutable path:line references and repository roots, but not commit-pinned permalinks. Please pin every external/internal code citation to exact SHAs so future line drift cannot invalidate the analysis or its “no code change” conclusion (Lines 13, 17-18, 56-57, 147-151, 168-170).

Proposed doc hardening pattern
- The buggy code is in `contracts/contract/src/margin_trading.rs`, in ...
+ The buggy code is in `contracts/contract/src/margin_trading.rs` at Burrow commit
+ `<sha>` (permalink: `https://github.com/<org>/<repo>/blob/<sha>/contracts/contract/src/margin_trading.rs#L86-L113`), in ...

- ... `contract/market/src/impl_token_receiver.rs:26-32` ...
+ ... `contract/market/src/impl_token_receiver.rs` at Templar commit `<templar_sha>`
+ (`https://github.com/<org>/<repo>/blob/<templar_sha>/contract/market/src/impl_token_receiver.rs#L26-L32`) ...

Also applies to: 17-18, 56-57, 147-151, 168-170

🧰 Tools
🪛 LanguageTool

[grammar] ~13-~13: Ensure spelling is correct
Context: ... ## Investigation constraints External writeups (Halborn, Phemex, AMBCrypto, TechFlowPo...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audits/2026-04-29/rhea-exploit-analysis.md` at line 13, The document
currently cites mutable repo paths and path:line references; update every
external/internal code citation in audits/2026-04-29/rhea-exploit-analysis.md to
use commit-pinned permalinks (exact SHA commit URLs) for
github.com/rhea-finance/burrowland and github.com/ref-finance/burrowland and any
other repo cited, replacing path:line links with the corresponding blob/commit
SHA permalinks; follow a consistent pattern (e.g.,
https://github.com/<org>/<repo>/blob/<commit-sha>/<path>#Lstart-Lend), add a
short "Sources / SHAs" section enumerating each repo + commit SHA used, and
ensure every existing inline code reference and quoted snippet links to the
exact commit so future line drift cannot invalidate the analysis.

Comment on lines +15 to +16
Instead we reviewed the deployed contract source from `github.com/sweatco/hodl-lockup` (`Cargo.toml` matches: `name = "hodl-lockup"`, `version = "1.1.0"`, `authors = ["Sweat Economy"]`).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Pin references to exact commits for forensic reliability.

The document makes high-confidence security claims but cites mutable path:line references. Please add commit-pinned permalinks (both SWEAT source and Templar source) so readers can independently verify claims later without line-drift ambiguity (Lines 15-16, 63-68, 70-71).

Also applies to: 63-68, 70-71

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audits/2026-04-29/sweat-exploit-analysis.md` around lines 15 - 16, Replace
any mutable "path:line" references with commit-pinned permalinks to the exact
commits for both the SWEAT repo (github.com/sweatco/hodl-lockup — reference the
commit that matches Cargo.toml: name "hodl-lockup", version "1.1.0") and the
Templar source; update every instance where you currently cite file:line
(including the places around the Cargo.toml mention and the two later citations)
so each link points to the specific commit SHA permalink on GitHub and include
the file path within that commit to preserve forensic reliability.

Comment on lines +26 to +31
```rust
const EDITABLE_ACCOUNTS: &[&str] = &[
"baalhasulam5785.near",
"e8b49a44e01f2927638a9475e608089238de2befe98eae3807d0844724231b64",
];
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix fenced code spacing to satisfy markdownlint (MD031).

Add blank lines before and after the fenced block to avoid lint noise and keep docs CI-clean (Line 26 to Line 31).

Minimal markdown fix
    - Lets the caller overwrite `schedule` and `termination_config` for any lockup whose `account_id` matches the hardcoded `EDITABLE_ACCOUNTS` constant at `contract/src/lib.rs:54-57`:
+
      ```rust
      const EDITABLE_ACCOUNTS: &[&str] = &[
          "baalhasulam5785.near",
          "e8b49a44e01f2927638a9475e608089238de2befe98eae3807d0844724231b64",
      ];
      ```
+
    - The second entry has the same shape (64-hex-char implicit account) as the exploiter's address, suggesting the on-chain owner of one of those lockups is controlled by the attacker — overwriting the schedule to fully unlocked then calling `claim()` drains it.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```rust
const EDITABLE_ACCOUNTS: &[&str] = &[
"baalhasulam5785.near",
"e8b49a44e01f2927638a9475e608089238de2befe98eae3807d0844724231b64",
];
```
- Lets the caller overwrite `schedule` and `termination_config` for any lockup whose `account_id` matches the hardcoded `EDITABLE_ACCOUNTS` constant at `contract/src/lib.rs:54-57`:
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 26-26: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)


[warning] 31-31: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audits/2026-04-29/sweat-exploit-analysis.md` around lines 26 - 31, Add blank
lines immediately before the opening ```rust fence and after the closing ```
fence surrounding the EDITABLE_ACCOUNTS const block so the fenced code block has
a blank line above and below (fixing MD031); locate the block containing the
symbol EDITABLE_ACCOUNTS and insert a single empty line above the ```rust line
and a single empty line after the closing ``` to satisfy markdownlint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants