> For the complete documentation index, see [llms.txt](https://docs.axis.to/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.axis.to/backing-reserves-and-transparency/security/onchain-safety-properties.md).

# Onchain Safety Properties

The properties below describe intended contract invariants. A violation would indicate a defect, misconfiguration, or exploit. They do not make claims about offchain asset value, custody, venue solvency, or strategy execution. These onchain invariants are only one half of the trust model: the protocol minimizes trust where it can, but real trust assumptions remain, notably the centralized liquidity needed to scale, which Axis plans to reduce gradually over time. See [Security Overview](/backing-reserves-and-transparency/security.md) for those offchain trust assumptions and the roles behind them.

## Accounting formulas

| Property                  | Formula or bound                                                                                                                                                            |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| sUSDx exchange rate       | `exchangeRate() = totalAssets() / totalSupply()` (WAD ratio, floor-rounded; returns `1e18` when supply is zero)                                                             |
| Total assets              | `accountedAssets`, active principal plus already-vested rewards; excludes reserved redemption liabilities and unvested rewards                                              |
| Reward vesting            | Rewards vest **linearly over a configured window**: `rewardRate` assets per second until `periodFinish`. The live duration is a configured parameter, not a fixed constant. |
| Unvested rewards          | `unvestedRewards`, funded rewards not yet dripped into `accountedAssets`; excluded from `totalAssets` and the exchange rate until vested                                    |
| Vested rewards            | Rewards already checkpointed into `accountedAssets` (for the active tranche, funded amount minus `unvestedRewards`)                                                         |
| Redemption liabilities    | `redeemLiabilities = pendingRedeemAssets + claimableRedeemAssets`, carved out of `accountedAssets` so the same USDx is never counted as both active assets and a claim      |
| Solvency                  | `assetBalance ≥ requiredAssets`, where `requiredAssets = accountedAssets + pendingRedeemAssets + claimableRedeemAssets + unvestedRewards`                                   |
| Settlement capacity       | Each settled order stays within its configured per-scope caps (`CapConfig` over `GLOBAL` / `ASSET` / `ROUTE` / `ACCOUNT` / `CHANNEL`)                                       |
| Route and channel binding | A settled order matches an enabled `route` and an approved `channel` whose custodian is allowlisted                                                                         |

Solidity integer division rounds down, which is why the reward and share-conversion calculations above floor-round: `convertToAssets` / `convertToShares` are computed against `accountedAssets` with floor rounding, and `previewWithdraw` / `previewRedeem` revert because redemption claims are asynchronous and share-exact.

Vault rewards originate offchain, Axis's structural edge in cross-venue and cross-asset fragmentation, and are funded to the vault as USDx via `fundRewards`; see [How Axis Earns Yield](/susdx-the-rewards-vault/how-axis-earns-yield.md). These onchain invariants govern how funded rewards vest and how the exchange rate moves, not whether returns are generated.

## USDx and minting

* Only `MARKET_ROLE` can create USDx, and that role is held by the `USDxMarket` contract, so issuance is only reachable through approved, settled primary market orders, never open user actions.
* Root admin authority (`DEFAULT_ADMIN_ROLE`) is intended to sit with the **governance Safe (multisig)** rather than a hot EOA, a deployment/configuration choice verifiable onchain, not enforced by the contract. **Contract upgrades are governed by a separate `TimelockController`**, the owner of each `ProxyAdmin`, so proxy upgrades pass through a timelock delay (set on the `TimelockController`, verifiable onchain), whereas the governance Safe's non-upgrade admin actions are direct and not behind the timelock. The V2 contracts use stock OpenZeppelin `AccessControlUpgradeable` with no `renounceRole` override, so role management follows default OZ semantics: an account can renounce its own roles, including `DEFAULT_ADMIN_ROLE`. There is no onchain guarantee that admin authority cannot be renounced.
* Each nonce is single-use per `accountId`, must be non-zero, and is consumed only on successful settlement; an order past its `deadline` cannot settle.
* Orders require valid authorization, a direct EIP-712 signature, an accepted delegated signer, or ERC-1271 smart-account validation, and settle only on their declared side (`OrderSide.MINT` or `REDEEM`).
* Every settled order stays within its configured per-scope capacity caps; a failed settlement consumes neither the nonce nor the capacity, so a rejected order can be safely retried.
* A settled order binds an enabled `route` and an approved `channel`, and the channel's `custodian` is on the allowlist (`isCustodian`).
* `EMERGENCY_ROLE` is risk-**down** only: it can pause capacity, disable mint/redeem, and remove hot market roles, but it cannot grant roles, increase risk, or upgrade.

## Rewards vault

* The sUSDx exchange rate can only increase over time as rewards vest, excluding rounding.
* Deposits are **synchronous** ERC-4626 entries priced at the exchange rate at execution; redemptions are **asynchronous** (ERC-7540) and settle through the redemption queue, not at deposit time.
* Rewards vest linearly over a configured window (`rewardRate` until `periodFinish`); the live value is a configured parameter of the deployed contract. A `fundRewards` top-up folds into the *active* vesting window rather than resetting the clock, and is bounded by an optional `maxRewardRate` cap.
* Restriction status is enforced per action via a blocked-actions model (`RESTRICTION_ROLE`). A fully restricted owner or controller cannot open a redeem request; a soft-restricted owner may open a request only to exit to itself. Ordinary ERC-20 allowance operations are not blocked by restriction status alone.
* Redemption liabilities live **inside the vault** as `pendingRedeemAssets` and `claimableRedeemAssets` buckets. There is no separate escrow contract. Reserved amounts are carved out of `accountedAssets`, so they accrue no further rewards and cannot dilute active holders.
* A pending redeem request can be cancelled (`cancelRedeemRequest`), which releases its reserved assets back to `accountedAssets` and re-mints the burned shares to the owner; cancellation is blocked for fully restricted accounts and while cancellations are paused.

## Redemption queue and rewards

* Async redemption follows ERC-7540: `requestRedeem` burns the owner's shares and moves assets from `accountedAssets` into `pendingRedeemAssets`, snapshotting `eligibleAt = requestedAt + policy.cooldown` per request (later cooldown changes affect only future requests).
* Only `REDEMPTION_SERVICER_ROLE` can service the queue: `serviceRedemptions` scans `PENDING` requests in request-id order within a bounded per-call scan and moves eligible ones to `CLAIMABLE`, shifting reserved assets from the pending to the claimable bucket. Ineligible requests are skipped, but a forward-progress guarantee ensures the first eligible request always advances.
* A controller claims the underlying USDx only after its request is `CLAIMABLE`; a submitted request is never treated as claimed until serviced.
* Only `REWARD_MANAGER_ROLE` can fund rewards (`fundRewards`), and funding cannot exceed configured reward bounds.
* Solvency holds continuously: `assetBalance ≥ requiredAssets`, where `requiredAssets` covers active shares, both reserved redemption buckets, and unvested rewards, so servicing and claims can never spend principal or rewards twice.
* Upgrades are owner-gated through a **`TimelockController`** (the `ProxyAdmin` owner) over `TransparentUpgradeableProxy` (no implementation self-upgrades). An upgrade must pass a timelock delay before it can execute; the delay is set on the `TimelockController` and is verifiable onchain. This upgrade authority is distinct from `DEFAULT_ADMIN_ROLE`, which is held by the governance Safe and is not behind the timelock. Role authority itself follows stock OpenZeppelin `AccessControlUpgradeable`, the contracts add no `renounceRole` override, so there is no onchain guarantee that authority over these system contracts cannot be renounced.

See [Smart Contract Protections](/backing-reserves-and-transparency/security/smart-contract-protections.md) for the mechanisms behind these properties, the [Protocol Taxonomy](/usdx-the-synthetic-dollar/usdx.md) for canonical symbol definitions, and [Core Contracts Reference](/reference/core-contracts.md) or [Staking Contracts Reference](/reference/staking-contracts.md) for function-level detail.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.axis.to/backing-reserves-and-transparency/security/onchain-safety-properties.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
