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

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 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. 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 for the mechanisms behind these properties, the Protocol Taxonomy for canonical symbol definitions, and Core Contracts Reference or Staking Contracts Reference for function-level detail.

Last updated