Withdrawals
Withdrawals work quite differently from deposits and follow a very complex architecture on the L1 and L2 to make sure they work in all possible scenarios.
They generally commence in three stages:
- User-sent L2 withdrawal transaction is sequenced and executed
- Withdrawal is part of the next settlement
- Withdrawals get unrolled onto the L1 iteratively.
- Withdrawals get claimed by the user
Steps 3. and 4. might be a bit confusing, so lets walk through that mechanism in detail:
Because of Mina’s account update limit, the process to get all L2 withdrawal onto the L1’s ledger is by iteratively unrolling them. This happens in batches of 6 and can be executed by anyone (doesn’t have to be the sequencer, but will be in most cases).
Now, because of the way that the L1’s zkapps protocol is designed, we have to use a extra step before the tokens are actually in the user’s wallet. During this step, every users gets their withdrawal minted as a special custom token on the L1. This custom token is managed by the protokit bridging contract and does two things: It mints customs tokens during the unrolling, and it lets users redeem those custom tokens for the real tokens. This claiming step is done by each user individually at their own pace. Further reasoning and design choices can be found in this page’s references
Implementing withdrawals
The protokit library already offers a pre-built Withdrawals runtime module, that provides a implementation for
token withdrawals.
On the other side, the default BridgingContract offers processing of token withdrawals on the L1 side.
References
// TODO Add links to spec issues