Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
2d0601ca
Unverified
Commit
2d0601ca
authored
Dec 02, 2022
by
Joshua Gutow
Committed by
GitHub
Dec 02, 2022
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4056 from ethereum-optimism/clabby/specs/two-step-withdrawals
specs: Update `withdrawals` spec
parents
3659a097
2617c9ae
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
50 additions
and
37 deletions
+50
-37
withdrawals.md
specs/withdrawals.md
+50
-37
No files found.
specs/withdrawals.md
View file @
2d0601ca
# Withdrawals
# Withdrawals
<!-- All glossary references in this file. -->
<!-- All glossary references in this file. -->
[
g-deposits
]:
glossary.md#deposits
[
g-deposits
]:
glossary.md#deposits
[
g-deposited
]:
glossary.md#deposited-transaction
[
g-deposited
]:
glossary.md#deposited-transaction
[
deposit-tx-type
]:
glossary.md#deposited-transaction-type
[
deposit-tx-type
]:
glossary.md#deposited-transaction-type
[
g-withdrawal
]:
glossary.md#withdrawal
[
g-withdrawal
]:
glossary.md#withdrawal
[
g-mpt
]:
glossary.md#merkle-patricia-trie
[
g-mpt
]:
glossary.md#merkle-patricia-trie
[
g-relayer
]:
glossary.md#withdrawals
[
g-relayer
]:
glossary.md#withdrawals
[
g-execution-engine
]:
glossary.md#execution-engine
[
g-execution-engine
]:
glossary.md#execution-engine
[
Withdrawals
][
g-withdrawal
]
are cross domain transactions which are initiated on L2, and finalized by a transaction
[
Withdrawals
][
g-withdrawal
]
are cross domain transactions which are initiated on L2, and finalized by a transaction
executed on L1. Notably, withdrawals may be used by an
d
L2 account to call an L1 contract, or to transfer ETH from
executed on L1. Notably, withdrawals may be used by an L2 account to call an L1 contract, or to transfer ETH from
an L2 account to an L1 account.
an L2 account to an L1 account.
**Vocabulary note**
:
*withdrawal*
can refer to the transaction at various stages of the process, but we introduce
**Vocabulary note**
:
_withdrawal_
can refer to the transaction at various stages of the process, but we introduce
more specific terms to differentiate:
more specific terms to differentiate:
-
A
*withdrawal initiating transaction*
refers specifically to a transaction on L2 sent to the Withdrawals predeploy.
-
A
_withdrawal initiating transaction_
refers specifically to a transaction on L2 sent to the Withdrawals predeploy.
-
A
*withdrawal finalizing transaction*
refers specifically to an L1 transaction which finalizes and relays the
-
A
_withdrawal finalizing transaction_
refers specifically to an L1 transaction which finalizes and relays the
withdrawal.
withdrawal.
Withdrawals are initiated on L2 via a call to the Message Passer predeploy contract, which records the important
Withdrawals are initiated on L2 via a call to the Message Passer predeploy contract, which records the important
...
@@ -55,18 +55,27 @@ We first describe the end to end flow of initiating and finalizing a withdrawal:
...
@@ -55,18 +55,27 @@ We first describe the end to end flow of initiating and finalizing a withdrawal:
### On L2
### On L2
An L2 account sends a withdrawal message (and possibly also ETH) to the
`L2ToL1MessagePasser`
predeploy contract.
An L2 account sends a withdrawal message (and possibly also ETH) to the
`L2ToL1MessagePasser`
predeploy contract.
This is a very simple contract that stores the a hash of the withdrawal data.
This is a very simple contract that stores the a hash of the withdrawal data.
### On L1
### On L1
1.
A
[
relayer
][
g-relayer
]
submits the required inputs to the
`OptimismPortal`
contract. The relayer need
1.
A
[
relayer
][
g-relayer
]
submits the required inputs to the
`OptimismPortal`
contract. The relayer need
not be the same entity which initiated the withdrawal on L2.
not be the same entity which initiated the withdrawal on L2.
These inputs include the withdrawal transaction data, inclusion proofs, and a
timestamp. The timestamp
These inputs include the withdrawal transaction data, inclusion proofs, and a
block number. The block number
must be one for which an L2 output root exists, which commits to the withdrawal as registered on L2.
must be one for which an L2 output root exists, which commits to the withdrawal as registered on L2.
2.
The
`OptimismPortal`
contract retrieves the output root for the given timestamp from the
`OutputOracle`
's
1.
The
`OptimismPortal`
contract retrieves the output root for the given block number from the
`L2OutputOracle`
's
`l2Outputs()`
function, and performs the remainder of the verification process internally.
`getL2OutputAfter()`
function, and performs the remainder of the verification process internally.
3.
If verification fails, the call reverts. Otherwise the call is forwarded, and the hash is recorded to prevent it from
1.
If proof verification fails, the call reverts. Otherwise the call is forwarded, and the hash is recorded to
from being replayed.
prevent it from being re-proven. Note that the withdrawal can be proven more than once if the corresponding
output root changes.
1.
After the withdrawal is proven, it enters a 7 day challenge period, allowing time for other network participants
to challenge its integrity.
1.
Once the challenge period has passed, a relayer submits the withdrawal transaction once again to the
`OptimismPortal`
contract. Again, the relayer need not be the same entity which initiated the withdrawal on L2.
1.
The
`OptimismPortal`
contract receives the withdrawal transaction data and verifies that the withdrawal has
both been proven and passed the challenge period.
1.
If the requirements are not met, the call reverts. Otherwise the call is forwarded, and the hash is recorded to
prevent it from being replayed.
## The L2ToL1MessagePasser Contract
## The L2ToL1MessagePasser Contract
...
@@ -113,7 +122,7 @@ of withdrawals, which do not modify the sender's address. The difference is that
...
@@ -113,7 +122,7 @@ of withdrawals, which do not modify the sender's address. The difference is that
-
on L2, the deposit sender's address is returned by the
`CALLER`
opcode, meaning a contract cannot easily tell if the
-
on L2, the deposit sender's address is returned by the
`CALLER`
opcode, meaning a contract cannot easily tell if the
call originated on L1 or L2, whereas
call originated on L1 or L2, whereas
-
on L1, the withdrawal sender's address is accessed by calling the
`l2Sender
`
()
function on the
`OptimismPortal`
-
on L1, the withdrawal sender's address is accessed by calling the
`l2Sender
()`
function on the
`OptimismPortal`
contract.
contract.
Calling
`l2Sender()`
removes any ambiguity about which domain the call originated from. Still, developers will need to
Calling
`l2Sender()`
removes any ambiguity about which domain the call originated from. Still, developers will need to
...
@@ -125,6 +134,9 @@ The Optimism Portal serves as both the entry and exit point to the Optimism L2.
...
@@ -125,6 +134,9 @@ The Optimism Portal serves as both the entry and exit point to the Optimism L2.
the
[
DepositFeed
](
./deposits.md#deposit-contract
)
contract, and in addition provides the following interface for
the
[
DepositFeed
](
./deposits.md#deposit-contract
)
contract, and in addition provides the following interface for
withdrawals:
withdrawals:
-
[
WithdrawalTransaction type
](
https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/contracts/libraries/Types.sol#L46-L56
)
-
[
OutputRootProof type
](
https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/contracts/libraries/Types.sol#L20-L29
)
```
js
```
js
interface
OptimismPortal
{
interface
OptimismPortal
{
...
@@ -132,23 +144,22 @@ interface OptimismPortal {
...
@@ -132,23 +144,22 @@ interface OptimismPortal {
function
l2Sender
()
returns
(
address
)
external
;
function
l2Sender
()
returns
(
address
)
external
;
function
proveWithdrawalTransaction
(
Types
.
WithdrawalTransaction
memory
_tx
,
uint256
_l2BlockNumber
,
Types
.
OutputRootProof
calldata
_outputRootProof
,
bytes
[]
calldata
_withdrawalProof
)
external
;
function
finalizeWithdrawalTransaction
(
function
finalizeWithdrawalTransaction
(
uint256
_nonce
,
Types
.
WithdrawalTransaction
memory
_tx
address
_sender
,
)
external
;
address
_target
,
uint256
_value
,
uint256
_gasLimit
,
bytes
calldata
_data
,
uint256
_timestamp
,
WithdrawalVerifier
.
OutputRootProof
calldata
_outputRootProof
,
bytes
calldata
_withdrawalProof
)
}
}
```
```
## Withdrawal Verification and Finalization
## Withdrawal Verification and Finalization
The following inputs are required to
verify
and finalize a withdrawal:
The following inputs are required to
prove
and finalize a withdrawal:
-
Withdrawal transaction data:
-
Withdrawal transaction data:
-
`nonce`
: Nonce for the provided message.
-
`nonce`
: Nonce for the provided message.
...
@@ -158,15 +169,15 @@ The following inputs are required to verify and finalize a withdrawal:
...
@@ -158,15 +169,15 @@ The following inputs are required to verify and finalize a withdrawal:
-
`data`
: Data to send to the target.
-
`data`
: Data to send to the target.
-
`gasLimit`
: Gas to be forwarded to the target.
-
`gasLimit`
: Gas to be forwarded to the target.
-
Proof and verification data:
-
Proof and verification data:
-
`
timestamp`
: The L2 timestamp corresponding with
the output root.
-
`
l2BlockNumber`
: The L2 block number that corresponds to
the output root.
-
`outputRootProof`
: Four
`bytes32`
values which are used to derive the output root.
-
`outputRootProof`
: Four
`bytes32`
values which are used to derive the output root.
-
`withdrawalProof`
: An inclusion proof for the given withdrawal in the L2ToL1MessagePasser contract.
-
`withdrawalProof`
: An inclusion proof for the given withdrawal in the L2ToL1MessagePasser contract.
These inputs must satisfy the following conditions:
These inputs must satisfy the following conditions:
1.
The
`
timestamp`
is at least
`FINALIZATION_PERIOD`
seconds old
.
1.
The
`
l2BlockNumber`
must be the block number that corresponds to the
`OutputProposal`
being proven
.
1.
`
OutputOracle.l2Outputs(timestamp)`
returns a non-zero value
`l2Output
`
.
1.
`
L2OutputOracle.getL2OutputAfter(l2BlockNumber)`
returns a non-zero
`OutputProposal
`
.
1.
The keccak256 hash of the
`outputRootProof`
values is equal to the
`
l2Outpu
t`
.
1.
The keccak256 hash of the
`outputRootProof`
values is equal to the
`
outputRoo
t`
.
1.
The
`withdrawalProof`
is a valid inclusion proof demonstrating that a hash of the Withdrawal transaction data
1.
The
`withdrawalProof`
is a valid inclusion proof demonstrating that a hash of the Withdrawal transaction data
is contained in the storage of the L2ToL1MessagePasser contract on L2.
is contained in the storage of the L2ToL1MessagePasser contract on L2.
...
@@ -175,19 +186,21 @@ These inputs must satisfy the following conditions:
...
@@ -175,19 +186,21 @@ These inputs must satisfy the following conditions:
### Key Properties of Withdrawal Verification
### Key Properties of Withdrawal Verification
1.
It should not be possible 'double spend' a withdrawal, ie. to relay a withdrawal on L1 which does not
1.
It should not be possible 'double spend' a withdrawal, ie. to relay a withdrawal on L1 which does not
correspond to a message initiated on L2. For reference, see
[
this writeup
][
polygon-dbl-spend
]
of a vulnerability
correspond to a message initiated on L2. For reference, see
[
this writeup
][
polygon-dbl-spend
]
of a vulnerability
of this type found on Polygon.
of this type found on Polygon.
[polygon-dbl-spend]: https://gerhard-wagner.medium.com/double-spending-bug-in-polygons-plasma-bridge-2e0954ccadf1
[
polygon-dbl-spend
]:
https://gerhard-wagner.medium.com/double-spending-bug-in-polygons-plasma-bridge-2e0954ccadf1
1.
For each withdrawal initiated on L2 (ie. with a unique
`nonce`
), the following properties must hold:
1.
For each withdrawal initiated on L2 (ie. with a unique
`nonce`
), the following properties must hold:
1.
It should only be possible to finalize the withdrawal once.
1.
It should only be possible to prove the withdrawal once, unless the outputRoot for the withdrawal
1.
It should not be possible to relay the message with any of its fields modified, ie.
has changed.
1.
Modifying the
`sender`
field would enable a 'spoofing' attack.
1.
It should only be possible to finalize the withdrawal once.
1.
Modifying the
`target`
,
`message`
, or
`value`
fields would enable an attacker to dangerously change the
1.
It should not be possible to relay the message with any of its fields modified, ie.
intended outcome of the withdrawal.
1.
Modifying the
`sender`
field would enable a 'spoofing' attack.
1.
Modifying the
`gasLimit`
could make the cost of relaying too high, or allow the relayer to cause execution
1.
Modifying the
`target`
,
`message`
, or
`value`
fields would enable an attacker to dangerously change the
to fail (out of gas) in the
`target`
.
intended outcome of the withdrawal.
1.
Modifying the
`gasLimit`
could make the cost of relaying too high, or allow the relayer to cause execution
to fail (out of gas) in the
`target`
.
### Handling Successfully Verified Messages That Fail When Relayed
### Handling Successfully Verified Messages That Fail When Relayed
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment