1use alloy_primitives::{address, bytes, Address, Bytes, FixedBytes};
6
7pub const SYSTEM_ADDRESS: Address = address!("fffffffffffffffffffffffffffffffffffffffe");
10
11pub const WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS: Address =
13 address!("0x00000961Ef480Eb55e80D19ad83579A64c007002");
14
15pub static WITHDRAWAL_REQUEST_PREDEPLOY_CODE: Bytes = bytes!(" 3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd");
17
18pub const WITHDRAWAL_REQUEST_TYPE: u8 = 0x01;
20
21pub const MAX_WITHDRAWAL_REQUESTS_PER_BLOCK: usize = 16;
23
24#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
29#[cfg_attr(feature = "ssz", derive(ssz_derive::Encode, ssz_derive::Decode))]
30#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
31pub struct WithdrawalRequest {
32 pub source_address: Address,
34 pub validator_pubkey: FixedBytes<48>,
36 #[cfg_attr(feature = "serde", serde(with = "alloy_serde::displayfromstr"))]
38 pub amount: u64,
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44 use alloy_primitives::hex;
45
46 #[test]
47 #[cfg(feature = "serde")]
48 fn test_serde_withdrawal_request() {
49 let json_data = r#"{
51 "source_address":"0xAE0E8770147AaA6828a0D6f642504663F10F7d1E",
52 "validator_pubkey":"0x8e8d8749f6bc79b78be7cc6e49ff640e608454840c360b344c3a4d9b7428e280e7f40d2271bad65d8cbbfdd43cb8793b",
53 "amount":"1"
54 }"#;
55
56 let withdrawal_request: WithdrawalRequest =
58 serde_json::from_str(json_data).expect("Failed to deserialize");
59
60 assert_eq!(
62 withdrawal_request.source_address,
63 address!("AE0E8770147AaA6828a0D6f642504663F10F7d1E")
64 );
65 assert_eq!(
66 withdrawal_request.validator_pubkey,
67 FixedBytes::<48>::from(hex!("8e8d8749f6bc79b78be7cc6e49ff640e608454840c360b344c3a4d9b7428e280e7f40d2271bad65d8cbbfdd43cb8793b"))
68 );
69 assert_eq!(withdrawal_request.amount, 1);
70
71 let serialized_json =
73 serde_json::to_string(&withdrawal_request).expect("Failed to serialize");
74
75 let expected_json = r#"{"source_address":"0xae0e8770147aaa6828a0d6f642504663f10f7d1e","validator_pubkey":"0x8e8d8749f6bc79b78be7cc6e49ff640e608454840c360b344c3a4d9b7428e280e7f40d2271bad65d8cbbfdd43cb8793b","amount":"1"}"#;
77 assert_eq!(serialized_json, expected_json);
78 }
79}