Skip to content

SwapFacility Deep Dive

Architecture Overview

SwapFacility serves as the universal router for the M0 Extension ecosystem, enabling atomic conversions between any approved M0 Extensions and the foundational $M token. The contract maintains minimal state while relying on the TTG governance system for extension approval and access control.

Core Dependencies

  • $M Token: The foundational rebasing token that backs all extensions
  • TTG Registrar: Governance-controlled registry that maintains the approved earners list
  • ReentrancyLock: Advanced protection using transient storage for atomic operations

Swap Operations

Extension-to-Extension Swaps

function swap(address extensionIn, address extensionOut, uint256 amount, address recipient) external
Process Flow:
  1. Validates both extensions are approved earners via _revertIfNotApprovedExtension()
  2. Transfers extension tokens from user to SwapFacility
  3. Calls extensionIn.unwrap() to convert to $M
  4. Measures actual $M received (accounts for rounding differences in v1 extensions)
  5. Approves and calls extensionOut.wrap() to mint target extension tokens

Direct M Token Operations

function swapInM(address extensionOut, uint256 amount, address recipient) external
function swapOutM(address extensionIn, uint256 amount, address recipient) external
Access Control Differences:
  • swapInM: Anyone can convert $M to extensions
  • swapOutM: Requires M_SWAPPER_ROLE or permission for specific extension

Permission System

Two-Tier Extension Model

  1. Standard Extensions: Open for general extension-to-extension swaps
  2. Permissioned Extensions: Require special authorization for $M conversions
function setPermissionedExtension(address extension, bool permissioned) external
function setPermissionedMSwapper(address extension, address swapper, bool allowed) external

Role-Based Access

  • DEFAULT_ADMIN_ROLE: Contract administration and upgrades
  • M_SWAPPER_ROLE: Global permission for swapOutM operations on standard extensions

Security Features

Advanced Reentrancy Protection

The contract inherits from ReentrancyLock which implements transient storage-based locking:

modifier isNotLocked() {
    if (Locker.get() != address(0)) revert ContractLocked();
    address caller_ = isTrustedRouter(msg.sender) ? IMsgSender(msg.sender).msgSender() : msg.sender;
    Locker.set(caller_);
    _;
    Locker.set(address(0));
}

Trusted Router System

For complex integrations (like UniswapV3SwapAdapter), trusted routers can specify the original caller:

  • Direct calls: msg.sender is stored as the locker
  • Trusted router calls: IMsgSender(msg.sender).msgSender() retrieves the original user

Extensions can call swapFacility.msgSender() to get the true transaction initiator.

Governance Integration

All extension approvals are checked against the TTG Registrar:

function _isApprovedEarner(address extension) private view returns (bool) {
    return IRegistrarLike(registrar).get(EARNERS_LIST_IGNORED_KEY) != bytes32(0) ||
           IRegistrarLike(registrar).listContains(EARNERS_LIST_NAME, extension);
}

Gas Optimization

Permit Integration

All swap functions include permit variants supporting both EIP-2612 and EIP-712 signatures:

function swapWithPermit(..., uint256 deadline, uint8 v, bytes32 r, bytes32 s) external
function swapWithPermit(..., uint256 deadline, bytes calldata signature) external

Balance Tracking Precision

For compatibility with Wrapped M v1, the contract measures actual balance changes:

uint256 mBalanceBefore = _mBalanceOf(address(this));
IMExtension(extensionIn).unwrap(address(this), amount);
amount = _mBalanceOf(address(this)) - mBalanceBefore;

Technical Implementation

Immutable Architecture

address public immutable mToken;
address public immutable registrar;

Core dependencies are immutable for security, while operational parameters remain upgradeable.

State Management

The contract maintains minimal state:

  • permissionedExtensions: Extensions requiring special authorization
  • permissionedMSwappers: Authorized swappers for specific permissioned extensions

Event System

event Swapped(address indexed extensionIn, address indexed extensionOut, uint256 amount, address indexed recipient);
event SwappedInM(address indexed extensionOut, uint256 amount, address indexed recipient);
event SwappedOutM(address indexed extensionIn, uint256 amount, address indexed recipient);

Economic Guarantees

SwapFacility maintains perfect 1:1 value relationships by design:

  • No slippage or trading fees
  • Atomic execution prevents arbitrage
  • All conversions preserve dollar parity
  • Extensions remain fully backed by $M reserves

The contract creates implicit liquidity between all M0 Extensions without requiring separate AMM pools, concentrating liquidity in the foundational $M token while enabling seamless cross-extension value transfer.