> ## Documentation Index
> Fetch the complete documentation index at: https://docs.darkmatter.rdytobash.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Vaults Custody

> Vaults Custody — Dark Matter Protocol on Robinhood Chain.

# The Two Vaults & Custody

Dark Matter has exactly two places where player money rests. They are deliberately
built differently, because their jobs are different.

## 1. Reactor custody — `UltimateSingularityProtocol`

Reactor deposits (ETH sent to `injectMass`) become part of the **shared protocol
balance**. Yield works like a bonding curve: deposits raise the pool, withdrawals sell
radiation back into it. There is no per-user escrow — a depositor's security is the
**2× withdrawal cap**:

```solidity theme={null}
uint256 public constant MAX_WITHDRAW_MULTIPLIER = 2;
// extractRadiation() clamps lifetime claims:
uint256 maxLimit = userDeposits[msg.sender] * MAX_WITHDRAW_MULTIPLIER;
```

Nobody — including the owner — can withdraw more than 2× their own lifetime deposit.
The owner's only fee income is the fixed 10% deposit fee stream (see
[Reactor Waterfall](reactor/waterfall.md)).

## 2. Casino custody — `CrashVault`

Casino chips (ETH + USDG balances used by Crash and the Entropy dice games) are held by
`CrashVault`. The design goal: **the server can run the game but can never touch funds
it didn't earn.**

### Deposits — always player-initiated

```solidity theme={null}
function depositEth() external payable;                    // native ETH
function depositToken(address token, uint256 amount) external;  // USDG (transferFrom)
```

Both record the balance against `msg.sender` and update the aggregate liabilities
(`ethLiabilities` / `tokenLiabilities`). The server mirrors custody in the off-chain
ledger (`darkmatter.crash_chips`) by sweeping `Deposited` events — bets are then pure
ledger operations: instant, gas-free, mobile-friendly.

### Withdrawals — gasless but signature-gated

The player signs an **EIP-191** message over `(player, token, amount, nonce)`. The
relayer submits and pays gas, but the chain enforces the signature:

```solidity theme={null}
function withdraw(
    address player, address token,      // token = address(0) for ETH
    uint256 amount, uint256 nonce,
    bytes calldata signature
) external onlyRelayer;
```

Three on-chain guards:

1. **`ecrecover` must equal `player`** — the server has no way to produce a valid
   signature for a user's funds.
2. **Strict nonce increment** (`nonce == nonceOf[player] + 1`) — no replay, no gaps,
   deterministic sequencing even across relayer instances.
3. **Balance check** — the payout reverts if the ledger and the vault disagree.

### Admin powers — deliberately weak

| Power | Guard |
| - | - |
| Pause new deposits | Emergency brake only — withdrawals always stay open |
| Change relayer | **48h timelock**; anyone (even players) can finalize after it expires |
| Route realized edge | Relayer-only, 50/50 split fixed by constructor (see below) |
| Withdraw player funds | **Impossible. No such function exists.** |

```
TIMELOCK = 48 hours
setRelayer(new)      → pendingRelayer = new, pendingAt = now + 48h
acceptRelayer()      → anyone may call after pendingAt
```

The timelock means players always have a 48-hour window to withdraw before any relayer
change lands — even a malicious owner cannot strand funds without giving everyone an
exit.

## Edge routing — the vault's only "operator" flow

Realized house edge (round stakes minus payouts, see [Crash Money Model](casino/crash-economy.md))
is forwarded on-chain by the relayer:

```solidity theme={null}
function routeEdge() external payable onlyRelayer;   // splits msg.value 50/50:
                                                     //  → rewardsPool (EventHorizonPool)
                                                     //  → lpTreasury (LP bootstrap)
```

* The 50/50 split is **fixed in code**, not admin-tunable.
* A zero address sink keeps its share in the vault as protocol revenue.
* If the rewards pool sink is unwired, the entire value routes to the LP treasury
  (the half-share is only computed once — `rewards = share` when wired).

## USDG

USDG (Paxos) is the second casino currency — 6 decimals, used via
`depositToken(usdg, amount)`. Bet bounds, chip math and the fee split all apply
identically to both currencies; see [Crash Money Model](casino/crash-economy.md#bet-bounds).

## Deposit fee note (casino side)

At **ledger-credit time**, the server charges a 1% deposit fee on casino deposits —
the player's chip credit is `deposited − 1%`, split half to the dev address and half
to the VIP pool. Importantly the **vault itself still custodies 100% of the assets** —
the fee rows are claims against the same custody, settled through the same ledger:

```
player chips   = custody − fee
dev chips      = fee / 2 (ceil)
VIP pool chips = fee − devShare
```

Full mechanics: [Reactor Waterfall §The casino's own 1%](reactor/waterfall.md#casino-fee).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.