MigrationManager

Git Source

Inherits: IBridgeMessageReceiver, Initializable, AccessControlUpgradeable, PausableUpgradeable, ReentrancyGuardTransientUpgradeable, Versioned

Author: See https://github.com/agglayer/vault-bridge

Migration Manager is a singleton contract on Layer X.

Backing for Custom Tokens minted by Native Converters on Layer Ys can be migrated to Migration Manager on Layer X. Migration Manager completes migrations by calling completeMigration on the corresponidng vbToken, which mints vbToken and bridges it to address zero on the Layer Ys, effectively locking the backing in LxLy Bridge. Please refer to onMessageReceived for more information.

Main functionality.

Other functionality.

Libraries.

External contracts.

This contract exists to prevent manipulation of vbTokens' internal accounting through reentrancy (specifically, claiming assets on LxLy Bridge to vbToken mid-execution).

State Variables

_MIGRATION_MANAGER_STORAGE

The storage slot at which Migration Manager storage starts, following the EIP-7201 standard.

Calculated as keccak256(abi.encode(uint256(keccak256("agglayer.vault-bridge.MigrationManager.storage")) - 1)) & ~bytes32(uint256(0xff)).

bytes32 private constant _MIGRATION_MANAGER_STORAGE =
    hex"30cf29e424d82bdf294fbec113ef39ac73137edfdb802b37ef3fc9ad433c5000";

PAUSER_ROLE

bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

Functions

onlyLxLyBridge

Checks if the sender is LxLy Bridge.

modifier onlyLxLyBridge();

receive

receive() external payable;

constructor

constructor();

initialize

Initializes the Migration Manager contract.

function initialize(address owner_, address lxlyBridge_, address wrappedGasToken_) external initializer;

Parameters

NameTypeDescription
owner_address(ATTENTION) This address will be granted the DEFAULT_ADMIN_ROLE, as well as all basic roles. Roles can be modified at any time.
lxlyBridge_address
wrappedGasToken_addressThe address of the wrapped gas token (e.g., WETH, if the gas token is ETH). Must be the same as the underlying token of the corresponding vbToken (e.g., vbETH, if the gas token is ETH).

lxlyBridge

LxLy Bridge, which connects AggLayer networks.

function lxlyBridge() public view returns (ILxLyBridge);

nativeConvertersConfiguration

Tells which vbToken Native Converter on Layer a Y belongs to.

function nativeConvertersConfiguration(uint32 layerYLxlyId, address nativeConverter)
    public
    view
    returns (TokenPair memory tokenPair);

Parameters

NameTypeDescription
layerYLxlyIduint32Layer Y's LxLy ID.
nativeConverteraddressThe address of Native Converter on Layer Y.

_getMigrationManagerStorage

Returns a pointer to the ERC-7201 storage namespace.

function _getMigrationManagerStorage() private pure returns (MigrationManagerStorage storage $);

configureNativeConverters

Maps Native Converters on Layer Ys to vbToken and underlying token on Layer X.

This function can be called by the owner only.

CAUTION! Misconfiguration could allow an attacker to gain unauthorized access to vbToken and other contracts.

function configureNativeConverters(
    uint32[] calldata layerYLxlyIds,
    address[] calldata nativeConverters,
    address payable vbToken
) external onlyRole(DEFAULT_ADMIN_ROLE) nonReentrant;

Parameters

NameTypeDescription
layerYLxlyIdsuint32[]The Layer Ys' LxLy IDs.
nativeConvertersaddress[]The addresses of Native Converters on Layer Ys.
vbTokenaddress payableThe address of vbToken on Layer X Native Converter belongs to. Set to address zero to unset the tokens. You can override tokens without unsetting them first.

onMessageReceived

When Native Converter migrates backing, it calls both bridgeAsset and bridgeMessage on LxLy Bridge to migrateBackingToLayerX.

The asset must be claimed before the message on LxLy Bridge.

The message tells vbToken how much Custom Token must be backed by vbToken, which is minted and bridged to address zero on the respective Layer Y. This action provides liquidity when bridging Custom Token to from Layer Ys to Layer X and increments the pessimistic proof.

This function can be called by LxLy Bridge only.

function onMessageReceived(address originAddress, uint32 originNetwork, bytes memory data)
    external
    payable
    whenNotPaused
    onlyLxLyBridge
    nonReentrant;

pause

Prevents usage of functions with the whenNotPaused modifier.

This function can be called by the owner only.

function pause() external onlyRole(PAUSER_ROLE) nonReentrant;

unpause

Allows usage of functions with the whenNotPaused modifier.

This function can be called by the owner only.

function unpause() external onlyRole(DEFAULT_ADMIN_ROLE) nonReentrant;

Events

NativeConverterConfigured

event NativeConverterConfigured(uint32 indexed layerYLxlyId, address indexed nativeConverter, address indexed vbToken);

Errors

InvalidOwner

error InvalidOwner();

InvalidLxLyBridge

error InvalidLxLyBridge();

InvalidWrappedGasToken

error InvalidWrappedGasToken();

NonMatchingInputLengths

error NonMatchingInputLengths();

InvalidLayerYLxLyId

error InvalidLayerYLxLyId();

InvalidNativeConverter

error InvalidNativeConverter();

InvalidUnderlyingToken

error InvalidUnderlyingToken();

Unauthorized

error Unauthorized();

CannotWrapGasToken

error CannotWrapGasToken();

InsufficientUnderlyingTokenBalanceAfterWrapping

error InsufficientUnderlyingTokenBalanceAfterWrapping(uint256 newBalance, uint256 expectedBalance);

Structs

TokenPair

Used for mapping Native Converters to vbTokens.

struct TokenPair {
    VaultBridgeToken vbToken;
    IERC20 underlyingToken;
}

MigrationManagerStorage

Storage of the Migration Manager contract.

It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions when using with upgradeable contracts.

Note: storage-location: erc7201:agglayer.vault-bridge.MigrationManager.storage

struct MigrationManagerStorage {
    ILxLyBridge lxlyBridge;
    uint32 _lxlyId;
    mapping(uint32 layerYLxLyId => mapping(address nativeConverter => TokenPair tokenPair))
        nativeConvertersConfiguration;
    IWETH9 _wrappedGasToken;
}

Enums

CrossNetworkInstruction

Used in cross-network communication.

enum CrossNetworkInstruction {
    _0_COMPLETE_MIGRATION,
    _1_WRAP_GAS_TOKEN_AND_COMPLETE_MIGRATION
}