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

Smart Contract Reference (V3)

Technical reference for PrimeStakedXDC_V3_2, the V3 liquid staking vault. The contract is an ERC-4626-style native-XDC vault with self-service withdrawals, a buffer-aware queue, on-chain masternode integration, and time-locked governance.

Address: 0xDc74c0DaED82ae94486DeeF22991d2F54173c734. Non-upgradeable: deployed with a regular constructor, no proxy.


User functions

stake() payable

Deposits native XDC and mints psXDC shares to the sender at the current exchange rate.

Parameter
Detail

msg.value

Amount of native XDC to deposit

Returns

psXDC shares minted

depositNative(uint256 assets, address receiver) payable

Same as stake but lets you specify a separate receiver. msg.value must equal assets.

withdraw(uint256 assets, address receiver, address owner) / redeem(uint256 shares, address receiver, address owner)

Standard ERC-4626 instant redemption. Reverts if the vault's liquid buffer cannot cover the request.

withdrawWithQueue(uint256 assets, address receiver, address owner) / redeemWithQueue(uint256 shares, address receiver, address owner)

The "smart" redemption used by the app. Settles instantly when the buffer is sufficient, otherwise escrows the shares and adds a request to the FIFO queue.

claimQueuedAssets(address receiver)

Pays out any XDC parked in pendingQueuedAssets for the caller (e.g. from previously failed receiver payouts or processed queue requests where the receiver could not receive directly).

cancelQueuedWithdrawal(uint256 requestId)

Cancels a pending queued withdrawal you previously created and returns the escrowed shares to your wallet.

migrate(address receiver, uint256 assets, uint256 minSharesOut) (bridge-only)

Mints V3 shares to receiver against assets of XDC contributed by the migration bridge. Only callable by the configured PrimeStakedXDC_V3MigrationBridge while the migration window is open. minSharesOut protects callers from unfavorable exchange-rate movement.


Read-only helpers

Function
Returns

totalAssets()

Total XDC tracked by the vault (includes principal staked with masternodes)

convertToShares(uint256 assets) / convertToAssets(uint256 shares)

Exchange-rate conversions

previewDeposit / previewWithdraw / previewRedeem

UI-friendly previews using the current rate

maxWithdraw(address) / maxRedeem(address)

Liquidity-aware caps that reflect the buffer

outstandingValidatorPrincipalByOperator(address operator)

Principal currently staked with a specific masternode operator


Operator functions (validator management)

Anyone with the appropriate role can call these; users do not call them directly.

Function
Role
Purpose

proposeMasternode(...)

PROPOSER_ROLE

Manually propose a new masternode

triggerAutoPropose(uint256 maxNodes)

anyone

Trigger the bounded auto-propose loop. Always blocked while there is a withdrawal queue backlog so user redemptions are prioritized over new proposals

processWithdrawalQueue(uint256 maxRequests)

anyone

Process up to maxRequests FIFO entries

syncTrackedAssets()

anyone

Reconcile trackedTotalAssets with the contract's native balance after unexpected inflows


Operations & risk

These are gated by the V3 role split. They never let an admin move user funds; they only tune parameters and report validator outcomes.

Function
Role
Notes

setBufferBps(uint256)

OPERATIONS_MANAGER_ROLE

Sets the percentage of total assets kept liquid for instant redeem

setOperatorScanLimit(uint256) / setQueueScanLimit(uint256)

OPERATIONS_MANAGER_ROLE

Bounded scan limits used by auto-propose and queue processing

setMinStake(uint256)

OPERATIONS_MANAGER_ROLE

Minimum XDC required to attempt a masternode propose

setValidator(address)

OPERATIONS_MANAGER_ROLE

Configures the XDC validator contract address

reportValidatorLoss(address operator, uint256 assets)

RISK_MANAGER_ROLE

Reports a validator loss; capped per-report (maxLossBpsPerReport) and per-day (maxDailyLossBps)

reportMasternodeResignPrincipal(address operator)

PROPOSER_ROLE

Accounts for masternode principal that has been returned to the vault after resignation cooldown

grantRole, revokeRole, and renounceRole are intentionally disabled. Sensitive role rotations must go through the delayed governance path below to prevent bypassing the time-lock.


Delayed governance

Every sensitive change is a schedule → wait → execute flow gated by governanceDelay:

Schedule
Execute
Cancel

setGovernanceDelay(delay_)

executeGovernanceDelay()

cancelGovernanceDelayChange()

setOperationsManager(account)

executeOperationsManager()

cancelOperationsManagerChange()

setRiskManager(account)

executeRiskManager()

cancelRiskManagerChange()

setMaxLossBpsPerReport(bps)

executeMaxLossBpsPerReport()

cancelMaxLossBpsPerReportChange()

setMaxDailyLossBps(bps)

executeMaxDailyLossBps()

cancelMaxDailyLossBpsChange()

The owner handoff itself uses the same pattern:

  • scheduleOwnerTransfer(newOwner) → wait governanceDelayexecuteOwnerTransfer(). Cancel any time with cancelOwnerTransfer().

transferOwnership and renounceOwnership are disabled so ownership can never change without the delay.


Migration controls

Function
Role
Purpose

setMigrationBridge(address)

admin

Configures the address allowed to call migrate(...)

setMigrationInProgress(bool)

MIGRATION_MANAGER_ROLE

Opens or closes the migration window

fundMigrationLiquidity() payable

MIGRATION_MANAGER_ROLE

Tops up backing liquidity for migrated shares. Only callable while the migration window is open

Direct native sends to the vault while migration is in progress are accepted only from the migration manager and are treated as migration liquidity (they do not inflate totalAssets or convertToShares).


V3.1 additions: under-backed mode

V3.1 adds a single mechanism on top of the audited V3 design so the vault could launch while the legacy masternode collateral is still being transferred in:

Surface
Detail

underBackedMode (public bool)

Set once at go-live if the vault's liquid + tracked backing was below its share liability. Auto-clears inside syncTrackedAssets() when real backing catches up; no admin can force it back on.

queueBackingBudget (public uint)

A ring-fenced budget, active only while under-backed. Migration-manager funding and returned masternode principal accrue here and are reserved for the FIFO withdrawal queue.

Withdrawal behaviour

Immediate withdrawals draw only from unencumbered surplus liquidity (new stakes stay withdrawable); queued requests are paid from queueBackingBudget as funding tranches arrive.

NAV protection

While under-backed, syncTrackedAssets() cannot write NAV down, so the transition mechanics can never reduce the value of existing shares.

fundMigrationLiquidity()

Callable by the MIGRATION_MANAGER_ROLE during under-backed mode to inject collateral tranches (roughly one masternode's worth per week) without minting shares or inflating NAV.

Once the full collateral has been transferred, underBackedMode clears itself and the contract behaves exactly like the audited V3.


Events worth indexing

Event
When

Deposit(sender, owner, assets, shares)

Stake / deposit

Withdraw(sender, receiver, owner, assets, shares)

Instant or queued payout

WithdrawalQueued(requestId, owner, shares)

A request entered the FIFO queue

WithdrawalProcessed(requestId, receiver, assets, shares)

The queue processed a request

WithdrawalCanceled(requestId, owner, shares)

User cancelled their own queued request

AutoProposeFailed(reason)

Auto-propose was attempted but didn't execute; never reverts the stake flow

ValidatorLossReported(operator, assets, reporter)

Risk manager recorded a loss

MigrationLiquidityFunded(amount)

Migration manager topped up bridge liquidity


Security properties

  • Non-blocking auto-propose path: stake never reverts because of a failed propose.

  • Deferred payout fallback for rejecting receivers via pendingQueuedAssets + claimQueuedAssets.

  • Liquidity-aware maxWithdraw / maxRedeem.

  • Bounded scans (operatorScanLimit, queueScanLimit) to prevent gas-griefing.

  • AccessControl role split (proposer / operations / risk / migration).

  • Delayed execution for every sensitive role / risk parameter change.

  • Per-report and cumulative per-day loss caps.

  • Direct role mutation (grantRole, revokeRole) disabled to prevent delayed-governance bypass.

V3 ArchitectureDeployed Contracts & Addresses

Last updated