-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Create safeDeposit.md Wrote up the issue of deposits being added after unseen validator blocks along with a few solutions. * Update safeDeposit.md Bold solutions * Update safeDeposit.md Include the solution that we will use in our implementation.
- Loading branch information
1 parent
7694183
commit da3b1ec
Showing
1 changed file
with
36 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
## Safe Deposits on Plasma | ||
|
||
A naive implementation of deposit allows a malicious validator to steal a user's deposit. | ||
|
||
To deposit on a child chain: | ||
|
||
1. The user validates the child chain up to latest block n | ||
2. The user submits a deposit transaction to the Ethereum rootchain | ||
|
||
A malicious validator want to steal the user's deposit. The validator sees the user's deposit transaction in the transaction mempool, and can steal the deposit by doing the following: | ||
|
||
1. Create an invalid block of size n + 1 that contains a UTXO created out of thin air that is equal in denomination to the user's deposit. | ||
2. Submit the invalid submitBlock transaction to Ethereum rootchain with a very high gasPrice | ||
3. There is some probability that the Ethereum rootchain processes invalid submitBlock transaction before user's deposit transaction. Everyone on the child chain including the validator submits a startExit transaction after seeing invalid block. | ||
|
||
Since the deposit transaction occurs in a block after the invalid block, it will have higher priority than the invalid block and will be processed later. | ||
|
||
The validator can successfully withdraw his invalid UTXO, and the smart contract is drained before it can process the user's deposit. | ||
|
||
#### Solution #1: | ||
|
||
Assign all deposits a priority = 0. This does not work because it will be easy to DOS a child chain by simply depositing and exiting repeatedly. The attacker loses gas, but for a relatively low price he can indefinitely stall exits on the child chain. | ||
|
||
#### Solution #2: | ||
|
||
Change deposit function to ``deposit(validatorBlockNum, txBytes)`` so that user can commit to the latest validatorBlockNum they have seen. If a new validator block gets added before the deposit transaction gets processed, the deposit reverts and the user may resubmit the transaction if the new block is valid. | ||
|
||
This may require users to deposit multiple times before succeeding. | ||
|
||
#### Solution #3: | ||
|
||
Have validator-submitted blocks increment in multiples of 1000. Fill in deposits at positions starting from 1 that are not multiples of 1000. This allows the deposit to have a much lower priority than any recent submitted block however the deposit amount is limited to ~1000*(number of submitted blocks). For the vast majority of child chains this will not be an issue. | ||
|
||
#### Solution #4: | ||
|
||
This is the solution that will be in our implementation. Notice that the sidechain only needs to include a deposit if someone tries to spend that deposit on the sidechain. We maintain a seperate mapping that maps an incrementing nonce to every deposit. When a user wants to spend a deposit with nonce n, they simply spend position (0, 0, 0, n) on the sidechain where the first three regular position indices are zeroed out. The validator checks to see if the mapping contains the deposit at key n and that the deposit is presumed final before allowing a spend from the deposit. The validator must also keep track of all previously spent deposits so that users can only spend deposits once. When a user tries to exit a deposit, they are processed in a seperate exitDeposit queue. One can challenge these exiting deposits by proving that the deposit was spent on the child chain. We fix the inflight attack described above by making the waiting period smaller on the deposit queue than on the regular queue. Thus a deposit can exit earlier than an invalid utxo in a submitted block even if the deposit was included shortly after the invalid block. |