Conversation
Assess USDat per issue #135. USDat is an M0 extension token backed 1:1 by $M (tokenized US Treasuries); STRC/BTC credit exposure sits in the sUSDat yield layer. Final score 3.0/5.0 (Medium Risk). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Ingested the issue's deeper sources (Notion DD FAQ/Ops&Risk/STRC pages via Notion's public API, and the Google Doc contract spec via text export). Adds verified detail: auditors (Three Sigma + Certora), the two-leg redemption path (USDat->wM->USDC, 1bps), legal structure (Cayman foundation / BVI Saturn Capital & Fund / Panama), off-chain providers (Galaxy, Clear Street, Securitize, Fireblocks), PoR cadence, and a note that the Ops doc's "Copper custodial / 3-of-5" design is stale vs the live on-chain M0 design. Score unchanged (~3.0, Medium). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add a Tools subsection on pulling content from JS-rendered/doc-host links (Notion public API loadCachedPageChunkV2 with the double-nested block gotcha; Google Docs export?format=txt for link-shared docs), since WebFetch only sees their static shell and Playwright lacks Chromium system libs in the sandbox. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add the GitBook tricks to the doc-fetching subsection: append .md for clean markdown, and the built-in ?ask= Q&A endpoint for filling gaps. Also firm up the USDat report's bug-bounty finding (confirmed none via the docs Q&A endpoint). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Read the four published audit PDFs (Three Sigma Audit #1; Certora Audit #2/#3/Formal Verification). Key finding: all four cover a pre-pivot self-issued USDat ERC20 (PROCESSOR mint + blacklist), not the M0 JMIExtension actually deployed on 2026-03-10 — so the live token leans on M0's separate m-extensions audits plus an un-audited Saturn whitelist wrapper. Adds audit table, findings context, the coverage-gap as a key/critical risk, and records the GitHub repos. Audits subscore 2.5->3.0; final score 3.0/5.0 (Medium) unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
I flagged some minor changes, the rest LGTM. I agree with the risk rating being Medium, however we need to be cautious due to sUSDat's STRC exposure and offchain custody/execution, NAV/oracle reliance, and withdrawal queue liquidity risk. The yield is not "stablecoin yield", it is packaged STRC credit/dividend exposure. |
- Certora Audit #3 (Saturn Dollar M0 Extensions, Apr 30 2026) recorded; remove "deployed token not covered by audits" caveat - Record live Accountable-backed Chainlink "Saturn sUSDat NAV" feed (0x73B8…D318), verified on-chain June 7 2026 - ASSET_CAP_MANAGER_ROLE moved to Saturn Timelock (5-day delay) - Adjust Audits score 3.0->2.5 and final 3.02->2.97 (~3.0) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
LGTM |
…lds DEFAULT_ADMIN_ROLE and ProxyAdmin
…nance now timelocked
| - Past security incidents: none known (none expected given age). | ||
| - Peg history: USDat trades near $1; the Curve USDC/USDat pool is roughly balanced (see Liquidity). No depeg events observed. **TODO: pull historical peg/price series for a fuller picture.** | ||
| - Concentration risk from large depositors / holder distribution: **TODO** (holder list requires Etherscan Pro). A large fraction of supply is staked into sUSDat (sUSDat supply ≈ 106.5M shares). | ||
| - Funding: seed round (Jan 2026) led by **YZi Labs** and **Sora Ventures** plus angels. Reported amount conflicts across sources ($800K vs $2M) — **TODO: confirm**. |
There was a problem hiding this comment.
Rounds:
- Pre-Seed: 800k lead by YZI and Sora
- Seed: $2 mil lead by Spartan
| ``` | ||
|
|
||
| - The protocol delegates backing entirely to **M0** (the `$M` token). There is no other delegation for USDat itself. The collateral asset is held as `$M` on the USDat contract. | ||
| - **Monitoring delegation changes:** the `ASSET_CAP_MANAGER_ROLE` can authorize additional backing assets (the M0 "JMI / Just Mint It" model supports collateral assets beyond `$M`). Today `totalAssets()` ≈ 0 (backing is effectively all `$M`), but this is a parameter to watch — see Monitoring. |
There was a problem hiding this comment.
The protocol support caps on assets used to mint. The limits the maximum exposure a USDat can have to a minting asset. Currently USDC is the only allowed asset to mint with a cap of $10 mil
|
|
||
| - **Who can mint/redeem:** only **whitelisted ("onboarded") addresses**. The whitelist is enforced on `wrap` (mint) and `unwrap` (redeem) via `_revertIfNotWhitelisted` (verified in source). `isWhitelistEnabled()` = **true** on-chain. | ||
| - **Regular transfers are NOT whitelist-gated** — verified: the whitelist hooks fire only on `_beforeWrap`/`_beforeUnwrap`, not on `transfer`/`transferFrom`. This is why the Curve pool (not whitelisted) trades freely. **Implication for Yearn: a non-onboarded holder can hold and transfer USDat but cannot mint or redeem directly — its only exit is the secondary market (Curve/Pancake) unless Yearn is whitelisted.** | ||
| - **Atomicity:** the on-chain wrap (M → USDat) and unwrap (USDat → M) are atomic. The USDC↔M leg runs through the M0 Swap Facility in the same user flow. USDat→USDC redemption for onboarded users is effectively 1:1 and prompt (Treasury-backed, no queue). The **sUSDat** layer has a withdrawal queue (STRC liquidation); USDat itself does not. |
There was a problem hiding this comment.
This might be to in the weeds but wanted to make sure the flows are clear.
wrap:
- Takes m/usdc and wraps to USDat atomically
solverscan swap the USDC to $M asynchronously. The contract enforces that the amount of USDC leaving is equal to the amount of $M being deposited.
unwrap
- Converts USDat to wM which can then be swapped to USDC on uniswap. Liquidity on uniswap for wM/USDC is maintained by M0.
- wM acts as the M0 maintained stablecoin and is equivalent to USDat but maintained by M0.
- M0 has also built a limit order protocol which acts as an OTC desk where "solvers" can fill orders partially or fully. This flow is async unlike the the uniswap pool.
| | Address | Can Mint | Can Burn | Role / Mechanism | Notes | | ||
| |---------|:--------:|:--------:|------------------|-------| | ||
| | [`0xB6807116b3B1B321a390594e31ECD6e0076f6278`](https://etherscan.io/address/0xB6807116b3B1B321a390594e31ECD6e0076f6278) | ✓ | ✓ | `onlySwapFacility` (`wrap`/`unwrap`) | M0 Swap Facility ("Mint and Redeem Contract"). Sole mint/burn path; mint pulls `$M` 1:1 first. Caller must be whitelisted. | | ||
| | [`0x10D59F776db12b4B271b2609CB8b7Ddd0A82703B`](https://etherscan.io/address/0x10D59F776db12b4B271b2609CB8b7Ddd0A82703B) | — | (seize) | `FORCED_TRANSFER_MANAGER_ROLE` | Compliance (Fireblocks 2/3 MPC). Cannot mint; can `forceTransfer` tokens out of **frozen** accounts. Also holds `FREEZE_MANAGER_ROLE`, `PAUSER_ROLE`, `WHITELIST_MANAGER_ROLE`. | |
There was a problem hiding this comment.
Would you recommend the FORCED_TRANSFER_MANAGER_ROLE is held by the Admin Timelock?
| | `ASSET_CAP_MANAGER_ROLE` | `0x7d34…78f7` (Saturn Timelock) | Timelock contract (`getMinDelay()` = 5 days) | Authorize/cap additional backing assets | | ||
|
|
||
| - **Can governance pause, freeze, or seize user funds? Yes** — freeze + forced transfer + pause are all live and held by the Compliance MPC. These are standard regulated-stablecoin compliance controls (cf. USDG, USDC) but represent real holder risk and a notable centralization signal. | ||
| - **Documentation discrepancy (resolved in favour of on-chain):** Saturn's internal Ops/Risk doc describes an *earlier* design in which "funds that back USDat are held in a Copper custodial multisig wallet" (not in the contract) and the admin is a "3-of-5 multisig." The **live, on-chain design supersedes this**: USDat is an M0 extension, the `$M` backing sits **in the token contract** (verified: `M.balanceOf(USDat)` = $126M), and the main admin/compliance roles are held by **Fireblocks 2/3 MPC** addresses (per the key-addresses page), while **admin and asset-cap management now sit behind timelocks** (5-day delay each). The "off-chain custody / 3-of-5" framing is stale. The exact MPC signer threshold cannot be verified on-chain (MPC is off-chain) — taken from docs. |
There was a problem hiding this comment.
I can work to update our docs. This is a good find.
| ### Programmability | ||
|
|
||
| - Core mint/redeem and accounting are **programmatic and on-chain**: USDat is 1:1 non-rebasing; the index/exchange rate is read from M0 (`currentIndex()`); backing is verifiable on-chain. | ||
| - Off-chain dependencies: user **onboarding/KYC** (whitelist), the USDC↔`$M` swap routing in Saturn's app, and the sUSDat STRC management (off-chain). For USDat-as-collateral the critical accounting is on-chain. |
There was a problem hiding this comment.
what do you mean by
user onboarding/KYC (whitelist), the USDC↔
$Mswap routing in Saturn's app
| USDat is an M0 extension. The fund flow is: | ||
|
|
||
| ``` | ||
| USDC ──(Saturn app, onboarded user)──▶ M0 Swap Facility ──swap──▶ $M ──wrap──▶ USDat (1:1) |
There was a problem hiding this comment.
For correctness there is a solver in this flow. USDat minting flow of funds:
- USDC deposited through
swapFacilityand USDat minted 1:1 solverasynchronously swaps USDC to $M 1:1- USDat now backed by $M.
Minting fails if the contract has more than $10 mil in USDC exposure.
Closes #135.
Adds
reports/report/saturn-usdat.md— a risk assessment of USDat, Saturn's non-yielding stablecoin (assessment subject per the issue: "USDat as collateral").