# Architecture

> hstXDC is two vault contracts (one on Canton, one on XDC) connected by an attestation-only bridge layer. This section walks each piece in mechanical detail: contract surface, party structure, admin authority, state transitions, and where the security perimeter actually sits.

### Component map

<table><thead><tr><th width="149.265625">Component</th><th width="184.19140625">Chain</th><th width="131.8671875">Language</th><th>Role</th></tr></thead><tbody><tr><td><strong>Helix Vault -- Canton side</strong></td><td>Canton (dedicated synchronizer)</td><td>Daml</td><td>Mints <code>hstXDC</code> against bridge-attested deposits; burns <code>hstXDC</code> on user redemption and emits unlock attestations; tracks the per-user staked balance and the global exchange rate</td></tr><tr><td><strong>Helix Vault -- XDC side</strong></td><td>XDC mainnet</td><td>Solidity</td><td>Receives XDC deposits; delegates them through the standard XDC masternode delegation lifecycle; emits deposit and unstake events that the bridge layer attests to</td></tr><tr><td><strong>Bridge attestor layer</strong></td><td>Off-chain (FROST/TSS network) + on-chain witness contracts on both sides</td><td>Rust / Solidity / Daml</td><td>Watches both vaults; produces threshold-signed attestations of state transitions; submits attestations to the opposite-side vault to authorize mint or unlock</td></tr><tr><td><strong><code>hstXDC</code> token</strong></td><td>Canton</td><td>Daml (CIP-56 compliant)</td><td>Liquid staking token. Non-rebasing, share-based. Exchange rate against XDC drifts upward as native staking yield accrues.</td></tr></tbody></table>

The hstXDC architecture has **no off-chain custody process**. The XDC sits in the on-chain vault contract on XDC mainnet at all times. The Canton-side vault holds Daml state, not custody of XDC. The bridge layer holds threshold signature shares, not assets.

### Canton-side vault

The Canton-side vault is a Daml workflow built around three template families:

#### Template family 1 -- `HelixVaultConfig`

Singleton contract that holds the vault's global parameters. Authored by the Helix operator party. Read by every other vault contract.

<table><thead><tr><th width="256.87890625">Field</th><th>Purpose</th></tr></thead><tbody><tr><td><code>operator</code></td><td>The Helix operator party -- has authority to update vault parameters, never authority over user balances</td></tr><tr><td><code>bridgeAttestorParty</code></td><td>The Canton-side party representing the threshold-signed attestor set. The only party authorized to issue mint authorizations.</td></tr><tr><td><code>exchangeRate</code></td><td>Global accumulator. Updates as XDC native staking yield is reported by the bridge layer. Monotonically non-decreasing.</td></tr><tr><td><code>pausedFlag</code></td><td>Operator-controlled circuit breaker. When set, blocks new mints but never blocks redemptions.</td></tr></tbody></table>

#### Template family 2 -- `UserPosition`

Per-user contract recording the holder's `hstXDC` balance and entitlement. Authored jointly by the holder party and the operator party (multi-party authorization).

| Choice     | Authorization                  | Effect                                                                                                       |
| ---------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `Mint`     | bridgeAttestorParty + operator | Creates `hstXDC` to the holder party against an attested deposit                                             |
| `Burn`     | holder                         | Holder-initiated. Marks the position for redemption. Burns the `hstXDC` and emits a Canton-side burn record. |
| `Transfer` | holder                         | Standard CIP-56 transfer. Transfers `hstXDC` to another Canton party.                                        |

The critical authorization rule: **the operator cannot mint on its own.** Mint requires the `bridgeAttestorParty` co-signature, which only exists when the threshold-signed attestor set has produced a valid attestation. The operator's authority is limited to vault configuration, not to creating or moving holder assets.

#### Template family 3 -- `RedemptionRequest`

Per-redemption contract that captures a holder's intent to unstake. Authored by the holder party; consumed by the bridge attestor party once the XDC-side unstake completes.

| Field            | Purpose                                                    |
| ---------------- | ---------------------------------------------------------- |
| `holder`         | The redeeming party                                        |
| `amount`         | hstXDC amount being redeemed                               |
| `xdcDestination` | The XDC mainnet address that will receive the unstaked XDC |
| `requestedAt`    | Canton-side timestamp; used to anchor the unbonding clock  |

The redemption flow is asynchronous by design -- XDC's masternode unbonding lifecycle introduces a chain-native delay that the Canton vault cannot shortcut. The `RedemptionRequest` contract represents the redemption commitment during that window.

### XDC-side vault

The XDC-side vault is a Solidity contract deployed on XDC mainnet, structured around three responsibilities:

#### Responsibility 1 -- Deposit and delegation

Holders deposit XDC by calling `deposit()`. The contract:

1. Records the deposit in per-holder accounting
2. Routes the deposited XDC into a delegation to a Helix-operated masternode (or a configured masternode set; see admin model below)
3. Emits a `Deposited(holder, amount, blockNumber)` event that the bridge attestor layer watches

The contract does not mint anything on the XDC side. There is no `xXDC` or `wXDC`. The deposit event is the entire output -- the corresponding `hstXDC` mint happens on Canton, against the attestation of this event.

#### Responsibility 2 -- Yield accrual reporting

The contract exposes a `currentExchangeRate()` view function that returns the current XDC-denominated value of one share of the vault's staked position. As the underlying delegation accrues native staking yield, this rate increases.

The bridge attestor layer periodically reads this view function, produces a threshold-signed attestation of the new rate, and submits it to the Canton-side vault to update the global `exchangeRate`. **The exchange rate is monotonically non-decreasing on both sides.** No rebasing, no negative rate adjustments. Slashing (which on XDC affects only the masternode operator's stake, not delegated stakes) does not propagate to holder positions.

#### Responsibility 3 -- Unstake and redemption

When a holder requests redemption on the Canton side, the bridge attestor layer submits an attestation to the XDC contract authorizing an unstake. The XDC contract:

1. Initiates an unstake of the appropriate proportion of the delegated position
2. Waits the standard XDC masternode unbonding window
3. Returns the unstaked XDC to the holder's specified XDC mainnet address
4. Emits an `Unstaked(holder, amount, blockNumber)` event that the bridge layer attests to, allowing the Canton-side `RedemptionRequest` to be consumed and the corresponding `hstXDC` to be permanently burned

The unbonding window is a property of XDC's consensus, not of hstXDC. Holders should expect the redemption flow to take the full XDC unbonding period. This is consistent with all native PoS staking on the chain.

### Admin key model

The admin key model is the part of the architecture institutional users will scrutinize first. The design intent is to **minimize the powers any single key holder has**, and to ensure that **no admin operation can move user assets**.

| Admin role                     | Who holds it                                                                                                                 | What it can do                                                                                                                                           | What it CANNOT do                                                                                                                                                                                                          |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Vault operator (multi-sig)** | Helix operator multi-sig (target: 3-of-5 across geographically distributed key holders)                                      | Update vault parameters (paused flag, masternode selection, fee parameters); pause new deposits                                                          | **Cannot mint hstXDC**. Cannot move holder assets. Cannot bypass the bridge attestor layer. Cannot accelerate unbonding. Cannot redirect redemptions.                                                                      |
| **Bridge attestor set**        | Threshold-signature attestor network (target: distributed across institutional operators including but not limited to Helix) | Produce attestations of state transitions on both vaults; authorize mints on Canton against XDC deposits; authorize unstakes on XDC against Canton burns | **Cannot mint without an underlying XDC deposit.** Cannot mint to an address that didn't deposit. Cannot redirect deposits. Cannot pause the vault.                                                                        |
| **Holder**                     | Individual depositor                                                                                                         | Deposit XDC; transfer hstXDC; initiate redemption                                                                                                        | Cannot mint hstXDC outside the deposit flow. Cannot bypass the unbonding period.                                                                                                                                           |
| **Upgrade authority**          | TBD -- under design                                                                                                          | Future contract upgrades on either side                                                                                                                  | The current intent is to make the vault contracts non-upgradable on the XDC side and use Daml package migration on the Canton side. Upgrade authority itself is under active scoping and will be specified before mainnet. |

**The two load-bearing rules:**

1. **No single key can mint hstXDC.** Mint authorization requires the threshold-signed attestor set to produce an attestation. The operator multi-sig is a separate role and cannot substitute for the attestor set.
2. **No admin role can move user assets.** Admin powers are limited to parameter updates and circuit-breaker controls. Moving holder XDC, holder hstXDC, or the underlying delegation requires the standard user-initiated flows (deposit, redeem, transfer) -- not an admin operation.

These two rules are the security perimeter. Everything else in the admin model is parameter management.

### State transitions, end to end

The full lifecycle of a hstXDC position, mapped to which contracts authorize each step:

| Step                                    | Initiator             | XDC-side contract                                                        | Bridge attestor                                                                 | Canton-side contract                                                                            |
| --------------------------------------- | --------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| 1. User deposits XDC                    | Holder                | `deposit()` records deposit, routes to delegation, emits `Deposited`     | Watches `Deposited` event; produces threshold-signed attestation of the deposit | -                                                                                               |
| 2. Mint authorization arrives on Canton | Bridge attestor layer | -                                                                        | Submits attestation to Canton vault                                             | Attestation received; `Mint` choice exercised on `UserPosition` template                        |
| 3. hstXDC minted to holder              | -                     | -                                                                        | -                                                                               | `UserPosition` contract created with holder's balance; `hstXDC` token in holder's Canton wallet |
| 4. Yield accrues                        | XDC consensus         | Delegation earns native staking yield; `currentExchangeRate()` increases | Periodically reads rate, attests, submits to Canton                             | `HelixVaultConfig.exchangeRate` updated; holder's hstXDC appreciates against XDC                |
| 5. Holder initiates redemption          | Holder                | -                                                                        | -                                                                               | `Burn` choice exercised; `RedemptionRequest` contract created                                   |
| 6. Unstake authorization arrives on XDC | Bridge attestor layer | -                                                                        | Submits unstake attestation to XDC vault                                        | -                                                                                               |
| 7. XDC unstake initiated                | XDC vault contract    | Calls XDC unbonding; waits unbonding window                              | -                                                                               | --                                                                                              |
| 8. Unbonding completes                  | XDC consensus         | Unstaked XDC returned to holder address; emits `Unstaked` event          | Watches `Unstaked` event; attests                                               | -                                                                                               |
| 9. Canton-side redemption finalized     | Bridge attestor layer | -                                                                        | Submits unstake-completion attestation to Canton                                | `RedemptionRequest` consumed; `hstXDC` permanently burned                                       |

The full deposit-mint flow (steps 1-3) completes in the time it takes for XDC finality plus one bridge attestation round -- on the order of tens of seconds. The redemption flow (steps 5-9) is bounded by the XDC unbonding window, which is a property of the chain, not of hstXDC.

### v1 versus v1.1 -- what ships when

The hstXDC v1 product is the deposit, mint, hold, and redeem flow described above. **v1 does not include the recursive staking loop.**

The recursive staking loop -- borrow stables against `hstXDC` collateral on Canton, swap stables for XDC, redeposit, repeat -- is the v1.1 expansion. It depends on two conditions that are not yet met:

1. A USDC-denominated lending market on Canton that accepts `hstXDC` as collateral. This depends on Canton-side lending venues activating CIP-56 collateral support -- which is in scope for those venues but not yet shipped at the time of writing.
2. Adequate execution depth for the stable-to-XDC swap leg. The current XDC mainnet DEX depth (see sec7) is insufficient for institutional-size loops; the loop becomes practical when execution can route through CCTP V2 to deeper-liquidity chains and settle back.

Both conditions are external to hstXDC itself. v1 ships independently of them. v1.1 unlocks when the conditions are met.

The architecture in v1 is forward-compatible with v1.1 -- no contract rewrites are required. The loop is composed of standard `hstXDC` transfers and CIP-56 collateral interactions. When the lending venues are ready, the loop is just a workflow, not a new product.
