List of functions:
deposit()
withdraw()
processWithdraw()
executeBlock()
startExodus()
Deposit ETH to the contract. This function should:
- Check that exodus mode is not active.
- Increase number of
mintedCoinsCounter
. - Use this
mintedCoinsCounter
ascoinId
for theDeposit
event. - Mint event
Deposit
with the amount of ETH deposited and address of the sender. - Add deposit to map of address to amount of ETH,
coinId
andL1BlockNumber
of the deposit. - Increase unprocessed deposits amount.
If exodus is not started:
- Get
merkleRoot
frommerkleRoots
byL2blockNumber
- Verify that
merklePath
from arguments is valid merkle path tomerkleRoot
- Verify that
coinId
is not used before. If it's used - check thatcoinId
> currentcoinId
fromusedCoinIds
- Remove previous withdraw from
WaitingForWithdrawals
- Emmit
WaitingForWithdraw
event withamount
andaddress
of the sender - Add this withdraw to
WaitingForWithdrawals
map. Setamount
andaddress
andL1BlockNumber
andmerklePosition
andcoinId
of the deposit.
- Check that
withdrawId
inWaitingForWithdraw
structure. - Check that
L1BlockNumber
+WITHDRAW_WAITING_TIME
of the deposit is less than currentL1BlockNumber
- Start exodus if it's not started.
- Set
prevMerkleRoot
as value frommerkleRoots
by keylastL2blockNumber
- Calculate
hash(DepositsBytes)
- Calculate
hash(WithdrawsBytes)
- Verify proof with
prevMerkleRoot
,newMerkleRoot
,hash(DepositsBytes)
,hash(WithdrawsBytes)
andproof
- Remove all elements of
DepositsBytes
from some magic structure of the deposits - Send ETH to all
WithdrawsBytes
- Remove all elements of
WithdrawsBytes
fromWaitingForWithdrawals
map - Emmit
BlockExecuted
event withL2blockNumber
,newMerkleRoot
,hash(DepositsBytes)
,hash(WithdrawsBytes)
TODO PART: publish coinId in Withdrawals, ProcessWithdraw
- Check that
exodusStarted
is false - Set
censouredDeposits
as value from some magic structure of the deposits with keycensouredDepositId
- Check that L1BlockNumber from
censouredDeposits
+DEPOSIT_WAITING_TIME
is less than currentL1BlockNumber
- Emmit
ExodusStarted
event exodusStarted
= true
Circuit separetadet do 4 parts:
- Contract withdraw parts
- Deposit parts
- Transfer commitment parts
- Transfer execution parts
Public inputs:
initallStateRoot
finalStateRoot
hash(contractWithdrawals)
hash(withdrawals)
markle_root(wrongWithdrawals)
hash(deposits)
hash(contractWithdrawals) = contractWithdrawals
accomulatorWrongWithdrawals = empty_merkle_tree
initallStateRoot == state
for every contractWithdrawal:
contractWithdrawal = (coinId, amount, address, merklePosition)
(stateCoinId, stateAmount, stateAddress) = state_tree[merklePosition]
check this statment:
(
coinId == stateCoinId
amount == stateAmount
address == stateAddress
state == removeElement(state, merklePosition)
) or
(
(
coinId != stateCoinId
or
amount != stateAmount
or
address != stateAddress
)
nextCccomulatorWrongWithdrawals = addOneToMerkleTree(prevAccomulatorWrongWithdrawals, withdrawal)
)
and check that accomulatorWrongWithdrawals == markle_root(wrongWithdrawals)
save final state to stateAfterWithdrawals
hash(deposits) = deposits
state = stateAfterWithdrawals
for every deposit:
deposit = (coinId, amount, address)
state = addOneToMerkleTree(state, deposit)
save final state to stateAfterDeposit
hash(transactions) = transactions_hash
transferAccomulator = empty_merkle_tree
for every transaction:
transaction = (from_address, to_address, amount, coin_id, signature)
verify merkle proof of note from transaction
savedAmount + fee = amount
operatorFee = fee + operatorFee
check(signature, from_address)
state = addOneToMerkleTree(state, from_address, to_address, amount, coin_id, signature)
transferAccomulator = addOneToMerkleTree(transferAccomulator, transaction)
for every withdrawal:
state == removeElement(state, withdrawal)
transferAccomulator == removeElement(transferAccomulator, withdrawal)
for every transaction_confirmation:
transaction_confirmation = (transaction, signature)
transaction = (from_address, to_address, amount, coin_id, signature)
check(signature, to_address)
transferAccomulator == removeElement(transferAccomulator, transaction)
in the end check that transferAccomulator == empty_merkle_tree
It's trivial.
- Get from the contract: Deposits, Withdrawals
- Colect transactions from senders
- Collect confirmations from receivers
- Withdrawals without confirmations
- Commit block