# Contract Suite

The rwaUSD system is modular. Each contract has a narrow responsibility and an explicit permission boundary.

#### 1. Overview diagram

```mermaid
flowchart TB
  subgraph User
    U[EOA / Safe]
  end

  subgraph Core
    L[Ledger Core]
    R[Account Manager]
    X[Risk Registry]
    F[Fee Accumulator]
  end

  subgraph Collateral
    A1[Asset Adapter: TBill]
    A2[Asset Adapter: Stable]
    A3[Asset Adapter: Gold]
  end

  subgraph Pricing
    P[Price Router]
    G[Price Guards]
    S[Signed Feed Verifier]
  end

  subgraph Liquidation
    W[Unwind Engine]
    H[Auction House]
  end

  subgraph Peg
    PR[Peg Rail]
  end

  subgraph Backstop
    B[Reserve Buffer]
    D[Deficit Recorder]
    C[Recap Mechanism]
  end

  U --> R
  R --> A1
  R --> A2
  R --> A3
  A1 --> L
  A2 --> L
  A3 --> L

  P --> L
  X --> L
  F --> L

  W --> L
  W --> H
  H --> L

  PR --> L
  L --> B
  D --> L
  B --> C
```

***

#### 2. rwaUSD Token (`RwaUsdToken`)

**Type:** ERC‑20 (+ EIP‑2612 permit recommended)

**Responsibilities**

* Maintain rwaUSD balances
* Mint/burn only by authorized core module(s)

**Key rules**

* `mint(to, amount)` only callable by `Ledger Core`
* `burn(from, amount)` only callable by `Ledger Core` (or via allowance-based `burnFrom` gated to core)

**Interfaces (Solidity-style)**

```solidity
function mint(address to, uint256 amt) external;
function burn(address from, uint256 amt) external;
function permit(...) external; // optional
```

***

#### 3. Ledger Core (`Ledger`)

This is the accounting kernel. Keep it small, boring, and difficult to upgrade.

**Responsibilities**

* Store collateral balances per account/profile
* Store principal per account/profile
* Enforce all solvency checks using prices and parameters
* Mint/burn rwaUSD
* Record protocol revenue and deficits

**Key storage**

* `locked[accountId][profileId] -> uint256`
* `principal[accountId][profileId] -> uint256`
* `index[profileId] -> uint256` (fee index)
* `totalPrincipal[profileId] -> uint256`
* `pausedFlags -> bitmask`
* `badDebt -> uint256` (explicit deficit tally)

**External entrypoints (only from authorized modules)**

* `lock(profile, account, amount)`
* `unlock(profile, account, amount)`
* `increasePrincipal(profile, account, delta)`
* `decreasePrincipal(profile, account, delta)`
* `applyIndex(profile)` (or invoked by Fee Accumulator)
* `startUnwind(account)` (called by Unwind Engine)
* `settleUnwind(account, clearedPrincipal, clearedFees, collateralOut)` (called by Auction House)

**Important:** the Ledger never calls untrusted external contracts. Anything that touches tokens goes through adapters. Anything that moves collateral in liquidation goes through the Auction House.

***

#### 4. Account Manager (`AccountManager`)

User-facing orchestration: creates accounts, manages permissions, bundles operations.

**Responsibilities**

* Create Collateral Accounts (`accountId`)
* Operator permissions per account
* Convenience methods: deposit+mint, repay+withdraw, multi-call sequences

**Permissions model**

* account owner can grant operators
* operators can be scoped:
  * collateral management
  * issuance/repayment
  * withdrawals
  * full control

**Recommended interfaces**

```solidity
function openAccount(address owner) external returns (uint256 accountId);
function setOperator(uint256 accountId, address operator, uint256 permissions) external;

function deposit(uint256 accountId, bytes32 profileId, uint256 amount) external;
function withdraw(uint256 accountId, bytes32 profileId, uint256 amount, address to) external;

function mint(uint256 accountId, bytes32 profileId, uint256 amount, address to) external;
function repay(uint256 accountId, bytes32 profileId, uint256 amount, address from) external;

// Convenience
function depositAndMint(...) external;
function repayAndWithdraw(...) external;
```

***

#### 5. Asset Adapters (`AssetAdapter` per profile)

Each collateral token requires an adapter to normalize token behavior and enforce custody constraints.

**Responsibilities**

* Pull collateral tokens from user and hold in adapter custody
* Push collateral tokens to user (withdrawals) or Auction House (unwinds)
* Normalize decimals and non-standard ERC‑20 behavior
* Enforce allowlist constraints if token requires eligible holders

**Non-negotiables**

* No collateral leaves an adapter without a corresponding Ledger state update
* Adapter must be approved holder if upstream token has restrictions
* Adapter must handle tokens with:
  * 6 decimals
  * missing return values
  * fee-on-transfer (ideally disallowed for v1)

**Interfaces**

```solidity
function deposit(uint256 accountId, uint256 amount) external;
function withdraw(uint256 accountId, uint256 amount, address to) external;
function seizeToAuction(uint256 accountId, uint256 amount, address auctionHouse) external;
```

***

#### 6. Risk Registry (`RiskRegistry`)

On-chain parameter store for collateral profiles and global settings.

**Per-profile parameters**

* `safetyFactor` (min coverage multiplier)
* `haircut` (price discount used for solvency checks)
* `mintCap` (max principal allowed for profile)
* `minPosition` (dust threshold)
* `penaltyFactor` (extra charge when unwound)
* `auctionConfig` (see Auction House section)
* `oracleConfig` (feed set + guardrails)
* `borrowEnabled` / `collateralEnabled` flags

**Global parameters**

* global issuance cap (optional)
* peg rail limits
* pause flags

**Update rules**

* all changes via governance timelock
* emergency roles may only tighten risk or pause modules

***

#### 7. Fee Accumulator (`FeeAccumulator`)

Maintains fee indices for profiles.

**Model**

* Each profile has a per-second growth factor `ratePerSecond` in RATE precision
* `index[p]` increases over time

**Mechanics**

* Lazy update: `accrue(profile)` updates index based on `block.timestamp - lastAccrual[p]`
* Mint/repay operations call `accrue(profile)` before computing new liability

**Interfaces**

```solidity
function accrue(bytes32 profileId) external;
function setRate(bytes32 profileId, uint256 ratePerSecond) external; // timelock
```
