LayerX SettlementAnchor, LayerXVault, and Deployment Contracts
On-chain contracts for LayerX: SettlementAnchor (immutable root log), LayerXVault (reserve custody, deposits, settlement, force-exit), in-house safety libraries, and the Foundry deployment script.
Overview
The LayerX contract suite is self-contained: production src/ has zero external imports. Safety primitives (ECDSA, EIP-712, SafeERC20, Governed, Pausable) are reimplemented in-house under src/lib. The two primary contracts are LayerXVault (reserve custody and settlement) and SettlementAnchor (immutable root log).
Foundry Configuration
Source: layerx/contracts/foundry.toml
| Key | Value |
|---|---|
src | src |
test | test |
script | script |
solc | 0.8.27 |
evm_version | shanghai |
optimizer | true (200 runs) |
[rpc_endpoints].paxeer | ${PAXEER_RPC_URL} |
forge-std is vendored under lib/ for tests only; production src/ never imports it.
Deployment Script
Source: layerx/contracts/script/Deploy.s.sol
Deploy.run reads environment variables, deploys SettlementAnchor first, then LayerXVault, and conditionally wires the anchor writer when the broadcaster matches the governor.
| Environment variable | Role |
|---|---|
LAYERX_GOVERNOR | Protocol root authority |
LAYERX_OPERATOR_ADDR | Sequencer EVM key |
LAYERX_GUARDIAN | Emergency pause authority |
LAYERX_USDL_ADDR | USDL reserve token |
LAYERX_DEX_ROUTER | Paxeer DEX router |
LAYERX_WRAPPED_NATIVE | Wrapped native asset |
LAYERX_EXIT_DELAY | Force-exit challenge window (seconds) |
SettlementAnchor
Source: layerx/contracts/src/SettlementAnchor.sol
Minimal, append-only registry for settled batch Merkle roots. Never holds funds.
Properties
| Property | Type | Description |
|---|---|---|
writer | address | Authorized writer |
rootOf | mapping(bytes32 => bytes32) | Anchored root per batch id |
anchored | mapping(bytes32 => bool) | Idempotency flag |
Methods
| Method | Access | Description |
|---|---|---|
record(batchId, root, totalSettled, count, windowEnd) | Writer | Anchor one batch root, emit SettlementAnchored |
setWriter(newWriter) | Governor | Rotate authorized writer |
Errors
NotWriter, AlreadyAnchored, ZeroRoot
Event
SettlementAnchored(batchId, root, totalSettled, count, windowEnd, anchoredAt)
LayerXVault
Source: layerx/contracts/src/LayerXVault.sol
On-chain custody and settlement contract. Holds the USDL reserve, mints USDX accounting against deposits, executes settlement payouts, and provides the unilateral force-exit escape hatch.
Constructor
| Parameter | Type | Description |
|---|---|---|
usdl_ | address | Reserve asset (USDL) |
governor_ | address | Protocol root authority |
operator_ | address | Sequencer key |
guardian_ | address | Emergency pause |
anchor_ | address | SettlementAnchor contract |
dexRouter_ | address | PECOR DEX router |
wrappedNative_ | address | Wrapped native token |
exitDelay_ | uint64 | Force-exit challenge window |
Deposit methods
| Method | Description |
|---|---|
depositUSDL(amount, did) | Direct USDL deposit, mints USDX 1:1 |
depositSwap(tokenIn, amountIn, amountOutMin, deadline, did) | Swap allowlisted token to USDL, mint from realized output |
depositNative(amountOutMin, deadline, did) | Wrap native PAX, swap to USDL, mint |
All deposit paths measure token balance deltas before/after transfer (fee-on-transfer safe).
Settlement
settle(batch) anchors the root via SettlementAnchor.record, then pays batch recipients via SafeERC20.safeTransfer. Protected by reentrancy guard. Batch is idempotent via settledBatch[batchId].
Force-exit (L1 escape hatch)
| Method | Description |
|---|---|
initiateExit(amount, epoch, operatorSig) | Start exit using operator's co-signed balance proof (EIP-712) |
challengeExit(amount, epoch, operatorSig) | Replace pending exit with strictly newer proof |
finalizeExit() | Complete matured exit after exitDelay |
Admin methods
setOperator, setGuardian, setDexRouter, setAnchor, setWrappedNative, setExitDelay, setMaxSettlementPerBatch, setSwapAllowed, pause, unpause
Key properties
| Property | Type | Description |
|---|---|---|
usdl | IERC20 | Reserve token |
operator | address | Settlement operator |
guardian | address | Pause authority |
anchor | ISettlementAnchor | Root log |
totalDeposited | uint256 | Cumulative USDL deposited |
totalSettledOut | uint256 | Cumulative USDL settled |
totalExited | uint256 | Cumulative USDL exited |
exitDelay | uint64 | Force-exit window |
maxSettlementPerBatch | uint256 | Per-batch cap (0 = uncapped) |
In-House Safety Libraries
ECDSA (src/lib/ECDSA.sol)
secp256k1 signer recovery. Rejects high-s signatures, invalid v values, zero-address recovery.
EIP712 (src/lib/EIP712.sol)
Typed-data domain hashing. Domain separator cached at construction, re-derived on chain ID change (fork-safe).
SafeERC20 (src/lib/SafeERC20.sol)
Token-call wrapper. Tolerates no-boolean-return ERC-20 variants. forceApprove handles USDT-style reset-to-zero.
Governed (src/lib/Governed.sol)
Two-step governance handoff: transferGovernance + acceptGovernance.
Pausable (src/lib/Pausable.sol)
Emergency stop with _pause/_unpause and whenNotPaused/whenPaused modifiers.
Chain Bindings (Go side)
Source: layerx/internal/chain/bindings.go
Minimal inline ABI fragments for the contracts the sequencer touches:
| ABI | Contract | Methods |
|---|---|---|
layerXVaultABI | LayerXVault | settle, reserveBalance, operator, settledBatch, exited + Deposit/Settled events |
settlementAnchorABI | SettlementAnchor | rootOf, anchored, writer + SettlementAnchored event |
erc20ABI | IERC20 | balanceOf, decimals |
pecorRouterABI | IPECORRouter | swapBestRoute |
PackSettle ABI-encodes a LayerXVault.settle(batch) call.
Paxeer Chain Integration
Source: layerx/internal/chain/settler.go, layerx/internal/chain/watcher.go, layerx/internal/chain/operator.go
The Settler submits settlement batches to the vault contract. The Watcher monitors Deposit events for chain-in crediting. The Operator manages the sequencer's on-chain transactions.
