# Typus Finance (Sui) — October 2025

Bracketed numbers cite the URLs in §5.

## 1. What happened
On **October 15, 2025** (first malicious tx 13:05 UTC) the TLP liquidity pool of Typus Finance
(a real-yield / perpetuals and options protocol on **Sui**) was drained via oracle-price
manipulation. The team was alerted 13:24 UTC and paused all contracts by 13:39 UTC, but the pool
was already empty [1][2].

Project post-mortem figure: **~$3.44M USD at the time**, comprising **588,357.9 SUI, 1,604,034.7
USDC, 0.6 xBTC and 32.227 suiETH** [1]. SlowMist/MistTrack gives the same breakdown and ~$3.44M
[2]; Halborn [3] and Defimon [4] also cite ~$3.44M. **Sources disagree on the headline figure:**
crypto.news/Hacken say ~$3.4M [6], Unchained says $3.4M [7], Coinspeaker reports ~$3M [8]. The
date is consistent (Oct 15; Coinspeaker/Unchained published Oct 16-17 [7][8]). The attacker
swapped to USDC on Sui and bridged ~3,430,717 USDC to Ethereum via Circle CCTP (14 txs),
converting to 3,430,241.91 DAI [2]. SAFU, DeFi Options Vaults and open-position collateral were
reported unaffected; the vaults' cranker wallets validated prices against an independent oracle
and rejected the manipulated value [1].

## 2. Root cause
A **smart-contract bug, not a key or signer compromise**. In the custom oracle module
(`typus_oracle/sources/oracle.move`), public `update_v2` was meant to restrict price updates to a
whitelist: it called `vector::contains(&update_authority.authority, &sender)` but the returned
`bool` was computed and **discarded** — never wrapped in `assert!`. `UpdateAuthority` was a
**shared object** (`transfer::share_object`), so anyone could reference it. The whitelist existed
but was never enforced, letting any address overwrite oracle prices [1][2]. Confirmed in the
pre-fix source, commit `a918e98` [9]. Two process failures compounded it: the module (deployed
Nov 13, 2024) was **excluded from the scope** of the May 2025 MoveBit audit, and monitoring
alerts did not fire immediately [1].

## 3. Pattern
**Missing access control / authorization bypass** (a check whose result is not enforced).
Vulnerable shape:

```
// intended: only whitelisted callers update prices
public fun update_v2(oracle, update_authority /* shared object, anyone may pass */,
                     price, twap_price, clock, ctx) {
  vector::contains(&update_authority.authority, &tx_context::sender(ctx)); // bool discarded
  update_(oracle, price, twap_price, clock, ctx);                          // runs regardless
}
```

The check "passes" for legitimate callers, so nothing looks wrong, but it also passes for
everyone else. Prices became freely writable; the attacker set one oracle to 651,548,270 and
another to 1, then used the pool's swap path (which prices swaps purely from the oracle, not a
constant-product curve) to trade a trivial amount for a large one — e.g. 1 SUI for ~60,000,000
xBTC base units (~0.6 BTC) — repeating across pools [2][4].

## 4. The check that would have caught it
1. **Unit / negative test:** call the price-update entry point from an address *not* in the
   authority whitelist and assert the tx **aborts**. The pre-fix code would not abort — the bug
   shape is visible in [9].
2. **Review rule / lint:** every security predicate returned by a pure function (e.g.
   `vector::contains`) must be consumed by an `assert!` or `if` branch; flag discarded
   authorization results. Move emits no "unused return value" warning, so this needs an explicit
   rule [5]. Invariant: *the set of addresses able to mutate oracle prices equals the configured
   whitelist* (fuzz updates from random non-whitelisted senders, requiring abort). Operationally,
   put every state-mutating module in audit scope before deployment.

## 5. Sources
1. Project post-mortem (Medium): https://medium.com/@TypusFinance/typus-finance-tlp-oracle-exploit-post-mortem-report-response-plan-ce2d0800808b
2. SlowMist, "Is the Move Language Secure? The Typus Permission-Validation Vulnerability": https://slowmist.medium.com/is-the-move-language-secure-the-typus-permission-validation-vulnerability-755a5175f7c3
3. Halborn, "Explained: The Typus Finance Hack (October 2025)": https://www.halborn.com/blog/post/explained-the-typus-finance-hack-october-2025
4. Defimon, "Typus Finance Hack: $3.44M Oracle Manipulation on Sui": https://defimon.xyz/blog/typus-finance-hack-october-2025
5. mehvetero, "How a Missing `assert!` Drained $3.44M From Typus Finance": https://mehvetero.com/how-a-missing-assert-drained-3-44m-from-typus-finance-and-why-the-code-looked-correct
6. crypto.news, "Sui-based Typus Finance plummets 35% after oracle exploit": https://crypto.news/sui-based-typus-finance-plummets-35-after-oracle-exploit/
7. Unchained, "Sui-Based Typus Finance Loses $3.4 Million in Hack": https://unchainedcrypto.com/sui-based-typus-finance-loses-3-4-million-in-hack/
8. Coinspeaker, "$3M, 3rd Major Sui Exploit in 2025": https://www.coinspeaker.com/typus-finances-unaudited-contract-loses-3m-3rd-major-sui-exploit-in-2025/
9. Vulnerable source, commit `a918e98` (pre-fix): https://github.com/Typus-Lab/typus/blob/a918e98c4f7d3a28d0d809d3263d8c21e90d3c01/typus_oracle/sources/oracle.move
10. rekt.news October 2025 security brief: https://newsletter.rekt.news/p/blockchain-security-brief-aws-outage-kadena-s-collapse-copy-paste-exploits
11. rekt.news leaderboard (checked; no dedicated Typus Oct 2025 entry): https://rekt.news/leaderboard

Note: I found no dedicated rekt.news post-mortem [11], and no BlockSec, CertiK or Verichains
write-up specific to Typus. The Medium pages [1][2] returned HTTP 403 to a direct fetch and were
read via Wayback snapshots:
http://web.archive.org/web/20261004122615/https://medium.com/@TypusFinance/typus-finance-tlp-oracle-exploit-post-mortem-report-response-plan-ce2d0800808b
and
http://web.archive.org/web/20261004122627/https://slowmist.medium.com/is-the-move-language-secure-the-typus-permission-validation-vulnerability-755a5175f7c3.
