hotshot_contract_adapter/
reward.rs1use alloy::{
2 primitives::{Bytes, B256, U256},
3 sol_types::SolValue,
4};
5use derive_more::{From, Into};
6use serde::{Deserialize, Serialize};
7
8#[derive(Clone, Debug, Eq, PartialEq, From)]
9pub struct RewardProofSiblings([B256; 160]);
10
11#[derive(Clone, Debug, Eq, PartialEq, From, Default)]
12pub struct RewardAuthRootInputs([B256; 7]);
13
14#[derive(Clone, Debug, Eq, PartialEq)]
15pub struct RewardAuthData {
16 siblings: RewardProofSiblings,
17 auth_root_inputs: RewardAuthRootInputs,
18}
19
20impl RewardAuthData {
21 pub fn new(siblings: RewardProofSiblings, auth_root_inputs: RewardAuthRootInputs) -> Self {
22 RewardAuthData {
23 siblings,
24 auth_root_inputs,
25 }
26 }
27}
28
29impl From<([B256; 160], [B256; 7])> for RewardAuthData {
30 fn from((siblings, auth_root_inputs): ([B256; 160], [B256; 7])) -> Self {
31 RewardAuthData {
32 siblings: siblings.into(),
33 auth_root_inputs: auth_root_inputs.into(),
34 }
35 }
36}
37
38impl TryFrom<RewardAuthDataEncoded> for RewardAuthData {
39 type Error = alloy::sol_types::Error;
40
41 fn try_from(value: RewardAuthDataEncoded) -> Result<Self, Self::Error> {
42 let decoded: ([B256; 160], [B256; 7]) = SolValue::abi_decode(&value.0)?;
43 Ok(decoded.into())
44 }
45}
46
47#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, From, Into)]
48pub struct RewardAuthDataEncoded(Bytes);
49
50impl From<RewardAuthData> for RewardAuthDataEncoded {
51 fn from(value: RewardAuthData) -> Self {
52 Self(
53 (value.siblings.0, value.auth_root_inputs.0)
54 .abi_encode()
55 .into(),
56 )
57 }
58}
59
60#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
61pub struct RewardClaimInput {
62 pub lifetime_rewards: U256,
63 pub auth_data: RewardAuthDataEncoded,
64}
65
66#[cfg(test)]
67mod tests {
68 use serde_json;
69
70 use super::*;
71
72 fn test_input() -> RewardClaimInput {
73 let siblings = RewardProofSiblings([B256::random(); 160]);
74 let auth_root_inputs = RewardAuthRootInputs([B256::random(); 7]);
75 RewardClaimInput {
76 lifetime_rewards: B256::random().into(),
77 auth_data: RewardAuthData::new(siblings, auth_root_inputs).into(),
78 }
79 }
80
81 #[test]
82 fn test_reward_claim_input_roundtrip_json() {
83 let original = test_input();
84 let json = serde_json::to_string(&original).unwrap();
85 let decoded: RewardClaimInput = serde_json::from_str(&json).unwrap();
86 assert_eq!(decoded, original);
87 }
88
89 #[test]
90 fn test_decode_abi_auth_data() {
91 let original = test_input();
92 let auth_data = RewardAuthData::try_from(original.auth_data.clone()).unwrap();
93 let json = serde_json::to_string(&original).unwrap();
94 let value: serde_json::Value = serde_json::from_str(&json).unwrap();
95 let auth_str = value.get("auth_data").unwrap().as_str().unwrap();
96 assert!(auth_str.starts_with("0x"));
97
98 let (siblings, auth_root_inputs): ([B256; 160], [B256; 7]) =
102 SolValue::abi_decode(&alloy::hex::decode(&auth_str[2..]).unwrap()).unwrap();
103 assert_eq!(siblings, auth_data.siblings.0);
104 assert_eq!(auth_root_inputs, auth_data.auth_root_inputs.0);
105 }
106}