Skip to content

Instantly share code, notes, and snippets.

@maurelian
Created January 20, 2021 00:11
Show Gist options
  • Save maurelian/7ae127f3c838feeebfe9f77e1928f3ff to your computer and use it in GitHub Desktop.
Save maurelian/7ae127f3c838feeebfe9f77e1928f3ff to your computer and use it in GitHub Desktop.
Description of the withdrawal flow from Optimistic Ethereum's L2

Description of the withdrawal flow

Starting on L2:

  • Any account on L2 may call OVM_L2CrossDomainMessenger.sendMessage() with the information for the L1 message (aka xDomainCalldata)
    • (ie. _target, msg.sender, _message)
    • This data is hashed with the messageNonce storage variable, and the hash is store in the sentMessages mapping (this is not actually used AFAIK)
    • The messageNonce is then incremented.
  • The OVM_L2CrossDomainMessenger then passes the xDomainCalldata to OVM_L2ToL1MessagePasser.passMessageToL1()
    • the xDomainCalldata is hashed with msg.sender (ie. ovmCaller), and written to the sentMessages mapping.

Then on L1:

  • The Relayer (and only the Relayer) may call OVM_L1CrossDomainMessenger.relayMessage() providing the raw message inputs and an L2 inclusion proof.
    • The relayer checks the following things:
      • in _verifyStateRootProof():
        • checks that the fraud proof window has closed for the batch to which the transaction belongs
        • checks that the batch is stored in the OVM_ChainStorageContainer
          • (all state changing functions are onlyOwner protected in the OVM_ChainStorageContainer)
      • in _verifyStorageProof():
        • checks the proof to confirm that the message data provided is in the OVM_L2ToL1MessagePasser.sentMessages mapping
      • checks that this transaction has not already been written to the successfulMessages mapping.
    • The address of the L2 call is then written to the xDomainMessageSender state var
    • the call is then executed
    • if it succeeds it is added to the successfulMessages and cannot be relayed again
    • regardless of success, and entry is written to the relayedMessages mapping

Then the receiver (in this case SynthetixBridgeToOptimism):

  • Checks that the caller is the OVM_L1CrossDomainMessenger and that the xDomainMessageSender is the synthetixBridgeToBase on L2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment