Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(target_chains/starknet): use EthAddress and is_eth_signature_valid #1556

Merged
merged 1 commit into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 14 additions & 28 deletions target_chains/starknet/contracts/src/wormhole.cairo
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use super::byte_array::ByteArray;
use core::starknet::secp256_trait::Signature;
use core::starknet::EthAddress;
use pyth::util::UnwrapWithFelt252;

mod governance;

#[starknet::interface]
pub trait IWormhole<T> {
fn submit_new_guardian_set(ref self: T, set_index: u32, guardians: Array<felt252>);
fn submit_new_guardian_set(ref self: T, set_index: u32, guardians: Array<EthAddress>);
fn parse_and_verify_vm(self: @T, encoded_vm: ByteArray) -> VerifiedVM;

// We don't need to implement other governance actions for now.
Expand Down Expand Up @@ -133,9 +134,10 @@ mod wormhole {
use core::starknet::secp256_trait::{Signature, recover_public_key, Secp256PointTrait};
use core::starknet::secp256k1::Secp256k1Point;
use core::starknet::{
ContractAddress, get_execution_info, get_caller_address, get_block_timestamp
ContractAddress, get_execution_info, get_caller_address, get_block_timestamp, EthAddress,
};
use core::keccak::cairo_keccak;
use core::starknet::eth_signature::is_eth_signature_valid;
use core::integer::u128_byte_reverse;
use core::panic_with_felt252;
use pyth::hash::{Hasher, HasherImpl};
Expand All @@ -158,14 +160,14 @@ mod wormhole {
consumed_governance_actions: LegacyMap<u256, bool>,
guardian_sets: LegacyMap<u32, GuardianSet>,
// (guardian_set_index, guardian_index) => guardian_address
guardian_keys: LegacyMap<(u32, u8), u256>,
guardian_keys: LegacyMap<(u32, u8), EthAddress>,
}

#[constructor]
fn constructor(
ref self: ContractState,
owner: ContractAddress,
initial_guardians: Array<felt252>,
initial_guardians: Array<EthAddress>,
chain_id: u16,
governance_chain_id: u16,
governance_contract: u256,
Expand All @@ -178,7 +180,7 @@ mod wormhole {
store_guardian_set(ref self, set_index, @initial_guardians);
}

fn store_guardian_set(ref self: ContractState, set_index: u32, guardians: @Array<felt252>) {
fn store_guardian_set(ref self: ContractState, set_index: u32, guardians: @Array<EthAddress>) {
if guardians.len() == 0 {
panic_with_felt252(SubmitNewGuardianSetError::NoGuardiansSpecified.into());
}
Expand All @@ -188,7 +190,7 @@ mod wormhole {

let mut i = 0;
while i < guardians.len() {
if *guardians.at(i) == 0 {
if (*guardians.at(i)).into() == 0 {
panic_with_felt252(SubmitNewGuardianSetError::InvalidGuardianKey.into());
}
i += 1;
Expand Down Expand Up @@ -217,7 +219,7 @@ mod wormhole {
#[abi(embed_v0)]
impl WormholeImpl of IWormhole<ContractState> {
fn submit_new_guardian_set(
ref self: ContractState, set_index: u32, guardians: Array<felt252>
ref self: ContractState, set_index: u32, guardians: Array<EthAddress>
) {
let execution_info = get_execution_info().unbox();
if self.owner.read() != execution_info.caller_address {
Expand Down Expand Up @@ -271,9 +273,12 @@ mod wormhole {

let guardian_key = self
.guardian_keys
.read((vm.guardian_set_index, signature.guardian_index));
.read((vm.guardian_set_index, signature.guardian_index))
.try_into()
.expect(UNEXPECTED_OVERFLOW);

verify_signature(vm.hash, signature.signature, guardian_key);
is_eth_signature_valid(vm.hash, signature.signature, guardian_key)
.unwrap_with_felt252();
};
vm
}
Expand Down Expand Up @@ -359,25 +364,6 @@ mod wormhole {
}
}

fn verify_signature(body_hash: u256, signature: Signature, guardian_key: u256,) {
let point: Secp256k1Point = recover_public_key(body_hash, signature)
.expect(ParseAndVerifyVmError::InvalidSignature.into());
let address = eth_address(point);
assert(guardian_key != 0, SubmitNewGuardianSetError::InvalidGuardianKey.into());
if address != guardian_key {
panic_with_felt252(ParseAndVerifyVmError::InvalidSignature.into());
}
}

fn eth_address(point: Secp256k1Point) -> u256 {
let (x, y) = point.get_coordinates().expect(ParseAndVerifyVmError::InvalidSignature.into());

let mut hasher = HasherImpl::new();
hasher.push_u256(x);
hasher.push_u256(y);
hasher.finalize() % ONE_SHIFT_160
}

#[generate_trait]
impl PrivateImpl of PrivateImplTrait {
fn verify_governance_vm(self: @ContractState, vm: @VerifiedVM) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use pyth::reader::{Reader, ReaderImpl};
use pyth::util::UNEXPECTED_OVERFLOW;
use super::GovernanceError;
use core::panic_with_felt252;
use core::starknet::EthAddress;

// "Core" (left padded)
const MODULE: u256 = 0x00000000000000000000000000000000000000000000000000000000436f7265;
Expand Down Expand Up @@ -40,7 +41,7 @@ pub struct Header {
#[derive(Drop, Debug, Clone)]
pub struct NewGuardianSet {
pub set_index: u32,
pub keys: Array<felt252>,
pub keys: Array<EthAddress>,
}

pub fn parse_header(ref reader: Reader) -> Header {
Expand Down
146 changes: 76 additions & 70 deletions target_chains/starknet/contracts/tests/wormhole.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use pyth::wormhole::{IWormholeDispatcher, IWormholeDispatcherTrait, ParseAndVeri
use pyth::reader::ReaderImpl;
use pyth::byte_array::{ByteArray, ByteArrayImpl};
use pyth::util::{UnwrapWithFelt252, array_try_into};
use core::starknet::ContractAddress;
use core::starknet::{ContractAddress, EthAddress};
use core::panic_with_felt252;

#[test]
Expand Down Expand Up @@ -118,7 +118,7 @@ fn test_submit_guardian_set_rejects_non_governance(pos: usize, random1: usize, r

fn deploy(
owner: ContractAddress,
guardians: Array<felt252>,
guardians: Array<EthAddress>,
chain_id: u16,
governance_chain_id: u16,
governance_contract: u256,
Expand Down Expand Up @@ -211,80 +211,86 @@ fn corrupted_byte(value: u8, random: usize) -> u8 {
(v % 256).try_into().unwrap()
}

fn guardian_set0() -> Array<felt252> {
array![0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5]
fn guardian_set0() -> Array<EthAddress> {
array_try_into(array![0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5])
}

// Below are actual guardian keys from
// https://github.com/wormhole-foundation/wormhole-networks/tree/master/mainnetv2/guardianset
fn guardian_set1() -> Array<felt252> {
array![
0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5,
0xfF6CB952589BDE862c25Ef4392132fb9D4A42157,
0x114De8460193bdf3A2fCf81f86a09765F4762fD1,
0x107A0086b32d7A0977926A205131d8731D39cbEB,
0x8C82B2fd82FaeD2711d59AF0F2499D16e726f6b2,
0x11b39756C042441BE6D8650b69b54EbE715E2343,
0x54Ce5B4D348fb74B958e8966e2ec3dBd4958a7cd,
0xeB5F7389Fa26941519f0863349C223b73a6DDEE7,
0x74a3bf913953D695260D88BC1aA25A4eeE363ef0,
0x000aC0076727b35FBea2dAc28fEE5cCB0fEA768e,
0xAF45Ced136b9D9e24903464AE889F5C8a723FC14,
0xf93124b7c738843CBB89E864c862c38cddCccF95,
0xD2CC37A4dc036a8D232b48f62cDD4731412f4890,
0xDA798F6896A3331F64b48c12D1D57Fd9cbe70811,
0x71AA1BE1D36CaFE3867910F99C09e347899C19C3,
0x8192b6E7387CCd768277c17DAb1b7a5027c0b3Cf,
0x178e21ad2E77AE06711549CFBB1f9c7a9d8096e8,
0x5E1487F35515d02A92753504a8D75471b9f49EdB,
0x6FbEBc898F403E4773E95feB15E80C9A99c8348d,
]
fn guardian_set1() -> Array<EthAddress> {
array_try_into(
array![
0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5,
0xfF6CB952589BDE862c25Ef4392132fb9D4A42157,
0x114De8460193bdf3A2fCf81f86a09765F4762fD1,
0x107A0086b32d7A0977926A205131d8731D39cbEB,
0x8C82B2fd82FaeD2711d59AF0F2499D16e726f6b2,
0x11b39756C042441BE6D8650b69b54EbE715E2343,
0x54Ce5B4D348fb74B958e8966e2ec3dBd4958a7cd,
0xeB5F7389Fa26941519f0863349C223b73a6DDEE7,
0x74a3bf913953D695260D88BC1aA25A4eeE363ef0,
0x000aC0076727b35FBea2dAc28fEE5cCB0fEA768e,
0xAF45Ced136b9D9e24903464AE889F5C8a723FC14,
0xf93124b7c738843CBB89E864c862c38cddCccF95,
0xD2CC37A4dc036a8D232b48f62cDD4731412f4890,
0xDA798F6896A3331F64b48c12D1D57Fd9cbe70811,
0x71AA1BE1D36CaFE3867910F99C09e347899C19C3,
0x8192b6E7387CCd768277c17DAb1b7a5027c0b3Cf,
0x178e21ad2E77AE06711549CFBB1f9c7a9d8096e8,
0x5E1487F35515d02A92753504a8D75471b9f49EdB,
0x6FbEBc898F403E4773E95feB15E80C9A99c8348d,
]
)
}
fn guardian_set2() -> Array<felt252> {
array![
0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5,
0xfF6CB952589BDE862c25Ef4392132fb9D4A42157,
0x114De8460193bdf3A2fCf81f86a09765F4762fD1,
0x107A0086b32d7A0977926A205131d8731D39cbEB,
0x8C82B2fd82FaeD2711d59AF0F2499D16e726f6b2,
0x11b39756C042441BE6D8650b69b54EbE715E2343,
0x54Ce5B4D348fb74B958e8966e2ec3dBd4958a7cd,
0x66B9590e1c41e0B226937bf9217D1d67Fd4E91F5,
0x74a3bf913953D695260D88BC1aA25A4eeE363ef0,
0x000aC0076727b35FBea2dAc28fEE5cCB0fEA768e,
0xAF45Ced136b9D9e24903464AE889F5C8a723FC14,
0xf93124b7c738843CBB89E864c862c38cddCccF95,
0xD2CC37A4dc036a8D232b48f62cDD4731412f4890,
0xDA798F6896A3331F64b48c12D1D57Fd9cbe70811,
0x71AA1BE1D36CaFE3867910F99C09e347899C19C3,
0x8192b6E7387CCd768277c17DAb1b7a5027c0b3Cf,
0x178e21ad2E77AE06711549CFBB1f9c7a9d8096e8,
0x5E1487F35515d02A92753504a8D75471b9f49EdB,
0x6FbEBc898F403E4773E95feB15E80C9A99c8348d,
]
fn guardian_set2() -> Array<EthAddress> {
array_try_into(
array![
0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5,
0xfF6CB952589BDE862c25Ef4392132fb9D4A42157,
0x114De8460193bdf3A2fCf81f86a09765F4762fD1,
0x107A0086b32d7A0977926A205131d8731D39cbEB,
0x8C82B2fd82FaeD2711d59AF0F2499D16e726f6b2,
0x11b39756C042441BE6D8650b69b54EbE715E2343,
0x54Ce5B4D348fb74B958e8966e2ec3dBd4958a7cd,
0x66B9590e1c41e0B226937bf9217D1d67Fd4E91F5,
0x74a3bf913953D695260D88BC1aA25A4eeE363ef0,
0x000aC0076727b35FBea2dAc28fEE5cCB0fEA768e,
0xAF45Ced136b9D9e24903464AE889F5C8a723FC14,
0xf93124b7c738843CBB89E864c862c38cddCccF95,
0xD2CC37A4dc036a8D232b48f62cDD4731412f4890,
0xDA798F6896A3331F64b48c12D1D57Fd9cbe70811,
0x71AA1BE1D36CaFE3867910F99C09e347899C19C3,
0x8192b6E7387CCd768277c17DAb1b7a5027c0b3Cf,
0x178e21ad2E77AE06711549CFBB1f9c7a9d8096e8,
0x5E1487F35515d02A92753504a8D75471b9f49EdB,
0x6FbEBc898F403E4773E95feB15E80C9A99c8348d,
]
)
}
fn guardian_set3() -> Array<felt252> {
array![
0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5,
0xfF6CB952589BDE862c25Ef4392132fb9D4A42157,
0x114De8460193bdf3A2fCf81f86a09765F4762fD1,
0x107A0086b32d7A0977926A205131d8731D39cbEB,
0x8C82B2fd82FaeD2711d59AF0F2499D16e726f6b2,
0x11b39756C042441BE6D8650b69b54EbE715E2343,
0x54Ce5B4D348fb74B958e8966e2ec3dBd4958a7cd,
0x15e7cAF07C4e3DC8e7C469f92C8Cd88FB8005a20,
0x74a3bf913953D695260D88BC1aA25A4eeE363ef0,
0x000aC0076727b35FBea2dAc28fEE5cCB0fEA768e,
0xAF45Ced136b9D9e24903464AE889F5C8a723FC14,
0xf93124b7c738843CBB89E864c862c38cddCccF95,
0xD2CC37A4dc036a8D232b48f62cDD4731412f4890,
0xDA798F6896A3331F64b48c12D1D57Fd9cbe70811,
0x71AA1BE1D36CaFE3867910F99C09e347899C19C3,
0x8192b6E7387CCd768277c17DAb1b7a5027c0b3Cf,
0x178e21ad2E77AE06711549CFBB1f9c7a9d8096e8,
0x5E1487F35515d02A92753504a8D75471b9f49EdB,
0x6FbEBc898F403E4773E95feB15E80C9A99c8348d,
]
fn guardian_set3() -> Array<EthAddress> {
array_try_into(
array![
0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5,
0xfF6CB952589BDE862c25Ef4392132fb9D4A42157,
0x114De8460193bdf3A2fCf81f86a09765F4762fD1,
0x107A0086b32d7A0977926A205131d8731D39cbEB,
0x8C82B2fd82FaeD2711d59AF0F2499D16e726f6b2,
0x11b39756C042441BE6D8650b69b54EbE715E2343,
0x54Ce5B4D348fb74B958e8966e2ec3dBd4958a7cd,
0x15e7cAF07C4e3DC8e7C469f92C8Cd88FB8005a20,
0x74a3bf913953D695260D88BC1aA25A4eeE363ef0,
0x000aC0076727b35FBea2dAc28fEE5cCB0fEA768e,
0xAF45Ced136b9D9e24903464AE889F5C8a723FC14,
0xf93124b7c738843CBB89E864c862c38cddCccF95,
0xD2CC37A4dc036a8D232b48f62cDD4731412f4890,
0xDA798F6896A3331F64b48c12D1D57Fd9cbe70811,
0x71AA1BE1D36CaFE3867910F99C09e347899C19C3,
0x8192b6E7387CCd768277c17DAb1b7a5027c0b3Cf,
0x178e21ad2E77AE06711549CFBB1f9c7a9d8096e8,
0x5E1487F35515d02A92753504a8D75471b9f49EdB,
0x6FbEBc898F403E4773E95feB15E80C9A99c8348d,
]
)
}

// A random VAA pulled from Hermes.
Expand Down
Loading