Skip to main content
Tokenized RWAs OFT delegates security policies to independently upgradeable module contracts. Each module is set on Nexus via admin-only setters (setPauseModule, setFeeConfigModule, setRateLimiterModule). If a module is not set, its extension is inactive. The fee and pause modules share the same 4-level priority resolution over composite Nexus IDs, giving operators fine-grained control per token, per destination, or globally. The rate limiter operates per destination (EID) only — all tokens on the same destination share the same bucket.

Priority Resolution

Nexus IDs encode both the token and destination:
nexusId = (uint256(tokenId) << 32) | uint256(eid)
Each module resolves configs by checking four key levels in order, from least specific to most specific:
LevelKeyScope
Global0All tokens, all destinations
Destination-onlynexusId & 0xFFFFFFFFAll tokens for a specific destination
Token-onlynexusId & 0xFFFFFFFF00000000All destinations for a specific token
CompositenexusIdSpecific token + destination pair
The config with the highest priority wins. On equal priority, the least specific key (checked first) wins. A config with MAX_PRIORITY (type(uint128).max) short-circuits resolution immediately. This means you can set a global default and override it for specific tokens or destinations without touching the global config.

Fee Config Module

Same BPS-based fee calculation as Stablecoin OFT’s fee extension, but with priority resolution. Fees are collected by burning amountSentLD from the sender and minting the fee portion to the configured feeDeposit address.

Configuration

Each config entry stores:
FieldTypeDescription
priorityuint128Resolution priority (higher wins)
feeBpsuint16Fee in basis points (0–10000)
function setFeeBps(SetFeeBpsParam[] calldata _params) public;
Setting priority = 0 and feeBps = 0 removes the config entry.

Role

FEE_CONFIG_MANAGER_ROLE (authenticated via Nexus access control).

Pause Module

Controls whether outbound transfers are allowed for a given pathway. Nexus checks _isPaused(nexusId) before every send — if paused, the transaction reverts.

Configuration

Each config entry stores:
FieldTypeDescription
priorityuint128Resolution priority (higher wins)
pausedboolWhether the pathway is paused
function setPaused(SetPausedParam[] calldata _params) public;

Role Logic

The pause module enforces a nuanced role check per batch based on the effective impact of each config change:
  • PAUSER_ROLE — required when the net effect is pausing or strengthening a pause config
  • UNPAUSER_ROLE — required when the net effect is unpausing, weakening a pause config, or a no-op (to prevent unauthorized no-ops)
  • Mixed batch (some entries pause, some unpause) → requires both roles
This ensures a compromised pauser key cannot also undo a legitimate security pause.

Pause vs NexusERC20Guard Pause

ConcernControlled ByScope
Cross-chain sendsNexusPauseModulePer (token, destination) with priority resolution
Local transfersNexusERC20GuardPer token (uint160(tokenAddress))
Pausing a cross-chain pathway does not block local transfers. Pausing a token via the guard blocks both local and cross-chain transfers for that token.

Rate Limiter Module

Enforces token bucket rate limits on inbound and outbound transfers, shared across all tokens per destination EID.

How It Works

Rate limits are tracked per EID (not per Nexus ID). All tokens on the same destination share a single bucket. Token amounts are converted to a common unit via per-token scales before consumption, allowing heterogeneous tokens to share a meaningful limit.

Token Scales

Because all tokens on a destination share one rate limit bucket, raw token amounts aren’t directly comparable — transferring 1,000 of a stablecoin is not the same as transferring 1,000 of a governance token. Token scales assign a relative price to each token so that higher-value tokens consume proportionally more of the shared limit.
FieldTypeDescription
scaleuint256Fixed-point price multiplier (denominator: 1e18)
enabledboolWhether scaling is active for this token
A scale of 1e18 means the token’s amount counts at face value (1:1). A scale of 2e18 means each token unit consumes twice as much of the bucket. Setting enabled = true with scale = 0 effectively prices the token at zero, exempting it from rate limit consumption.
function setScales(SetScaleParam[] calldata _params) public;

Configuration

Same as Stablecoin OFT’s rate limiter — token bucket with linear decay, configurable capacity and refill rate, address exemptions, net/gross accounting. The key difference is that limits operate on scaled amounts rather than raw token amounts.

Role

RATE_LIMITER_MANAGER_ROLE (authenticated via Nexus access control). Controls rate limit configs, states, address exemptions, checkpoints, and token scales.

Module Execution Order

On an outbound nexusSend():
1. Pause          → _isPaused(nexusId) reverts if paused
2. Fee            → _debitView() calculates fee, reduces amountReceivedLD
3. Rate Limiter   → _outflow(nexusId) checks and updates outbound bucket
4. Token Transfer → burn amountSentLD, mint fee to feeDeposit
On an inbound _lzReceive():
1. Rate Limiter   → _inflow(nexusId) checks and updates inbound bucket
2. Token Transfer → mint amountLD to recipient

Next Steps