Skip to content

Commit 44fbd54

Browse files
committed
removing use of 'as' and cleaning byte conversion of parse_vm
1 parent e852118 commit 44fbd54

File tree

1 file changed

+84
-43
lines changed
  • target_chains/stylus/contracts/wormhole/src

1 file changed

+84
-43
lines changed

target_chains/stylus/contracts/wormhole/src/lib.rs

Lines changed: 84 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ sol! {
5757
error InsufficientSignatures();
5858
error InvalidGuardianIndex();
5959
error InvalidAddressLength();
60+
error InvalidSignatures();
6061
error VerifyVAAError();
6162
}
6263

@@ -82,6 +83,7 @@ impl_debug_for_sol_error!(
8283
NotInitialized,
8384
InvalidInput,
8485
InsufficientSignatures,
86+
InvalidSignatures,
8587
InvalidGuardianIndex,
8688
InvalidAddressLength,
8789
VerifyVAAError
@@ -100,6 +102,7 @@ pub enum WormholeError {
100102
NotInitialized(NotInitialized),
101103
InvalidInput(InvalidInput),
102104
InsufficientSignatures(InsufficientSignatures),
105+
InvalidSignatures(InvalidSignatures),
103106
InvalidGuardianIndex(InvalidGuardianIndex),
104107
InvalidAddressLength(InvalidAddressLength),
105108
VerifyVAAError(VerifyVAAError),
@@ -130,6 +133,7 @@ pub struct WormholeContract {
130133
guardian_keys: StorageMap<U256, StorageAddress>,
131134
}
132135

136+
#[public]
133137
impl WormholeContract {
134138
pub fn initialize(
135139
&mut self,
@@ -229,6 +233,8 @@ impl WormholeContract {
229233
Self::parse_vm_static(encoded_vaa)
230234
}
231235

236+
// Parsing a Wormhole VAA according to the structure defined
237+
// by https://wormhole.com/docs/protocol/infrastructure/vaas/
232238
fn parse_vm_static(encoded_vaa: &[u8]) -> Result<VAA, WormholeError> {
233239
if encoded_vaa.len() < 6 {
234240
return Err(WormholeError::InvalidVAAFormat(InvalidVAAFormat {}));
@@ -243,18 +249,23 @@ impl WormholeContract {
243249
return Err(WormholeError::InvalidVAAFormat(InvalidVAAFormat {}));
244250
}
245251

246-
let guardian_set_index = u32::from_be_bytes([
247-
encoded_vaa[cursor],
248-
encoded_vaa[cursor + 1],
249-
encoded_vaa[cursor + 2],
250-
encoded_vaa[cursor + 3],
251-
]);
252+
let guardian_set_index_bytes: [u8; 4] = encoded_vaa[cursor..cursor + 4]
253+
.try_into()
254+
.map_err(|_| WormholeError::InvalidVAAFormat(InvalidVAAFormat {}))?;
255+
256+
let guardian_set_index = u32::from_be_bytes(guardian_set_index_bytes);
257+
252258
cursor += 4;
253259

254260
let len_signatures = encoded_vaa[cursor];
255261
cursor += 1;
256262

257263
let mut signatures = Vec::new();
264+
265+
if len_signatures > 19 {
266+
return Err(WormholeError::InvalidVAAFormat(InvalidVAAFormat {}));
267+
}
268+
258269
for _ in 0..len_signatures {
259270
if cursor + 66 > encoded_vaa.len() {
260271
return Err(WormholeError::InvalidVAAFormat(InvalidVAAFormat {}));
@@ -277,20 +288,18 @@ impl WormholeContract {
277288
return Err(WormholeError::InvalidVAAFormat(InvalidVAAFormat {}));
278289
}
279290

280-
let timestamp = u32::from_be_bytes([
281-
encoded_vaa[cursor],
282-
encoded_vaa[cursor + 1],
283-
encoded_vaa[cursor + 2],
284-
encoded_vaa[cursor + 3],
285-
]);
291+
let timestamp_bytes: [u8; 4] = encoded_vaa[cursor..cursor + 4]
292+
.try_into()
293+
.map_err(|_| WormholeError::InvalidVAAFormat(InvalidVAAFormat {}))?;
294+
295+
let timestamp = u32::from_be_bytes(timestamp_bytes);
286296
cursor += 4;
287297

288-
let nonce = u32::from_be_bytes([
289-
encoded_vaa[cursor],
290-
encoded_vaa[cursor + 1],
291-
encoded_vaa[cursor + 2],
292-
encoded_vaa[cursor + 3],
293-
]);
298+
let nonce_bytes: [u8; 4] = encoded_vaa[cursor..cursor + 4]
299+
.try_into()
300+
.map_err(|_| WormholeError::InvalidVAAFormat(InvalidVAAFormat {}))?;
301+
302+
let nonce = u32::from_be_bytes(nonce_bytes);
294303
cursor += 4;
295304

296305
let emitter_chain_id = u16::from_be_bytes([
@@ -303,16 +312,12 @@ impl WormholeContract {
303312
emitter_address_bytes.copy_from_slice(&encoded_vaa[cursor..cursor + 32]);
304313
cursor += 32;
305314

306-
let sequence = u64::from_be_bytes([
307-
encoded_vaa[cursor],
308-
encoded_vaa[cursor + 1],
309-
encoded_vaa[cursor + 2],
310-
encoded_vaa[cursor + 3],
311-
encoded_vaa[cursor + 4],
312-
encoded_vaa[cursor + 5],
313-
encoded_vaa[cursor + 6],
314-
encoded_vaa[cursor + 7],
315-
]);
315+
let sequence_bytes: [u8; 8] = encoded_vaa[cursor..cursor + 8]
316+
.try_into()
317+
.map_err(|_| WormholeError::InvalidVAAFormat(InvalidVAAFormat {}))?;
318+
319+
let sequence = u64::from_be_bytes(sequence_bytes);
320+
316321
cursor += 8;
317322

318323
let consistency_level = encoded_vaa[cursor];
@@ -345,10 +350,13 @@ impl WormholeContract {
345350
&& guardian_set.expiration_time > 0 {
346351
return Err(WormholeError::GuardianSetExpired(GuardianSetExpired {}))
347352
}
353+
354+
let num_guardians : u32 = guardian_set.keys.len().try_into().map_err(|_| WormholeError::InvalidInput(InvalidInput {}))?;
348355

349-
let required_signatures = Self::quorum(guardian_set.keys.len() as u32);
356+
let required_signatures = Self::quorum(num_guardians);
357+
let num_signatures : u32 = vaa.signatures.len().try_into().map_err(|_| WormholeError::InvalidInput(InvalidInput {}))?;
350358

351-
if vaa.signatures.len() < required_signatures as usize {
359+
if num_signatures < required_signatures {
352360
return Err(WormholeError::InsufficientSignatures(InsufficientSignatures {}));
353361
}
354362

@@ -362,11 +370,16 @@ impl WormholeContract {
362370
}
363371
last_guardian_index = Some(signature.guardian_index);
364372

365-
if signature.guardian_index as usize >= guardian_set.keys.len() {
373+
let index: usize = signature
374+
.guardian_index
375+
.try_into()
376+
.map_err(|_| WormholeError::InvalidGuardianIndex(InvalidGuardianIndex {}))?;
377+
378+
if index >= guardian_set.keys.len() {
366379
return Err(WormholeError::InvalidGuardianIndex(InvalidGuardianIndex {}));
367380
}
368381

369-
let guardian_address = guardian_set.keys[signature.guardian_index as usize];
382+
let guardian_address = guardian_set.keys[index];
370383
let hashed_vaa_hash: FixedBytes<32> = FixedBytes::from(keccak256(vaa.hash));
371384

372385
match self.verify_signature(&hashed_vaa_hash, &signature.signature, guardian_address) {
@@ -404,7 +417,9 @@ impl WormholeContract {
404417
self.guardian_set_expiry.setter(U256::from(set_index)).set(U256::from(expiration_time));
405418

406419
for (i, guardian) in guardians.iter().enumerate() {
407-
let key = self.compute_guardian_key(set_index, i as u8);
420+
let i_u8: u8 = i.try_into()
421+
.map_err(|_| WormholeError::InvalidGuardianIndex(InvalidGuardianIndex {}))?;
422+
let key = self.compute_guardian_key(set_index, i_u8);
408423
self.guardian_keys.setter(key).set(*guardian);
409424
}
410425

@@ -424,7 +439,10 @@ impl WormholeContract {
424439

425440
let secp = Secp256k1::new();
426441

427-
let recid = RecoveryId::try_from(signature[64] as i32)
442+
let recid_raw_i32: i32 = signature[64].try_into()
443+
.map_err(|_| WormholeError::InvalidGuardianIndex(InvalidGuardianIndex {}))?;
444+
445+
let recid = RecoveryId::try_from(recid_raw_i32)
428446
.map_err(|_| WormholeError::InvalidSignature(InvalidSignature {}))?;
429447
let recoverable_sig = RecoverableSignature::from_compact(&signature[..64], recid)
430448
.map_err(|_| WormholeError::InvalidSignature(InvalidSignature {}))?;
@@ -453,7 +471,13 @@ impl WormholeContract {
453471
let mut keys = Vec::new();
454472
let size_u32: u32 = size.try_into().unwrap_or(0);
455473
for i in 0..size_u32 {
456-
let key = self.compute_guardian_key(index, i as u8);
474+
let i_u8: u8 = match i.try_into() {
475+
Ok(val) => val,
476+
Err(_) => {
477+
return None;
478+
}
479+
};
480+
let key = self.compute_guardian_key(index, i_u8);
457481
let guardian_address = self.guardian_keys.getter(key).get();
458482
keys.push(guardian_address);
459483
}
@@ -705,7 +729,7 @@ mod tests {
705729
}
706730
}
707731

708-
fn create_valid_guardian_signature(guardian_index: u8, hash: &FixedBytes<32>) -> GuardianSignature {
732+
fn create_valid_guardian_signature(guardian_index: u8, hash: &FixedBytes<32>) -> Result<GuardianSignature, WormholeError> {
709733
// Select a test guardian secret key
710734
let secret: SecretKey = match guardian_index {
711735
0 => test_guardian_secret1(),
@@ -724,18 +748,23 @@ mod tests {
724748

725749
// Build Ethereum-compatible 65-byte signature (r || s || v)
726750
let mut signature_bytes = [0u8; 65];
727-
signature_bytes[..64].copy_from_slice(&sig_bytes);
751+
signature_bytes
752+
.get_mut(..64)
753+
.ok_or(WormholeError::InvalidInput(InvalidInput {}))?
754+
.copy_from_slice(&sig_bytes);
755+
728756
signature_bytes[64] = match recovery_id {
729757
RecoveryId::Zero => 27,
730758
RecoveryId::One => 28,
731759
RecoveryId::Two => 29,
732760
RecoveryId::Three => 30,
761+
_ => return Err(WormholeError::InvalidInput(InvalidInput {})),
733762
};
734763

735-
GuardianSignature {
764+
Ok(GuardianSignature {
736765
guardian_index,
737766
signature: FixedBytes::from(signature_bytes),
738-
}
767+
})
739768
}
740769

741770
fn create_guardian_signature(guardian_index: u8) -> GuardianSignature {
@@ -932,7 +961,13 @@ mod tests {
932961
let _contract = deploy_with_mainnet_guardians();
933962

934963
for i in 0..10 {
935-
let corrupted_data = corrupted_vaa(vec![1, 0, 0, 1, 0, 0], i, i as u8, (i * 2) as u8);
964+
let i_u8: u8 = match i.try_into() {
965+
Ok(val) => val,
966+
Err(_) => {
967+
panic!("Invalid index");
968+
}
969+
};
970+
let corrupted_data = corrupted_vaa(vec![1, 0, 0, 1, 0, 0], i, i_u8, (i_u8 * 2));
936971
let result = WormholeContract::parse_vm_static(&corrupted_data);
937972
assert!(result.is_err());
938973
}
@@ -943,8 +978,14 @@ mod tests {
943978
let contract = deploy_with_mainnet_guardians();
944979

945980
for i in 0..5 {
981+
let i_u8: u8 = match i.try_into() {
982+
Ok(val) => val,
983+
Err(_) => {
984+
panic!("Invalid index");
985+
}
986+
};
946987
let base_vaa = vec![1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
947-
let corrupted_data = corrupted_vaa(base_vaa, i, i as u8, (i * 3) as u8);
988+
let corrupted_data = corrupted_vaa(base_vaa, i, i_u8, (i_u8 * 3));
948989
let result = WormholeContract::parse_vm_static(&corrupted_data);
949990
assert!(result.is_err());
950991
}
@@ -1032,8 +1073,8 @@ mod tests {
10321073
version: 1,
10331074
guardian_set_index: 0,
10341075
signatures: vec![
1035-
create_valid_guardian_signature(0, &hash),
1036-
create_valid_guardian_signature(1, &hash),
1076+
create_valid_guardian_signature(0, &hash).unwrap(),
1077+
create_valid_guardian_signature(1, &hash).unwrap(),
10371078
],
10381079
timestamp: 0,
10391080
nonce: 0,

0 commit comments

Comments
 (0)