For the complete documentation index, see llms.txt. This page is also available as Markdown.

Architecture

Section 4 (sec4)

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

Component
Chain
Language
Role

Helix Vault -- Canton side

Canton (dedicated synchronizer)

Daml

Mints hstXDC against bridge-attested deposits; burns hstXDC on user redemption and emits unlock attestations; tracks the per-user staked balance and the global exchange rate

Helix Vault -- XDC side

XDC mainnet

Solidity

Receives XDC deposits; delegates them through the standard XDC masternode delegation lifecycle; emits deposit and unstake events that the bridge layer attests to

Bridge attestor layer

Off-chain (FROST/TSS network) + on-chain witness contracts on both sides

Rust / Solidity / Daml

Watches both vaults; produces threshold-signed attestations of state transitions; submits attestations to the opposite-side vault to authorize mint or unlock

hstXDC token

Canton

Daml (CIP-56 compliant)

Liquid staking token. Non-rebasing, share-based. Exchange rate against XDC drifts upward as native staking yield accrues.

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.

Field
Purpose

operator

The Helix operator party -- has authority to update vault parameters, never authority over user balances

bridgeAttestorParty

The Canton-side party representing the threshold-signed attestor set. The only party authorized to issue mint authorizations.

exchangeRate

Global accumulator. Updates as XDC native staking yield is reported by the bridge layer. Monotonically non-decreasing.

pausedFlag

Operator-controlled circuit breaker. When set, blocks new mints but never blocks redemptions.

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.

Last updated