From 04906de2e14e65a30484fc1b495aaa772d2d49da Mon Sep 17 00:00:00 2001 From: Ayush Suresh Date: Wed, 16 Jul 2025 12:07:14 -0700 Subject: [PATCH 1/5] checking whether this works --- target_chains/fuel/contracts/Cargo.lock | 99 +++++++++-- target_chains/fuel/contracts/Forc.lock | 38 ++-- .../fuel/contracts/fuel-toolchain.toml | 6 +- .../fuel/contracts/pyth-contract/Forc.toml | 4 +- .../fuel/contracts/pyth-contract/src/main.sw | 162 +++++++++++------- .../fuel/contracts/pyth-interface/Forc.toml | 3 - .../data_structures/governance_instruction.sw | 2 +- .../src/data_structures/price.sw | 8 +- .../src/data_structures/wormhole_light.sw | 13 +- .../pyth-interface/src/pyth_merkle_proof.sw | 14 +- 10 files changed, 232 insertions(+), 117 deletions(-) diff --git a/target_chains/fuel/contracts/Cargo.lock b/target_chains/fuel/contracts/Cargo.lock index 0ae3a77fd2..d21429249f 100644 --- a/target_chains/fuel/contracts/Cargo.lock +++ b/target_chains/fuel/contracts/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "Inflector" @@ -62,6 +62,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "ahash" version = "0.8.11" @@ -599,29 +610,63 @@ dependencies = [ "generic-array", ] +[[package]] +name = "borsh" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" +dependencies = [ + "borsh-derive 0.9.3", + "hashbrown 0.11.2", +] + [[package]] name = "borsh" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" dependencies = [ - "borsh-derive", + "borsh-derive 0.10.3", "hashbrown 0.13.2", ] +[[package]] +name = "borsh-derive" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" +dependencies = [ + "borsh-derive-internal 0.9.3", + "borsh-schema-derive-internal 0.9.3", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + [[package]] name = "borsh-derive" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" dependencies = [ - "borsh-derive-internal", - "borsh-schema-derive-internal", + "borsh-derive-internal 0.10.3", + "borsh-schema-derive-internal 0.10.3", "proc-macro-crate 0.1.5", "proc-macro2", "syn 1.0.109", ] +[[package]] +name = "borsh-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "borsh-derive-internal" version = "0.10.3" @@ -633,6 +678,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "borsh-schema-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "borsh-schema-derive-internal" version = "0.10.3" @@ -2717,6 +2773,15 @@ dependencies = [ "byteorder", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.8", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -2729,7 +2794,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash", + "ahash 0.8.11", ] [[package]] @@ -2738,7 +2803,7 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash", + "ahash 0.8.11", "allocator-api2", "serde", ] @@ -4762,6 +4827,19 @@ dependencies = [ "psl-types", ] +[[package]] +name = "pyth-sdk" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5c805ba3dfb5b7ed6a8ffa62ec38391f485a79c7cf6b3b11d3bd44fb0325824" +dependencies = [ + "borsh 0.9.3", + "borsh-derive 0.9.3", + "hex", + "schemars", + "serde", +] + [[package]] name = "pyth_sdk" version = "0.1.0" @@ -4784,15 +4862,16 @@ dependencies = [ [[package]] name = "pythnet-sdk" -version = "2.3.0" +version = "2.3.1" dependencies = [ "bincode", - "borsh", + "borsh 0.10.3", "bytemuck", "byteorder", "fast-math", "hex", "libsecp256k1", + "pyth-sdk", "rand", "rustc_version", "serde", @@ -6559,7 +6638,7 @@ version = "0.212.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d28bc49ba1e5c5b61ffa7a2eace10820443c4b7d1c0b144109261d14570fdf8" dependencies = [ - "ahash", + "ahash 0.8.11", "bitflags 2.6.0", "hashbrown 0.14.5", "indexmap 2.4.0", @@ -7261,4 +7340,4 @@ checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", "pkg-config", -] \ No newline at end of file +] diff --git a/target_chains/fuel/contracts/Forc.lock b/target_chains/fuel/contracts/Forc.lock index 16dd234c19..4a7371d817 100644 --- a/target_chains/fuel/contracts/Forc.lock +++ b/target_chains/fuel/contracts/Forc.lock @@ -1,44 +1,34 @@ [[package]] -name = "core" -source = "path+from-root-8357A6DDC5F39D14" +name = "ownership" +version = "0.26.0" +source = "registry+ownership?0.26.0#QmbVoNUrvCTyQTdE8ZP83XxTQQVzhrevfMqk1rAJAkMFVo!" +dependencies = [ + "src5", + "std", +] [[package]] name = "pyth-contract" source = "member" dependencies = [ + "ownership", "pyth_interface", - "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.4.4#a001d3c248595112aae67e5633a06ef9bc0536ae", + "src5", "std", - "sway_libs", ] [[package]] name = "pyth_interface" source = "path+from-root-555D3D27A908977B" -dependencies = [ - "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.4.4#a001d3c248595112aae67e5633a06ef9bc0536ae", - "std", -] - -[[package]] -name = "standards" -source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.4.3#6f63eb7dff2458a7d976184e565b5cbf26f61da2" dependencies = ["std"] [[package]] -name = "standards" -source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.4.4#a001d3c248595112aae67e5633a06ef9bc0536ae" +name = "src5" +version = "0.8.0" +source = "registry+src5?0.8.0#QmNRPZrPHFBiEAyWPU8gesdPsD2zb3cMKwEgxJwV1ZEjyD!" dependencies = ["std"] [[package]] name = "std" -source = "git+https://github.com/fuellabs/sway?tag=v0.65.2#66bb430395daf5b8f7205f7b9d8d008e2e812d54" -dependencies = ["core"] - -[[package]] -name = "sway_libs" -source = "git+https://github.com/FuelLabs/sway-libs?tag=v0.21.0#6a227ed34c86fe1ebd334dbdfeccf66c43e3915b" -dependencies = [ - "standards git+https://github.com/FuelLabs/sway-standards?tag=v0.4.3#6f63eb7dff2458a7d976184e565b5cbf26f61da2", - "std", -] +version = "0.68.9" +source = "registry+std?0.68.9#QmUaBxMs2JvY1bXgRCdeCsG3o6TN82ftRgv4Tq7ytqUGUT!" diff --git a/target_chains/fuel/contracts/fuel-toolchain.toml b/target_chains/fuel/contracts/fuel-toolchain.toml index 5a4d48d5da..03991c2c68 100644 --- a/target_chains/fuel/contracts/fuel-toolchain.toml +++ b/target_chains/fuel/contracts/fuel-toolchain.toml @@ -1,6 +1,6 @@ [toolchain] -channel = "latest-aarch64-apple-darwin" +channel = "mainnet" [components] -forc = "0.65.2" -fuel-core = "0.37.1" +forc = "0.68.9" +fuel-core = "0.43.2" \ No newline at end of file diff --git a/target_chains/fuel/contracts/pyth-contract/Forc.toml b/target_chains/fuel/contracts/pyth-contract/Forc.toml index 984813fed8..7cd7976cbc 100644 --- a/target_chains/fuel/contracts/pyth-contract/Forc.toml +++ b/target_chains/fuel/contracts/pyth-contract/Forc.toml @@ -5,6 +5,6 @@ license = "Apache-2.0" name = "pyth-contract" [dependencies] -sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.21.0" } pyth_interface = { path = "../pyth-interface" } -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.4.4" } +ownership = "0.26.0" +src5 = "0.8.0" diff --git a/target_chains/fuel/contracts/pyth-contract/src/main.sw b/target_chains/fuel/contracts/pyth-contract/src/main.sw index 137288e804..7a4aaf2e50 100644 --- a/target_chains/fuel/contracts/pyth-contract/src/main.sw +++ b/target_chains/fuel/contracts/pyth-contract/src/main.sw @@ -53,8 +53,8 @@ use pyth_interface::{ WormholeGuardians, }; -use sway_libs::ownership::*; -use standards::src5::{SRC5, State}; +use ownership::*; +use src5::{SRC5, State}; const GUARDIAN_SET_EXPIRATION_TIME_SECONDS: u64 = 86400; // 24 hours in seconds configurable { @@ -209,7 +209,7 @@ impl PythCore for Contract { while i_2 < number_of_attestations { let (_, slice) = vm.payload.split_at(attestation_index + 32); let (price_feed_id, _) = slice.split_at(32); - let price_feed_id: PriceFeedId = price_feed_id.into(); + let price_feed_id: PriceFeedId = b256::from_le_bytes(price_feed_id.clone()); if price_feed_id.is_target(target_price_feed_ids) == false { attestation_index += attestation_size_u16; @@ -272,7 +272,56 @@ impl PythCore for Contract { #[storage(read, write), payable] fn update_price_feeds(update_data: Vec) { - update_price_feeds(update_data) + require( + msg_asset_id() == AssetId::base(), + PythError::FeesCanOnlyBePaidInTheBaseAsset, + ); + + let mut total_number_of_updates = 0; + + // let mut updated_price_feeds: Vec = Vec::new(); // TODO: requires append for Vec + let mut i = 0; + while i < update_data.len() { + let data = update_data.get(i).unwrap(); + + match UpdateType::determine_type(data) { + UpdateType::Accumulator(accumulator_update) => { + let (number_of_updates, _updated_ids) = accumulator_update.update_price_feeds( + current_guardian_set_index(), + storage + .wormhole_guardian_sets, + storage + .latest_price_feed, + storage + .is_valid_data_source, + ); + // updated_price_feeds.append(updated_ids); // TODO: requires append for Vec + total_number_of_updates += number_of_updates; + }, + UpdateType::BatchAttestation(batch_attestation_update) => { + let _updated_ids = batch_attestation_update.update_price_feeds( + current_guardian_set_index(), + storage + .wormhole_guardian_sets, + storage + .latest_price_feed, + storage + .is_valid_data_source, + ); + // updated_price_feeds.append(updated_ids); // TODO: requires append for Vec + total_number_of_updates += 1; + }, + } + + i += 1; + } + + let required_fee = total_fee(total_number_of_updates, storage.single_update_fee); + require(msg_amount() >= required_fee, PythError::InsufficientFee); + + // log(UpdatedPriceFeedsEvent { // TODO: requires append for Vec + // updated_price_feeds, + // }) } #[storage(read, write), payable] @@ -292,7 +341,56 @@ impl PythCore for Contract { while i < price_feed_ids.len() { if latest_publish_time(price_feed_ids.get(i).unwrap()) < publish_times.get(i).unwrap() { - update_price_feeds(update_data); + require( + msg_asset_id() == AssetId::base(), + PythError::FeesCanOnlyBePaidInTheBaseAsset, + ); + + let mut total_number_of_updates = 0; + + // let mut updated_price_feeds: Vec = Vec::new(); // TODO: requires append for Vec + let mut i = 0; + while i < update_data.len() { + let data = update_data.get(i).unwrap(); + + match UpdateType::determine_type(data) { + UpdateType::Accumulator(accumulator_update) => { + let (number_of_updates, _updated_ids) = accumulator_update.update_price_feeds( + current_guardian_set_index(), + storage + .wormhole_guardian_sets, + storage + .latest_price_feed, + storage + .is_valid_data_source, + ); + // updated_price_feeds.append(updated_ids); // TODO: requires append for Vec + total_number_of_updates += number_of_updates; + }, + UpdateType::BatchAttestation(batch_attestation_update) => { + let _updated_ids = batch_attestation_update.update_price_feeds( + current_guardian_set_index(), + storage + .wormhole_guardian_sets, + storage + .latest_price_feed, + storage + .is_valid_data_source, + ); + // updated_price_feeds.append(updated_ids); // TODO: requires append for Vec + total_number_of_updates += 1; + }, + } + + i += 1; + } + + let required_fee = total_fee(total_number_of_updates, storage.single_update_fee); + require(msg_amount() >= required_fee, PythError::InsufficientFee); + + // log(UpdatedPriceFeedsEvent { // TODO: requires append for Vec + // updated_price_feeds, + // }) return; } @@ -374,60 +472,6 @@ fn update_fee(update_data: Vec) -> u64 { total_fee(total_number_of_updates, storage.single_update_fee) } -#[storage(read, write), payable] -fn update_price_feeds(update_data: Vec) { - require( - msg_asset_id() == AssetId::base(), - PythError::FeesCanOnlyBePaidInTheBaseAsset, - ); - - let mut total_number_of_updates = 0; - - // let mut updated_price_feeds: Vec = Vec::new(); // TODO: requires append for Vec - let mut i = 0; - while i < update_data.len() { - let data = update_data.get(i).unwrap(); - - match UpdateType::determine_type(data) { - UpdateType::Accumulator(accumulator_update) => { - let (number_of_updates, _updated_ids) = accumulator_update.update_price_feeds( - current_guardian_set_index(), - storage - .wormhole_guardian_sets, - storage - .latest_price_feed, - storage - .is_valid_data_source, - ); - // updated_price_feeds.append(updated_ids); // TODO: requires append for Vec - total_number_of_updates += number_of_updates; - }, - UpdateType::BatchAttestation(batch_attestation_update) => { - let _updated_ids = batch_attestation_update.update_price_feeds( - current_guardian_set_index(), - storage - .wormhole_guardian_sets, - storage - .latest_price_feed, - storage - .is_valid_data_source, - ); - // updated_price_feeds.append(updated_ids); // TODO: requires append for Vec - total_number_of_updates += 1; - }, - } - - i += 1; - } - - let required_fee = total_fee(total_number_of_updates, storage.single_update_fee); - require(msg_amount() >= required_fee, PythError::InsufficientFee); - - // log(UpdatedPriceFeedsEvent { // TODO: requires append for Vec - // updated_price_feeds, - // }) -} - #[storage(read)] fn valid_time_period() -> u64 { storage.valid_time_period_seconds.read() diff --git a/target_chains/fuel/contracts/pyth-interface/Forc.toml b/target_chains/fuel/contracts/pyth-interface/Forc.toml index 7cb44a4edc..39cf1a3f19 100644 --- a/target_chains/fuel/contracts/pyth-interface/Forc.toml +++ b/target_chains/fuel/contracts/pyth-interface/Forc.toml @@ -3,6 +3,3 @@ authors = ["Fuel Labs "] entry = "interface.sw" license = "Apache-2.0" name = "pyth_interface" - -[dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.4.4" } diff --git a/target_chains/fuel/contracts/pyth-interface/src/data_structures/governance_instruction.sw b/target_chains/fuel/contracts/pyth-interface/src/data_structures/governance_instruction.sw index f927a7d69e..8d154bea47 100644 --- a/target_chains/fuel/contracts/pyth-interface/src/data_structures/governance_instruction.sw +++ b/target_chains/fuel/contracts/pyth-interface/src/data_structures/governance_instruction.sw @@ -139,7 +139,7 @@ impl GovernanceInstruction { index += 2; let (_, slice) = encoded_payload.split_at(index); let (slice, _) = slice.split_at(32); - let emitter_address: b256 = slice.into(); + let emitter_address: b256 = b256::from_le_bytes(slice.clone()); index += 32; data_sources.push(DataSource { diff --git a/target_chains/fuel/contracts/pyth-interface/src/data_structures/price.sw b/target_chains/fuel/contracts/pyth-interface/src/data_structures/price.sw index 7827d1d64a..da8f7fa7d2 100644 --- a/target_chains/fuel/contracts/pyth-interface/src/data_structures/price.sw +++ b/target_chains/fuel/contracts/pyth-interface/src/data_structures/price.sw @@ -1,6 +1,6 @@ library; -use std::{bytes::Bytes, block::timestamp}; +use std::{bytes::Bytes, block::timestamp, bytes_conversions::b256::*}; use ::errors::PythError; use ::utils::absolute_of_exponent; @@ -99,7 +99,7 @@ impl PriceFeed { let mut offset = 1u64; let (_, slice) = encoded_price_feed.split_at(offset); let (price_feed_id, _) = slice.split_at(32); - let price_feed_id: PriceFeedId = price_feed_id.into(); + let price_feed_id: PriceFeedId = b256::from_le_bytes(price_feed_id.clone()); offset += 32; let price = u64::from_be_bytes([ encoded_price_feed.get(offset).unwrap(), @@ -186,7 +186,7 @@ impl PriceFeed { let mut attestation_index = index + 32; let (_, slice) = encoded_payload.split_at(attestation_index); let (price_feed_id, _) = slice.split_at(32); - let price_feed_id: PriceFeedId = price_feed_id.into(); + let price_feed_id: PriceFeedId = b256::from_le_bytes(price_feed_id.clone()); attestation_index += 32; let mut price = u64::from_be_bytes([ encoded_payload.get(attestation_index).unwrap(), @@ -321,7 +321,7 @@ impl PriceFeed { } impl PriceFeed { - pub fn extract_from_merkle_proof(digest: Bytes, encoded_proof: Bytes, offset: u64) -> (u64, self) { + pub fn extract_from_merkle_proof(digest: Bytes, encoded_proof: Bytes, offset: u64) -> (u64, Self) { // In order to avoid `ref mut` param related MemoryWriteOverlap error let mut current_offset = offset; diff --git a/target_chains/fuel/contracts/pyth-interface/src/data_structures/wormhole_light.sw b/target_chains/fuel/contracts/pyth-interface/src/data_structures/wormhole_light.sw index 920e2144a6..7830d2cedb 100644 --- a/target_chains/fuel/contracts/pyth-interface/src/data_structures/wormhole_light.sw +++ b/target_chains/fuel/contracts/pyth-interface/src/data_structures/wormhole_light.sw @@ -12,6 +12,7 @@ use std::{ b512::B512, block::timestamp, bytes::Bytes, + bytes_conversions::b256::*, constants::ZERO_B256, hash::{ Hash, @@ -85,7 +86,7 @@ impl GuardianSetUpgrade { let mut index = 0; let (_, slice) = encoded_upgrade.split_at(index); let (module, _) = slice.split_at(32); - let module: b256 = module.into(); + let module: b256 = b256::from_le_bytes(module.clone()); require(module == UPGRADE_MODULE, WormholeError::InvalidModule); index += 32; let action = encoded_upgrade.get(index).unwrap(); @@ -114,7 +115,7 @@ impl GuardianSetUpgrade { while i < guardian_length { let (_, slice) = encoded_upgrade.split_at(index); let (key, _) = slice.split_at(20); - let key: b256 = key.into(); + let key: b256 = b256::from_le_bytes(key.clone()); new_guardian_set.keys.push(key.rsh(96)); index += 20; i += 1; @@ -352,10 +353,10 @@ impl WormholeVM { index += 1; let (_, slice) = encoded_vm.split_at(index); let (slice, remainder) = slice.split_at(32); - let r: b256 = slice.into(); + let r: b256 = b256::from_le_bytes(slice.clone()); index += 32; let (slice, remainder) = remainder.split_at(32); - let s: b256 = slice.into(); + let s: b256 = b256::from_le_bytes(slice.clone()); index += 32; let v = remainder.get(0); require(v.is_some(), WormholeError::SignatureVIrretrievable); @@ -408,7 +409,7 @@ impl WormholeVM { index += 2; let (_, slice) = encoded_vm.split_at(index); let (slice, _) = slice.split_at(32); - let emitter_address: b256 = slice.into(); + let emitter_address: b256 = b256::from_le_bytes(slice.clone()); index += 32; let (_, slice) = encoded_vm.split_at(index); let (slice, _) = slice.split_at(8); @@ -511,7 +512,7 @@ impl WormholeVM { index += 2; let (_, slice) = encoded_vm.split_at(index); let (slice, _) = slice.split_at(32); - let emitter_address: b256 = slice.into(); + let emitter_address: b256 = b256::from_le_bytes(slice.clone()); index += 32; let (_, slice) = encoded_vm.split_at(index); let (slice, _) = slice.split_at(8); diff --git a/target_chains/fuel/contracts/pyth-interface/src/pyth_merkle_proof.sw b/target_chains/fuel/contracts/pyth-interface/src/pyth_merkle_proof.sw index a26f91fcb0..9c63633a43 100644 --- a/target_chains/fuel/contracts/pyth-interface/src/pyth_merkle_proof.sw +++ b/target_chains/fuel/contracts/pyth-interface/src/pyth_merkle_proof.sw @@ -1,6 +1,6 @@ library; -use std::{bytes::Bytes, hash::{Hash, keccak256}}; +use std::{bytes::Bytes, hash::{Hash, keccak256}, bytes_conversions::b256::*}; use ::errors::PythError; pub const MERKLE_LEAF_PREFIX = 0u8; @@ -20,8 +20,12 @@ fn node_hash(child_a: Bytes, child_b: Bytes) -> Bytes { let mut bytes = Bytes::with_capacity(41); bytes.push(MERKLE_NODE_PREFIX); - let a: b256 = child_a.into(); - let b: b256 = child_b.into(); + // let a: b256 = child_a.into(); + // let b: b256 = child_b.into(); + + let a: b256 = b256::from_le_bytes(child_a.clone()); + let b: b256 = b256::from_le_bytes(child_b.clone()); + if a > b { bytes.append(child_b); bytes.append(child_a); @@ -54,8 +58,8 @@ pub fn validate_proof( i += 1; } - let current_digest_b256: b256 = current_digest.into(); - let root_b256: b256 = root.into(); + let current_digest_b256: b256 = b256::from_le_bytes(current_digest.clone()); + let root_b256: b256 = b256::from_le_bytes(root.clone()); require(current_digest_b256 == root_b256, PythError::InvalidProof); From 9a7a1d49ce176fef441db77cea888ae506bdf38b Mon Sep 17 00:00:00 2001 From: Ayush Suresh Date: Wed, 16 Jul 2025 12:26:00 -0700 Subject: [PATCH 2/5] reinstated update_price_feeds function --- .../fuel/contracts/pyth-contract/src/main.sw | 155 ++++++------------ 1 file changed, 54 insertions(+), 101 deletions(-) diff --git a/target_chains/fuel/contracts/pyth-contract/src/main.sw b/target_chains/fuel/contracts/pyth-contract/src/main.sw index 7a4aaf2e50..cdda9ccf70 100644 --- a/target_chains/fuel/contracts/pyth-contract/src/main.sw +++ b/target_chains/fuel/contracts/pyth-contract/src/main.sw @@ -272,56 +272,7 @@ impl PythCore for Contract { #[storage(read, write), payable] fn update_price_feeds(update_data: Vec) { - require( - msg_asset_id() == AssetId::base(), - PythError::FeesCanOnlyBePaidInTheBaseAsset, - ); - - let mut total_number_of_updates = 0; - - // let mut updated_price_feeds: Vec = Vec::new(); // TODO: requires append for Vec - let mut i = 0; - while i < update_data.len() { - let data = update_data.get(i).unwrap(); - - match UpdateType::determine_type(data) { - UpdateType::Accumulator(accumulator_update) => { - let (number_of_updates, _updated_ids) = accumulator_update.update_price_feeds( - current_guardian_set_index(), - storage - .wormhole_guardian_sets, - storage - .latest_price_feed, - storage - .is_valid_data_source, - ); - // updated_price_feeds.append(updated_ids); // TODO: requires append for Vec - total_number_of_updates += number_of_updates; - }, - UpdateType::BatchAttestation(batch_attestation_update) => { - let _updated_ids = batch_attestation_update.update_price_feeds( - current_guardian_set_index(), - storage - .wormhole_guardian_sets, - storage - .latest_price_feed, - storage - .is_valid_data_source, - ); - // updated_price_feeds.append(updated_ids); // TODO: requires append for Vec - total_number_of_updates += 1; - }, - } - - i += 1; - } - - let required_fee = total_fee(total_number_of_updates, storage.single_update_fee); - require(msg_amount() >= required_fee, PythError::InsufficientFee); - - // log(UpdatedPriceFeedsEvent { // TODO: requires append for Vec - // updated_price_feeds, - // }) + } #[storage(read, write), payable] @@ -341,57 +292,7 @@ impl PythCore for Contract { while i < price_feed_ids.len() { if latest_publish_time(price_feed_ids.get(i).unwrap()) < publish_times.get(i).unwrap() { - require( - msg_asset_id() == AssetId::base(), - PythError::FeesCanOnlyBePaidInTheBaseAsset, - ); - - let mut total_number_of_updates = 0; - - // let mut updated_price_feeds: Vec = Vec::new(); // TODO: requires append for Vec - let mut i = 0; - while i < update_data.len() { - let data = update_data.get(i).unwrap(); - - match UpdateType::determine_type(data) { - UpdateType::Accumulator(accumulator_update) => { - let (number_of_updates, _updated_ids) = accumulator_update.update_price_feeds( - current_guardian_set_index(), - storage - .wormhole_guardian_sets, - storage - .latest_price_feed, - storage - .is_valid_data_source, - ); - // updated_price_feeds.append(updated_ids); // TODO: requires append for Vec - total_number_of_updates += number_of_updates; - }, - UpdateType::BatchAttestation(batch_attestation_update) => { - let _updated_ids = batch_attestation_update.update_price_feeds( - current_guardian_set_index(), - storage - .wormhole_guardian_sets, - storage - .latest_price_feed, - storage - .is_valid_data_source, - ); - // updated_price_feeds.append(updated_ids); // TODO: requires append for Vec - total_number_of_updates += 1; - }, - } - - i += 1; - } - - let required_fee = total_fee(total_number_of_updates, storage.single_update_fee); - require(msg_amount() >= required_fee, PythError::InsufficientFee); - - // log(UpdatedPriceFeedsEvent { // TODO: requires append for Vec - // updated_price_feeds, - // }) - return; + update_price_feeds(update_data); } i += 1; @@ -472,6 +373,58 @@ fn update_fee(update_data: Vec) -> u64 { total_fee(total_number_of_updates, storage.single_update_fee) } +#[storage(read, write)] +fn update_price_feeds(update_data: Vec) { + require( + msg_asset_id() == AssetId::base(), + PythError::FeesCanOnlyBePaidInTheBaseAsset, + ); + + let required_fee = update_fee(update_data); + require(msg_amount() >= required_fee, PythError::InsufficientFee); + + let mut total_number_of_updates = 0; + + let mut i = 0; + while i < update_data.len() { + let data = update_data.get(i).unwrap(); + + match UpdateType::determine_type(data) { + UpdateType::Accumulator(accumulator_update) => { + let (number_of_updates, updated_ids) = accumulator_update.update_price_feeds( + current_guardian_set_index(), + storage + .wormhole_guardian_sets, + storage + .latest_price_feed, + storage + .is_valid_data_source, + ); + total_number_of_updates += number_of_updates; + log(UpdatedPriceFeedsEvent { updated_price_feeds: updated_ids }); + }, + UpdateType::BatchAttestation(batch_attestation_update) => { + let updated_ids = batch_attestation_update.update_price_feeds( + current_guardian_set_index(), + storage + .wormhole_guardian_sets, + storage + .latest_price_feed, + storage + .is_valid_data_source, + ); + total_number_of_updates += 1; + log(UpdatedPriceFeedsEvent { updated_price_feeds: updated_ids }); + }, + } + + i += 1; + } + + let fee = total_fee(total_number_of_updates, storage.single_update_fee); + require(msg_amount() >= fee, PythError::InsufficientFee); +} + #[storage(read)] fn valid_time_period() -> u64 { storage.valid_time_period_seconds.read() From 6c59d09b2ea78ef2157da463a4a68a8291b5e295 Mon Sep 17 00:00:00 2001 From: Ayush Suresh Date: Wed, 16 Jul 2025 12:30:35 -0700 Subject: [PATCH 3/5] reset most of main.sw update_price_feeds helper function --- .../fuel/contracts/pyth-contract/src/main.sw | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/target_chains/fuel/contracts/pyth-contract/src/main.sw b/target_chains/fuel/contracts/pyth-contract/src/main.sw index cdda9ccf70..65d6f26a09 100644 --- a/target_chains/fuel/contracts/pyth-contract/src/main.sw +++ b/target_chains/fuel/contracts/pyth-contract/src/main.sw @@ -272,7 +272,7 @@ impl PythCore for Contract { #[storage(read, write), payable] fn update_price_feeds(update_data: Vec) { - + update_price_feeds(update_data) } #[storage(read, write), payable] @@ -293,6 +293,7 @@ impl PythCore for Contract { if latest_publish_time(price_feed_ids.get(i).unwrap()) < publish_times.get(i).unwrap() { update_price_feeds(update_data); + return; } i += 1; @@ -373,25 +374,23 @@ fn update_fee(update_data: Vec) -> u64 { total_fee(total_number_of_updates, storage.single_update_fee) } -#[storage(read, write)] +#[storage(read, write), payable] fn update_price_feeds(update_data: Vec) { require( msg_asset_id() == AssetId::base(), PythError::FeesCanOnlyBePaidInTheBaseAsset, ); - let required_fee = update_fee(update_data); - require(msg_amount() >= required_fee, PythError::InsufficientFee); - let mut total_number_of_updates = 0; + // let mut updated_price_feeds: Vec = Vec::new(); // TODO: requires append for Vec let mut i = 0; while i < update_data.len() { let data = update_data.get(i).unwrap(); match UpdateType::determine_type(data) { UpdateType::Accumulator(accumulator_update) => { - let (number_of_updates, updated_ids) = accumulator_update.update_price_feeds( + let (number_of_updates, _updated_ids) = accumulator_update.update_price_feeds( current_guardian_set_index(), storage .wormhole_guardian_sets, @@ -400,11 +399,11 @@ fn update_price_feeds(update_data: Vec) { storage .is_valid_data_source, ); + // updated_price_feeds.append(updated_ids); // TODO: requires append for Vec total_number_of_updates += number_of_updates; - log(UpdatedPriceFeedsEvent { updated_price_feeds: updated_ids }); }, UpdateType::BatchAttestation(batch_attestation_update) => { - let updated_ids = batch_attestation_update.update_price_feeds( + let _updated_ids = batch_attestation_update.update_price_feeds( current_guardian_set_index(), storage .wormhole_guardian_sets, @@ -413,16 +412,20 @@ fn update_price_feeds(update_data: Vec) { storage .is_valid_data_source, ); + // updated_price_feeds.append(updated_ids); // TODO: requires append for Vec total_number_of_updates += 1; - log(UpdatedPriceFeedsEvent { updated_price_feeds: updated_ids }); }, } i += 1; } - let fee = total_fee(total_number_of_updates, storage.single_update_fee); - require(msg_amount() >= fee, PythError::InsufficientFee); + let required_fee = total_fee(total_number_of_updates, storage.single_update_fee); + require(msg_amount() >= required_fee, PythError::InsufficientFee); + + // log(UpdatedPriceFeedsEvent { // TODO: requires append for Vec + // updated_price_feeds, + // }) } #[storage(read)] @@ -931,4 +934,4 @@ fn verify_governance_vm(encoded_vm: Bytes) -> WormholeVM { set_last_executed_governance_sequence(vm.sequence); vm -} +} \ No newline at end of file From 57a24850c2a5e2094f41287750a0f0803e1a17bc Mon Sep 17 00:00:00 2001 From: Ayush Suresh Date: Wed, 16 Jul 2025 12:33:00 -0700 Subject: [PATCH 4/5] fixed forc build for main.sw file --- target_chains/fuel/contracts/pyth-contract/src/main.sw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target_chains/fuel/contracts/pyth-contract/src/main.sw b/target_chains/fuel/contracts/pyth-contract/src/main.sw index 65d6f26a09..da91995a07 100644 --- a/target_chains/fuel/contracts/pyth-contract/src/main.sw +++ b/target_chains/fuel/contracts/pyth-contract/src/main.sw @@ -374,7 +374,7 @@ fn update_fee(update_data: Vec) -> u64 { total_fee(total_number_of_updates, storage.single_update_fee) } -#[storage(read, write), payable] +#[storage(read, write)] fn update_price_feeds(update_data: Vec) { require( msg_asset_id() == AssetId::base(), From 10e5345ea2e29a5cc43311d43e681cf335e834f3 Mon Sep 17 00:00:00 2001 From: Ayush Suresh Date: Fri, 18 Jul 2025 08:39:46 -0700 Subject: [PATCH 5/5] cleaned le to be switch --- .../fuel/contracts/pyth-contract/src/main.sw | 4 ++-- .../src/data_structures/governance_instruction.sw | 2 +- .../pyth-interface/src/data_structures/price.sw | 4 ++-- .../src/data_structures/wormhole_light.sw | 12 ++++++------ .../pyth-interface/src/pyth_merkle_proof.sw | 11 ++++------- 5 files changed, 15 insertions(+), 18 deletions(-) diff --git a/target_chains/fuel/contracts/pyth-contract/src/main.sw b/target_chains/fuel/contracts/pyth-contract/src/main.sw index da91995a07..332d96547d 100644 --- a/target_chains/fuel/contracts/pyth-contract/src/main.sw +++ b/target_chains/fuel/contracts/pyth-contract/src/main.sw @@ -58,7 +58,7 @@ use src5::{SRC5, State}; const GUARDIAN_SET_EXPIRATION_TIME_SECONDS: u64 = 86400; // 24 hours in seconds configurable { - DEPLOYER: Identity = Identity::Address(Address::from(ZERO_B256)), + DEPLOYER: Identity = Identity::Address(Address::from(b256::zero())), } storage { @@ -209,7 +209,7 @@ impl PythCore for Contract { while i_2 < number_of_attestations { let (_, slice) = vm.payload.split_at(attestation_index + 32); let (price_feed_id, _) = slice.split_at(32); - let price_feed_id: PriceFeedId = b256::from_le_bytes(price_feed_id.clone()); + let price_feed_id: PriceFeedId = b256::from_be_bytes(price_feed_id.clone()); if price_feed_id.is_target(target_price_feed_ids) == false { attestation_index += attestation_size_u16; diff --git a/target_chains/fuel/contracts/pyth-interface/src/data_structures/governance_instruction.sw b/target_chains/fuel/contracts/pyth-interface/src/data_structures/governance_instruction.sw index 8d154bea47..5b57bc8a0a 100644 --- a/target_chains/fuel/contracts/pyth-interface/src/data_structures/governance_instruction.sw +++ b/target_chains/fuel/contracts/pyth-interface/src/data_structures/governance_instruction.sw @@ -139,7 +139,7 @@ impl GovernanceInstruction { index += 2; let (_, slice) = encoded_payload.split_at(index); let (slice, _) = slice.split_at(32); - let emitter_address: b256 = b256::from_le_bytes(slice.clone()); + let emitter_address: b256 = b256::from_be_bytes(slice.clone()); index += 32; data_sources.push(DataSource { diff --git a/target_chains/fuel/contracts/pyth-interface/src/data_structures/price.sw b/target_chains/fuel/contracts/pyth-interface/src/data_structures/price.sw index da8f7fa7d2..709d299c35 100644 --- a/target_chains/fuel/contracts/pyth-interface/src/data_structures/price.sw +++ b/target_chains/fuel/contracts/pyth-interface/src/data_structures/price.sw @@ -99,7 +99,7 @@ impl PriceFeed { let mut offset = 1u64; let (_, slice) = encoded_price_feed.split_at(offset); let (price_feed_id, _) = slice.split_at(32); - let price_feed_id: PriceFeedId = b256::from_le_bytes(price_feed_id.clone()); + let price_feed_id: PriceFeedId = b256::from_be_bytes(price_feed_id.clone()); offset += 32; let price = u64::from_be_bytes([ encoded_price_feed.get(offset).unwrap(), @@ -186,7 +186,7 @@ impl PriceFeed { let mut attestation_index = index + 32; let (_, slice) = encoded_payload.split_at(attestation_index); let (price_feed_id, _) = slice.split_at(32); - let price_feed_id: PriceFeedId = b256::from_le_bytes(price_feed_id.clone()); + let price_feed_id: PriceFeedId = b256::from_be_bytes(price_feed_id.clone()); attestation_index += 32; let mut price = u64::from_be_bytes([ encoded_payload.get(attestation_index).unwrap(), diff --git a/target_chains/fuel/contracts/pyth-interface/src/data_structures/wormhole_light.sw b/target_chains/fuel/contracts/pyth-interface/src/data_structures/wormhole_light.sw index 7830d2cedb..aa85c48c0f 100644 --- a/target_chains/fuel/contracts/pyth-interface/src/data_structures/wormhole_light.sw +++ b/target_chains/fuel/contracts/pyth-interface/src/data_structures/wormhole_light.sw @@ -86,7 +86,7 @@ impl GuardianSetUpgrade { let mut index = 0; let (_, slice) = encoded_upgrade.split_at(index); let (module, _) = slice.split_at(32); - let module: b256 = b256::from_le_bytes(module.clone()); + let module: b256 = b256::from_be_bytes(module.clone()); require(module == UPGRADE_MODULE, WormholeError::InvalidModule); index += 32; let action = encoded_upgrade.get(index).unwrap(); @@ -115,7 +115,7 @@ impl GuardianSetUpgrade { while i < guardian_length { let (_, slice) = encoded_upgrade.split_at(index); let (key, _) = slice.split_at(20); - let key: b256 = b256::from_le_bytes(key.clone()); + let key: b256 = b256::from_be_bytes(key.clone()); new_guardian_set.keys.push(key.rsh(96)); index += 20; i += 1; @@ -353,10 +353,10 @@ impl WormholeVM { index += 1; let (_, slice) = encoded_vm.split_at(index); let (slice, remainder) = slice.split_at(32); - let r: b256 = b256::from_le_bytes(slice.clone()); + let r: b256 = b256::from_be_bytes(slice.clone()); index += 32; let (slice, remainder) = remainder.split_at(32); - let s: b256 = b256::from_le_bytes(slice.clone()); + let s: b256 = b256::from_be_bytes(slice.clone()); index += 32; let v = remainder.get(0); require(v.is_some(), WormholeError::SignatureVIrretrievable); @@ -409,7 +409,7 @@ impl WormholeVM { index += 2; let (_, slice) = encoded_vm.split_at(index); let (slice, _) = slice.split_at(32); - let emitter_address: b256 = b256::from_le_bytes(slice.clone()); + let emitter_address: b256 = b256::from_be_bytes(slice.clone()); index += 32; let (_, slice) = encoded_vm.split_at(index); let (slice, _) = slice.split_at(8); @@ -512,7 +512,7 @@ impl WormholeVM { index += 2; let (_, slice) = encoded_vm.split_at(index); let (slice, _) = slice.split_at(32); - let emitter_address: b256 = b256::from_le_bytes(slice.clone()); + let emitter_address: b256 = b256::from_be_bytes(slice.clone()); index += 32; let (_, slice) = encoded_vm.split_at(index); let (slice, _) = slice.split_at(8); diff --git a/target_chains/fuel/contracts/pyth-interface/src/pyth_merkle_proof.sw b/target_chains/fuel/contracts/pyth-interface/src/pyth_merkle_proof.sw index 9c63633a43..618778d102 100644 --- a/target_chains/fuel/contracts/pyth-interface/src/pyth_merkle_proof.sw +++ b/target_chains/fuel/contracts/pyth-interface/src/pyth_merkle_proof.sw @@ -20,11 +20,8 @@ fn node_hash(child_a: Bytes, child_b: Bytes) -> Bytes { let mut bytes = Bytes::with_capacity(41); bytes.push(MERKLE_NODE_PREFIX); - // let a: b256 = child_a.into(); - // let b: b256 = child_b.into(); - - let a: b256 = b256::from_le_bytes(child_a.clone()); - let b: b256 = b256::from_le_bytes(child_b.clone()); + let a: b256 = b256::from_be_bytes(child_a.clone()); + let b: b256 = b256::from_be_bytes(child_b.clone()); if a > b { bytes.append(child_b); @@ -58,8 +55,8 @@ pub fn validate_proof( i += 1; } - let current_digest_b256: b256 = b256::from_le_bytes(current_digest.clone()); - let root_b256: b256 = b256::from_le_bytes(root.clone()); + let current_digest_b256: b256 = b256::from_be_bytes(current_digest.clone()); + let root_b256: b256 = b256::from_be_bytes(root.clone()); require(current_digest_b256 == root_b256, PythError::InvalidProof);