hotshot_contract_adapter/
sol_types.rs

1//! Solidity types for interacting with contracts
2//! Re-export types that are used, sometimes renamed to avoid collision.
3//!
4//! TODO: (alex) Due to <https://github.com/foundry-rs/foundry/issues/10153>,
5//! try to re-export the same type from the "youngest" child contract since that is the contract whose functions are being called,
6//! thus from whom the rust bindings are expected.
7//! E.g. Both PlonkVerifier and LightClient, and LightClientV2 depends on BN254. The inheritance relationship is:
8//!   BN254 <- PlonkVerifier <- LIghtClient <- LightClientV2
9//! Most of the time, we interact with PlonkVerifier's function via LightClientV2, thus import BN254.G1Point from `bindings::plonkverifierv2`.
10//! When we need to directly interact with PlonkVerifier's method, implement stupid plain `From<lc2::BN254::G1Point> for pv::BN254::G1Point`.
11//! If you are lazy, you can even use unsafe memory transmute since they are literally the same representation, duplicated in different modules,
12//! thus treated by the rust type systems as distinct types.
13//!
14//! Another usage is in the differential testing in Solidity tests. In those cases, the actual types don't matter, since they will all `abi_encode()`
15//! into the exact same bytes before being communicated over to contract via FFI. Thus using any one of them is fine.
16
17use alloy::sol;
18
19/// # What to re-export, what to hide?
20/// - export contract struct itself, but try to avoid export instance type (instead, use ::new() to get a handle)
21/// - avoid exporting `xxCall` and `xxReturn` types, they usually can be converted/transmuted from existing struct
22/// - Event types should be exported
23/// - structs should be exported and renamed with `xxSol` suffix to avoid confusion with other rust types
24///   - see module doc for more explanation on types duplication issue in alloy
25pub use crate::bindings::{
26    erc1967proxy::ERC1967Proxy,
27    esptoken::EspToken,
28    esptokenv2::EspTokenV2,
29    feecontract::FeeContract::{self, Deposit},
30    lightclient::{
31        IPlonkVerifier::{PlonkProof as PlonkProofSol, VerifyingKey as VerifyingKeySol},
32        LightClient::{
33            self, LightClientErrors, LightClientInstance, LightClientState as LightClientStateSol,
34            StakeTableState as StakeTableStateSol,
35        },
36        BN254::G1Point as G1PointSol,
37    },
38    lightclientmock::{self, LightClientMock},
39    lightclientv2::{self, LightClientV2},
40    lightclientv2mock::{self, LightClientV2Mock},
41    plonkverifier::PlonkVerifier,
42    plonkverifierv2::PlonkVerifierV2,
43    staketable::StakeTable,
44    staketablev2::{
45        self, EdOnBN254::EdOnBN254Point as EdOnBN254PointSol, StakeTableV2,
46        BN254::G2Point as G2PointSol,
47    },
48    timelock::Timelock,
49};
50
51// For types that we need to interact with some functions but their bindings are not generated
52// we manually declare them there. It's possible that they get included in the future commits,
53// at which point, the rust type system will complain and we simply remove the manual declaration
54// and re-export the type from bindings instead.
55sol! {
56    /// types in src/legacy/Transcript.sol
57    struct TranscriptDataSol {
58        bytes32 state;
59        bytes transcript;
60    }
61
62    /// types in src/libraries/PlonkVerifierV2.sol
63    struct ChallengesSol {
64        uint256 alpha;
65        uint256 alpha2;
66        uint256 alpha3;
67        uint256 beta;
68        uint256 gamma;
69        uint256 zeta;
70        uint256 v;
71        uint256 u;
72    }
73
74}
75
76// Due to <https://github.com/foundry-rs/foundry/issues/10153> the rust bindings contain duplicate types for our solidity types.
77// In order to avoid writing a lot of boilerplate code we use transmute to convert between these duplicated types.
78// Since all the types we transmute between are generated by foundry from the same underlying solidity type
79// we expect that the order of fields and types of fields are always the same.
80impl From<LightClient::genesisStateReturn> for LightClientStateSol {
81    fn from(v: LightClient::genesisStateReturn) -> Self {
82        unsafe { std::mem::transmute(v) }
83    }
84}
85
86impl From<lightclientmock::LightClient::LightClientState> for LightClientStateSol {
87    fn from(v: lightclientmock::LightClient::LightClientState) -> Self {
88        unsafe { std::mem::transmute(v) }
89    }
90}
91impl From<lightclientmock::LightClientMock::finalizedStateReturn> for LightClientStateSol {
92    fn from(v: lightclientmock::LightClientMock::finalizedStateReturn) -> Self {
93        unsafe { std::mem::transmute(v) }
94    }
95}
96
97impl From<LightClientStateSol> for lightclientmock::LightClient::LightClientState {
98    fn from(v: LightClientStateSol) -> Self {
99        unsafe { std::mem::transmute(v) }
100    }
101}
102
103impl From<PlonkProofSol> for lightclientmock::IPlonkVerifier::PlonkProof {
104    fn from(v: PlonkProofSol) -> Self {
105        unsafe { std::mem::transmute(v) }
106    }
107}
108
109impl From<lightclientmock::LightClientMock::genesisStateReturn> for LightClientStateSol {
110    fn from(v: lightclientmock::LightClientMock::genesisStateReturn) -> Self {
111        unsafe { std::mem::transmute(v) }
112    }
113}
114
115impl From<LightClientV2::finalizedStateReturn> for LightClientStateSol {
116    fn from(v: LightClientV2::finalizedStateReturn) -> Self {
117        unsafe { std::mem::transmute(v) }
118    }
119}
120
121impl From<LightClientV2::votingStakeTableStateReturn> for StakeTableStateSol {
122    fn from(v: LightClientV2::votingStakeTableStateReturn) -> Self {
123        unsafe { std::mem::transmute(v) }
124    }
125}
126
127impl From<lightclientv2mock::LightClient::LightClientState> for LightClientStateSol {
128    fn from(v: lightclientv2mock::LightClient::LightClientState) -> Self {
129        unsafe { std::mem::transmute(v) }
130    }
131}
132impl From<LightClientStateSol> for lightclientv2mock::LightClient::LightClientState {
133    fn from(v: LightClientStateSol) -> Self {
134        unsafe { std::mem::transmute(v) }
135    }
136}
137impl From<LightClientStateSol> for lightclientv2::LightClient::LightClientState {
138    fn from(v: LightClientStateSol) -> Self {
139        unsafe { std::mem::transmute(v) }
140    }
141}
142
143impl From<StakeTableStateSol> for lightclientv2::LightClient::StakeTableState {
144    fn from(v: StakeTableStateSol) -> Self {
145        unsafe { std::mem::transmute(v) }
146    }
147}
148impl From<StakeTableStateSol> for lightclientv2mock::LightClient::StakeTableState {
149    fn from(v: StakeTableStateSol) -> Self {
150        unsafe { std::mem::transmute(v) }
151    }
152}
153
154impl From<LightClientV2Mock::genesisStateReturn> for LightClientStateSol {
155    fn from(v: LightClientV2Mock::genesisStateReturn) -> Self {
156        unsafe { std::mem::transmute(v) }
157    }
158}
159
160impl From<LightClientV2Mock::finalizedStateReturn> for LightClientStateSol {
161    fn from(v: LightClientV2Mock::finalizedStateReturn) -> Self {
162        unsafe { std::mem::transmute(v) }
163    }
164}
165
166impl From<PlonkProofSol> for lightclientv2::IPlonkVerifier::PlonkProof {
167    fn from(v: PlonkProofSol) -> Self {
168        unsafe { std::mem::transmute(v) }
169    }
170}
171
172impl From<LightClientV2Mock::votingStakeTableStateReturn> for StakeTableStateSol {
173    fn from(v: LightClientV2Mock::votingStakeTableStateReturn) -> Self {
174        unsafe { std::mem::transmute(v) }
175    }
176}
177
178impl From<G1PointSol> for staketablev2::BN254::G1Point {
179    fn from(v: G1PointSol) -> Self {
180        unsafe { std::mem::transmute(v) }
181    }
182}
183
184impl From<staketablev2::BN254::G1Point> for G1PointSol {
185    fn from(v: staketablev2::BN254::G1Point) -> Self {
186        unsafe { std::mem::transmute(v) }
187    }
188}
189
190use serde::{Deserialize, Deserializer, Serialize, Serializer};
191
192use self::{
193    staketablev2::{EdOnBN254::EdOnBN254Point, BN254::G2Point},
194    StakeTableV2::{
195        ConsensusKeysUpdated, ConsensusKeysUpdatedV2, Delegated, Undelegated, ValidatorExit,
196        ValidatorRegistered, ValidatorRegisteredV2,
197    },
198};
199
200impl PartialEq for ValidatorRegistered {
201    fn eq(&self, other: &Self) -> bool {
202        self.account == other.account
203            && self.blsVk == other.blsVk
204            && self.schnorrVk == other.schnorrVk
205            && self.commission == other.commission
206    }
207}
208
209impl PartialEq for ValidatorRegisteredV2 {
210    fn eq(&self, other: &Self) -> bool {
211        self.account == other.account
212            && self.blsVK == other.blsVK
213            && self.schnorrVK == other.schnorrVK
214            && self.commission == other.commission
215            && self.blsSig == other.blsSig
216            && self.schnorrSig == other.schnorrSig
217    }
218}
219
220impl PartialEq for ConsensusKeysUpdated {
221    fn eq(&self, other: &Self) -> bool {
222        self.account == other.account
223            && self.blsVK == other.blsVK
224            && self.schnorrVK == other.schnorrVK
225    }
226}
227
228impl PartialEq for ConsensusKeysUpdatedV2 {
229    fn eq(&self, other: &Self) -> bool {
230        self.account == other.account
231            && self.blsVK == other.blsVK
232            && self.schnorrVK == other.schnorrVK
233            && self.blsSig == other.blsSig
234            && self.schnorrSig == other.schnorrSig
235    }
236}
237
238impl Serialize for ValidatorRegistered {
239    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
240    where
241        S: Serializer,
242    {
243        (&self.account, &self.blsVk, &self.schnorrVk, self.commission).serialize(serializer)
244    }
245}
246
247#[allow(non_snake_case)]
248impl<'de> Deserialize<'de> for ValidatorRegistered {
249    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
250    where
251        D: Deserializer<'de>,
252    {
253        let (account, blsVk, schnorrVk, commission) = <(_, _, _, u16)>::deserialize(deserializer)?;
254        Ok(Self {
255            account,
256            blsVk,
257            schnorrVk,
258            commission,
259        })
260    }
261}
262
263impl Serialize for ValidatorRegisteredV2 {
264    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
265    where
266        S: Serializer,
267    {
268        (
269            &self.account,
270            &self.blsVK,
271            &self.schnorrVK,
272            self.commission,
273            &self.blsSig,
274            &self.schnorrSig,
275        )
276            .serialize(serializer)
277    }
278}
279
280#[allow(non_snake_case)]
281impl<'de> Deserialize<'de> for ValidatorRegisteredV2 {
282    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
283    where
284        D: Deserializer<'de>,
285    {
286        let (account, blsVK, schnorrVK, commission, blsSig, schnorrSig) =
287            <(_, _, _, u16, _, _)>::deserialize(deserializer)?;
288        Ok(ValidatorRegisteredV2 {
289            account,
290            blsVK,
291            schnorrVK,
292            commission,
293            blsSig,
294            schnorrSig,
295        })
296    }
297}
298
299impl Serialize for EdOnBN254Point {
300    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
301    where
302        S: Serializer,
303    {
304        (self.x, self.y).serialize(serializer)
305    }
306}
307
308impl<'de> Deserialize<'de> for EdOnBN254Point {
309    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
310    where
311        D: Deserializer<'de>,
312    {
313        let (x, y) = Deserialize::deserialize(deserializer)?;
314        Ok(Self { x, y })
315    }
316}
317
318impl Serialize for G2Point {
319    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
320    where
321        S: Serializer,
322    {
323        (&self.x0, &self.x1, &self.y0, &self.y1).serialize(serializer)
324    }
325}
326
327impl<'de> Deserialize<'de> for G2Point {
328    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
329    where
330        D: Deserializer<'de>,
331    {
332        let (x0, x1, y0, y1) = Deserialize::deserialize(deserializer)?;
333
334        Ok(Self { x0, x1, y0, y1 })
335    }
336}
337
338impl Serialize for staketablev2::BN254::G1Point {
339    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
340    where
341        S: Serializer,
342    {
343        (&self.x, &self.y).serialize(serializer)
344    }
345}
346
347impl<'de> Deserialize<'de> for staketablev2::BN254::G1Point {
348    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
349    where
350        D: Deserializer<'de>,
351    {
352        let (x, y) = Deserialize::deserialize(deserializer)?;
353        Ok(Self { x, y })
354    }
355}
356
357impl Serialize for ValidatorExit {
358    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
359    where
360        S: Serializer,
361    {
362        (&self.validator,).serialize(serializer)
363    }
364}
365
366impl<'de> Deserialize<'de> for ValidatorExit {
367    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
368    where
369        D: Deserializer<'de>,
370    {
371        let (validator,): (alloy::sol_types::private::Address,) =
372            Deserialize::deserialize(deserializer)?;
373        Ok(ValidatorExit { validator })
374    }
375}
376
377impl Serialize for Delegated {
378    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
379    where
380        S: Serializer,
381    {
382        (&self.delegator, &self.validator, &self.amount).serialize(serializer)
383    }
384}
385
386impl<'de> Deserialize<'de> for Delegated {
387    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
388    where
389        D: Deserializer<'de>,
390    {
391        let (delegator, validator, amount) = Deserialize::deserialize(deserializer)?;
392
393        Ok(Delegated {
394            delegator,
395            validator,
396            amount,
397        })
398    }
399}
400
401impl Serialize for Undelegated {
402    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
403    where
404        S: Serializer,
405    {
406        (&self.delegator, &self.validator, &self.amount).serialize(serializer)
407    }
408}
409
410impl<'de> Deserialize<'de> for Undelegated {
411    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
412    where
413        D: Deserializer<'de>,
414    {
415        let (delegator, validator, amount) = Deserialize::deserialize(deserializer)?;
416
417        Ok(Undelegated {
418            delegator,
419            validator,
420            amount,
421        })
422    }
423}
424
425impl Serialize for ConsensusKeysUpdated {
426    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
427    where
428        S: Serializer,
429    {
430        (&self.account, &self.blsVK, &self.schnorrVK).serialize(serializer)
431    }
432}
433
434#[allow(non_snake_case)]
435impl<'de> Deserialize<'de> for ConsensusKeysUpdated {
436    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
437    where
438        D: Deserializer<'de>,
439    {
440        let (account, blsVK, schnorrVK) = Deserialize::deserialize(deserializer)?;
441
442        Ok(ConsensusKeysUpdated {
443            account,
444            blsVK,
445            schnorrVK,
446        })
447    }
448}
449
450impl Serialize for ConsensusKeysUpdatedV2 {
451    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
452    where
453        S: Serializer,
454    {
455        (
456            &self.account,
457            &self.blsVK,
458            &self.schnorrVK,
459            &self.blsSig,
460            &self.schnorrSig,
461        )
462            .serialize(serializer)
463    }
464}
465
466#[allow(non_snake_case)]
467impl<'de> Deserialize<'de> for ConsensusKeysUpdatedV2 {
468    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
469    where
470        D: Deserializer<'de>,
471    {
472        let (account, blsVK, schnorrVK, blsSig, schnorrSig) =
473            Deserialize::deserialize(deserializer)?;
474
475        Ok(ConsensusKeysUpdatedV2 {
476            account,
477            blsVK,
478            schnorrVK,
479            blsSig,
480            schnorrSig,
481        })
482    }
483}