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    opstimelock::OpsTimelock,
42    ownableupgradeable::OwnableUpgradeable,
43    plonkverifier::PlonkVerifier,
44    plonkverifierv2::PlonkVerifierV2,
45    safeexittimelock::SafeExitTimelock,
46    staketable::StakeTable,
47    staketablev2::{
48        self, EdOnBN254::EdOnBN254Point as EdOnBN254PointSol, StakeTableV2,
49        BN254::G2Point as G2PointSol,
50    },
51};
52
53// For types that we need to interact with some functions but their bindings are not generated
54// we manually declare them there. It's possible that they get included in the future commits,
55// at which point, the rust type system will complain and we simply remove the manual declaration
56// and re-export the type from bindings instead.
57sol! {
58    /// types in src/legacy/Transcript.sol
59    struct TranscriptDataSol {
60        bytes32 state;
61        bytes transcript;
62    }
63
64    /// types in src/libraries/PlonkVerifierV2.sol
65    struct ChallengesSol {
66        uint256 alpha;
67        uint256 alpha2;
68        uint256 alpha3;
69        uint256 beta;
70        uint256 gamma;
71        uint256 zeta;
72        uint256 v;
73        uint256 u;
74    }
75
76}
77
78// Due to <https://github.com/foundry-rs/foundry/issues/10153> the rust bindings contain duplicate types for our solidity types.
79// In order to avoid writing a lot of boilerplate code we use transmute to convert between these duplicated types.
80// Since all the types we transmute between are generated by foundry from the same underlying solidity type
81// we expect that the order of fields and types of fields are always the same.
82impl From<LightClient::genesisStateReturn> for LightClientStateSol {
83    fn from(v: LightClient::genesisStateReturn) -> Self {
84        unsafe { std::mem::transmute(v) }
85    }
86}
87
88impl From<lightclientmock::LightClient::LightClientState> for LightClientStateSol {
89    fn from(v: lightclientmock::LightClient::LightClientState) -> Self {
90        unsafe { std::mem::transmute(v) }
91    }
92}
93impl From<lightclientmock::LightClientMock::finalizedStateReturn> for LightClientStateSol {
94    fn from(v: lightclientmock::LightClientMock::finalizedStateReturn) -> Self {
95        unsafe { std::mem::transmute(v) }
96    }
97}
98
99impl From<LightClientStateSol> for lightclientmock::LightClient::LightClientState {
100    fn from(v: LightClientStateSol) -> Self {
101        unsafe { std::mem::transmute(v) }
102    }
103}
104
105impl From<PlonkProofSol> for lightclientmock::IPlonkVerifier::PlonkProof {
106    fn from(v: PlonkProofSol) -> Self {
107        unsafe { std::mem::transmute(v) }
108    }
109}
110
111impl From<lightclientmock::LightClientMock::genesisStateReturn> for LightClientStateSol {
112    fn from(v: lightclientmock::LightClientMock::genesisStateReturn) -> Self {
113        unsafe { std::mem::transmute(v) }
114    }
115}
116
117impl From<LightClientV2::finalizedStateReturn> for LightClientStateSol {
118    fn from(v: LightClientV2::finalizedStateReturn) -> Self {
119        unsafe { std::mem::transmute(v) }
120    }
121}
122
123impl From<LightClientV2::votingStakeTableStateReturn> for StakeTableStateSol {
124    fn from(v: LightClientV2::votingStakeTableStateReturn) -> Self {
125        unsafe { std::mem::transmute(v) }
126    }
127}
128
129impl From<lightclientv2mock::LightClient::LightClientState> for LightClientStateSol {
130    fn from(v: lightclientv2mock::LightClient::LightClientState) -> Self {
131        unsafe { std::mem::transmute(v) }
132    }
133}
134impl From<LightClientStateSol> for lightclientv2mock::LightClient::LightClientState {
135    fn from(v: LightClientStateSol) -> Self {
136        unsafe { std::mem::transmute(v) }
137    }
138}
139impl From<LightClientStateSol> for lightclientv2::LightClient::LightClientState {
140    fn from(v: LightClientStateSol) -> Self {
141        unsafe { std::mem::transmute(v) }
142    }
143}
144
145impl From<StakeTableStateSol> for lightclientv2::LightClient::StakeTableState {
146    fn from(v: StakeTableStateSol) -> Self {
147        unsafe { std::mem::transmute(v) }
148    }
149}
150impl From<StakeTableStateSol> for lightclientv2mock::LightClient::StakeTableState {
151    fn from(v: StakeTableStateSol) -> Self {
152        unsafe { std::mem::transmute(v) }
153    }
154}
155
156impl From<LightClientV2Mock::genesisStateReturn> for LightClientStateSol {
157    fn from(v: LightClientV2Mock::genesisStateReturn) -> Self {
158        unsafe { std::mem::transmute(v) }
159    }
160}
161
162impl From<LightClientV2Mock::finalizedStateReturn> for LightClientStateSol {
163    fn from(v: LightClientV2Mock::finalizedStateReturn) -> Self {
164        unsafe { std::mem::transmute(v) }
165    }
166}
167
168impl From<PlonkProofSol> for lightclientv2::IPlonkVerifier::PlonkProof {
169    fn from(v: PlonkProofSol) -> Self {
170        unsafe { std::mem::transmute(v) }
171    }
172}
173
174impl From<LightClientV2Mock::votingStakeTableStateReturn> for StakeTableStateSol {
175    fn from(v: LightClientV2Mock::votingStakeTableStateReturn) -> Self {
176        unsafe { std::mem::transmute(v) }
177    }
178}
179
180impl From<G1PointSol> for staketablev2::BN254::G1Point {
181    fn from(v: G1PointSol) -> Self {
182        unsafe { std::mem::transmute(v) }
183    }
184}
185
186impl From<staketablev2::BN254::G1Point> for G1PointSol {
187    fn from(v: staketablev2::BN254::G1Point) -> Self {
188        unsafe { std::mem::transmute(v) }
189    }
190}
191
192use serde::{Deserialize, Deserializer, Serialize, Serializer};
193
194use self::{
195    staketablev2::{EdOnBN254::EdOnBN254Point, BN254::G2Point},
196    StakeTableV2::{
197        ConsensusKeysUpdated, ConsensusKeysUpdatedV2, Delegated, Undelegated, ValidatorExit,
198        ValidatorRegistered, ValidatorRegisteredV2,
199    },
200};
201
202impl PartialEq for ValidatorRegistered {
203    fn eq(&self, other: &Self) -> bool {
204        self.account == other.account
205            && self.blsVk == other.blsVk
206            && self.schnorrVk == other.schnorrVk
207            && self.commission == other.commission
208    }
209}
210
211impl PartialEq for ValidatorRegisteredV2 {
212    fn eq(&self, other: &Self) -> bool {
213        self.account == other.account
214            && self.blsVK == other.blsVK
215            && self.schnorrVK == other.schnorrVK
216            && self.commission == other.commission
217            && self.blsSig == other.blsSig
218            && self.schnorrSig == other.schnorrSig
219    }
220}
221
222impl PartialEq for ConsensusKeysUpdated {
223    fn eq(&self, other: &Self) -> bool {
224        self.account == other.account
225            && self.blsVK == other.blsVK
226            && self.schnorrVK == other.schnorrVK
227    }
228}
229
230impl PartialEq for ConsensusKeysUpdatedV2 {
231    fn eq(&self, other: &Self) -> bool {
232        self.account == other.account
233            && self.blsVK == other.blsVK
234            && self.schnorrVK == other.schnorrVK
235            && self.blsSig == other.blsSig
236            && self.schnorrSig == other.schnorrSig
237    }
238}
239
240impl Serialize for ValidatorRegistered {
241    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
242    where
243        S: Serializer,
244    {
245        (&self.account, &self.blsVk, &self.schnorrVk, self.commission).serialize(serializer)
246    }
247}
248
249#[allow(non_snake_case)]
250impl<'de> Deserialize<'de> for ValidatorRegistered {
251    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
252    where
253        D: Deserializer<'de>,
254    {
255        let (account, blsVk, schnorrVk, commission) = <(_, _, _, u16)>::deserialize(deserializer)?;
256        Ok(Self {
257            account,
258            blsVk,
259            schnorrVk,
260            commission,
261        })
262    }
263}
264
265impl Serialize for ValidatorRegisteredV2 {
266    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
267    where
268        S: Serializer,
269    {
270        (
271            &self.account,
272            &self.blsVK,
273            &self.schnorrVK,
274            self.commission,
275            &self.blsSig,
276            &self.schnorrSig,
277        )
278            .serialize(serializer)
279    }
280}
281
282#[allow(non_snake_case)]
283impl<'de> Deserialize<'de> for ValidatorRegisteredV2 {
284    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
285    where
286        D: Deserializer<'de>,
287    {
288        let (account, blsVK, schnorrVK, commission, blsSig, schnorrSig) =
289            <(_, _, _, u16, _, _)>::deserialize(deserializer)?;
290        Ok(ValidatorRegisteredV2 {
291            account,
292            blsVK,
293            schnorrVK,
294            commission,
295            blsSig,
296            schnorrSig,
297        })
298    }
299}
300
301impl Serialize for EdOnBN254Point {
302    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
303    where
304        S: Serializer,
305    {
306        (self.x, self.y).serialize(serializer)
307    }
308}
309
310impl<'de> Deserialize<'de> for EdOnBN254Point {
311    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
312    where
313        D: Deserializer<'de>,
314    {
315        let (x, y) = Deserialize::deserialize(deserializer)?;
316        Ok(Self { x, y })
317    }
318}
319
320impl Serialize for G2Point {
321    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
322    where
323        S: Serializer,
324    {
325        (&self.x0, &self.x1, &self.y0, &self.y1).serialize(serializer)
326    }
327}
328
329impl<'de> Deserialize<'de> for G2Point {
330    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
331    where
332        D: Deserializer<'de>,
333    {
334        let (x0, x1, y0, y1) = Deserialize::deserialize(deserializer)?;
335
336        Ok(Self { x0, x1, y0, y1 })
337    }
338}
339
340impl Serialize for staketablev2::BN254::G1Point {
341    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
342    where
343        S: Serializer,
344    {
345        (&self.x, &self.y).serialize(serializer)
346    }
347}
348
349impl<'de> Deserialize<'de> for staketablev2::BN254::G1Point {
350    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
351    where
352        D: Deserializer<'de>,
353    {
354        let (x, y) = Deserialize::deserialize(deserializer)?;
355        Ok(Self { x, y })
356    }
357}
358
359impl Serialize for ValidatorExit {
360    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
361    where
362        S: Serializer,
363    {
364        (&self.validator,).serialize(serializer)
365    }
366}
367
368impl<'de> Deserialize<'de> for ValidatorExit {
369    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
370    where
371        D: Deserializer<'de>,
372    {
373        let (validator,): (alloy::sol_types::private::Address,) =
374            Deserialize::deserialize(deserializer)?;
375        Ok(ValidatorExit { validator })
376    }
377}
378
379impl Serialize for Delegated {
380    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
381    where
382        S: Serializer,
383    {
384        (&self.delegator, &self.validator, &self.amount).serialize(serializer)
385    }
386}
387
388impl<'de> Deserialize<'de> for Delegated {
389    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
390    where
391        D: Deserializer<'de>,
392    {
393        let (delegator, validator, amount) = Deserialize::deserialize(deserializer)?;
394
395        Ok(Delegated {
396            delegator,
397            validator,
398            amount,
399        })
400    }
401}
402
403impl Serialize for Undelegated {
404    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
405    where
406        S: Serializer,
407    {
408        (&self.delegator, &self.validator, &self.amount).serialize(serializer)
409    }
410}
411
412impl<'de> Deserialize<'de> for Undelegated {
413    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
414    where
415        D: Deserializer<'de>,
416    {
417        let (delegator, validator, amount) = Deserialize::deserialize(deserializer)?;
418
419        Ok(Undelegated {
420            delegator,
421            validator,
422            amount,
423        })
424    }
425}
426
427impl Serialize for ConsensusKeysUpdated {
428    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
429    where
430        S: Serializer,
431    {
432        (&self.account, &self.blsVK, &self.schnorrVK).serialize(serializer)
433    }
434}
435
436#[allow(non_snake_case)]
437impl<'de> Deserialize<'de> for ConsensusKeysUpdated {
438    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
439    where
440        D: Deserializer<'de>,
441    {
442        let (account, blsVK, schnorrVK) = Deserialize::deserialize(deserializer)?;
443
444        Ok(ConsensusKeysUpdated {
445            account,
446            blsVK,
447            schnorrVK,
448        })
449    }
450}
451
452impl Serialize for ConsensusKeysUpdatedV2 {
453    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
454    where
455        S: Serializer,
456    {
457        (
458            &self.account,
459            &self.blsVK,
460            &self.schnorrVK,
461            &self.blsSig,
462            &self.schnorrSig,
463        )
464            .serialize(serializer)
465    }
466}
467
468#[allow(non_snake_case)]
469impl<'de> Deserialize<'de> for ConsensusKeysUpdatedV2 {
470    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
471    where
472        D: Deserializer<'de>,
473    {
474        let (account, blsVK, schnorrVK, blsSig, schnorrSig) =
475            Deserialize::deserialize(deserializer)?;
476
477        Ok(ConsensusKeysUpdatedV2 {
478            account,
479            blsVK,
480            schnorrVK,
481            blsSig,
482            schnorrSig,
483        })
484    }
485}