Skip to content

L2 Relayer

GitHub

The source code for the Relayer.vy contract slightly differ depending on the chain its deployed to.

A comprehensive list of all deployed contracts is available here .

The L2 Relayer contract acts as a middleman, receiving messages and relaying them to the specific agent (ownership, parameter, or emergency).

The Relayer receives the broadcasted message and, using the relay function, forwards this message to the appropriate agent. The agents defined in the L2 Relayer contract (OWNERSHIP_AGENT, PARAMETER_AGENT, EMERGENCY_AGENT) are responsible for executing the calldata in the message.

Warning

A Relayer's agent addresses cannot be altered. Once choosen, there is no way back.

The contract utilizes chain dependent Messenger contacts:

Chain Description Messenger Contract
Arbitrum ArbSys 0x0000000000000000000000000000000000000064
Optimism L2 Cross Chain Domain Messenger 0x4200000000000000000000000000000000000007
Base L2 Cross Chain Domain Messenger 0x4200000000000000000000000000000000000007
Mantle L2 Cross Chain Domain Messenger 0x4200000000000000000000000000000000000007
BinanceSmartChain MessageDigestProver 0xbfF1f56c8e48e2F2F52941e16FEecc76C49f1825
Fantom circle@2x Fantom MessageDigestProver 0xAb0ab357a10c0161002A91426912933750082A9d

Relaying Messages

The source code of the relay function may vary slightly depending on the type of Relayer used. However, the general concept remains consistent:

A message is broadcast through the Broadcaster contract from L1 to L2, where the Relayer relays the message and executes it via the corresponding agent.

relay

Relayer.relay(_agent: Agent, _messages: DynArray[Message, MAX_MESSAGES]):

Guarded Method

This function can only be called by the MESSENGER of the contract.

Function to receive a message from the Broadcaster and relay the message to the according agent. This function is automatically called by the MESSENGER contract of the according chain. There is no need to manually call this function, which would actually revert as it is a guarded function.

Input Type Description
_agent address Token to transfer
_messages address Destination of the asset
Source code
@external
def relay(_agent: Agent, _messages: DynArray[Message, MAX_MESSAGES]):
    """
    @notice Receive messages for an agent and relay them.
    @param _agent The agent to relay messages to.
    @param _messages The sequence of messages to relay.
    """
    assert IArbSys(ARBSYS).wasMyCallersAddressAliased()
    assert IArbSys(ARBSYS).myCallersAddressWithoutAliasing() == self

    IAgent(self.agent[_agent]).execute(_messages)
@external
def relay(_agent: Agent, _messages: DynArray[Message, MAX_MESSAGES]):
    """
    @notice Receive messages for an agent and relay them.
    @param _agent The agent to relay messages to.
    @param _messages The sequence of messages to relay.
    """
    assert msg.sender == MESSENGER
    assert IMessenger(MESSENGER).xDomainMessageSender() == self

    IAgent(self.agent[_agent]).execute(_messages)
@external
def relay(_agent: Agent, _messages: DynArray[Message, MAX_MESSAGES]):
    """
    @notice Receive messages for an agent and relay them.
    @param _agent The agent to relay messages to.
    @param _messages The sequence of messages to relay.
    """
    assert msg.sender == self.messenger

    IAgent(self.agent[_agent]).execute(_messages)
>>> Relayer.relay()

Agents

OWNERSHIP_AGENT

Relayer.OWNERSHIP_AGENT() -> address: view

Getter for the ownership agent.

Returns: ownership agent (address).

Source code
OWNERSHIP_AGENT: public(immutable(address))
>>> Relayer.OWNERSHIP_AGENT()
'0x452030a5D962d37D97A9D65487663cD5fd9C2B32'    # arbitrum
'0x28c4A1Fa47EEE9226F8dE7D6AF0a41C62Ca98267'    # optimism

PARAMETER_AGENT

Relayer.PARAMETER_AGENT() -> address: view

Getter for the parameter agent.

Returns: parameter agent (address).

Source code
PARAMETER_AGENT: public(immutable(address))
>>> Relayer.PARAMETER_AGENT()
'0x5ccbB27FB594c5cF6aC0670bbcb360c0072F6839'    # arbitrum
'0xE7F2B72E94d1c2497150c24EA8D65aFFf1027b9b'    # optimism

EMERGENCY_AGENT

Relayer.EMERGENCY_AGENT() -> address: view

Getter for the emergency agent.

Returns: emergency agent (address).

Source code
EMERGENCY_AGENT: public(immutable(address))
>>> Relayer.EMERGENCY_AGENT()
'0x2CB6E1Adf22Af1A38d7C3370441743a123991EC3'    # arbitrum
'0x9fF1ddE4BE9BbD891836863d227248047B3D881b'    # optimism