OAK — OnChain Attack Knowledge

Worked example · 2023-04

Sentiment Protocol read-only reentrancy via Balancer LP integration — Arbitrum — 2023-04-04

Loss
approximately $1M extracted from Sentiment Protocol on Arbitrum on 2023-04-04 via a read-only reentrancy against Sentiment's Balancer LP-token oracle integration. Sentiment was a permissionless margin / under-collateralised lending protocol on Arbitrum; the affected surface was the LP-token-collateral pricing pathway used to mark Balancer LP positions held as collateral by Sentiment's borrower accounts.
Recovery
near-total. Within roughly 24 hours of the exploit, the attacker negotiated a return via on-chain messages and Sentiment's public outreach. The attacker accepted a 5\% bug-bounty-style retention and returned the remaining ~95\%; Sentiment's public statements and industry coverage from BlockSec, PeckShield, and Halborn converged on ~$1M extracted with ~$905K returned. The recovery is the structurally interesting feature alongside the Technique classification.
OAK Techniques observed
OAK-T9.005 (Smart-Contract Exploit) in the read-only reentrancy sub-class — the canonical 2022–2023 example pattern in which an attacker reenters a view function on an integrated protocol mid-state-transition to obtain a stale or manipulated price reading, without needing to write to the integrated protocol's state. OAK-T9.002 (Flash-Loan-Enabled Exploit) as the working-capital precondition that scaled the per-iteration favorable mispricing to ~$1M in a single transaction window + OAK-T9.010 (Read-Only Reentrancy).
Attribution
pseudonymous. The attacker self-identified only via on-chain message during the recovery-negotiation channel and accepted a bounty-retention framing; no public named-individual attribution. The on-chain forensics chain is detailed but has not been converted to a public confirmed attribution.
Key teaching point
read-only reentrancy is reentrancy through integrated protocols' view functions, and oracle-priced integrations of complex AMM LP positions are the canonical surface. Sentiment is the canonical 2023 worked example for the read-only reentrancy via Balancer LP-token oracle sub-pattern; the dRome / Curve incident family in subsequent months extended the same pattern across Curve LP integrations. Contributors writing T9.005 sub-class taxonomy should treat read-only reentrancy as a first-class sub-class distinct from the canonical 2016 DAO write-side reentrancy.

Summary

Sentiment Protocol operated on Arbitrum as a permissionless under-collateralised lending platform. Borrowers could deposit collateral — including Balancer LP tokens — into Sentiment-controlled accounts and borrow against the marked value of that collateral. The marking was performed by an oracle pathway that, for Balancer LP collateral, queried a Balancer pool view function to derive an LP-token price.

The vulnerability sits at the boundary between Sentiment's oracle pathway and Balancer's pool-state mechanics. During a Balancer pool operation that involves an internal joinPool / exitPool callback to a Vault hook, the pool's externally-visible view function returned a price that was inconsistent with the pool's invariant in the post-callback state. The pool's reentrancy guard protected write paths into the same pool but did not protect read paths called from external integrators during the in-flight Vault operation. An attacker constructing a callback that re-entered Sentiment's oracle read pathway from within a Balancer pool operation could therefore observe and act on a stale / manipulated LP-token price.

The exploit shape: the attacker took a flash loan as working capital; opened a Sentiment account with Balancer LP collateral; engineered a Balancer pool operation that, through the pool's internal callback chain, caused Sentiment's oracle to read the LP-token price at a moment when the pool invariant was momentarily inconsistent with the steady-state price; borrowed against the collateral at that favourable mispricing; and closed out, leaving Sentiment with bad debt of approximately $1M.

For OAK's purposes the case is a clean T9.005 (read-only reentrancy sub-class) extraction with a T9.002 (flash-loan) working-capital precondition. The Balancer team had previously published advisories on the read-only reentrancy class in early 2023; protocols that had not retrofitted their integration paths to use Balancer's ensureNotInVaultContext reentrancy-context check were the cohort vulnerable to this pattern. Sentiment is the canonical 2023 case for that cohort.

Timeline (UTC)

When Event OAK ref
Pre-2023-Q1 Balancer publishes advisory describing the read-only reentrancy class on Vault-callback-enabled pools; recommends ensureNotInVaultContext for integrators querying pool state from oracle pathways T9.005 cohort surface (latent)
2023-Q1 Sentiment deploys Balancer LP collateral support on Arbitrum; oracle pathway queries pool view function without the recommended reentrancy-context check T9.005 surface present
2023-04-04 (attack tx window) Attacker opens flash-loan-funded position; deposits Balancer LP collateral into Sentiment account; constructs Balancer pool operation whose Vault callback re-enters Sentiment's oracle read pathway during the in-flight pool state T9.005 + T9.002 extraction
2023-04-04 (same tx) Sentiment oracle returns a stale / manipulated LP-token price; attacker borrows against collateral at favourable mispricing; closes out leaving ~$1M bad debt T9.005 extraction continues
2023-04-04 (within hours) Sentiment operations team detects the bad-debt position; pauses affected markets; publishes initial public acknowledgement (operator response)
2023-04-04 (within hours) Sentiment publishes a public bounty-style framing offering 5% retention if the attacker returns the remainder; on-chain message channel opened (recovery channel)
2023-04-05 (~24h post-event) Attacker returns ~$905K (~95%) to a Sentiment-designated address via on-chain transaction; retains 5% as accepted bounty near-total recovery
2023-04-05 onward Sentiment publishes incident write-up; BlockSec, PeckShield, Halborn publish converging post-incident analyses on the read-only reentrancy root cause (transparency / cohort signal)

What defenders observed

  • The Balancer read-only reentrancy class was already disclosed at advisory level before the Sentiment incident. Balancer had published guidance in early 2023 on the Vault-callback read-only reentrancy pattern and had recommended ensureNotInVaultContext for integrators querying pool view functions from oracle paths. Sentiment's affected oracle pathway had not been retrofitted with the recommended check at the time of the exploit. The Sentiment case is therefore a known-vulnerability-not-fixed cohort case in the same operational shape as the Onyx 2024 case at /examples/2024-09-onyx.md — public disclosure, deployable fix, gap in the operator's environment.
  • Read-only reentrancy is structurally distinct from canonical write-side reentrancy. The 2016 DAO and the 2020 Lendf.Me cases at /examples/2020-04-lendf-me.md are write-side reentrancy: the attacker re-enters a state-mutating function on the same protocol mid-transaction to extract twice. Sentiment is read-only reentrancy: the attacker re-enters a view function on an integrated protocol mid-state-transition to obtain a stale / manipulated reading. The integration boundary is what makes the surface emergent — neither protocol on its own is unsafe in isolation, but the composition is. Worked examples that conflate the two sub-classes lose the operationally important distinction.
  • The recovery channel followed the Euler 2023 pattern but at smaller scale. Sentiment's public bounty-style framing — explicit retention offer, on-chain message channel, designated return address — closely paralleled the recovery-negotiation pattern Euler executed two weeks earlier in March 2023 (see /examples/2023-03-euler-finance.md). The Sentiment case is structurally smaller and faster (~$1M, ~24h) but operationally similar: the operator-side preparation made the recovery primitive activate. The Penpie 2024 case at /examples/2024-09-penpie.md shows the same primitive failing to activate when the attacker had no incentive to return; the conditions for activation are not guaranteed.
  • Flash-loaned working capital scaled the per-iteration mispricing to useful size. Without flash-loaned working capital the per-iteration favorable mispricing would have netted thousands of dollars. T9.002 is the precondition Technique that converts a per-unit oracle inconsistency into a single-transaction ~$1M extraction. The Sentiment, Penpie, Onyx, Beanstalk, and bZx worked examples all share this precondition / extraction structure.
  • Detection latency was operator-acceptable; recovery latency was unusually fast for the class. Sentiment paused affected markets within hours of the on-chain attack window. Recovery completed within ~24 hours of the exploit. The base-rate expectation for T9.005 incidents is total loss; recovery here was not the base-rate outcome and should not be assumed in mitigation planning.

What this example tells contributors writing future Technique pages

  • T9.005 read-only reentrancy is a first-class sub-class deserving explicit vocabulary. The Sentiment case is the canonical 2023 worked example for the read-only reentrancy via integrated AMM LP-token oracle sub-pattern. Curve / dRome incidents in subsequent months extended the same pattern to Curve LP integrations. Contributors writing the T9.005 page should make read-only reentrancy a labelled sub-class distinct from canonical write-side reentrancy, and should treat the integration-boundary (rather than per-protocol logic) as the load-bearing dimension.
  • Cohort monitoring around AMM advisories is a discoverable defender practice. Balancer had published advisory guidance on the read-only reentrancy class before the Sentiment incident; the cohort of integrators querying Balancer pool view functions from oracle paths was discoverable on-chain (DefiLlama, Etherscan integration analysis). The set of those integrators that had retrofitted with the recommended ensureNotInVaultContext check was checkable on-chain. The Sentiment case is the canonical 2023 evidence that this cohort-monitoring discipline was not yet operationalised across the integrators layer at the time of the incident.
  • T9.002 is the precondition Technique that converts per-iteration mispricing into per-incident millions. Worked examples in the T9.005 sub-classes should preserve the precondition / extraction structure rather than collapsing them into a single classification. The Sentiment, Penpie, Onyx, and Beanstalk worked examples document the same structural pattern across distinct extraction sub-classes.
  • The recovery-negotiation primitive is conditional, not universal. The Sentiment case shows the conditions for the primitive can hold at ~$1M in ~24h on Arbitrum; the Euler case shows the conditions can hold at ~$200M in ~2 weeks on Ethereum mainnet; the Penpie case shows the conditions can fail. Mitigation planning should treat the primitive as a conditional rescue surface with operator-side preparation prerequisites (pre-drafted bounty framing, designated return address, no-prosecution authority chain) and attacker-side incentive prerequisites that may or may not hold per incident.

Public references

  • [sentimentpostmortem2023] — Sentiment Protocol public post-incident statement, including the read-only reentrancy root cause and the recovery framing.
  • [blocksecsentiment2023] — BlockSec post-incident technical write-up of the Sentiment read-only reentrancy exploit.
  • [peckshieldsentiment2023] — PeckShield headline figures and on-chain analytics for the Sentiment drain and recovery.
  • [halbornsentiment2023] — Halborn post-incident technical commentary on the Balancer LP-token oracle reentrancy pathway.
  • [balancerreentrancyadvisory2023] — Balancer public advisory on the read-only reentrancy class and the recommended ensureNotInVaultContext check for integrators.

Citations

  • [sentimentpostmortem2023] — Sentiment's own post-incident statement and bounty-framing public communications.
  • [blocksecsentiment2023] — BlockSec forensic analysis converging on the read-only reentrancy root cause.
  • [peckshieldsentiment2023] — PeckShield headline and analytics coverage.
  • [halbornsentiment2023] — Halborn commentary on the Balancer integration pathway.
  • [balancerreentrancyadvisory2023] — Balancer's pre-incident advisory on the vulnerability class, used here to establish the known-vulnerability-not-fixed framing.

Discussion

Sentiment is OAK's canonical 2023 case for the read-only reentrancy via integrated AMM LP-token oracle sub-pattern, paired with the Curve / dRome cohort cases later in 2023 as the secondary worked examples for the same sub-class. Together they illustrate the integration-boundary nature of the surface: the vulnerability is not within either protocol alone but in the composition of an oracle-querying integrator with an AMM whose Vault callback can re-enter the integrator's read path during an in-flight pool state. Contributors writing the T9.005 technique page should make this composition framing explicit rather than treating each cohort case as an independent incident.

The recovery dimension is structurally informative. Sentiment's ~24-hour recovery via 5% bounty retention was operationally similar to Euler's ~2-week recovery, scaled down. Both incidents activated the recovery-negotiation primitive successfully; both required operator-side preparation (public bounty framing, designated return address, on-chain message channel) and attacker-side incentive alignment. The Penpie 2024 case is the contrasting outcome where the primitive failed to activate. Worked examples should report recovery as a factual outcome, not as a mitigation that retires the underlying T9.005 surface.

The known-vulnerability-not-fixed framing pairs the Sentiment case with Onyx 2024 and Wintermute 2022 as the canonical OAK evidence that publicly-disclosed vulnerability classes recur in operator environments that did not deploy the canonical fix in time. The discoverability of the integrator cohort (on-chain) and of the patch status (on-chain check for the reentrancy-context guard) makes cohort monitoring an actionable defender practice; the Sentiment incident is direct evidence that the practice was not yet operating at sufficient coverage in 2023.

Techniques demonstrated (3)