Description 📹
On L2 we currently emit two logs per withdrawal:
BurnEvent { user, amount, nonce, commitment_hash }
WithdrawalHashAppended { index, commitment_hash, root_hash }
This forces the sequencer/indexer to correlate two events per withdrawal. We want one enriched event that includes both the business data and the MMR/commitment metadata.
✅ Proposed Actions
Branch: feat/single-withdrawal-event-with-id
1) Modify L2 MMR append function
Change the function that appends a withdrawal commitment (naming may differ; adjust to your module):
// before (example)
fn append_withdrawal_hash(commitment_hash: felt252) { ... }
// after
fn append_withdrawal_hash(commitment_hash: felt252) -> (new_root: felt252, leaf_index: u256, element_count: u256) {
// append to MMR
// return post-append metadata
}
2) Update the withdrawal entrypoint to accept an explicit ID and compute enriched commitment
Extend the L2 withdrawal flow (e.g., burn function) to accept a withdrawal_id: u256 provided by the sequencer:
#[external]
fn burn_xzb_for_unlock(
amount_usd: u256, // normalized units
user: ContractAddress,
withdrawal_id: u256, // NEW: sequencer-provided
) {
// ...
}
Commitment hash must include withdrawal_id:
let commitment_hash = keccak256_packed(
user,
amount_usd,
nonce, // current per-user or global nonce used in claims
block_timestamp()
);
3) Replace dual events with a single enriched event
Define a Cairo event struct and emit once with all fields.
#[event]
struct WithdrawalEvent {
#[key] withdrawal_id: u256, // indexed key
#[key] user: ContractAddress, // indexed key
amount_usd: u256,
nonce: u256,
leaf_index: u256, // from append_withdrawal_hash
commitment_hash: felt252, // or split u256 if you store as u256
new_root: felt252,
element_count: u256
}
In the withdrawal function:
let (new_root, leaf_index, element_count) = append_withdrawal_hash(commitment_hash);
emit WithdrawalEvent {
withdrawal_id,
user,
amount_usd,
nonce,
leaf_index,
commitment_hash,
new_root,
element_count
};
- Remove
emit BurnEvent { ... }.
- Remove
emit WithdrawalHashAppended { ... }.
4) Tests & listeners
-
Unit tests
- Update tests to expect one
WithdrawalEvent with the correct field values.
- Assert
leaf_index, new_root, element_count reflect post-append MMR state.
- Assert
commitment_hash equals what the verifier logic uses.
Acceptance Criteria 🧾
- Only one event (
WithdrawalEvent) is emitted per withdrawal.
- Event contains:
withdrawal_id, amount_usd, user, nonce, leaf_index, commitment_hash, new_root, element_count.
📋 Required Guidelines
- PR only if assigned
- Complete within 24 hours
- Include
Close #[issue_id] in PR description
- Ensure build/tests pass and sequencer logic updated before merge
Description 📹
On L2 we currently emit two logs per withdrawal:
BurnEvent { user, amount, nonce, commitment_hash }WithdrawalHashAppended { index, commitment_hash, root_hash }This forces the sequencer/indexer to correlate two events per withdrawal. We want one enriched event that includes both the business data and the MMR/commitment metadata.
✅ Proposed Actions
Branch:
feat/single-withdrawal-event-with-id1) Modify L2 MMR append function
Change the function that appends a withdrawal commitment (naming may differ; adjust to your module):
Return post-append metadata:
new_root(mmr.root after append)leaf_index(position of appended leaf; use u256 if needed)element_count(total leaves/elements after append)Remove any
emit WithdrawalHashAppended(...)in this code path.2) Update the withdrawal entrypoint to accept an explicit ID and compute enriched commitment
Extend the L2 withdrawal flow (e.g.,
burnfunction) to accept awithdrawal_id: u256provided by the sequencer:Commitment hash must include
withdrawal_id:3) Replace dual events with a single enriched event
Define a Cairo event struct and emit once with all fields.
In the withdrawal function:
emit BurnEvent { ... }.emit WithdrawalHashAppended { ... }.4) Tests & listeners
Unit tests
WithdrawalEventwith the correct field values.leaf_index,new_root,element_countreflect post-append MMR state.commitment_hashequals what the verifier logic uses.Acceptance Criteria 🧾
WithdrawalEvent) is emitted per withdrawal.withdrawal_id,amount_usd,user,nonce,leaf_index,commitment_hash,new_root,element_count.📋 Required Guidelines
Close #[issue_id]in PR description