diff --git a/target_chains/starknet/contracts/src/util.cairo b/target_chains/starknet/contracts/src/util.cairo index de6c7612eb..4fd3a759e6 100644 --- a/target_chains/starknet/contracts/src/util.cairo +++ b/target_chains/starknet/contracts/src/util.cairo @@ -62,3 +62,67 @@ pub fn u64_byte_reverse(value: u64) -> u64 { pub trait UnwrapWithFelt252 { fn unwrap_with_felt252(self: Result) -> T; } + +/// Reinterpret `u64` as `i64` as if it was a two's complement binary representation. +pub fn u64_as_i64(value: u64) -> i64 { + if value < 0x8000000000000000 { + value.try_into().unwrap() + } else { + let value: i128 = value.into(); + (value - 0x10000000000000000).try_into().unwrap() + } +} + +/// Reinterpret `u32` as `i32` as if it was a two's complement binary representation. +pub fn u32_as_i32(value: u32) -> i32 { + if value < 0x80000000 { + value.try_into().unwrap() + } else { + let value: i64 = value.into(); + (value - 0x100000000).try_into().unwrap() + } +} + +pub fn array_felt252_to_bytes31(mut input: Array) -> Array { + let mut output = array![]; + loop { + match input.pop_front() { + Option::Some(v) => { output.append(v.try_into().unwrap()); }, + Option::None => { break; }, + } + }; + output +} + +#[cfg(test)] +mod tests { + use super::{u64_as_i64, u32_as_i32}; + + #[test] + fn test_u64_as_i64() { + assert!(u64_as_i64(0) == 0); + assert!(u64_as_i64(1) == 1); + assert!(u64_as_i64(2) == 2); + assert!(u64_as_i64(3) == 3); + assert!(u64_as_i64(9223372036854775806) == 9223372036854775806); + assert!(u64_as_i64(9223372036854775807) == 9223372036854775807); + assert!(u64_as_i64(9223372036854775808) == -9223372036854775808); + assert!(u64_as_i64(9223372036854775809) == -9223372036854775807); + assert!(u64_as_i64(18446744073709551614) == -2); + assert!(u64_as_i64(18446744073709551615) == -1); + } + + #[test] + fn test_u32_as_i32() { + assert!(u32_as_i32(0) == 0); + assert!(u32_as_i32(1) == 1); + assert!(u32_as_i32(2) == 2); + assert!(u32_as_i32(3) == 3); + assert!(u32_as_i32(2147483646) == 2147483646); + assert!(u32_as_i32(2147483647) == 2147483647); + assert!(u32_as_i32(2147483648) == -2147483648); + assert!(u32_as_i32(2147483649) == -2147483647); + assert!(u32_as_i32(4294967294) == -2); + assert!(u32_as_i32(4294967295) == -1); + } +} diff --git a/target_chains/starknet/contracts/tests/wormhole.cairo b/target_chains/starknet/contracts/tests/wormhole.cairo index 68ec3e5539..071dcb4788 100644 --- a/target_chains/starknet/contracts/tests/wormhole.cairo +++ b/target_chains/starknet/contracts/tests/wormhole.cairo @@ -1,7 +1,7 @@ use snforge_std::{declare, ContractClassTrait, start_prank, stop_prank, CheatTarget}; use pyth::wormhole::{IWormholeDispatcher, IWormholeDispatcherTrait, ParseAndVerifyVmError}; use pyth::reader::{ByteArray, ByteArrayImpl, ReaderImpl}; -use pyth::util::UnwrapWithFelt252; +use pyth::util::{UnwrapWithFelt252, array_felt252_to_bytes31}; use core::starknet::ContractAddress; use core::panic_with_felt252; @@ -94,17 +94,6 @@ fn test_submit_guardian_set_rejects_empty() { dispatcher.submit_new_guardian_set(1, array![]).unwrap_with_felt252(); } -fn array_left252_to_bytes31(mut input: Array) -> Array { - let mut output = array![]; - loop { - match input.pop_front() { - Option::Some(v) => { output.append(v.try_into().unwrap()); }, - Option::None => { break; }, - } - }; - output -} - fn deploy(owner: ContractAddress, guardians: Array) -> IWormholeDispatcher { let mut args = array![]; (owner, guardians).serialize(ref args); @@ -300,5 +289,5 @@ fn good_vm1() -> ByteArray { 52685537088250779930155363779405986390839624071318818148325576008719597568, 14615204155786886573933667335033405822686404253588533, ]; - ByteArrayImpl::new(array_left252_to_bytes31(bytes), 22) + ByteArrayImpl::new(array_felt252_to_bytes31(bytes), 22) }