From 75120d393347c01e530d0ebc017c70e466378c31 Mon Sep 17 00:00:00 2001 From: Remo Date: Mon, 9 Feb 2026 11:58:17 +0200 Subject: [PATCH 01/10] Split to packages. Plece Primer in a package that maintain its classhash --- Scarb.lock | 37 +++- Scarb.toml | 2 +- account_factory/Scarb.toml | 27 +++ .../src}/account_factory.cairo | 6 +- account_factory/src/lib.cairo | 6 + .../src}/test.cairo | 46 ++++- .../src/test_utils.cairo | 30 +--- .../src}/utils.cairo | 3 +- contracts/Scarb.toml | 27 +-- contracts/src/account_factory.cairo | 4 - contracts/src/earn_reporter.cairo | 3 - contracts/src/lib.cairo | 7 - contracts/src/primer.cairo | 2 - contracts/src/primer/test.cairo | 43 ----- earn_reporter/Scarb.toml | 22 +++ .../src}/earn_reporter.cairo | 2 +- earn_reporter/src/lib.cairo | 5 + .../src}/test.cairo | 10 +- earn_reporter/src/test_utils.cairo | 63 +++++++ eth_712_account/Scarb.toml | 18 ++ .../src}/eth_712_account.cairo | 4 +- .../src}/eth_712_utils.cairo | 0 .../src}/interface.cairo | 0 .../src/lib.cairo | 0 .../src}/register_interfaces_eic.cairo | 2 +- strategy_implementation/Scarb.toml | 32 ++++ .../src}/avnu_interface.cairo | 1 - .../src}/interface.cairo | 0 .../src/known_addresses.cairo | 0 .../src/lib.cairo | 8 +- .../src}/strategy_implementation.cairo | 16 +- .../src}/test.cairo | 42 ++--- .../src}/test_utils.cairo | 161 ++++++++++++++++-- .../src}/utils.cairo | 11 +- 34 files changed, 457 insertions(+), 183 deletions(-) create mode 100644 account_factory/Scarb.toml rename {contracts/src/account_factory => account_factory/src}/account_factory.cairo (98%) create mode 100644 account_factory/src/lib.cairo rename {contracts/src/account_factory => account_factory/src}/test.cairo (85%) rename {contracts => account_factory}/src/test_utils.cairo (84%) rename {contracts/src/account_factory => account_factory/src}/utils.cairo (97%) delete mode 100644 contracts/src/account_factory.cairo delete mode 100644 contracts/src/earn_reporter.cairo delete mode 100644 contracts/src/primer/test.cairo create mode 100644 earn_reporter/Scarb.toml rename {contracts/src/earn_reporter => earn_reporter/src}/earn_reporter.cairo (98%) create mode 100644 earn_reporter/src/lib.cairo rename {contracts/src/earn_reporter => earn_reporter/src}/test.cairo (97%) create mode 100644 earn_reporter/src/test_utils.cairo create mode 100644 eth_712_account/Scarb.toml rename {contracts/src/eth_712_account => eth_712_account/src}/eth_712_account.cairo (98%) rename {contracts/src/eth_712_account => eth_712_account/src}/eth_712_utils.cairo (100%) rename {contracts/src/eth_712_account => eth_712_account/src}/interface.cairo (100%) rename contracts/src/eth_712_account.cairo => eth_712_account/src/lib.cairo (100%) rename {contracts/src/eth_712_account => eth_712_account/src}/register_interfaces_eic.cairo (95%) create mode 100644 strategy_implementation/Scarb.toml rename {contracts/src/strategy_implementation => strategy_implementation/src}/avnu_interface.cairo (99%) rename {contracts/src/strategy_implementation => strategy_implementation/src}/interface.cairo (100%) rename {contracts => strategy_implementation}/src/known_addresses.cairo (100%) rename contracts/src/strategy_implementation.cairo => strategy_implementation/src/lib.cairo (59%) rename {contracts/src/strategy_implementation => strategy_implementation/src}/strategy_implementation.cairo (98%) rename {contracts/src/strategy_implementation => strategy_implementation/src}/test.cairo (98%) rename {contracts/src/strategy_implementation => strategy_implementation/src}/test_utils.cairo (85%) rename {contracts/src/strategy_implementation => strategy_implementation/src}/utils.cairo (96%) diff --git a/Scarb.lock b/Scarb.lock index 7f52054..a48caa2 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -1,17 +1,39 @@ # Code generated by scarb DO NOT EDIT. version = 1 +[[package]] +name = "account_factory" +version = "0.1.0" +dependencies = [ + "contracts", + "openzeppelin", + "snforge_std", + "starkware_utils", + "starkware_utils_testing", +] + [[package]] name = "contracts" version = "0.1.0" + +[[package]] +name = "earn_reporter" +version = "0.1.0" dependencies = [ "openzeppelin", "openzeppelin_upgrades", "snforge_std", - "starkware_utils", "starkware_utils_testing", ] +[[package]] +name = "eth_712_account" +version = "0.1.0" +dependencies = [ + "openzeppelin", + "snforge_std", +] + [[package]] name = "openzeppelin" version = "2.0.0" @@ -162,3 +184,16 @@ dependencies = [ "snforge_std", "starkware_utils", ] + +[[package]] +name = "strategy_implementation" +version = "0.1.0" +dependencies = [ + "account_factory", + "contracts", + "earn_reporter", + "openzeppelin", + "snforge_std", + "starkware_utils", + "starkware_utils_testing", +] diff --git a/Scarb.toml b/Scarb.toml index bef16ec..1ba3db7 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -1,5 +1,5 @@ [workspace] -members = ["contracts"] +members = ["contracts", "eth_712_account", "account_factory", "earn_reporter", "strategy_implementation"] [workspace.package] edition = "2024_07" diff --git a/account_factory/Scarb.toml b/account_factory/Scarb.toml new file mode 100644 index 0000000..0c08cf1 --- /dev/null +++ b/account_factory/Scarb.toml @@ -0,0 +1,27 @@ +[package] +name = "account_factory" +edition.workspace = true +version.workspace = true + +[lib] + +[dependencies] +contracts = { path = "../contracts" } +openzeppelin.workspace = true +starknet.workspace = true +starkware_utils.workspace = true + +[dev-dependencies] +assert_macros.workspace = true +snforge_std.workspace = true +starkware_utils_testing.workspace = true + +[[target.starknet-contract]] +sierra = true + +[[test]] +build-external-contracts = ["contracts::primer::primer::Primer"] +name = "account_factory_unittest" + +[scripts] +test = "snforge test" diff --git a/contracts/src/account_factory/account_factory.cairo b/account_factory/src/account_factory.cairo similarity index 98% rename from contracts/src/account_factory/account_factory.cairo rename to account_factory/src/account_factory.cairo index c487162..5a83807 100644 --- a/contracts/src/account_factory/account_factory.cairo +++ b/account_factory/src/account_factory.cairo @@ -13,12 +13,12 @@ pub trait IAccountFactory { #[starknet::contract] pub mod AccountFactory { use RolesComponent::InternalTrait as RolesInternalTrait; - use contracts::account_factory::account_factory::IAccountFactory; - use contracts::account_factory::utils::{ + use crate::account_factory::IAccountFactory; + use contracts::primer::primer::{IPrimerDispatcher, IPrimerDispatcherTrait}; + use crate::utils::{ IEthAccountInitializerDispatcher, IEthAccountInitializerDispatcherTrait, PRIMER_CLASS_HASH, eth_address_to_account, is_deployed, }; - use contracts::primer::primer::{IPrimerDispatcher, IPrimerDispatcherTrait}; use core::traits::Into; use openzeppelin::access::accesscontrol::AccessControlComponent; use openzeppelin::introspection::src5::SRC5Component; diff --git a/account_factory/src/lib.cairo b/account_factory/src/lib.cairo new file mode 100644 index 0000000..1670125 --- /dev/null +++ b/account_factory/src/lib.cairo @@ -0,0 +1,6 @@ +pub mod account_factory; +pub mod utils; +#[cfg(test)] +pub(crate) mod test; +#[cfg(test)] +pub mod test_utils; diff --git a/contracts/src/account_factory/test.cairo b/account_factory/src/test.cairo similarity index 85% rename from contracts/src/account_factory/test.cairo rename to account_factory/src/test.cairo index a69a6be..70723b9 100644 --- a/contracts/src/account_factory/test.cairo +++ b/account_factory/src/test.cairo @@ -1,15 +1,18 @@ use snforge_std; use snforge_std::cheatcodes::events::{EventSpyTrait, EventsFilterTrait}; +use snforge_std::{ContractClassTrait, DeclareResultTrait}; +use starknet::get_contract_address; use starknet::secp256_trait::Signature; use starknet::syscalls::get_class_hash_at_syscall; use starknet::{ClassHash, ContractAddress, EthAddress, SyscallResultTrait}; use starkware_utils_testing::test_utils::{assert_expected_event_emitted, cheat_caller_address_once}; -use crate::account_factory::account_factory::AccountFactory::{ +use crate::account_factory::AccountFactory::{ AccountClassHashChanged, AccountDeployed, }; -use crate::account_factory::account_factory::{ +use crate::account_factory::{ IAccountFactoryDispatcher, IAccountFactoryDispatcherTrait, }; +use contracts::primer::primer::{IPrimerDispatcher, IPrimerDispatcherTrait}; use crate::test_utils::{ APP_GOVERNOR, declare_dummy_eth_address_contract, declare_second_dummy_eth_address_contract, eth_address_to_account, get_event_by_selector, get_event_by_selector_n, @@ -287,3 +290,42 @@ fn test_change_account_class_hash_affects_only_new_users() { ); } +// Primer tests + +#[test] +#[should_panic(expected: 'INVALID_CALLER')] +fn test_primer_update_class_hash_invalid_caller() { + /// set_class_hash should only be callable by the upgrade account set at construction. + /// Here we impersonate a different caller and expect the function to panic with + /// 'INVALID_CALLER'. + let primer_class = snforge_std::declare("Primer").unwrap().contract_class(); + let (primer_addr, _) = primer_class.deploy(@array![]).unwrap(); + + let primer = IPrimerDispatcher { contract_address: primer_addr }; + // Impersonate a non-upgrade caller for the next call. + starkware_utils_testing::test_utils::cheat_caller_address_once( + contract_address: primer_addr, caller_address: 0x1.try_into().unwrap(), + ); + // Attempt to update class hash with the wrong caller - should panic (see attribute above). + let dummy_eth_address_contract_class_hash = declare_dummy_eth_address_contract(); + primer.set_class_hash(new_class_hash: dummy_eth_address_contract_class_hash); +} + +#[test] +fn test_primer_sanity_set_class_hash() { + /// Happy path: after deployment, impersonate the upgrade account and update class hash. + /// Verifies the on-chain class hash equals the provided value. + let primer_class = snforge_std::declare("Primer").unwrap().contract_class(); + let (primer_addr, _) = primer_class.deploy(@array![]).unwrap(); + + let primer = IPrimerDispatcher { contract_address: primer_addr }; + // Impersonate the upgrade account (same address used by the test infra for this call). + // Update the class hash and assert it took effect. + let dummy_eth_address_contract_class_hash = declare_dummy_eth_address_contract(); + starkware_utils_testing::test_utils::cheat_caller_address_once( + contract_address: primer_addr, caller_address: get_contract_address(), + ); + primer.set_class_hash(new_class_hash: dummy_eth_address_contract_class_hash); + let class_hash = get_class_hash_at_syscall(primer_addr).unwrap(); + assert!(class_hash == dummy_eth_address_contract_class_hash, "class hash mismatch"); +} diff --git a/contracts/src/test_utils.cairo b/account_factory/src/test_utils.cairo similarity index 84% rename from contracts/src/test_utils.cairo rename to account_factory/src/test_utils.cairo index e5bb2ce..73d12c2 100644 --- a/contracts/src/test_utils.cairo +++ b/account_factory/src/test_utils.cairo @@ -1,9 +1,8 @@ -use contracts::account_factory::utils::{PRIMER_CLASS_HASH, compute_contract_address}; +use crate::utils::{PRIMER_CLASS_HASH, compute_contract_address}; use snforge_std::cheatcodes::events::Event; use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl}; use starknet::eth_address::EthAddress; use starknet::{ClassHash, ContractAddress, SyscallResultTrait}; -use starkware_utils::constants::SYMBOL; use starkware_utils_testing::test_utils::{ set_account_as_app_governor, set_account_as_app_role_admin, }; @@ -80,22 +79,6 @@ pub(crate) fn eth_address_to_account( ) } -//TODO - Move to starkware_utils_testing -pub(crate) fn deploy_mock_erc20_contract( - initial_supply: u256, owner_address: ContractAddress, name: ByteArray, -) -> ContractAddress { - let mut calldata = ArrayTrait::new(); - name.serialize(ref calldata); - SYMBOL().serialize(ref calldata); - initial_supply.serialize(ref calldata); - owner_address.serialize(ref calldata); - let erc20_contract = snforge_std::declare("DualCaseERC20Mock") - .unwrap_syscall() - .contract_class(); - let (token_address, _) = erc20_contract.deploy(@calldata).unwrap_syscall(); - token_address -} - /// Declare the `Primer` contract and return its class hash. pub(crate) fn declare_primer_contract() -> ClassHash { *snforge_std::declare("Primer").unwrap_syscall().contract_class().class_hash @@ -190,14 +173,3 @@ pub(crate) fn declare_second_dummy_eth_address_contract() -> ClassHash { .contract_class() .class_hash } - -/// Deploy the EarnReporter contract and return its address. -pub(crate) fn deploy_earn_reporter(owner: ContractAddress) -> ContractAddress { - let earn_reporter_class = snforge_std::declare("EarnReporter") - .unwrap_syscall() - .contract_class(); - let (earn_reporter_addr, _) = earn_reporter_class - .deploy(@array![owner.into()]) - .unwrap_syscall(); - earn_reporter_addr -} diff --git a/contracts/src/account_factory/utils.cairo b/account_factory/src/utils.cairo similarity index 97% rename from contracts/src/account_factory/utils.cairo rename to account_factory/src/utils.cairo index f8d739f..412d751 100644 --- a/contracts/src/account_factory/utils.cairo +++ b/account_factory/src/utils.cairo @@ -8,7 +8,7 @@ pub(crate) const CONTRACT_ADDRESS_SALT: felt252 = 0; #[cfg(target: "test")] pub(crate) const PRIMER_CLASS_HASH: ClassHash = - 0x279a9bb18604f4ae57633373d56656063203f236cc5aeceea8f2cf40f6336d7 + 0x0279a9bb18604f4ae57633373d56656063203f236cc5aeceea8f2cf40f6336d7 .try_into() .unwrap(); @@ -72,4 +72,3 @@ pub fn compute_contract_address( pub fn is_deployed(addr: ContractAddress) -> bool { get_class_hash_at_syscall(addr).unwrap_syscall() != Zero::zero() } - diff --git a/contracts/Scarb.toml b/contracts/Scarb.toml index 246ff78..7adc2e8 100644 --- a/contracts/Scarb.toml +++ b/contracts/Scarb.toml @@ -1,36 +1,15 @@ [package] -edition.workspace = true name = "contracts" +edition.workspace = true version.workspace = true +[lib] + [dependencies] -openzeppelin.workspace = true -openzeppelin_upgrades.workspace = true starknet.workspace = true -starkware_utils.workspace = true - -[dev-dependencies] -assert_macros.workspace = true -snforge_std.workspace = true -starkware_utils_testing.workspace = true [[target.starknet-contract]] sierra = true [scripts] test = "snforge test" - -[lib] - -[profile.dev.cairo] -inlining-strategy = "avoid" -panic-backtrace = true -unstable-add-statements-code-locations-debug-info = true -unstable-add-statements-functions-debug-info = true - -[profile.release.cairo] -inlining-strategy = 30 - -[[test]] -build-external-contracts = ["starkware_utils::erc20::erc20_mocks::DualCaseERC20Mock"] -name = "contracts_unittest" diff --git a/contracts/src/account_factory.cairo b/contracts/src/account_factory.cairo deleted file mode 100644 index a7f1bcf..0000000 --- a/contracts/src/account_factory.cairo +++ /dev/null @@ -1,4 +0,0 @@ -pub mod account_factory; -#[cfg(test)] -pub mod test; -pub mod utils; diff --git a/contracts/src/earn_reporter.cairo b/contracts/src/earn_reporter.cairo deleted file mode 100644 index 8160b07..0000000 --- a/contracts/src/earn_reporter.cairo +++ /dev/null @@ -1,3 +0,0 @@ -pub mod earn_reporter; -#[cfg(test)] -pub mod test; diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index ec12fb5..cca4fbf 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -1,8 +1 @@ -pub mod account_factory; -pub mod earn_reporter; -pub mod eth_712_account; -pub(crate) mod known_addresses; pub mod primer; -pub mod strategy_implementation; -#[cfg(test)] -pub(crate) mod test_utils; diff --git a/contracts/src/primer.cairo b/contracts/src/primer.cairo index e04386f..cca4fbf 100644 --- a/contracts/src/primer.cairo +++ b/contracts/src/primer.cairo @@ -1,3 +1 @@ pub mod primer; -#[cfg(test)] -pub mod test; diff --git a/contracts/src/primer/test.cairo b/contracts/src/primer/test.cairo deleted file mode 100644 index 04a872a..0000000 --- a/contracts/src/primer/test.cairo +++ /dev/null @@ -1,43 +0,0 @@ -use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl}; -use starknet::get_contract_address; -use starknet::syscalls::get_class_hash_at_syscall; -use crate::primer::primer::{IPrimerDispatcher, IPrimerDispatcherTrait}; -use crate::test_utils::declare_dummy_eth_address_contract; -#[test] -#[should_panic(expected: 'INVALID_CALLER')] -fn test_primer_update_class_hash_invalid_caller() { - /// set_class_hash should only be callable by the upgrade account set at construction. - /// Here we impersonate a different caller and expect the function to panic with - /// 'INVALID_CALLER'. - let primer_class = snforge_std::declare("Primer").unwrap().contract_class(); - let (primer_addr, _) = primer_class.deploy(@array![]).unwrap(); - - let primer = IPrimerDispatcher { contract_address: primer_addr }; - // Impersonate a non-upgrade caller for the next call. - starkware_utils_testing::test_utils::cheat_caller_address_once( - contract_address: primer_addr, caller_address: 0x1.try_into().unwrap(), - ); - // Attempt to update class hash with the wrong caller - should panic (see attribute above). - let dummy_eth_address_contract_class_hash = declare_dummy_eth_address_contract(); - primer.set_class_hash(new_class_hash: dummy_eth_address_contract_class_hash); -} - -#[test] -fn test_primer_sanity_set_class_hash() { - /// Happy path: after deployment, impersonate the upgrade account and update class hash. - /// Verifies the on-chain class hash equals the provided value. - let primer_class = snforge_std::declare("Primer").unwrap().contract_class(); - let (primer_addr, _) = primer_class.deploy(@array![]).unwrap(); - - let primer = IPrimerDispatcher { contract_address: primer_addr }; - // Impersonate the upgrade account (same address used by the test infra for this call). - // Update the class hash and assert it took effect. - let dummy_eth_address_contract_class_hash = declare_dummy_eth_address_contract(); - starkware_utils_testing::test_utils::cheat_caller_address_once( - contract_address: primer_addr, caller_address: get_contract_address(), - ); - primer.set_class_hash(new_class_hash: dummy_eth_address_contract_class_hash); - let class_hash = get_class_hash_at_syscall(primer_addr).unwrap(); - assert!(class_hash == dummy_eth_address_contract_class_hash, "class hash mismatch"); -} - diff --git a/earn_reporter/Scarb.toml b/earn_reporter/Scarb.toml new file mode 100644 index 0000000..936aadc --- /dev/null +++ b/earn_reporter/Scarb.toml @@ -0,0 +1,22 @@ +[package] +name = "earn_reporter" +edition.workspace = true +version.workspace = true + +[lib] + +[dependencies] +openzeppelin.workspace = true +openzeppelin_upgrades.workspace = true +starknet.workspace = true + +[dev-dependencies] +assert_macros.workspace = true +snforge_std.workspace = true +starkware_utils_testing.workspace = true + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/contracts/src/earn_reporter/earn_reporter.cairo b/earn_reporter/src/earn_reporter.cairo similarity index 98% rename from contracts/src/earn_reporter/earn_reporter.cairo rename to earn_reporter/src/earn_reporter.cairo index d0ed209..b5a2d81 100644 --- a/contracts/src/earn_reporter/earn_reporter.cairo +++ b/earn_reporter/src/earn_reporter.cairo @@ -22,7 +22,7 @@ pub trait IEarnReporter { #[starknet::contract] pub mod EarnReporter { - use contracts::earn_reporter::earn_reporter::IEarnReporter; + use crate::earn_reporter::IEarnReporter; use openzeppelin::access::ownable::OwnableComponent; use openzeppelin::access::ownable::OwnableComponent::InternalTrait as OwnableInternalTrait; use openzeppelin_upgrades::UpgradeableComponent; diff --git a/earn_reporter/src/lib.cairo b/earn_reporter/src/lib.cairo new file mode 100644 index 0000000..35d2e09 --- /dev/null +++ b/earn_reporter/src/lib.cairo @@ -0,0 +1,5 @@ +pub mod earn_reporter; +#[cfg(test)] +pub(crate) mod test; +#[cfg(test)] +pub(crate) mod test_utils; diff --git a/contracts/src/earn_reporter/test.cairo b/earn_reporter/src/test.cairo similarity index 97% rename from contracts/src/earn_reporter/test.cairo rename to earn_reporter/src/test.cairo index ea68ba9..caa9928 100644 --- a/contracts/src/earn_reporter/test.cairo +++ b/earn_reporter/src/test.cairo @@ -1,15 +1,15 @@ -use contracts::earn_reporter::earn_reporter::EarnReporter::OrderCreated; -use contracts::earn_reporter::earn_reporter::{ +use crate::earn_reporter::EarnReporter::OrderCreated; +use crate::earn_reporter::{ IEarnReporterDispatcher, IEarnReporterDispatcherTrait, }; +use crate::test_utils::{ + declare_dummy_eth_address_contract, deploy_earn_reporter, get_event_by_selector, +}; use openzeppelin::access::ownable::interface::{IOwnableDispatcher, IOwnableDispatcherTrait}; use snforge_std::cheatcodes::events::{EventSpyTrait, EventsFilterTrait}; use starknet::syscalls::get_class_hash_at_syscall; use starknet::{ContractAddress, SyscallResultTrait, get_contract_address}; use starkware_utils_testing::test_utils::{assert_expected_event_emitted, cheat_caller_address_once}; -use crate::test_utils::{ - declare_dummy_eth_address_contract, deploy_earn_reporter, get_event_by_selector, -}; fn default_order_created_event() -> OrderCreated { OrderCreated { diff --git a/earn_reporter/src/test_utils.cairo b/earn_reporter/src/test_utils.cairo new file mode 100644 index 0000000..962b41a --- /dev/null +++ b/earn_reporter/src/test_utils.cairo @@ -0,0 +1,63 @@ +use snforge_std::cheatcodes::events::Event; +use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl}; +use starknet::{ClassHash, ContractAddress, SyscallResultTrait}; + +/// Returns the index of the nth event whose first key equals the given selector. +pub(crate) fn find_event_index_by_selector( + events: Span<(ContractAddress, Event)>, selector: felt252, n: usize, +) -> Option { + let mut i = 0_usize; + let mut seen = 0_usize; + for (_, ev) in events { + if ev.keys.len() > 0 && *ev.keys.at(0) == selector { + if seen == n { + return Option::Some(i); + } + seen += 1; + } + i += 1; + } + None +} + +/// Returns a cloned copy of the first event emitted with the given selector (if any). +pub(crate) fn get_event_by_selector( + events: Span<(ContractAddress, Event)>, selector: felt252, +) -> Option<@(ContractAddress, Event)> { + match find_event_index_by_selector(:events, :selector, n: 0) { + Option::Some(i) => { + let (from, ev) = events.at(i); + Option::Some(@(*from, ev.clone())) + }, + None => None, + } +} + +/// Deploy the EarnReporter contract and return its address. +pub(crate) fn deploy_earn_reporter(owner: ContractAddress) -> ContractAddress { + let earn_reporter_class = snforge_std::declare("EarnReporter") + .unwrap_syscall() + .contract_class(); + let (earn_reporter_addr, _) = earn_reporter_class + .deploy(@array![owner.into()]) + .unwrap_syscall(); + earn_reporter_addr +} + +// Minimal no-op contract for tests: stores an EthAddress passed at construction. +#[starknet::contract] +pub mod DummyEthAddressContract { + use starknet::eth_address::EthAddress; + use starknet::secp256_trait::Signature; + #[storage] + struct Storage {} + + #[external(v0)] + fn initialize(ref self: ContractState, eth_address: EthAddress, signature: Signature) { + return; + } +} + +pub(crate) fn declare_dummy_eth_address_contract() -> ClassHash { + *snforge_std::declare("DummyEthAddressContract").unwrap_syscall().contract_class().class_hash +} diff --git a/eth_712_account/Scarb.toml b/eth_712_account/Scarb.toml new file mode 100644 index 0000000..60ff199 --- /dev/null +++ b/eth_712_account/Scarb.toml @@ -0,0 +1,18 @@ +[package] +name = "eth_712_account" +edition.workspace = true +version.workspace = true + +[dependencies] +openzeppelin.workspace = true +starknet.workspace = true + +[dev-dependencies] +assert_macros.workspace = true +snforge_std.workspace = true + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/contracts/src/eth_712_account/eth_712_account.cairo b/eth_712_account/src/eth_712_account.cairo similarity index 98% rename from contracts/src/eth_712_account/eth_712_account.cairo rename to eth_712_account/src/eth_712_account.cairo index 8429d20..4d19a9f 100644 --- a/contracts/src/eth_712_account/eth_712_account.cairo +++ b/eth_712_account/src/eth_712_account.cairo @@ -12,10 +12,10 @@ #[starknet::contract(account)] pub mod StarknetEth712Account { - use contracts::eth_712_account::eth_712_utils::{ + use crate::eth_712_utils::{ assert_valid_owner, extract_signature, get_outside_execution_hash, is_valid_signature, }; - use contracts::eth_712_account::interface::{ + use crate::interface::{ IAccount712Admin, IEICDispatcherTrait, IEICLibraryDispatcher, Upgraded, }; use core::num::traits::Zero; diff --git a/contracts/src/eth_712_account/eth_712_utils.cairo b/eth_712_account/src/eth_712_utils.cairo similarity index 100% rename from contracts/src/eth_712_account/eth_712_utils.cairo rename to eth_712_account/src/eth_712_utils.cairo diff --git a/contracts/src/eth_712_account/interface.cairo b/eth_712_account/src/interface.cairo similarity index 100% rename from contracts/src/eth_712_account/interface.cairo rename to eth_712_account/src/interface.cairo diff --git a/contracts/src/eth_712_account.cairo b/eth_712_account/src/lib.cairo similarity index 100% rename from contracts/src/eth_712_account.cairo rename to eth_712_account/src/lib.cairo diff --git a/contracts/src/eth_712_account/register_interfaces_eic.cairo b/eth_712_account/src/register_interfaces_eic.cairo similarity index 95% rename from contracts/src/eth_712_account/register_interfaces_eic.cairo rename to eth_712_account/src/register_interfaces_eic.cairo index 840e632..48e057b 100644 --- a/contracts/src/eth_712_account/register_interfaces_eic.cairo +++ b/eth_712_account/src/register_interfaces_eic.cairo @@ -5,7 +5,7 @@ #[starknet::contract] pub mod RegisterInterfacesEIC { - use contracts::eth_712_account::interface::IEIC; + use crate::interface::IEIC; use openzeppelin::introspection::src5::SRC5Component; use openzeppelin::introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait; diff --git a/strategy_implementation/Scarb.toml b/strategy_implementation/Scarb.toml new file mode 100644 index 0000000..2ae8712 --- /dev/null +++ b/strategy_implementation/Scarb.toml @@ -0,0 +1,32 @@ +[package] +name = "strategy_implementation" +edition.workspace = true +version.workspace = true + +[dependencies] +account_factory = { path = "../account_factory" } +contracts = { path = "../contracts" } +earn_reporter = { path = "../earn_reporter" } +openzeppelin.workspace = true +starknet.workspace = true +starkware_utils.workspace = true + +[dev-dependencies] +assert_macros.workspace = true +snforge_std.workspace = true +starkware_utils_testing.workspace = true + +[[target.starknet-contract]] +sierra = true + +[[test]] +build-external-contracts = [ + "starkware_utils::erc20::erc20_mocks::DualCaseERC20Mock", + "account_factory::account_factory::AccountFactory", + "contracts::primer::primer::Primer", + "earn_reporter::earn_reporter::EarnReporter", +] +name = "strategy_implementation_unittest" + +[scripts] +test = "snforge test" diff --git a/contracts/src/strategy_implementation/avnu_interface.cairo b/strategy_implementation/src/avnu_interface.cairo similarity index 99% rename from contracts/src/strategy_implementation/avnu_interface.cairo rename to strategy_implementation/src/avnu_interface.cairo index ddd055a..31f4545 100644 --- a/contracts/src/strategy_implementation/avnu_interface.cairo +++ b/strategy_implementation/src/avnu_interface.cairo @@ -39,4 +39,3 @@ pub(crate) struct AvnuParameters { pub integrator_fee_recipient: ContractAddress, pub routes: Array, } - diff --git a/contracts/src/strategy_implementation/interface.cairo b/strategy_implementation/src/interface.cairo similarity index 100% rename from contracts/src/strategy_implementation/interface.cairo rename to strategy_implementation/src/interface.cairo diff --git a/contracts/src/known_addresses.cairo b/strategy_implementation/src/known_addresses.cairo similarity index 100% rename from contracts/src/known_addresses.cairo rename to strategy_implementation/src/known_addresses.cairo diff --git a/contracts/src/strategy_implementation.cairo b/strategy_implementation/src/lib.cairo similarity index 59% rename from contracts/src/strategy_implementation.cairo rename to strategy_implementation/src/lib.cairo index 5714928..9cf2c4e 100644 --- a/contracts/src/strategy_implementation.cairo +++ b/strategy_implementation/src/lib.cairo @@ -1,9 +1,9 @@ pub mod avnu_interface; pub mod interface; +pub(crate) mod known_addresses; pub mod strategy_implementation; - +pub mod utils; #[cfg(test)] -pub mod test; +pub(crate) mod test; #[cfg(test)] -pub mod test_utils; -pub mod utils; +pub(crate) mod test_utils; diff --git a/contracts/src/strategy_implementation/strategy_implementation.cairo b/strategy_implementation/src/strategy_implementation.cairo similarity index 98% rename from contracts/src/strategy_implementation/strategy_implementation.cairo rename to strategy_implementation/src/strategy_implementation.cairo index 69f2a53..54b7cbf 100644 --- a/contracts/src/strategy_implementation/strategy_implementation.cairo +++ b/strategy_implementation/src/strategy_implementation.cairo @@ -1,25 +1,25 @@ #[starknet::contract] pub mod StrategyImplementation { use RolesComponent::InternalTrait as RolesInternalTrait; - use contracts::account_factory::account_factory::{ + use account_factory::account_factory::{ IAccountFactoryDispatcher, IAccountFactoryDispatcherTrait, }; - use contracts::earn_reporter::earn_reporter::{ - IEarnReporterDispatcher, IEarnReporterDispatcherTrait, - }; - use contracts::known_addresses::MIDAS_RE7_BTC; - use contracts::strategy_implementation::avnu_interface::AvnuParameters; - use contracts::strategy_implementation::interface::{ + use crate::avnu_interface::AvnuParameters; + use crate::interface::{ IStrategyImplementation, IStrategyImplementationSafeDispatcher, IStrategyImplementationSafeDispatcherTrait, }; - use contracts::strategy_implementation::utils::{ + use crate::known_addresses::MIDAS_RE7_BTC; + use crate::utils::{ IERC4626DepositDispatcher, IERC4626DepositDispatcherTrait, Strategy, StrategyTrait, avnu_multi_route_swap, deserialize_signature, strategy_from_protocol_and_token, }; use core::num::traits::Zero; use core::panic_with_felt252; use core::traits::Into; + use earn_reporter::earn_reporter::{ + IEarnReporterDispatcher, IEarnReporterDispatcherTrait, + }; use openzeppelin::access::accesscontrol::AccessControlComponent; use openzeppelin::introspection::src5::SRC5Component; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; diff --git a/contracts/src/strategy_implementation/test.cairo b/strategy_implementation/src/test.cairo similarity index 98% rename from contracts/src/strategy_implementation/test.cairo rename to strategy_implementation/src/test.cairo index e562fe3..3a65de3 100644 --- a/contracts/src/strategy_implementation/test.cairo +++ b/strategy_implementation/src/test.cairo @@ -1,13 +1,28 @@ -use contracts::known_addresses::{ +use core::array::ArrayTrait; +use core::num::traits::Zero; +use crate::interface::{ + IStrategyImplementationDispatcher, IStrategyImplementationDispatcherTrait, + IStrategyImplementationSafeDispatcher, IStrategyImplementationSafeDispatcherTrait, +}; +use crate::known_addresses::{ AVNU_EXCHANGE, ENDUR_TBTC, ENDUR_WBTC, FORGE_YIELDS_WBTC, LBTC, NOON_WBTC, TBTC, TROVES_TBTC, WBTC, }; -use contracts::strategy_implementation::interface::{ - IStrategyImplementationDispatcher, IStrategyImplementationDispatcherTrait, - IStrategyImplementationSafeDispatcher, IStrategyImplementationSafeDispatcherTrait, +use crate::test_utils::{ + APP_GOVERNOR, ApplyParameters, IERC4626DepositMintMockDispatcher, + IERC4626DepositMintMockDispatcherTrait, apply, assert_apply_failed_with_refund, + assert_deposited_event, build_prefunded_apply_parameters_with_amount, + build_prefunded_apply_parameters_with_token_address, build_prefunded_avnu, + cheat_transfer_and_approve, deploy_4626_failure_mock, deploy_and_prefund_dummy_erc20_at, + deploy_dummy_avnu, deploy_dummy_avnu_failure, deploy_dummy_avnu_false, + deploy_erc4626_deposit_mint_mock, deploy_earn_reporter, deploy_mock_erc20_contract_at, + dummy_apply_parameters, dummy_apply_parameters_with_protocol, get_account_factory, + get_event_by_selector, get_position_owner, serialize_signature, + setup_strategy_implementation_test_env, validate_avnu_swap, +}; +use crate::utils::{ + PROTOCOL_ENDUR, PROTOCOL_FORGE_YIELDS, PROTOCOL_NOON, PROTOCOL_TROVES, }; -use core::array::ArrayTrait; -use core::num::traits::Zero; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; use snforge_std::TokenImpl; use snforge_std::cheatcodes::events::{EventSpyTrait, EventsFilterTrait}; @@ -15,21 +30,6 @@ use starknet::ContractAddress; use starknet::eth_address::EthAddress; use starknet::secp256_trait::Signature; use starkware_utils_testing::test_utils::{assert_panic_with_felt_error, cheat_caller_address_once}; -use crate::strategy_implementation::test_utils::{ - ApplyParameters, IERC4626DepositMintMockDispatcher, IERC4626DepositMintMockDispatcherTrait, - apply, assert_apply_failed_with_refund, assert_deposited_event, - build_prefunded_apply_parameters_with_amount, - build_prefunded_apply_parameters_with_token_address, build_prefunded_avnu, - cheat_transfer_and_approve, deploy_4626_failure_mock, deploy_and_prefund_dummy_erc20_at, - deploy_dummy_avnu, deploy_dummy_avnu_failure, deploy_dummy_avnu_false, - deploy_erc4626_deposit_mint_mock, deploy_mock_erc20_contract_at, dummy_apply_parameters, - dummy_apply_parameters_with_protocol, get_account_factory, get_position_owner, - serialize_signature, setup_strategy_implementation_test_env, validate_avnu_swap, -}; -use crate::strategy_implementation::utils::{ - PROTOCOL_ENDUR, PROTOCOL_FORGE_YIELDS, PROTOCOL_NOON, PROTOCOL_TROVES, -}; -use crate::test_utils::{APP_GOVERNOR, deploy_earn_reporter, get_event_by_selector}; #[test] diff --git a/contracts/src/strategy_implementation/test_utils.cairo b/strategy_implementation/src/test_utils.cairo similarity index 85% rename from contracts/src/strategy_implementation/test_utils.cairo rename to strategy_implementation/src/test_utils.cairo index 60153b8..646b323 100644 --- a/contracts/src/strategy_implementation/test_utils.cairo +++ b/strategy_implementation/src/test_utils.cairo @@ -1,12 +1,13 @@ -use contracts::known_addresses::{AVNU_EXCHANGE, MIDAS_RE7_BTC}; -use contracts::strategy_implementation::avnu_interface::{AvnuParameters, Route}; -use contracts::strategy_implementation::interface::{ +use account_factory::utils::compute_contract_address; +use crate::avnu_interface::{AvnuParameters, Route}; +use crate::interface::{ IStrategyImplementationDispatcher, IStrategyImplementationDispatcherTrait, }; -use contracts::strategy_implementation::strategy_implementation::StrategyImplementation::{ +use crate::known_addresses::{AVNU_EXCHANGE, MIDAS_RE7_BTC}; +use crate::strategy_implementation::StrategyImplementation::{ ApplyFailed, Deposited, MultiRouteSwap, PositionOwnerDeployed, }; -use contracts::strategy_implementation::utils::{ +use crate::utils::{ PROTOCOL_AVNU, PROTOCOL_TROVES, Strategy, StrategyTrait, TokenTrait, deserialize_signature, strategy_from_protocol_and_token, }; @@ -21,10 +22,102 @@ use starkware_utils_testing::test_utils::{ assert_expected_event_emitted, cheat_caller_address_once, set_account_as_app_governor, set_account_as_app_role_admin, }; -use crate::test_utils::{ - APP_GOVERNOR, APP_ROLE_ADMIN, GOVERNANCE_ADMIN, eth_address_to_account, get_event_by_selector, - setup_account_factory_test_env, -}; + + +/// The Primer class hash used in tests. This must match what snforge produces when +/// compiling the Primer contract. +pub(crate) const PRIMER_CLASS_HASH: starknet::ClassHash = + 0x0279a9bb18604f4ae57633373d56656063203f236cc5aeceea8f2cf40f6336d7 + .try_into() + .unwrap(); + +// Test constants - mirrored from account_factory for use in strategy_implementation tests. +pub(crate) fn APP_ROLE_ADMIN() -> ContractAddress { + 'APP_ROLE_ADMIN'.try_into().unwrap() +} + +pub(crate) fn APP_GOVERNOR() -> ContractAddress { + 'APP_GOVERNOR'.try_into().unwrap() +} + +pub(crate) fn GOVERNANCE_ADMIN() -> ContractAddress { + 'GOVERNANCE_ADMIN'.try_into().unwrap() +} + +/// Mirrors AccountFactory.eth_address_to_account for tests. +pub(crate) fn eth_address_to_account( + account_factory: ContractAddress, eth_address: EthAddress, +) -> ContractAddress { + compute_contract_address( + salt: eth_address.into(), + class_hash: PRIMER_CLASS_HASH.into(), + constructor_calldata: array![].span(), + deployer_address: account_factory.into(), + ) +} + +/// Declare the `Primer` contract and return its class hash. +pub(crate) fn declare_primer_contract() -> starknet::ClassHash { + *snforge_std::declare("Primer").unwrap_syscall().contract_class().class_hash +} + +fn set_account_factory_default_roles(account_factory: ContractAddress) { + set_account_as_app_role_admin( + contract: account_factory, account: APP_ROLE_ADMIN(), governance_admin: GOVERNANCE_ADMIN(), + ); + set_account_as_app_governor( + contract: account_factory, account: APP_GOVERNOR(), app_role_admin: APP_ROLE_ADMIN(), + ); +} + +/// Declare the `DummyEthAddressContract` contract and return its class hash. +pub(crate) fn declare_dummy_eth_address_contract() -> starknet::ClassHash { + *snforge_std::declare("DummyEthAddressContract").unwrap_syscall().contract_class().class_hash +} + +/// Builds the constructor calldata array for AccountFactory. +pub(crate) fn account_factory_constructor_calldata() -> Array { + let governance_admin: ContractAddress = GOVERNANCE_ADMIN(); + let upgrade_delay: u64 = 0; + let account_class_hash: starknet::ClassHash = declare_dummy_eth_address_contract(); + let mut calldata: Array = array![]; + Serde::serialize(@governance_admin, ref calldata); + Serde::serialize(@upgrade_delay, ref calldata); + Serde::serialize(@account_class_hash, ref calldata); + calldata +} + +/// Sets up the AccountFactory test environment: +/// - deploys the `AccountFactory` contract, +/// - sets default roles, +/// - declares the `Primer` contract so its class hash is available. +pub(crate) fn setup_account_factory_test_env() -> ContractAddress { + let calldata = account_factory_constructor_calldata(); + let account_factory_contract = snforge_std::declare("AccountFactory") + .unwrap_syscall() + .contract_class(); + let (account_factory_contract_address, _) = account_factory_contract + .deploy(@calldata) + .unwrap_syscall(); + set_account_factory_default_roles(account_factory_contract_address); + declare_primer_contract(); + account_factory_contract_address +} + +// Minimal no-op contract for tests: stores an EthAddress passed at construction. +#[starknet::contract] +pub mod DummyEthAddressContract { + use starknet::eth_address::EthAddress; + use starknet::secp256_trait::Signature; + #[storage] + struct Storage {} + + + #[external(v0)] + fn initialize(ref self: ContractState, eth_address: EthAddress, signature: Signature) { + return; + } +} #[derive(Drop, Copy)] @@ -34,6 +127,48 @@ pub(crate) struct ApplyParameters { pub parameters: Span, } +/// Returns the index of the nth event whose first key equals the given selector. +pub(crate) fn find_event_index_by_selector( + events: Span<(ContractAddress, Event)>, selector: felt252, n: usize, +) -> Option { + let mut i = 0_usize; + let mut seen = 0_usize; + for (_, ev) in events { + if ev.keys.len() > 0 && *ev.keys.at(0) == selector { + if seen == n { + return Option::Some(i); + } + seen += 1; + } + i += 1; + } + None +} + +/// Returns a cloned copy of the first event emitted with the given selector (if any). +pub(crate) fn get_event_by_selector( + events: Span<(ContractAddress, Event)>, selector: felt252, +) -> Option<@(ContractAddress, Event)> { + match find_event_index_by_selector(:events, :selector, n: 0) { + Option::Some(i) => { + let (from, ev) = events.at(i); + Option::Some(@(*from, ev.clone())) + }, + None => None, + } +} + +/// Deploy the EarnReporter contract and return its address. +pub(crate) fn deploy_earn_reporter(owner: ContractAddress) -> ContractAddress { + let earn_reporter_class = snforge_std::declare("EarnReporter") + .unwrap_syscall() + .contract_class(); + let (earn_reporter_addr, _) = earn_reporter_class + .deploy(@array![owner.into()]) + .unwrap_syscall(); + earn_reporter_addr +} + /// Sets default StrategyImplementation roles using testing helpers and constants. pub(crate) fn set_strategy_implementation_default_roles(strategy_implementation: ContractAddress) { // App role admin @@ -578,7 +713,7 @@ pub trait IERC4626DepositMintMock { #[starknet::contract] pub mod ERC4626DepositMintMock { - use contracts::strategy_implementation::test_utils::IERC4626DepositMintMock; + use crate::test_utils::IERC4626DepositMintMock; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; use openzeppelin::token::erc20::{DefaultConfig, ERC20Component, ERC20HooksEmptyImpl}; use starknet::ContractAddress; @@ -694,7 +829,7 @@ pub(crate) fn deploy_4626_failure_mock(address_to_deploy_at: ContractAddress) { // ----------------------------------------------------------------------------- #[starknet::contract] pub mod DummyAvnu { - use contracts::strategy_implementation::avnu_interface::AvnuParameters; + use crate::avnu_interface::AvnuParameters; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; #[storage] @@ -731,7 +866,7 @@ pub(crate) fn deploy_dummy_avnu(address_to_deploy_at: ContractAddress) { // ----------------------------------------------------------------------------- #[starknet::contract] pub mod DummyAvnuFailure { - use contracts::strategy_implementation::avnu_interface::AvnuParameters; + use crate::avnu_interface::AvnuParameters; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; #[storage] @@ -767,7 +902,7 @@ pub(crate) fn deploy_dummy_avnu_failure(address_to_deploy_at: ContractAddress) { // ----------------------------------------------------------------------------- #[starknet::contract] pub mod DummyAvnuFalse { - use contracts::strategy_implementation::avnu_interface::AvnuParameters; + use crate::avnu_interface::AvnuParameters; #[storage] struct Storage {} diff --git a/contracts/src/strategy_implementation/utils.cairo b/strategy_implementation/src/utils.cairo similarity index 96% rename from contracts/src/strategy_implementation/utils.cairo rename to strategy_implementation/src/utils.cairo index 552b48a..a71a1b3 100644 --- a/contracts/src/strategy_implementation/utils.cairo +++ b/strategy_implementation/src/utils.cairo @@ -1,16 +1,15 @@ -use contracts::known_addresses::AVNU_EXCHANGE; -use contracts::strategy_implementation::avnu_interface::{ +use crate::avnu_interface::{ AvnuParameters, IAvnuDispatcher, IAvnuDispatcherTrait, }; +use crate::known_addresses::{ + AVNU_EXCHANGE, ENDUR_LBTC, ENDUR_SOLVBTC, ENDUR_TBTC, ENDUR_WBTC, FORGE_YIELDS_WBTC, LBTC, + NOON_WBTC, SOLVBTC, TBTC, TROVES_LBTC, TROVES_SOLVBTC, TROVES_TBTC, TROVES_WBTC, WBTC, +}; use core::hash::HashStateTrait; use core::panic_with_felt252; use core::pedersen::PedersenTrait; use starknet::ContractAddress; use starknet::secp256_trait::Signature; -use crate::known_addresses::{ - ENDUR_LBTC, ENDUR_SOLVBTC, ENDUR_TBTC, ENDUR_WBTC, FORGE_YIELDS_WBTC, LBTC, NOON_WBTC, SOLVBTC, - TBTC, TROVES_LBTC, TROVES_SOLVBTC, TROVES_TBTC, TROVES_WBTC, WBTC, -}; pub(crate) const CONTRACT_ADDRESS_SALT: felt252 = 0; From 5ca984bce33ef4745db38b584b15db348d044df0 Mon Sep 17 00:00:00 2001 From: Remo Date: Mon, 9 Feb 2026 22:51:05 +0200 Subject: [PATCH 02/10] Test: primer class-hash is expected value --- .github/workflows/on-pull-request.yaml | 3 ++ account_factory/Scarb.toml | 5 ++++ account_factory/src/account_factory.cairo | 10 +++---- account_factory/src/lib.cairo | 2 +- account_factory/src/test.cairo | 13 +++------ account_factory/src/test_utils.cairo | 2 +- contracts/Scarb.toml | 5 ++++ earn_reporter/Scarb.toml | 5 ++++ earn_reporter/src/earn_reporter.cairo | 2 +- earn_reporter/src/test.cairo | 12 ++++---- eth_712_account/Scarb.toml | 5 ++++ eth_712_account/src/eth_712_account.cairo | 10 +++---- .../src/register_interfaces_eic.cairo | 2 +- scripts/verify_primer_class_hash.sh | 25 +++++++++++++++++ strategy_implementation/Scarb.toml | 5 ++++ strategy_implementation/src/lib.cairo | 2 +- .../src/strategy_implementation.cairo | 24 ++++++++-------- strategy_implementation/src/test.cairo | 28 +++++++++---------- strategy_implementation/src/test_utils.cairo | 28 +++++++++---------- strategy_implementation/src/utils.cairo | 12 ++++---- 20 files changed, 118 insertions(+), 82 deletions(-) create mode 100755 scripts/verify_primer_class_hash.sh diff --git a/.github/workflows/on-pull-request.yaml b/.github/workflows/on-pull-request.yaml index 0ffe4a5..23d6d47 100644 --- a/.github/workflows/on-pull-request.yaml +++ b/.github/workflows/on-pull-request.yaml @@ -29,3 +29,6 @@ jobs: - name: run test and coverage run: scarb test -w --coverage + + - name: verify primer class hash + run: ./scripts/verify_primer_class_hash.sh diff --git a/account_factory/Scarb.toml b/account_factory/Scarb.toml index 0c08cf1..a9a48d7 100644 --- a/account_factory/Scarb.toml +++ b/account_factory/Scarb.toml @@ -23,5 +23,10 @@ sierra = true build-external-contracts = ["contracts::primer::primer::Primer"] name = "account_factory_unittest" +[profile.dev.cairo] +unstable-add-statements-functions-debug-info = true +unstable-add-statements-code-locations-debug-info = true +inlining-strategy = "avoid" + [scripts] test = "snforge test" diff --git a/account_factory/src/account_factory.cairo b/account_factory/src/account_factory.cairo index 5a83807..741c7af 100644 --- a/account_factory/src/account_factory.cairo +++ b/account_factory/src/account_factory.cairo @@ -13,12 +13,7 @@ pub trait IAccountFactory { #[starknet::contract] pub mod AccountFactory { use RolesComponent::InternalTrait as RolesInternalTrait; - use crate::account_factory::IAccountFactory; use contracts::primer::primer::{IPrimerDispatcher, IPrimerDispatcherTrait}; - use crate::utils::{ - IEthAccountInitializerDispatcher, IEthAccountInitializerDispatcherTrait, PRIMER_CLASS_HASH, - eth_address_to_account, is_deployed, - }; use core::traits::Into; use openzeppelin::access::accesscontrol::AccessControlComponent; use openzeppelin::introspection::src5::SRC5Component; @@ -29,6 +24,11 @@ pub mod AccountFactory { use starkware_utils::components::replaceability::ReplaceabilityComponent; use starkware_utils::components::replaceability::ReplaceabilityComponent::InternalReplaceabilityTrait; use starkware_utils::components::roles::RolesComponent; + use crate::account_factory::IAccountFactory; + use crate::utils::{ + IEthAccountInitializerDispatcher, IEthAccountInitializerDispatcherTrait, PRIMER_CLASS_HASH, + eth_address_to_account, is_deployed, + }; component!(path: RolesComponent, storage: roles, event: RolesEvent); component!(path: AccessControlComponent, storage: accesscontrol, event: accesscontrolEvent); component!(path: SRC5Component, storage: src5, event: src5Event); diff --git a/account_factory/src/lib.cairo b/account_factory/src/lib.cairo index 1670125..5375bbd 100644 --- a/account_factory/src/lib.cairo +++ b/account_factory/src/lib.cairo @@ -1,6 +1,6 @@ pub mod account_factory; -pub mod utils; #[cfg(test)] pub(crate) mod test; #[cfg(test)] pub mod test_utils; +pub mod utils; diff --git a/account_factory/src/test.cairo b/account_factory/src/test.cairo index 70723b9..63cbda4 100644 --- a/account_factory/src/test.cairo +++ b/account_factory/src/test.cairo @@ -1,18 +1,13 @@ +use contracts::primer::primer::{IPrimerDispatcher, IPrimerDispatcherTrait}; use snforge_std; use snforge_std::cheatcodes::events::{EventSpyTrait, EventsFilterTrait}; use snforge_std::{ContractClassTrait, DeclareResultTrait}; -use starknet::get_contract_address; use starknet::secp256_trait::Signature; use starknet::syscalls::get_class_hash_at_syscall; -use starknet::{ClassHash, ContractAddress, EthAddress, SyscallResultTrait}; +use starknet::{ClassHash, ContractAddress, EthAddress, SyscallResultTrait, get_contract_address}; use starkware_utils_testing::test_utils::{assert_expected_event_emitted, cheat_caller_address_once}; -use crate::account_factory::AccountFactory::{ - AccountClassHashChanged, AccountDeployed, -}; -use crate::account_factory::{ - IAccountFactoryDispatcher, IAccountFactoryDispatcherTrait, -}; -use contracts::primer::primer::{IPrimerDispatcher, IPrimerDispatcherTrait}; +use crate::account_factory::AccountFactory::{AccountClassHashChanged, AccountDeployed}; +use crate::account_factory::{IAccountFactoryDispatcher, IAccountFactoryDispatcherTrait}; use crate::test_utils::{ APP_GOVERNOR, declare_dummy_eth_address_contract, declare_second_dummy_eth_address_contract, eth_address_to_account, get_event_by_selector, get_event_by_selector_n, diff --git a/account_factory/src/test_utils.cairo b/account_factory/src/test_utils.cairo index 73d12c2..b903f9f 100644 --- a/account_factory/src/test_utils.cairo +++ b/account_factory/src/test_utils.cairo @@ -1,4 +1,3 @@ -use crate::utils::{PRIMER_CLASS_HASH, compute_contract_address}; use snforge_std::cheatcodes::events::Event; use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl}; use starknet::eth_address::EthAddress; @@ -6,6 +5,7 @@ use starknet::{ClassHash, ContractAddress, SyscallResultTrait}; use starkware_utils_testing::test_utils::{ set_account_as_app_governor, set_account_as_app_role_admin, }; +use crate::utils::{PRIMER_CLASS_HASH, compute_contract_address}; pub(crate) fn APP_ROLE_ADMIN() -> ContractAddress { 'APP_ROLE_ADMIN'.try_into().unwrap() diff --git a/contracts/Scarb.toml b/contracts/Scarb.toml index 7adc2e8..5e63d26 100644 --- a/contracts/Scarb.toml +++ b/contracts/Scarb.toml @@ -11,5 +11,10 @@ starknet.workspace = true [[target.starknet-contract]] sierra = true +[profile.dev.cairo] +unstable-add-statements-functions-debug-info = true +unstable-add-statements-code-locations-debug-info = true +inlining-strategy = "avoid" + [scripts] test = "snforge test" diff --git a/earn_reporter/Scarb.toml b/earn_reporter/Scarb.toml index 936aadc..0cdb64c 100644 --- a/earn_reporter/Scarb.toml +++ b/earn_reporter/Scarb.toml @@ -18,5 +18,10 @@ starkware_utils_testing.workspace = true [[target.starknet-contract]] sierra = true +[profile.dev.cairo] +unstable-add-statements-functions-debug-info = true +unstable-add-statements-code-locations-debug-info = true +inlining-strategy = "avoid" + [scripts] test = "snforge test" diff --git a/earn_reporter/src/earn_reporter.cairo b/earn_reporter/src/earn_reporter.cairo index b5a2d81..6888277 100644 --- a/earn_reporter/src/earn_reporter.cairo +++ b/earn_reporter/src/earn_reporter.cairo @@ -22,12 +22,12 @@ pub trait IEarnReporter { #[starknet::contract] pub mod EarnReporter { - use crate::earn_reporter::IEarnReporter; use openzeppelin::access::ownable::OwnableComponent; use openzeppelin::access::ownable::OwnableComponent::InternalTrait as OwnableInternalTrait; use openzeppelin_upgrades::UpgradeableComponent; use openzeppelin_upgrades::UpgradeableComponent::InternalTrait as UpgradeableInternalTrait; use starknet::{ClassHash, ContractAddress, EthAddress, get_caller_address}; + use crate::earn_reporter::IEarnReporter; component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent); diff --git a/earn_reporter/src/test.cairo b/earn_reporter/src/test.cairo index caa9928..d4a1743 100644 --- a/earn_reporter/src/test.cairo +++ b/earn_reporter/src/test.cairo @@ -1,15 +1,13 @@ -use crate::earn_reporter::EarnReporter::OrderCreated; -use crate::earn_reporter::{ - IEarnReporterDispatcher, IEarnReporterDispatcherTrait, -}; -use crate::test_utils::{ - declare_dummy_eth_address_contract, deploy_earn_reporter, get_event_by_selector, -}; use openzeppelin::access::ownable::interface::{IOwnableDispatcher, IOwnableDispatcherTrait}; use snforge_std::cheatcodes::events::{EventSpyTrait, EventsFilterTrait}; use starknet::syscalls::get_class_hash_at_syscall; use starknet::{ContractAddress, SyscallResultTrait, get_contract_address}; use starkware_utils_testing::test_utils::{assert_expected_event_emitted, cheat_caller_address_once}; +use crate::earn_reporter::EarnReporter::OrderCreated; +use crate::earn_reporter::{IEarnReporterDispatcher, IEarnReporterDispatcherTrait}; +use crate::test_utils::{ + declare_dummy_eth_address_contract, deploy_earn_reporter, get_event_by_selector, +}; fn default_order_created_event() -> OrderCreated { OrderCreated { diff --git a/eth_712_account/Scarb.toml b/eth_712_account/Scarb.toml index 60ff199..f08f6b4 100644 --- a/eth_712_account/Scarb.toml +++ b/eth_712_account/Scarb.toml @@ -14,5 +14,10 @@ snforge_std.workspace = true [[target.starknet-contract]] sierra = true +[profile.dev.cairo] +unstable-add-statements-functions-debug-info = true +unstable-add-statements-code-locations-debug-info = true +inlining-strategy = "avoid" + [scripts] test = "snforge test" diff --git a/eth_712_account/src/eth_712_account.cairo b/eth_712_account/src/eth_712_account.cairo index 4d19a9f..d17c879 100644 --- a/eth_712_account/src/eth_712_account.cairo +++ b/eth_712_account/src/eth_712_account.cairo @@ -12,12 +12,6 @@ #[starknet::contract(account)] pub mod StarknetEth712Account { - use crate::eth_712_utils::{ - assert_valid_owner, extract_signature, get_outside_execution_hash, is_valid_signature, - }; - use crate::interface::{ - IAccount712Admin, IEICDispatcherTrait, IEICLibraryDispatcher, Upgraded, - }; use core::num::traits::Zero; use openzeppelin::account::AccountComponent; use openzeppelin::account::extensions::src9::interface::ISRC9_V2_ID; @@ -33,6 +27,10 @@ pub mod StarknetEth712Account { }; use starknet::syscalls::replace_class_syscall; use starknet::{ClassHash, EthAddress, SyscallResultTrait}; + use crate::eth_712_utils::{ + assert_valid_owner, extract_signature, get_outside_execution_hash, is_valid_signature, + }; + use crate::interface::{IAccount712Admin, IEICDispatcherTrait, IEICLibraryDispatcher, Upgraded}; component!(path: SRC5Component, storage: src5, event: SRC5Event); component!(path: AccountComponent, storage: account, event: AccountEvent); diff --git a/eth_712_account/src/register_interfaces_eic.cairo b/eth_712_account/src/register_interfaces_eic.cairo index 48e057b..37fe854 100644 --- a/eth_712_account/src/register_interfaces_eic.cairo +++ b/eth_712_account/src/register_interfaces_eic.cairo @@ -5,9 +5,9 @@ #[starknet::contract] pub mod RegisterInterfacesEIC { - use crate::interface::IEIC; use openzeppelin::introspection::src5::SRC5Component; use openzeppelin::introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait; + use crate::interface::IEIC; component!(path: SRC5Component, storage: src5, event: SRC5Event); diff --git a/scripts/verify_primer_class_hash.sh b/scripts/verify_primer_class_hash.sh new file mode 100755 index 0000000..f7bec6f --- /dev/null +++ b/scripts/verify_primer_class_hash.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -e + +EXPECTED_CLASS_HASH="0x00123e6bc1c14ae9934e933d3f64916a6116dd6b036a922b2b1f0815e0d1d300" + +# Build with release profile +echo "Building with release profile..." +SCARB_PROFILE=release scarb build + +# Compute class hash using sncast (extract just the hash from output) +echo "Computing Primer class hash..." +SNCAST_OUTPUT=$(sncast utils class-hash --package contracts --contract-name Primer 2>&1) +ACTUAL_CLASS_HASH=$(echo "$SNCAST_OUTPUT" | grep "Class Hash:" | awk '{print $3}') + +# Compare +echo "Expected: $EXPECTED_CLASS_HASH" +echo "Actual: $ACTUAL_CLASS_HASH" + +if [ "$ACTUAL_CLASS_HASH" = "$EXPECTED_CLASS_HASH" ]; then + echo "SUCCESS: Primer class hash matches expected value" + exit 0 +else + echo "FAILURE: Primer class hash mismatch!" + exit 1 +fi diff --git a/strategy_implementation/Scarb.toml b/strategy_implementation/Scarb.toml index 2ae8712..b7585db 100644 --- a/strategy_implementation/Scarb.toml +++ b/strategy_implementation/Scarb.toml @@ -28,5 +28,10 @@ build-external-contracts = [ ] name = "strategy_implementation_unittest" +[profile.dev.cairo] +unstable-add-statements-functions-debug-info = true +unstable-add-statements-code-locations-debug-info = true +inlining-strategy = "avoid" + [scripts] test = "snforge test" diff --git a/strategy_implementation/src/lib.cairo b/strategy_implementation/src/lib.cairo index 9cf2c4e..7a9e190 100644 --- a/strategy_implementation/src/lib.cairo +++ b/strategy_implementation/src/lib.cairo @@ -2,8 +2,8 @@ pub mod avnu_interface; pub mod interface; pub(crate) mod known_addresses; pub mod strategy_implementation; -pub mod utils; #[cfg(test)] pub(crate) mod test; #[cfg(test)] pub(crate) mod test_utils; +pub mod utils; diff --git a/strategy_implementation/src/strategy_implementation.cairo b/strategy_implementation/src/strategy_implementation.cairo index 54b7cbf..57775d9 100644 --- a/strategy_implementation/src/strategy_implementation.cairo +++ b/strategy_implementation/src/strategy_implementation.cairo @@ -4,22 +4,10 @@ pub mod StrategyImplementation { use account_factory::account_factory::{ IAccountFactoryDispatcher, IAccountFactoryDispatcherTrait, }; - use crate::avnu_interface::AvnuParameters; - use crate::interface::{ - IStrategyImplementation, IStrategyImplementationSafeDispatcher, - IStrategyImplementationSafeDispatcherTrait, - }; - use crate::known_addresses::MIDAS_RE7_BTC; - use crate::utils::{ - IERC4626DepositDispatcher, IERC4626DepositDispatcherTrait, Strategy, StrategyTrait, - avnu_multi_route_swap, deserialize_signature, strategy_from_protocol_and_token, - }; use core::num::traits::Zero; use core::panic_with_felt252; use core::traits::Into; - use earn_reporter::earn_reporter::{ - IEarnReporterDispatcher, IEarnReporterDispatcherTrait, - }; + use earn_reporter::earn_reporter::{IEarnReporterDispatcher, IEarnReporterDispatcherTrait}; use openzeppelin::access::accesscontrol::AccessControlComponent; use openzeppelin::introspection::src5::SRC5Component; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; @@ -30,6 +18,16 @@ pub mod StrategyImplementation { use starkware_utils::components::replaceability::ReplaceabilityComponent; use starkware_utils::components::replaceability::ReplaceabilityComponent::InternalReplaceabilityTrait; use starkware_utils::components::roles::RolesComponent; + use crate::avnu_interface::AvnuParameters; + use crate::interface::{ + IStrategyImplementation, IStrategyImplementationSafeDispatcher, + IStrategyImplementationSafeDispatcherTrait, + }; + use crate::known_addresses::MIDAS_RE7_BTC; + use crate::utils::{ + IERC4626DepositDispatcher, IERC4626DepositDispatcherTrait, Strategy, StrategyTrait, + avnu_multi_route_swap, deserialize_signature, strategy_from_protocol_and_token, + }; component!(path: RolesComponent, storage: roles, event: RolesEvent); component!(path: AccessControlComponent, storage: accesscontrol, event: accesscontrolEvent); diff --git a/strategy_implementation/src/test.cairo b/strategy_implementation/src/test.cairo index 3a65de3..5e9e25e 100644 --- a/strategy_implementation/src/test.cairo +++ b/strategy_implementation/src/test.cairo @@ -1,5 +1,12 @@ use core::array::ArrayTrait; use core::num::traits::Zero; +use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; +use snforge_std::TokenImpl; +use snforge_std::cheatcodes::events::{EventSpyTrait, EventsFilterTrait}; +use starknet::ContractAddress; +use starknet::eth_address::EthAddress; +use starknet::secp256_trait::Signature; +use starkware_utils_testing::test_utils::{assert_panic_with_felt_error, cheat_caller_address_once}; use crate::interface::{ IStrategyImplementationDispatcher, IStrategyImplementationDispatcherTrait, IStrategyImplementationSafeDispatcher, IStrategyImplementationSafeDispatcherTrait, @@ -14,22 +21,13 @@ use crate::test_utils::{ assert_deposited_event, build_prefunded_apply_parameters_with_amount, build_prefunded_apply_parameters_with_token_address, build_prefunded_avnu, cheat_transfer_and_approve, deploy_4626_failure_mock, deploy_and_prefund_dummy_erc20_at, - deploy_dummy_avnu, deploy_dummy_avnu_failure, deploy_dummy_avnu_false, - deploy_erc4626_deposit_mint_mock, deploy_earn_reporter, deploy_mock_erc20_contract_at, - dummy_apply_parameters, dummy_apply_parameters_with_protocol, get_account_factory, - get_event_by_selector, get_position_owner, serialize_signature, - setup_strategy_implementation_test_env, validate_avnu_swap, -}; -use crate::utils::{ - PROTOCOL_ENDUR, PROTOCOL_FORGE_YIELDS, PROTOCOL_NOON, PROTOCOL_TROVES, + deploy_dummy_avnu, deploy_dummy_avnu_failure, deploy_dummy_avnu_false, deploy_earn_reporter, + deploy_erc4626_deposit_mint_mock, deploy_mock_erc20_contract_at, dummy_apply_parameters, + dummy_apply_parameters_with_protocol, get_account_factory, get_event_by_selector, + get_position_owner, serialize_signature, setup_strategy_implementation_test_env, + validate_avnu_swap, }; -use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; -use snforge_std::TokenImpl; -use snforge_std::cheatcodes::events::{EventSpyTrait, EventsFilterTrait}; -use starknet::ContractAddress; -use starknet::eth_address::EthAddress; -use starknet::secp256_trait::Signature; -use starkware_utils_testing::test_utils::{assert_panic_with_felt_error, cheat_caller_address_once}; +use crate::utils::{PROTOCOL_ENDUR, PROTOCOL_FORGE_YIELDS, PROTOCOL_NOON, PROTOCOL_TROVES}; #[test] diff --git a/strategy_implementation/src/test_utils.cairo b/strategy_implementation/src/test_utils.cairo index 646b323..cdcd7bc 100644 --- a/strategy_implementation/src/test_utils.cairo +++ b/strategy_implementation/src/test_utils.cairo @@ -1,16 +1,4 @@ use account_factory::utils::compute_contract_address; -use crate::avnu_interface::{AvnuParameters, Route}; -use crate::interface::{ - IStrategyImplementationDispatcher, IStrategyImplementationDispatcherTrait, -}; -use crate::known_addresses::{AVNU_EXCHANGE, MIDAS_RE7_BTC}; -use crate::strategy_implementation::StrategyImplementation::{ - ApplyFailed, Deposited, MultiRouteSwap, PositionOwnerDeployed, -}; -use crate::utils::{ - PROTOCOL_AVNU, PROTOCOL_TROVES, Strategy, StrategyTrait, TokenTrait, deserialize_signature, - strategy_from_protocol_and_token, -}; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; use snforge_std::cheatcodes::events::Event; use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl}; @@ -22,6 +10,16 @@ use starkware_utils_testing::test_utils::{ assert_expected_event_emitted, cheat_caller_address_once, set_account_as_app_governor, set_account_as_app_role_admin, }; +use crate::avnu_interface::{AvnuParameters, Route}; +use crate::interface::{IStrategyImplementationDispatcher, IStrategyImplementationDispatcherTrait}; +use crate::known_addresses::{AVNU_EXCHANGE, MIDAS_RE7_BTC}; +use crate::strategy_implementation::StrategyImplementation::{ + ApplyFailed, Deposited, MultiRouteSwap, PositionOwnerDeployed, +}; +use crate::utils::{ + PROTOCOL_AVNU, PROTOCOL_TROVES, Strategy, StrategyTrait, TokenTrait, deserialize_signature, + strategy_from_protocol_and_token, +}; /// The Primer class hash used in tests. This must match what snforge produces when @@ -713,11 +711,11 @@ pub trait IERC4626DepositMintMock { #[starknet::contract] pub mod ERC4626DepositMintMock { - use crate::test_utils::IERC4626DepositMintMock; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; use openzeppelin::token::erc20::{DefaultConfig, ERC20Component, ERC20HooksEmptyImpl}; use starknet::ContractAddress; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + use crate::test_utils::IERC4626DepositMintMock; component!(path: ERC20Component, storage: erc20, event: ERC20Event); @@ -829,8 +827,8 @@ pub(crate) fn deploy_4626_failure_mock(address_to_deploy_at: ContractAddress) { // ----------------------------------------------------------------------------- #[starknet::contract] pub mod DummyAvnu { - use crate::avnu_interface::AvnuParameters; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; + use crate::avnu_interface::AvnuParameters; #[storage] struct Storage {} @@ -866,8 +864,8 @@ pub(crate) fn deploy_dummy_avnu(address_to_deploy_at: ContractAddress) { // ----------------------------------------------------------------------------- #[starknet::contract] pub mod DummyAvnuFailure { - use crate::avnu_interface::AvnuParameters; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; + use crate::avnu_interface::AvnuParameters; #[storage] struct Storage {} diff --git a/strategy_implementation/src/utils.cairo b/strategy_implementation/src/utils.cairo index a71a1b3..fd9c380 100644 --- a/strategy_implementation/src/utils.cairo +++ b/strategy_implementation/src/utils.cairo @@ -1,15 +1,13 @@ -use crate::avnu_interface::{ - AvnuParameters, IAvnuDispatcher, IAvnuDispatcherTrait, -}; -use crate::known_addresses::{ - AVNU_EXCHANGE, ENDUR_LBTC, ENDUR_SOLVBTC, ENDUR_TBTC, ENDUR_WBTC, FORGE_YIELDS_WBTC, LBTC, - NOON_WBTC, SOLVBTC, TBTC, TROVES_LBTC, TROVES_SOLVBTC, TROVES_TBTC, TROVES_WBTC, WBTC, -}; use core::hash::HashStateTrait; use core::panic_with_felt252; use core::pedersen::PedersenTrait; use starknet::ContractAddress; use starknet::secp256_trait::Signature; +use crate::avnu_interface::{AvnuParameters, IAvnuDispatcher, IAvnuDispatcherTrait}; +use crate::known_addresses::{ + AVNU_EXCHANGE, ENDUR_LBTC, ENDUR_SOLVBTC, ENDUR_TBTC, ENDUR_WBTC, FORGE_YIELDS_WBTC, LBTC, + NOON_WBTC, SOLVBTC, TBTC, TROVES_LBTC, TROVES_SOLVBTC, TROVES_TBTC, TROVES_WBTC, WBTC, +}; pub(crate) const CONTRACT_ADDRESS_SALT: felt252 = 0; From 0bcdbca5f3b8f315406abe08cada32822e2cdf3d Mon Sep 17 00:00:00 2001 From: Remo Date: Wed, 11 Feb 2026 16:03:18 +0200 Subject: [PATCH 03/10] review comments --- account_factory/src/test.cairo | 22 +++++++++++++------- account_factory/src/test_utils.cairo | 5 +++++ account_factory/src/utils.cairo | 7 ++++--- earn_reporter/src/test_utils.cairo | 5 +++++ scripts/verify_primer_class_hash.sh | 8 +++++++ strategy_implementation/src/test_utils.cairo | 14 ++++++------- 6 files changed, 42 insertions(+), 19 deletions(-) diff --git a/account_factory/src/test.cairo b/account_factory/src/test.cairo index 63cbda4..71031d7 100644 --- a/account_factory/src/test.cairo +++ b/account_factory/src/test.cairo @@ -285,11 +285,17 @@ fn test_change_account_class_hash_affects_only_new_users() { ); } -// Primer tests +// ============================================================================= +// Primer Tests +// ============================================================================= +// The Primer contract is tested here alongside AccountFactory because: +// 1. Primer is deployed by AccountFactory as a lightweight placeholder contract +// 2. The tests share the same test infrastructure and helper functions +// 3. Primer's class hash is a critical dependency for AccountFactory's deploy_account #[test] #[should_panic(expected: 'INVALID_CALLER')] -fn test_primer_update_class_hash_invalid_caller() { +fn test_primer_set_class_hash_invalid_caller() { /// set_class_hash should only be callable by the upgrade account set at construction. /// Here we impersonate a different caller and expect the function to panic with /// 'INVALID_CALLER'. @@ -302,12 +308,12 @@ fn test_primer_update_class_hash_invalid_caller() { contract_address: primer_addr, caller_address: 0x1.try_into().unwrap(), ); // Attempt to update class hash with the wrong caller - should panic (see attribute above). - let dummy_eth_address_contract_class_hash = declare_dummy_eth_address_contract(); - primer.set_class_hash(new_class_hash: dummy_eth_address_contract_class_hash); + let test_class_hash = declare_dummy_eth_address_contract(); + primer.set_class_hash(new_class_hash: test_class_hash); } #[test] -fn test_primer_sanity_set_class_hash() { +fn test_primer_set_class_hash_success() { /// Happy path: after deployment, impersonate the upgrade account and update class hash. /// Verifies the on-chain class hash equals the provided value. let primer_class = snforge_std::declare("Primer").unwrap().contract_class(); @@ -316,11 +322,11 @@ fn test_primer_sanity_set_class_hash() { let primer = IPrimerDispatcher { contract_address: primer_addr }; // Impersonate the upgrade account (same address used by the test infra for this call). // Update the class hash and assert it took effect. - let dummy_eth_address_contract_class_hash = declare_dummy_eth_address_contract(); + let test_class_hash = declare_dummy_eth_address_contract(); starkware_utils_testing::test_utils::cheat_caller_address_once( contract_address: primer_addr, caller_address: get_contract_address(), ); - primer.set_class_hash(new_class_hash: dummy_eth_address_contract_class_hash); + primer.set_class_hash(new_class_hash: test_class_hash); let class_hash = get_class_hash_at_syscall(primer_addr).unwrap(); - assert!(class_hash == dummy_eth_address_contract_class_hash, "class hash mismatch"); + assert!(class_hash == test_class_hash, "class hash mismatch"); } diff --git a/account_factory/src/test_utils.cairo b/account_factory/src/test_utils.cairo index b903f9f..225692f 100644 --- a/account_factory/src/test_utils.cairo +++ b/account_factory/src/test_utils.cairo @@ -1,3 +1,8 @@ +// NOTE: Some test utilities (APP_GOVERNOR, find_event_index_by_selector, DummyEthAddressContract, +// etc.) are duplicated across packages. This is intentional to keep package dependencies simple +// and avoid circular dependencies. Consider consolidating into a shared test utils package if +// the duplication becomes burdensome. + use snforge_std::cheatcodes::events::Event; use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl}; use starknet::eth_address::EthAddress; diff --git a/account_factory/src/utils.cairo b/account_factory/src/utils.cairo index 412d751..9ffd9e1 100644 --- a/account_factory/src/utils.cairo +++ b/account_factory/src/utils.cairo @@ -7,14 +7,14 @@ use starknet::{ClassHash, ContractAddress, EthAddress, SyscallResultTrait, get_c pub(crate) const CONTRACT_ADDRESS_SALT: felt252 = 0; #[cfg(target: "test")] -pub(crate) const PRIMER_CLASS_HASH: ClassHash = +pub const PRIMER_CLASS_HASH: ClassHash = 0x0279a9bb18604f4ae57633373d56656063203f236cc5aeceea8f2cf40f6336d7 .try_into() .unwrap(); #[cfg(not(target: "test"))] -pub(crate) const PRIMER_CLASS_HASH: ClassHash = - 0x123e6bc1c14ae9934e933d3f64916a6116dd6b036a922b2b1f0815e0d1d300 +pub const PRIMER_CLASS_HASH: ClassHash = + 0x00123e6bc1c14ae9934e933d3f64916a6116dd6b036a922b2b1f0815e0d1d300 .try_into() .unwrap(); @@ -26,6 +26,7 @@ pub(crate) trait IEthAccountInitializer { } /// Computes the Pedersen hash on the elements of the span using a hash state. +// TODO: Move this function to a shared utils package to avoid duplication across packages. pub fn compute_pedersen_on_elements(data: Span) -> felt252 { let mut state = PedersenTrait::new(0); for value in data { diff --git a/earn_reporter/src/test_utils.cairo b/earn_reporter/src/test_utils.cairo index 962b41a..5fc0e31 100644 --- a/earn_reporter/src/test_utils.cairo +++ b/earn_reporter/src/test_utils.cairo @@ -1,3 +1,8 @@ +// NOTE: Some test utilities (find_event_index_by_selector, DummyEthAddressContract, etc.) are +// duplicated across packages. This is intentional to keep package dependencies simple and avoid +// circular dependencies. Consider consolidating into a shared test utils package if the +// duplication becomes burdensome. + use snforge_std::cheatcodes::events::Event; use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl}; use starknet::{ClassHash, ContractAddress, SyscallResultTrait}; diff --git a/scripts/verify_primer_class_hash.sh b/scripts/verify_primer_class_hash.sh index f7bec6f..6e04e3f 100755 --- a/scripts/verify_primer_class_hash.sh +++ b/scripts/verify_primer_class_hash.sh @@ -3,6 +3,14 @@ set -e EXPECTED_CLASS_HASH="0x00123e6bc1c14ae9934e933d3f64916a6116dd6b036a922b2b1f0815e0d1d300" +# Verify Scarb version for reproducible class hash computation +REQUIRED_SCARB_VERSION="2.12.2" +CURRENT_SCARB_VERSION=$(scarb --version | grep -oP 'scarb \K[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown") +echo "Scarb version: $CURRENT_SCARB_VERSION (expected: $REQUIRED_SCARB_VERSION)" +if [ "$CURRENT_SCARB_VERSION" != "$REQUIRED_SCARB_VERSION" ]; then + echo "WARNING: Scarb version mismatch. Class hash may differ." +fi + # Build with release profile echo "Building with release profile..." SCARB_PROFILE=release scarb build diff --git a/strategy_implementation/src/test_utils.cairo b/strategy_implementation/src/test_utils.cairo index cdcd7bc..23be2b6 100644 --- a/strategy_implementation/src/test_utils.cairo +++ b/strategy_implementation/src/test_utils.cairo @@ -1,4 +1,9 @@ -use account_factory::utils::compute_contract_address; +// NOTE: Some test utilities (APP_GOVERNOR, find_event_index_by_selector, DummyEthAddressContract, +// etc.) are duplicated across packages. This is intentional to keep package dependencies simple +// and avoid circular dependencies. Consider consolidating into a shared test utils package if +// the duplication becomes burdensome. + +use account_factory::utils::{PRIMER_CLASS_HASH, compute_contract_address}; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; use snforge_std::cheatcodes::events::Event; use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl}; @@ -22,13 +27,6 @@ use crate::utils::{ }; -/// The Primer class hash used in tests. This must match what snforge produces when -/// compiling the Primer contract. -pub(crate) const PRIMER_CLASS_HASH: starknet::ClassHash = - 0x0279a9bb18604f4ae57633373d56656063203f236cc5aeceea8f2cf40f6336d7 - .try_into() - .unwrap(); - // Test constants - mirrored from account_factory for use in strategy_implementation tests. pub(crate) fn APP_ROLE_ADMIN() -> ContractAddress { 'APP_ROLE_ADMIN'.try_into().unwrap() From d1ac7ad1f7b2540eda78a429becf03b1d5a1ebbf Mon Sep 17 00:00:00 2001 From: Remo Date: Wed, 11 Feb 2026 16:42:22 +0200 Subject: [PATCH 04/10] review comments 2 --- Scarb.lock | 4 +++ account_factory/src/test.cairo | 64 +++++----------------------------- contracts/Scarb.toml | 4 +++ contracts/src/lib.cairo | 3 ++ contracts/src/test.cairo | 54 ++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+), 56 deletions(-) create mode 100644 contracts/src/test.cairo diff --git a/Scarb.lock b/Scarb.lock index a48caa2..5a8676d 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -15,6 +15,10 @@ dependencies = [ [[package]] name = "contracts" version = "0.1.0" +dependencies = [ + "snforge_std", + "starkware_utils_testing", +] [[package]] name = "earn_reporter" diff --git a/account_factory/src/test.cairo b/account_factory/src/test.cairo index 71031d7..aaf5ce8 100644 --- a/account_factory/src/test.cairo +++ b/account_factory/src/test.cairo @@ -1,18 +1,16 @@ -use contracts::primer::primer::{IPrimerDispatcher, IPrimerDispatcherTrait}; +use account_factory::account_factory::AccountFactory::{AccountClassHashChanged, AccountDeployed}; +use account_factory::account_factory::{IAccountFactoryDispatcher, IAccountFactoryDispatcherTrait}; +use account_factory::test_utils::{ + APP_GOVERNOR, declare_dummy_eth_address_contract, declare_second_dummy_eth_address_contract, + eth_address_to_account, get_event_by_selector, get_event_by_selector_n, + setup_account_factory_test_env, +}; use snforge_std; use snforge_std::cheatcodes::events::{EventSpyTrait, EventsFilterTrait}; -use snforge_std::{ContractClassTrait, DeclareResultTrait}; use starknet::secp256_trait::Signature; use starknet::syscalls::get_class_hash_at_syscall; -use starknet::{ClassHash, ContractAddress, EthAddress, SyscallResultTrait, get_contract_address}; +use starknet::{ClassHash, ContractAddress, EthAddress, SyscallResultTrait}; use starkware_utils_testing::test_utils::{assert_expected_event_emitted, cheat_caller_address_once}; -use crate::account_factory::AccountFactory::{AccountClassHashChanged, AccountDeployed}; -use crate::account_factory::{IAccountFactoryDispatcher, IAccountFactoryDispatcherTrait}; -use crate::test_utils::{ - APP_GOVERNOR, declare_dummy_eth_address_contract, declare_second_dummy_eth_address_contract, - eth_address_to_account, get_event_by_selector, get_event_by_selector_n, - setup_account_factory_test_env, -}; fn deploy_account_wrapper( @@ -284,49 +282,3 @@ fn test_change_account_class_hash_affects_only_new_users() { "original account should keep its original class hash", ); } - -// ============================================================================= -// Primer Tests -// ============================================================================= -// The Primer contract is tested here alongside AccountFactory because: -// 1. Primer is deployed by AccountFactory as a lightweight placeholder contract -// 2. The tests share the same test infrastructure and helper functions -// 3. Primer's class hash is a critical dependency for AccountFactory's deploy_account - -#[test] -#[should_panic(expected: 'INVALID_CALLER')] -fn test_primer_set_class_hash_invalid_caller() { - /// set_class_hash should only be callable by the upgrade account set at construction. - /// Here we impersonate a different caller and expect the function to panic with - /// 'INVALID_CALLER'. - let primer_class = snforge_std::declare("Primer").unwrap().contract_class(); - let (primer_addr, _) = primer_class.deploy(@array![]).unwrap(); - - let primer = IPrimerDispatcher { contract_address: primer_addr }; - // Impersonate a non-upgrade caller for the next call. - starkware_utils_testing::test_utils::cheat_caller_address_once( - contract_address: primer_addr, caller_address: 0x1.try_into().unwrap(), - ); - // Attempt to update class hash with the wrong caller - should panic (see attribute above). - let test_class_hash = declare_dummy_eth_address_contract(); - primer.set_class_hash(new_class_hash: test_class_hash); -} - -#[test] -fn test_primer_set_class_hash_success() { - /// Happy path: after deployment, impersonate the upgrade account and update class hash. - /// Verifies the on-chain class hash equals the provided value. - let primer_class = snforge_std::declare("Primer").unwrap().contract_class(); - let (primer_addr, _) = primer_class.deploy(@array![]).unwrap(); - - let primer = IPrimerDispatcher { contract_address: primer_addr }; - // Impersonate the upgrade account (same address used by the test infra for this call). - // Update the class hash and assert it took effect. - let test_class_hash = declare_dummy_eth_address_contract(); - starkware_utils_testing::test_utils::cheat_caller_address_once( - contract_address: primer_addr, caller_address: get_contract_address(), - ); - primer.set_class_hash(new_class_hash: test_class_hash); - let class_hash = get_class_hash_at_syscall(primer_addr).unwrap(); - assert!(class_hash == test_class_hash, "class hash mismatch"); -} diff --git a/contracts/Scarb.toml b/contracts/Scarb.toml index 5e63d26..0ea4b54 100644 --- a/contracts/Scarb.toml +++ b/contracts/Scarb.toml @@ -8,6 +8,10 @@ version.workspace = true [dependencies] starknet.workspace = true +[dev-dependencies] +snforge_std.workspace = true +starkware_utils_testing.workspace = true + [[target.starknet-contract]] sierra = true diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index cca4fbf..6fe721e 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -1 +1,4 @@ pub mod primer; + +#[cfg(test)] +mod test; diff --git a/contracts/src/test.cairo b/contracts/src/test.cairo new file mode 100644 index 0000000..0547564 --- /dev/null +++ b/contracts/src/test.cairo @@ -0,0 +1,54 @@ +use contracts::primer::primer::{IPrimerDispatcher, IPrimerDispatcherTrait}; +use snforge_std::{ContractClassTrait, DeclareResultTrait}; +use starknet::syscalls::get_class_hash_at_syscall; +use starknet::{ClassHash, SyscallResultTrait, get_contract_address}; +use starkware_utils_testing::test_utils::cheat_caller_address_once; + +// Minimal no-op contract used as upgrade target in tests. +#[starknet::contract] +mod DummyUpgradeTarget { + #[storage] + struct Storage {} +} + +fn declare_dummy_upgrade_target() -> ClassHash { + *snforge_std::declare("DummyUpgradeTarget").unwrap_syscall().contract_class().class_hash +} + +#[test] +#[should_panic(expected: 'INVALID_CALLER')] +fn test_primer_set_class_hash_invalid_caller() { + /// set_class_hash should only be callable by the upgrade account set at construction. + /// Here we impersonate a different caller and expect the function to panic with + /// 'INVALID_CALLER'. + let primer_class = snforge_std::declare("Primer").unwrap().contract_class(); + let (primer_addr, _) = primer_class.deploy(@array![]).unwrap(); + + let primer = IPrimerDispatcher { contract_address: primer_addr }; + // Impersonate a non-upgrade caller for the next call. + cheat_caller_address_once( + contract_address: primer_addr, caller_address: 0x1.try_into().unwrap(), + ); + // Attempt to update class hash with the wrong caller - should panic (see attribute above). + let test_class_hash = declare_dummy_upgrade_target(); + primer.set_class_hash(new_class_hash: test_class_hash); +} + +#[test] +fn test_primer_set_class_hash_success() { + /// Happy path: after deployment, impersonate the upgrade account and update class hash. + /// Verifies the on-chain class hash equals the provided value. + let primer_class = snforge_std::declare("Primer").unwrap().contract_class(); + let (primer_addr, _) = primer_class.deploy(@array![]).unwrap(); + + let primer = IPrimerDispatcher { contract_address: primer_addr }; + // Impersonate the upgrade account (same address used by the test infra for this call). + // Update the class hash and assert it took effect. + let test_class_hash = declare_dummy_upgrade_target(); + cheat_caller_address_once( + contract_address: primer_addr, caller_address: get_contract_address(), + ); + primer.set_class_hash(new_class_hash: test_class_hash); + let class_hash = get_class_hash_at_syscall(primer_addr).unwrap(); + assert!(class_hash == test_class_hash, "class hash mismatch"); +} From 151c00e9afbd6cce87dc4e7a237d0de908ed67a1 Mon Sep 17 00:00:00 2001 From: Remo Date: Thu, 12 Feb 2026 13:06:12 +0200 Subject: [PATCH 05/10] fix primer clash validation script --- scripts/verify_primer_class_hash.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/verify_primer_class_hash.sh b/scripts/verify_primer_class_hash.sh index 6e04e3f..43bd6f6 100755 --- a/scripts/verify_primer_class_hash.sh +++ b/scripts/verify_primer_class_hash.sh @@ -4,7 +4,7 @@ set -e EXPECTED_CLASS_HASH="0x00123e6bc1c14ae9934e933d3f64916a6116dd6b036a922b2b1f0815e0d1d300" # Verify Scarb version for reproducible class hash computation -REQUIRED_SCARB_VERSION="2.12.2" +REQUIRED_SCARB_VERSION="2.14.0" CURRENT_SCARB_VERSION=$(scarb --version | grep -oP 'scarb \K[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown") echo "Scarb version: $CURRENT_SCARB_VERSION (expected: $REQUIRED_SCARB_VERSION)" if [ "$CURRENT_SCARB_VERSION" != "$REQUIRED_SCARB_VERSION" ]; then From 20387337cac6367545bf2acc938d405ba26cbd7a Mon Sep 17 00:00:00 2001 From: Remo Date: Sun, 15 Feb 2026 14:06:32 +0200 Subject: [PATCH 06/10] extract some common stuff to testing_utils --- Scarb.lock | 15 ++ Scarb.toml | 2 +- account_factory/Scarb.toml | 7 +- account_factory/src/test_utils.cairo | 190 +----------------- earn_reporter/Scarb.toml | 7 + earn_reporter/src/test_utils.cairo | 61 +----- strategy_implementation/Scarb.toml | 2 + strategy_implementation/src/test_utils.cairo | 158 ++------------- testing_utils/Scarb.toml | 29 +++ testing_utils/src/account_factory_utils.cairo | 68 +++++++ testing_utils/src/constants.cairo | 13 ++ testing_utils/src/dummy_contracts.cairo | 51 +++++ testing_utils/src/event_helpers.cairo | 46 +++++ testing_utils/src/lib.cairo | 4 + 14 files changed, 281 insertions(+), 372 deletions(-) create mode 100644 testing_utils/Scarb.toml create mode 100644 testing_utils/src/account_factory_utils.cairo create mode 100644 testing_utils/src/constants.cairo create mode 100644 testing_utils/src/dummy_contracts.cairo create mode 100644 testing_utils/src/event_helpers.cairo create mode 100644 testing_utils/src/lib.cairo diff --git a/Scarb.lock b/Scarb.lock index 5a8676d..3f440d4 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -10,6 +10,7 @@ dependencies = [ "snforge_std", "starkware_utils", "starkware_utils_testing", + "testing_utils", ] [[package]] @@ -28,6 +29,7 @@ dependencies = [ "openzeppelin_upgrades", "snforge_std", "starkware_utils_testing", + "testing_utils", ] [[package]] @@ -200,4 +202,17 @@ dependencies = [ "snforge_std", "starkware_utils", "starkware_utils_testing", + "testing_utils", +] + +[[package]] +name = "testing_utils" +version = "0.1.0" +dependencies = [ + "account_factory", + "contracts", + "openzeppelin", + "snforge_std", + "starkware_utils", + "starkware_utils_testing", ] diff --git a/Scarb.toml b/Scarb.toml index 1ba3db7..b80e75f 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -1,5 +1,5 @@ [workspace] -members = ["contracts", "eth_712_account", "account_factory", "earn_reporter", "strategy_implementation"] +members = ["contracts", "eth_712_account", "account_factory", "earn_reporter", "strategy_implementation", "testing_utils"] [workspace.package] edition = "2024_07" diff --git a/account_factory/Scarb.toml b/account_factory/Scarb.toml index a9a48d7..4b09068 100644 --- a/account_factory/Scarb.toml +++ b/account_factory/Scarb.toml @@ -15,12 +15,17 @@ starkware_utils.workspace = true assert_macros.workspace = true snforge_std.workspace = true starkware_utils_testing.workspace = true +testing_utils = { path = "../testing_utils" } [[target.starknet-contract]] sierra = true [[test]] -build-external-contracts = ["contracts::primer::primer::Primer"] +build-external-contracts = [ + "contracts::primer::primer::Primer", + "testing_utils::dummy_contracts::DummyEthAddressContract", + "testing_utils::dummy_contracts::SecondDummyEthAddressContract", +] name = "account_factory_unittest" [profile.dev.cairo] diff --git a/account_factory/src/test_utils.cairo b/account_factory/src/test_utils.cairo index 225692f..34f5cd2 100644 --- a/account_factory/src/test_utils.cairo +++ b/account_factory/src/test_utils.cairo @@ -1,180 +1,12 @@ -// NOTE: Some test utilities (APP_GOVERNOR, find_event_index_by_selector, DummyEthAddressContract, -// etc.) are duplicated across packages. This is intentional to keep package dependencies simple -// and avoid circular dependencies. Consider consolidating into a shared test utils package if -// the duplication becomes burdensome. - -use snforge_std::cheatcodes::events::Event; -use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl}; -use starknet::eth_address::EthAddress; -use starknet::{ClassHash, ContractAddress, SyscallResultTrait}; -use starkware_utils_testing::test_utils::{ - set_account_as_app_governor, set_account_as_app_role_admin, +// Re-export shared testing utilities from the testing_utils package. +pub use testing_utils::account_factory_utils::{ + account_factory_constructor_calldata, declare_primer_contract, eth_address_to_account, + set_account_factory_default_roles, setup_account_factory_test_env, +}; +pub use testing_utils::constants::{APP_GOVERNOR, APP_ROLE_ADMIN, GOVERNANCE_ADMIN}; +pub use testing_utils::dummy_contracts::{ + declare_dummy_eth_address_contract, declare_second_dummy_eth_address_contract, +}; +pub use testing_utils::event_helpers::{ + find_event_index_by_selector, get_event_by_selector, get_event_by_selector_n, }; -use crate::utils::{PRIMER_CLASS_HASH, compute_contract_address}; - -pub(crate) fn APP_ROLE_ADMIN() -> ContractAddress { - 'APP_ROLE_ADMIN'.try_into().unwrap() -} - -pub(crate) fn APP_GOVERNOR() -> ContractAddress { - 'APP_GOVERNOR'.try_into().unwrap() -} - - -pub(crate) fn GOVERNANCE_ADMIN() -> ContractAddress { - 'GOVERNANCE_ADMIN'.try_into().unwrap() -} - -/// Returns the index of the nth event whose first key equals the given selector. -pub(crate) fn find_event_index_by_selector( - events: Span<(ContractAddress, Event)>, selector: felt252, n: usize, -) -> Option { - let mut i = 0_usize; - let mut seen = 0_usize; - for (_, ev) in events { - if ev.keys.len() > 0 && *ev.keys.at(0) == selector { - if seen == n { - return Option::Some(i); - } - seen += 1; - } - i += 1; - } - None -} -/// Returns a cloned copy of the first event emitted with the given selector (if any). -pub(crate) fn get_event_by_selector( - events: Span<(ContractAddress, Event)>, selector: felt252, -) -> Option<@(ContractAddress, Event)> { - match find_event_index_by_selector(:events, :selector, n: 0) { - Option::Some(i) => { - let (from, ev) = events.at(i); - Option::Some(@(*from, ev.clone())) - }, - None => None, - } -} - -/// Returns a cloned copy of the nth event emitted with the given selector (if any). -pub(crate) fn get_event_by_selector_n( - events: Span<(ContractAddress, Event)>, selector: felt252, n: usize, -) -> Option<@(ContractAddress, Event)> { - match find_event_index_by_selector(:events, :selector, :n) { - Option::Some(i) => { - let (from, ev) = events.at(i); - Option::Some(@(*from, ev.clone())) - }, - None => None, - } -} - - -/// Mirrors AccountFactory.eth_address_to_account for tests, using the -/// PRIMER_CLASS_HASH and the account factory address as the deployer address. The difference -/// between this and AccountFactory.eth_address_to_account is that this function gets the deployer -/// address from the caller. -pub(crate) fn eth_address_to_account( - account_factory: ContractAddress, eth_address: EthAddress, -) -> ContractAddress { - compute_contract_address( - salt: eth_address.into(), - class_hash: PRIMER_CLASS_HASH.into(), - constructor_calldata: array![].span(), - deployer_address: account_factory.into(), - ) -} - -/// Declare the `Primer` contract and return its class hash. -pub(crate) fn declare_primer_contract() -> ClassHash { - *snforge_std::declare("Primer").unwrap_syscall().contract_class().class_hash -} - - -fn set_account_factory_default_roles(account_factory: ContractAddress) { - // App role admin - set_account_as_app_role_admin( - contract: account_factory, account: APP_ROLE_ADMIN(), governance_admin: GOVERNANCE_ADMIN(), - ); - // App governor (requires app role admin) - set_account_as_app_governor( - contract: account_factory, account: APP_GOVERNOR(), app_role_admin: APP_ROLE_ADMIN(), - ); -} - - -/// Sets up the AccountFactory test environment: -/// - deploys the `AccountFactory` contract, -/// - sets default roles, -/// - declares the `Primer` contract so its class hash is available. -pub(crate) fn setup_account_factory_test_env() -> ContractAddress { - let calldata = account_factory_constructor_calldata(); - let account_factory_contract = snforge_std::declare("AccountFactory") - .unwrap_syscall() - .contract_class(); - let (account_factory_contract_address, _) = account_factory_contract - .deploy(@calldata) - .unwrap_syscall(); - set_account_factory_default_roles(account_factory_contract_address); - declare_primer_contract(); - account_factory_contract_address -} - -/// Builds the constructor calldata array for AccountFactory. -pub(crate) fn account_factory_constructor_calldata() -> Array { - let governance_admin: ContractAddress = GOVERNANCE_ADMIN(); - let upgrade_delay: u64 = 0; - let account_class_hash: ClassHash = declare_dummy_eth_address_contract(); - let mut calldata: Array = array![]; - Serde::serialize(@governance_admin, ref calldata); - Serde::serialize(@upgrade_delay, ref calldata); - Serde::serialize(@account_class_hash, ref calldata); - calldata -} - -// Minimal no-op contract for tests: stores an EthAddress passed at construction. -#[starknet::contract] -pub mod DummyEthAddressContract { - use starknet::eth_address::EthAddress; - use starknet::secp256_trait::Signature; - #[storage] - struct Storage {} - - - #[external(v0)] - fn initialize(ref self: ContractState, eth_address: EthAddress, signature: Signature) { - return; - } -} - - -pub(crate) fn declare_dummy_eth_address_contract() -> ClassHash { - *snforge_std::declare("DummyEthAddressContract").unwrap_syscall().contract_class().class_hash -} - - -/// Declare the `SecondDummyEthAddressContract` contract and return its class hash. -#[starknet::contract] -pub mod SecondDummyEthAddressContract { - use starknet::eth_address::EthAddress; - use starknet::secp256_trait::Signature; - #[storage] - struct Storage {} - - #[constructor] - pub fn constructor(ref self: ContractState) { - // This assert is just to get a different class hash for the contract. - assert!(true, "ERROR"); - } - #[external(v0)] - fn initialize(ref self: ContractState, eth_address: EthAddress, signature: Signature) { - return; - } -} - -/// Declare the `SecondDummyEthAddressContract` contract and return its class hash. -pub(crate) fn declare_second_dummy_eth_address_contract() -> ClassHash { - *snforge_std::declare("SecondDummyEthAddressContract") - .unwrap_syscall() - .contract_class() - .class_hash -} diff --git a/earn_reporter/Scarb.toml b/earn_reporter/Scarb.toml index 0cdb64c..208ba64 100644 --- a/earn_reporter/Scarb.toml +++ b/earn_reporter/Scarb.toml @@ -14,10 +14,17 @@ starknet.workspace = true assert_macros.workspace = true snforge_std.workspace = true starkware_utils_testing.workspace = true +testing_utils = { path = "../testing_utils" } [[target.starknet-contract]] sierra = true +[[test]] +build-external-contracts = [ + "testing_utils::dummy_contracts::DummyEthAddressContract", +] +name = "earn_reporter_unittest" + [profile.dev.cairo] unstable-add-statements-functions-debug-info = true unstable-add-statements-code-locations-debug-info = true diff --git a/earn_reporter/src/test_utils.cairo b/earn_reporter/src/test_utils.cairo index 5fc0e31..d3a7419 100644 --- a/earn_reporter/src/test_utils.cairo +++ b/earn_reporter/src/test_utils.cairo @@ -1,42 +1,11 @@ -// NOTE: Some test utilities (find_event_index_by_selector, DummyEthAddressContract, etc.) are -// duplicated across packages. This is intentional to keep package dependencies simple and avoid -// circular dependencies. Consider consolidating into a shared test utils package if the -// duplication becomes burdensome. +// Re-export shared testing utilities from the testing_utils package. -use snforge_std::cheatcodes::events::Event; -use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl}; -use starknet::{ClassHash, ContractAddress, SyscallResultTrait}; +// Package-specific helpers -/// Returns the index of the nth event whose first key equals the given selector. -pub(crate) fn find_event_index_by_selector( - events: Span<(ContractAddress, Event)>, selector: felt252, n: usize, -) -> Option { - let mut i = 0_usize; - let mut seen = 0_usize; - for (_, ev) in events { - if ev.keys.len() > 0 && *ev.keys.at(0) == selector { - if seen == n { - return Option::Some(i); - } - seen += 1; - } - i += 1; - } - None -} - -/// Returns a cloned copy of the first event emitted with the given selector (if any). -pub(crate) fn get_event_by_selector( - events: Span<(ContractAddress, Event)>, selector: felt252, -) -> Option<@(ContractAddress, Event)> { - match find_event_index_by_selector(:events, :selector, n: 0) { - Option::Some(i) => { - let (from, ev) = events.at(i); - Option::Some(@(*from, ev.clone())) - }, - None => None, - } -} +use snforge_std::{ContractClassTrait, DeclareResultTrait}; +use starknet::{ContractAddress, SyscallResultTrait}; +pub use testing_utils::dummy_contracts::declare_dummy_eth_address_contract; +pub use testing_utils::event_helpers::{find_event_index_by_selector, get_event_by_selector}; /// Deploy the EarnReporter contract and return its address. pub(crate) fn deploy_earn_reporter(owner: ContractAddress) -> ContractAddress { @@ -48,21 +17,3 @@ pub(crate) fn deploy_earn_reporter(owner: ContractAddress) -> ContractAddress { .unwrap_syscall(); earn_reporter_addr } - -// Minimal no-op contract for tests: stores an EthAddress passed at construction. -#[starknet::contract] -pub mod DummyEthAddressContract { - use starknet::eth_address::EthAddress; - use starknet::secp256_trait::Signature; - #[storage] - struct Storage {} - - #[external(v0)] - fn initialize(ref self: ContractState, eth_address: EthAddress, signature: Signature) { - return; - } -} - -pub(crate) fn declare_dummy_eth_address_contract() -> ClassHash { - *snforge_std::declare("DummyEthAddressContract").unwrap_syscall().contract_class().class_hash -} diff --git a/strategy_implementation/Scarb.toml b/strategy_implementation/Scarb.toml index b7585db..dfcc425 100644 --- a/strategy_implementation/Scarb.toml +++ b/strategy_implementation/Scarb.toml @@ -15,6 +15,7 @@ starkware_utils.workspace = true assert_macros.workspace = true snforge_std.workspace = true starkware_utils_testing.workspace = true +testing_utils = { path = "../testing_utils" } [[target.starknet-contract]] sierra = true @@ -25,6 +26,7 @@ build-external-contracts = [ "account_factory::account_factory::AccountFactory", "contracts::primer::primer::Primer", "earn_reporter::earn_reporter::EarnReporter", + "testing_utils::dummy_contracts::DummyEthAddressContract", ] name = "strategy_implementation_unittest" diff --git a/strategy_implementation/src/test_utils.cairo b/strategy_implementation/src/test_utils.cairo index 23be2b6..ef5e50e 100644 --- a/strategy_implementation/src/test_utils.cairo +++ b/strategy_implementation/src/test_utils.cairo @@ -1,9 +1,7 @@ -// NOTE: Some test utilities (APP_GOVERNOR, find_event_index_by_selector, DummyEthAddressContract, -// etc.) are duplicated across packages. This is intentional to keep package dependencies simple -// and avoid circular dependencies. Consider consolidating into a shared test utils package if -// the duplication becomes burdensome. +// Re-export shared testing utilities from the testing_utils package. + +// Package-specific helpers -use account_factory::utils::{PRIMER_CLASS_HASH, compute_contract_address}; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; use snforge_std::cheatcodes::events::Event; use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl}; @@ -15,6 +13,14 @@ use starkware_utils_testing::test_utils::{ assert_expected_event_emitted, cheat_caller_address_once, set_account_as_app_governor, set_account_as_app_role_admin, }; +pub use testing_utils::account_factory_utils::{ + declare_primer_contract, eth_address_to_account, setup_account_factory_test_env, +}; +pub use testing_utils::constants::{APP_GOVERNOR, APP_ROLE_ADMIN, GOVERNANCE_ADMIN}; +pub use testing_utils::dummy_contracts::declare_dummy_eth_address_contract; +pub use testing_utils::event_helpers::{ + find_event_index_by_selector, get_event_by_selector, get_event_by_selector_n, +}; use crate::avnu_interface::{AvnuParameters, Route}; use crate::interface::{IStrategyImplementationDispatcher, IStrategyImplementationDispatcherTrait}; use crate::known_addresses::{AVNU_EXCHANGE, MIDAS_RE7_BTC}; @@ -27,95 +33,6 @@ use crate::utils::{ }; -// Test constants - mirrored from account_factory for use in strategy_implementation tests. -pub(crate) fn APP_ROLE_ADMIN() -> ContractAddress { - 'APP_ROLE_ADMIN'.try_into().unwrap() -} - -pub(crate) fn APP_GOVERNOR() -> ContractAddress { - 'APP_GOVERNOR'.try_into().unwrap() -} - -pub(crate) fn GOVERNANCE_ADMIN() -> ContractAddress { - 'GOVERNANCE_ADMIN'.try_into().unwrap() -} - -/// Mirrors AccountFactory.eth_address_to_account for tests. -pub(crate) fn eth_address_to_account( - account_factory: ContractAddress, eth_address: EthAddress, -) -> ContractAddress { - compute_contract_address( - salt: eth_address.into(), - class_hash: PRIMER_CLASS_HASH.into(), - constructor_calldata: array![].span(), - deployer_address: account_factory.into(), - ) -} - -/// Declare the `Primer` contract and return its class hash. -pub(crate) fn declare_primer_contract() -> starknet::ClassHash { - *snforge_std::declare("Primer").unwrap_syscall().contract_class().class_hash -} - -fn set_account_factory_default_roles(account_factory: ContractAddress) { - set_account_as_app_role_admin( - contract: account_factory, account: APP_ROLE_ADMIN(), governance_admin: GOVERNANCE_ADMIN(), - ); - set_account_as_app_governor( - contract: account_factory, account: APP_GOVERNOR(), app_role_admin: APP_ROLE_ADMIN(), - ); -} - -/// Declare the `DummyEthAddressContract` contract and return its class hash. -pub(crate) fn declare_dummy_eth_address_contract() -> starknet::ClassHash { - *snforge_std::declare("DummyEthAddressContract").unwrap_syscall().contract_class().class_hash -} - -/// Builds the constructor calldata array for AccountFactory. -pub(crate) fn account_factory_constructor_calldata() -> Array { - let governance_admin: ContractAddress = GOVERNANCE_ADMIN(); - let upgrade_delay: u64 = 0; - let account_class_hash: starknet::ClassHash = declare_dummy_eth_address_contract(); - let mut calldata: Array = array![]; - Serde::serialize(@governance_admin, ref calldata); - Serde::serialize(@upgrade_delay, ref calldata); - Serde::serialize(@account_class_hash, ref calldata); - calldata -} - -/// Sets up the AccountFactory test environment: -/// - deploys the `AccountFactory` contract, -/// - sets default roles, -/// - declares the `Primer` contract so its class hash is available. -pub(crate) fn setup_account_factory_test_env() -> ContractAddress { - let calldata = account_factory_constructor_calldata(); - let account_factory_contract = snforge_std::declare("AccountFactory") - .unwrap_syscall() - .contract_class(); - let (account_factory_contract_address, _) = account_factory_contract - .deploy(@calldata) - .unwrap_syscall(); - set_account_factory_default_roles(account_factory_contract_address); - declare_primer_contract(); - account_factory_contract_address -} - -// Minimal no-op contract for tests: stores an EthAddress passed at construction. -#[starknet::contract] -pub mod DummyEthAddressContract { - use starknet::eth_address::EthAddress; - use starknet::secp256_trait::Signature; - #[storage] - struct Storage {} - - - #[external(v0)] - fn initialize(ref self: ContractState, eth_address: EthAddress, signature: Signature) { - return; - } -} - - #[derive(Drop, Copy)] pub(crate) struct ApplyParameters { pub token_in: ContractAddress, @@ -123,48 +40,6 @@ pub(crate) struct ApplyParameters { pub parameters: Span, } -/// Returns the index of the nth event whose first key equals the given selector. -pub(crate) fn find_event_index_by_selector( - events: Span<(ContractAddress, Event)>, selector: felt252, n: usize, -) -> Option { - let mut i = 0_usize; - let mut seen = 0_usize; - for (_, ev) in events { - if ev.keys.len() > 0 && *ev.keys.at(0) == selector { - if seen == n { - return Option::Some(i); - } - seen += 1; - } - i += 1; - } - None -} - -/// Returns a cloned copy of the first event emitted with the given selector (if any). -pub(crate) fn get_event_by_selector( - events: Span<(ContractAddress, Event)>, selector: felt252, -) -> Option<@(ContractAddress, Event)> { - match find_event_index_by_selector(:events, :selector, n: 0) { - Option::Some(i) => { - let (from, ev) = events.at(i); - Option::Some(@(*from, ev.clone())) - }, - None => None, - } -} - -/// Deploy the EarnReporter contract and return its address. -pub(crate) fn deploy_earn_reporter(owner: ContractAddress) -> ContractAddress { - let earn_reporter_class = snforge_std::declare("EarnReporter") - .unwrap_syscall() - .contract_class(); - let (earn_reporter_addr, _) = earn_reporter_class - .deploy(@array![owner.into()]) - .unwrap_syscall(); - earn_reporter_addr -} - /// Sets default StrategyImplementation roles using testing helpers and constants. pub(crate) fn set_strategy_implementation_default_roles(strategy_implementation: ContractAddress) { // App role admin @@ -915,3 +790,14 @@ pub(crate) fn deploy_dummy_avnu_false(address_to_deploy_at: ContractAddress) { let (addr, _) = cls.deploy_at(@calldata, address_to_deploy_at).unwrap_syscall(); assert!(addr == address_to_deploy_at, "deploy_at failed"); } + +/// Deploy the EarnReporter contract and return its address. +pub(crate) fn deploy_earn_reporter(owner: ContractAddress) -> ContractAddress { + let earn_reporter_class = snforge_std::declare("EarnReporter") + .unwrap_syscall() + .contract_class(); + let (earn_reporter_addr, _) = earn_reporter_class + .deploy(@array![owner.into()]) + .unwrap_syscall(); + earn_reporter_addr +} diff --git a/testing_utils/Scarb.toml b/testing_utils/Scarb.toml new file mode 100644 index 0000000..cd2ac04 --- /dev/null +++ b/testing_utils/Scarb.toml @@ -0,0 +1,29 @@ +[package] +name = "testing_utils" +edition.workspace = true +version.workspace = true + +[lib] + +[dependencies] +account_factory = { path = "../account_factory" } +contracts = { path = "../contracts" } +openzeppelin.workspace = true +snforge_std.workspace = true +starknet.workspace = true +starkware_utils.workspace = true +starkware_utils_testing.workspace = true + +[[target.starknet-contract]] +sierra = true + +[[test]] +name = "testing_utils_unittest" + +[profile.dev.cairo] +unstable-add-statements-functions-debug-info = true +unstable-add-statements-code-locations-debug-info = true +inlining-strategy = "avoid" + +[scripts] +test = "snforge test" diff --git a/testing_utils/src/account_factory_utils.cairo b/testing_utils/src/account_factory_utils.cairo new file mode 100644 index 0000000..77ad9a1 --- /dev/null +++ b/testing_utils/src/account_factory_utils.cairo @@ -0,0 +1,68 @@ +use account_factory::utils::{PRIMER_CLASS_HASH, compute_contract_address}; +use snforge_std::{ContractClassTrait, DeclareResultTrait}; +use starknet::eth_address::EthAddress; +use starknet::{ClassHash, ContractAddress, SyscallResultTrait}; +use starkware_utils_testing::test_utils::{ + set_account_as_app_governor, set_account_as_app_role_admin, +}; +use crate::constants::{APP_GOVERNOR, APP_ROLE_ADMIN, GOVERNANCE_ADMIN}; +use crate::dummy_contracts::declare_dummy_eth_address_contract; + +/// Mirrors AccountFactory.eth_address_to_account for tests, using the +/// PRIMER_CLASS_HASH and the account factory address as the deployer address. +pub fn eth_address_to_account( + account_factory: ContractAddress, eth_address: EthAddress, +) -> ContractAddress { + compute_contract_address( + salt: eth_address.into(), + class_hash: PRIMER_CLASS_HASH.into(), + constructor_calldata: array![].span(), + deployer_address: account_factory.into(), + ) +} + +/// Declare the `Primer` contract and return its class hash. +pub fn declare_primer_contract() -> ClassHash { + *snforge_std::declare("Primer").unwrap_syscall().contract_class().class_hash +} + +/// Sets default roles for the AccountFactory contract. +pub fn set_account_factory_default_roles(account_factory: ContractAddress) { + // App role admin + set_account_as_app_role_admin( + contract: account_factory, account: APP_ROLE_ADMIN(), governance_admin: GOVERNANCE_ADMIN(), + ); + // App governor (requires app role admin) + set_account_as_app_governor( + contract: account_factory, account: APP_GOVERNOR(), app_role_admin: APP_ROLE_ADMIN(), + ); +} + +/// Builds the constructor calldata array for AccountFactory. +pub fn account_factory_constructor_calldata() -> Array { + let governance_admin: ContractAddress = GOVERNANCE_ADMIN(); + let upgrade_delay: u64 = 0; + let account_class_hash: ClassHash = declare_dummy_eth_address_contract(); + let mut calldata: Array = array![]; + Serde::serialize(@governance_admin, ref calldata); + Serde::serialize(@upgrade_delay, ref calldata); + Serde::serialize(@account_class_hash, ref calldata); + calldata +} + +/// Sets up the AccountFactory test environment: +/// - deploys the `AccountFactory` contract, +/// - sets default roles, +/// - declares the `Primer` contract so its class hash is available. +pub fn setup_account_factory_test_env() -> ContractAddress { + let calldata = account_factory_constructor_calldata(); + let account_factory_contract = snforge_std::declare("AccountFactory") + .unwrap_syscall() + .contract_class(); + let (account_factory_contract_address, _) = account_factory_contract + .deploy(@calldata) + .unwrap_syscall(); + set_account_factory_default_roles(account_factory_contract_address); + declare_primer_contract(); + account_factory_contract_address +} diff --git a/testing_utils/src/constants.cairo b/testing_utils/src/constants.cairo new file mode 100644 index 0000000..3b3695d --- /dev/null +++ b/testing_utils/src/constants.cairo @@ -0,0 +1,13 @@ +use starknet::ContractAddress; + +pub fn APP_ROLE_ADMIN() -> ContractAddress { + 'APP_ROLE_ADMIN'.try_into().unwrap() +} + +pub fn APP_GOVERNOR() -> ContractAddress { + 'APP_GOVERNOR'.try_into().unwrap() +} + +pub fn GOVERNANCE_ADMIN() -> ContractAddress { + 'GOVERNANCE_ADMIN'.try_into().unwrap() +} diff --git a/testing_utils/src/dummy_contracts.cairo b/testing_utils/src/dummy_contracts.cairo new file mode 100644 index 0000000..8d3dd8d --- /dev/null +++ b/testing_utils/src/dummy_contracts.cairo @@ -0,0 +1,51 @@ +use snforge_std::DeclareResultTrait; +use starknet::{ClassHash, SyscallResultTrait}; + +/// Minimal no-op contract for tests: stores an EthAddress passed at construction. +#[starknet::contract] +pub mod DummyEthAddressContract { + use starknet::eth_address::EthAddress; + use starknet::secp256_trait::Signature; + + #[storage] + struct Storage {} + + #[external(v0)] + fn initialize(ref self: ContractState, eth_address: EthAddress, signature: Signature) { + return; + } +} + +/// Declare the `DummyEthAddressContract` contract and return its class hash. +pub fn declare_dummy_eth_address_contract() -> ClassHash { + *snforge_std::declare("DummyEthAddressContract").unwrap_syscall().contract_class().class_hash +} + +/// Second dummy contract with a different class hash for upgrade testing. +#[starknet::contract] +pub mod SecondDummyEthAddressContract { + use starknet::eth_address::EthAddress; + use starknet::secp256_trait::Signature; + + #[storage] + struct Storage {} + + #[constructor] + pub fn constructor(ref self: ContractState) { + // This assert is just to get a different class hash for the contract. + assert!(true, "ERROR"); + } + + #[external(v0)] + fn initialize(ref self: ContractState, eth_address: EthAddress, signature: Signature) { + return; + } +} + +/// Declare the `SecondDummyEthAddressContract` contract and return its class hash. +pub fn declare_second_dummy_eth_address_contract() -> ClassHash { + *snforge_std::declare("SecondDummyEthAddressContract") + .unwrap_syscall() + .contract_class() + .class_hash +} diff --git a/testing_utils/src/event_helpers.cairo b/testing_utils/src/event_helpers.cairo new file mode 100644 index 0000000..5afd11a --- /dev/null +++ b/testing_utils/src/event_helpers.cairo @@ -0,0 +1,46 @@ +use snforge_std::cheatcodes::events::Event; +use starknet::ContractAddress; + +/// Returns the index of the nth event whose first key equals the given selector. +pub fn find_event_index_by_selector( + events: Span<(ContractAddress, Event)>, selector: felt252, n: usize, +) -> Option { + let mut i = 0_usize; + let mut seen = 0_usize; + for (_, ev) in events { + if ev.keys.len() > 0 && *ev.keys.at(0) == selector { + if seen == n { + return Option::Some(i); + } + seen += 1; + } + i += 1; + } + None +} + +/// Returns a cloned copy of the first event emitted with the given selector (if any). +pub fn get_event_by_selector( + events: Span<(ContractAddress, Event)>, selector: felt252, +) -> Option<@(ContractAddress, Event)> { + match find_event_index_by_selector(:events, :selector, n: 0) { + Option::Some(i) => { + let (from, ev) = events.at(i); + Option::Some(@(*from, ev.clone())) + }, + None => None, + } +} + +/// Returns a cloned copy of the nth event emitted with the given selector (if any). +pub fn get_event_by_selector_n( + events: Span<(ContractAddress, Event)>, selector: felt252, n: usize, +) -> Option<@(ContractAddress, Event)> { + match find_event_index_by_selector(:events, :selector, :n) { + Option::Some(i) => { + let (from, ev) = events.at(i); + Option::Some(@(*from, ev.clone())) + }, + None => None, + } +} diff --git a/testing_utils/src/lib.cairo b/testing_utils/src/lib.cairo new file mode 100644 index 0000000..82376c2 --- /dev/null +++ b/testing_utils/src/lib.cairo @@ -0,0 +1,4 @@ +pub mod account_factory_utils; +pub mod constants; +pub mod dummy_contracts; +pub mod event_helpers; From b1e97bd7f25f7028a14c2cf89c59701d897469a3 Mon Sep 17 00:00:00 2001 From: Remo Date: Sun, 15 Feb 2026 15:35:21 +0200 Subject: [PATCH 07/10] Add explicit release settings to contracts/Scarb.toml to ensure Primer class-hash rigidness --- contracts/Scarb.toml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/contracts/Scarb.toml b/contracts/Scarb.toml index 0ea4b54..44ddcf3 100644 --- a/contracts/Scarb.toml +++ b/contracts/Scarb.toml @@ -1,12 +1,14 @@ [package] name = "contracts" -edition.workspace = true -version.workspace = true +# Pinned to ensure Primer class hash stability - do not change, is it would break PRIMER_CLASS_HASH +edition = "2024_07" +version = "0.1.0" [lib] [dependencies] -starknet.workspace = true +# Pinned to ensure Primer class hash stability - do not change, is it would break PRIMER_CLASS_HASH +starknet = "2.12.2" [dev-dependencies] snforge_std.workspace = true @@ -20,5 +22,9 @@ unstable-add-statements-functions-debug-info = true unstable-add-statements-code-locations-debug-info = true inlining-strategy = "avoid" +[profile.release.cairo] +# Explicit release settings for deterministic Primer class hash +sierra-replace-ids = true + [scripts] test = "snforge test" From 15f452e56f9961154162ba99e998e48ddd5f593b Mon Sep 17 00:00:00 2001 From: Remo Date: Sun, 15 Feb 2026 15:43:21 +0200 Subject: [PATCH 08/10] review issues --- Scarb.toml | 1 - earn_reporter/Scarb.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Scarb.toml b/Scarb.toml index b80e75f..f366b93 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -9,7 +9,6 @@ version = "0.1.0" assert_macros = "2.12.3" openzeppelin = "2.0.0" openzeppelin_upgrades = "2.0.0" -openzeppelin_testing = "3.0.0" snforge_std = "0.54.1" starknet = "2.12.2" starkware_utils = {git = "https://github.com/starkware-libs/starkware-starknet-utils", rev = "9aa2ec0b1dc1bc54bc01705cb2d4f5227e28e1e7"} diff --git a/earn_reporter/Scarb.toml b/earn_reporter/Scarb.toml index 208ba64..0f24f14 100644 --- a/earn_reporter/Scarb.toml +++ b/earn_reporter/Scarb.toml @@ -11,7 +11,6 @@ openzeppelin_upgrades.workspace = true starknet.workspace = true [dev-dependencies] -assert_macros.workspace = true snforge_std.workspace = true starkware_utils_testing.workspace = true testing_utils = { path = "../testing_utils" } From 1096b636a3d37874df02afd115befb1330248c27 Mon Sep 17 00:00:00 2001 From: Remo Date: Sun, 15 Feb 2026 17:40:49 +0200 Subject: [PATCH 09/10] use absolute imports --- account_factory/src/account_factory.cairo | 10 +++---- earn_reporter/src/earn_reporter.cairo | 2 +- earn_reporter/src/test.cairo | 10 +++---- eth_712_account/src/eth_712_account.cairo | 10 ++++--- .../src/register_interfaces_eic.cairo | 2 +- .../src/strategy_implementation.cairo | 8 ++--- strategy_implementation/src/test.cairo | 10 ++++--- strategy_implementation/src/test_utils.cairo | 30 ++++++++++--------- strategy_implementation/src/utils.cairo | 6 ++-- testing_utils/src/account_factory_utils.cairo | 4 +-- 10 files changed, 50 insertions(+), 42 deletions(-) diff --git a/account_factory/src/account_factory.cairo b/account_factory/src/account_factory.cairo index 741c7af..f273f71 100644 --- a/account_factory/src/account_factory.cairo +++ b/account_factory/src/account_factory.cairo @@ -13,6 +13,11 @@ pub trait IAccountFactory { #[starknet::contract] pub mod AccountFactory { use RolesComponent::InternalTrait as RolesInternalTrait; + use account_factory::account_factory::IAccountFactory; + use account_factory::utils::{ + IEthAccountInitializerDispatcher, IEthAccountInitializerDispatcherTrait, PRIMER_CLASS_HASH, + eth_address_to_account, is_deployed, + }; use contracts::primer::primer::{IPrimerDispatcher, IPrimerDispatcherTrait}; use core::traits::Into; use openzeppelin::access::accesscontrol::AccessControlComponent; @@ -24,11 +29,6 @@ pub mod AccountFactory { use starkware_utils::components::replaceability::ReplaceabilityComponent; use starkware_utils::components::replaceability::ReplaceabilityComponent::InternalReplaceabilityTrait; use starkware_utils::components::roles::RolesComponent; - use crate::account_factory::IAccountFactory; - use crate::utils::{ - IEthAccountInitializerDispatcher, IEthAccountInitializerDispatcherTrait, PRIMER_CLASS_HASH, - eth_address_to_account, is_deployed, - }; component!(path: RolesComponent, storage: roles, event: RolesEvent); component!(path: AccessControlComponent, storage: accesscontrol, event: accesscontrolEvent); component!(path: SRC5Component, storage: src5, event: src5Event); diff --git a/earn_reporter/src/earn_reporter.cairo b/earn_reporter/src/earn_reporter.cairo index 6888277..fd523fa 100644 --- a/earn_reporter/src/earn_reporter.cairo +++ b/earn_reporter/src/earn_reporter.cairo @@ -22,12 +22,12 @@ pub trait IEarnReporter { #[starknet::contract] pub mod EarnReporter { + use earn_reporter::earn_reporter::IEarnReporter; use openzeppelin::access::ownable::OwnableComponent; use openzeppelin::access::ownable::OwnableComponent::InternalTrait as OwnableInternalTrait; use openzeppelin_upgrades::UpgradeableComponent; use openzeppelin_upgrades::UpgradeableComponent::InternalTrait as UpgradeableInternalTrait; use starknet::{ClassHash, ContractAddress, EthAddress, get_caller_address}; - use crate::earn_reporter::IEarnReporter; component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent); diff --git a/earn_reporter/src/test.cairo b/earn_reporter/src/test.cairo index d4a1743..a2a23bc 100644 --- a/earn_reporter/src/test.cairo +++ b/earn_reporter/src/test.cairo @@ -1,13 +1,13 @@ +use earn_reporter::earn_reporter::EarnReporter::OrderCreated; +use earn_reporter::earn_reporter::{IEarnReporterDispatcher, IEarnReporterDispatcherTrait}; +use earn_reporter::test_utils::{ + declare_dummy_eth_address_contract, deploy_earn_reporter, get_event_by_selector, +}; use openzeppelin::access::ownable::interface::{IOwnableDispatcher, IOwnableDispatcherTrait}; use snforge_std::cheatcodes::events::{EventSpyTrait, EventsFilterTrait}; use starknet::syscalls::get_class_hash_at_syscall; use starknet::{ContractAddress, SyscallResultTrait, get_contract_address}; use starkware_utils_testing::test_utils::{assert_expected_event_emitted, cheat_caller_address_once}; -use crate::earn_reporter::EarnReporter::OrderCreated; -use crate::earn_reporter::{IEarnReporterDispatcher, IEarnReporterDispatcherTrait}; -use crate::test_utils::{ - declare_dummy_eth_address_contract, deploy_earn_reporter, get_event_by_selector, -}; fn default_order_created_event() -> OrderCreated { OrderCreated { diff --git a/eth_712_account/src/eth_712_account.cairo b/eth_712_account/src/eth_712_account.cairo index d17c879..70f7579 100644 --- a/eth_712_account/src/eth_712_account.cairo +++ b/eth_712_account/src/eth_712_account.cairo @@ -13,6 +13,12 @@ #[starknet::contract(account)] pub mod StarknetEth712Account { use core::num::traits::Zero; + use eth_712_account::eth_712_utils::{ + assert_valid_owner, extract_signature, get_outside_execution_hash, is_valid_signature, + }; + use eth_712_account::interface::{ + IAccount712Admin, IEICDispatcherTrait, IEICLibraryDispatcher, Upgraded, + }; use openzeppelin::account::AccountComponent; use openzeppelin::account::extensions::src9::interface::ISRC9_V2_ID; use openzeppelin::account::extensions::src9::{ISRC9_V2, OutsideExecution}; @@ -27,10 +33,6 @@ pub mod StarknetEth712Account { }; use starknet::syscalls::replace_class_syscall; use starknet::{ClassHash, EthAddress, SyscallResultTrait}; - use crate::eth_712_utils::{ - assert_valid_owner, extract_signature, get_outside_execution_hash, is_valid_signature, - }; - use crate::interface::{IAccount712Admin, IEICDispatcherTrait, IEICLibraryDispatcher, Upgraded}; component!(path: SRC5Component, storage: src5, event: SRC5Event); component!(path: AccountComponent, storage: account, event: AccountEvent); diff --git a/eth_712_account/src/register_interfaces_eic.cairo b/eth_712_account/src/register_interfaces_eic.cairo index 37fe854..ed24149 100644 --- a/eth_712_account/src/register_interfaces_eic.cairo +++ b/eth_712_account/src/register_interfaces_eic.cairo @@ -5,9 +5,9 @@ #[starknet::contract] pub mod RegisterInterfacesEIC { + use eth_712_account::interface::IEIC; use openzeppelin::introspection::src5::SRC5Component; use openzeppelin::introspection::src5::SRC5Component::InternalTrait as SRC5InternalTrait; - use crate::interface::IEIC; component!(path: SRC5Component, storage: src5, event: SRC5Event); diff --git a/strategy_implementation/src/strategy_implementation.cairo b/strategy_implementation/src/strategy_implementation.cairo index 57775d9..c05c55e 100644 --- a/strategy_implementation/src/strategy_implementation.cairo +++ b/strategy_implementation/src/strategy_implementation.cairo @@ -18,13 +18,13 @@ pub mod StrategyImplementation { use starkware_utils::components::replaceability::ReplaceabilityComponent; use starkware_utils::components::replaceability::ReplaceabilityComponent::InternalReplaceabilityTrait; use starkware_utils::components::roles::RolesComponent; - use crate::avnu_interface::AvnuParameters; - use crate::interface::{ + use strategy_implementation::avnu_interface::AvnuParameters; + use strategy_implementation::interface::{ IStrategyImplementation, IStrategyImplementationSafeDispatcher, IStrategyImplementationSafeDispatcherTrait, }; - use crate::known_addresses::MIDAS_RE7_BTC; - use crate::utils::{ + use strategy_implementation::known_addresses::MIDAS_RE7_BTC; + use strategy_implementation::utils::{ IERC4626DepositDispatcher, IERC4626DepositDispatcherTrait, Strategy, StrategyTrait, avnu_multi_route_swap, deserialize_signature, strategy_from_protocol_and_token, }; diff --git a/strategy_implementation/src/test.cairo b/strategy_implementation/src/test.cairo index 5e9e25e..bbcdf76 100644 --- a/strategy_implementation/src/test.cairo +++ b/strategy_implementation/src/test.cairo @@ -7,15 +7,15 @@ use starknet::ContractAddress; use starknet::eth_address::EthAddress; use starknet::secp256_trait::Signature; use starkware_utils_testing::test_utils::{assert_panic_with_felt_error, cheat_caller_address_once}; -use crate::interface::{ +use strategy_implementation::interface::{ IStrategyImplementationDispatcher, IStrategyImplementationDispatcherTrait, IStrategyImplementationSafeDispatcher, IStrategyImplementationSafeDispatcherTrait, }; -use crate::known_addresses::{ +use strategy_implementation::known_addresses::{ AVNU_EXCHANGE, ENDUR_TBTC, ENDUR_WBTC, FORGE_YIELDS_WBTC, LBTC, NOON_WBTC, TBTC, TROVES_TBTC, WBTC, }; -use crate::test_utils::{ +use strategy_implementation::test_utils::{ APP_GOVERNOR, ApplyParameters, IERC4626DepositMintMockDispatcher, IERC4626DepositMintMockDispatcherTrait, apply, assert_apply_failed_with_refund, assert_deposited_event, build_prefunded_apply_parameters_with_amount, @@ -27,7 +27,9 @@ use crate::test_utils::{ get_position_owner, serialize_signature, setup_strategy_implementation_test_env, validate_avnu_swap, }; -use crate::utils::{PROTOCOL_ENDUR, PROTOCOL_FORGE_YIELDS, PROTOCOL_NOON, PROTOCOL_TROVES}; +use strategy_implementation::utils::{ + PROTOCOL_ENDUR, PROTOCOL_FORGE_YIELDS, PROTOCOL_NOON, PROTOCOL_TROVES, +}; #[test] diff --git a/strategy_implementation/src/test_utils.cairo b/strategy_implementation/src/test_utils.cairo index ef5e50e..88f675b 100644 --- a/strategy_implementation/src/test_utils.cairo +++ b/strategy_implementation/src/test_utils.cairo @@ -13,6 +13,18 @@ use starkware_utils_testing::test_utils::{ assert_expected_event_emitted, cheat_caller_address_once, set_account_as_app_governor, set_account_as_app_role_admin, }; +use strategy_implementation::avnu_interface::{AvnuParameters, Route}; +use strategy_implementation::interface::{ + IStrategyImplementationDispatcher, IStrategyImplementationDispatcherTrait, +}; +use strategy_implementation::known_addresses::{AVNU_EXCHANGE, MIDAS_RE7_BTC}; +use strategy_implementation::strategy_implementation::StrategyImplementation::{ + ApplyFailed, Deposited, MultiRouteSwap, PositionOwnerDeployed, +}; +use strategy_implementation::utils::{ + PROTOCOL_AVNU, PROTOCOL_TROVES, Strategy, StrategyTrait, TokenTrait, deserialize_signature, + strategy_from_protocol_and_token, +}; pub use testing_utils::account_factory_utils::{ declare_primer_contract, eth_address_to_account, setup_account_factory_test_env, }; @@ -21,16 +33,6 @@ pub use testing_utils::dummy_contracts::declare_dummy_eth_address_contract; pub use testing_utils::event_helpers::{ find_event_index_by_selector, get_event_by_selector, get_event_by_selector_n, }; -use crate::avnu_interface::{AvnuParameters, Route}; -use crate::interface::{IStrategyImplementationDispatcher, IStrategyImplementationDispatcherTrait}; -use crate::known_addresses::{AVNU_EXCHANGE, MIDAS_RE7_BTC}; -use crate::strategy_implementation::StrategyImplementation::{ - ApplyFailed, Deposited, MultiRouteSwap, PositionOwnerDeployed, -}; -use crate::utils::{ - PROTOCOL_AVNU, PROTOCOL_TROVES, Strategy, StrategyTrait, TokenTrait, deserialize_signature, - strategy_from_protocol_and_token, -}; #[derive(Drop, Copy)] @@ -588,7 +590,7 @@ pub mod ERC4626DepositMintMock { use openzeppelin::token::erc20::{DefaultConfig, ERC20Component, ERC20HooksEmptyImpl}; use starknet::ContractAddress; use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; - use crate::test_utils::IERC4626DepositMintMock; + use strategy_implementation::test_utils::IERC4626DepositMintMock; component!(path: ERC20Component, storage: erc20, event: ERC20Event); @@ -701,7 +703,7 @@ pub(crate) fn deploy_4626_failure_mock(address_to_deploy_at: ContractAddress) { #[starknet::contract] pub mod DummyAvnu { use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; - use crate::avnu_interface::AvnuParameters; + use strategy_implementation::avnu_interface::AvnuParameters; #[storage] struct Storage {} @@ -738,7 +740,7 @@ pub(crate) fn deploy_dummy_avnu(address_to_deploy_at: ContractAddress) { #[starknet::contract] pub mod DummyAvnuFailure { use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; - use crate::avnu_interface::AvnuParameters; + use strategy_implementation::avnu_interface::AvnuParameters; #[storage] struct Storage {} @@ -773,7 +775,7 @@ pub(crate) fn deploy_dummy_avnu_failure(address_to_deploy_at: ContractAddress) { // ----------------------------------------------------------------------------- #[starknet::contract] pub mod DummyAvnuFalse { - use crate::avnu_interface::AvnuParameters; + use strategy_implementation::avnu_interface::AvnuParameters; #[storage] struct Storage {} diff --git a/strategy_implementation/src/utils.cairo b/strategy_implementation/src/utils.cairo index fd9c380..d60f721 100644 --- a/strategy_implementation/src/utils.cairo +++ b/strategy_implementation/src/utils.cairo @@ -3,8 +3,10 @@ use core::panic_with_felt252; use core::pedersen::PedersenTrait; use starknet::ContractAddress; use starknet::secp256_trait::Signature; -use crate::avnu_interface::{AvnuParameters, IAvnuDispatcher, IAvnuDispatcherTrait}; -use crate::known_addresses::{ +use strategy_implementation::avnu_interface::{ + AvnuParameters, IAvnuDispatcher, IAvnuDispatcherTrait, +}; +use strategy_implementation::known_addresses::{ AVNU_EXCHANGE, ENDUR_LBTC, ENDUR_SOLVBTC, ENDUR_TBTC, ENDUR_WBTC, FORGE_YIELDS_WBTC, LBTC, NOON_WBTC, SOLVBTC, TBTC, TROVES_LBTC, TROVES_SOLVBTC, TROVES_TBTC, TROVES_WBTC, WBTC, }; diff --git a/testing_utils/src/account_factory_utils.cairo b/testing_utils/src/account_factory_utils.cairo index 77ad9a1..9702527 100644 --- a/testing_utils/src/account_factory_utils.cairo +++ b/testing_utils/src/account_factory_utils.cairo @@ -5,8 +5,8 @@ use starknet::{ClassHash, ContractAddress, SyscallResultTrait}; use starkware_utils_testing::test_utils::{ set_account_as_app_governor, set_account_as_app_role_admin, }; -use crate::constants::{APP_GOVERNOR, APP_ROLE_ADMIN, GOVERNANCE_ADMIN}; -use crate::dummy_contracts::declare_dummy_eth_address_contract; +use testing_utils::constants::{APP_GOVERNOR, APP_ROLE_ADMIN, GOVERNANCE_ADMIN}; +use testing_utils::dummy_contracts::declare_dummy_eth_address_contract; /// Mirrors AccountFactory.eth_address_to_account for tests, using the /// PRIMER_CLASS_HASH and the account factory address as the deployer address. From a0e038b6bb60a9ea32473b89292d5a1da626639d Mon Sep 17 00:00:00 2001 From: Remo Date: Sun, 15 Feb 2026 18:42:40 +0200 Subject: [PATCH 10/10] remove tests re-export facades --- account_factory/src/lib.cairo | 2 -- account_factory/src/test.cairo | 11 ++++++----- account_factory/src/test_utils.cairo | 12 ------------ earn_reporter/src/test.cairo | 6 +++--- earn_reporter/src/test_utils.cairo | 6 ------ strategy_implementation/src/test.cairo | 13 +++++++------ strategy_implementation/src/test_utils.cairo | 15 +++------------ 7 files changed, 19 insertions(+), 46 deletions(-) delete mode 100644 account_factory/src/test_utils.cairo diff --git a/account_factory/src/lib.cairo b/account_factory/src/lib.cairo index 5375bbd..6835736 100644 --- a/account_factory/src/lib.cairo +++ b/account_factory/src/lib.cairo @@ -1,6 +1,4 @@ pub mod account_factory; #[cfg(test)] pub(crate) mod test; -#[cfg(test)] -pub mod test_utils; pub mod utils; diff --git a/account_factory/src/test.cairo b/account_factory/src/test.cairo index aaf5ce8..95a2f12 100644 --- a/account_factory/src/test.cairo +++ b/account_factory/src/test.cairo @@ -1,16 +1,17 @@ use account_factory::account_factory::AccountFactory::{AccountClassHashChanged, AccountDeployed}; use account_factory::account_factory::{IAccountFactoryDispatcher, IAccountFactoryDispatcherTrait}; -use account_factory::test_utils::{ - APP_GOVERNOR, declare_dummy_eth_address_contract, declare_second_dummy_eth_address_contract, - eth_address_to_account, get_event_by_selector, get_event_by_selector_n, - setup_account_factory_test_env, -}; use snforge_std; use snforge_std::cheatcodes::events::{EventSpyTrait, EventsFilterTrait}; use starknet::secp256_trait::Signature; use starknet::syscalls::get_class_hash_at_syscall; use starknet::{ClassHash, ContractAddress, EthAddress, SyscallResultTrait}; use starkware_utils_testing::test_utils::{assert_expected_event_emitted, cheat_caller_address_once}; +use testing_utils::account_factory_utils::{eth_address_to_account, setup_account_factory_test_env}; +use testing_utils::constants::APP_GOVERNOR; +use testing_utils::dummy_contracts::{ + declare_dummy_eth_address_contract, declare_second_dummy_eth_address_contract, +}; +use testing_utils::event_helpers::{get_event_by_selector, get_event_by_selector_n}; fn deploy_account_wrapper( diff --git a/account_factory/src/test_utils.cairo b/account_factory/src/test_utils.cairo deleted file mode 100644 index 34f5cd2..0000000 --- a/account_factory/src/test_utils.cairo +++ /dev/null @@ -1,12 +0,0 @@ -// Re-export shared testing utilities from the testing_utils package. -pub use testing_utils::account_factory_utils::{ - account_factory_constructor_calldata, declare_primer_contract, eth_address_to_account, - set_account_factory_default_roles, setup_account_factory_test_env, -}; -pub use testing_utils::constants::{APP_GOVERNOR, APP_ROLE_ADMIN, GOVERNANCE_ADMIN}; -pub use testing_utils::dummy_contracts::{ - declare_dummy_eth_address_contract, declare_second_dummy_eth_address_contract, -}; -pub use testing_utils::event_helpers::{ - find_event_index_by_selector, get_event_by_selector, get_event_by_selector_n, -}; diff --git a/earn_reporter/src/test.cairo b/earn_reporter/src/test.cairo index a2a23bc..211a139 100644 --- a/earn_reporter/src/test.cairo +++ b/earn_reporter/src/test.cairo @@ -1,13 +1,13 @@ use earn_reporter::earn_reporter::EarnReporter::OrderCreated; use earn_reporter::earn_reporter::{IEarnReporterDispatcher, IEarnReporterDispatcherTrait}; -use earn_reporter::test_utils::{ - declare_dummy_eth_address_contract, deploy_earn_reporter, get_event_by_selector, -}; +use earn_reporter::test_utils::deploy_earn_reporter; use openzeppelin::access::ownable::interface::{IOwnableDispatcher, IOwnableDispatcherTrait}; use snforge_std::cheatcodes::events::{EventSpyTrait, EventsFilterTrait}; use starknet::syscalls::get_class_hash_at_syscall; use starknet::{ContractAddress, SyscallResultTrait, get_contract_address}; use starkware_utils_testing::test_utils::{assert_expected_event_emitted, cheat_caller_address_once}; +use testing_utils::dummy_contracts::declare_dummy_eth_address_contract; +use testing_utils::event_helpers::get_event_by_selector; fn default_order_created_event() -> OrderCreated { OrderCreated { diff --git a/earn_reporter/src/test_utils.cairo b/earn_reporter/src/test_utils.cairo index d3a7419..87ccde5 100644 --- a/earn_reporter/src/test_utils.cairo +++ b/earn_reporter/src/test_utils.cairo @@ -1,11 +1,5 @@ -// Re-export shared testing utilities from the testing_utils package. - -// Package-specific helpers - use snforge_std::{ContractClassTrait, DeclareResultTrait}; use starknet::{ContractAddress, SyscallResultTrait}; -pub use testing_utils::dummy_contracts::declare_dummy_eth_address_contract; -pub use testing_utils::event_helpers::{find_event_index_by_selector, get_event_by_selector}; /// Deploy the EarnReporter contract and return its address. pub(crate) fn deploy_earn_reporter(owner: ContractAddress) -> ContractAddress { diff --git a/strategy_implementation/src/test.cairo b/strategy_implementation/src/test.cairo index bbcdf76..d8cc469 100644 --- a/strategy_implementation/src/test.cairo +++ b/strategy_implementation/src/test.cairo @@ -16,20 +16,21 @@ use strategy_implementation::known_addresses::{ WBTC, }; use strategy_implementation::test_utils::{ - APP_GOVERNOR, ApplyParameters, IERC4626DepositMintMockDispatcher, - IERC4626DepositMintMockDispatcherTrait, apply, assert_apply_failed_with_refund, - assert_deposited_event, build_prefunded_apply_parameters_with_amount, + ApplyParameters, IERC4626DepositMintMockDispatcher, IERC4626DepositMintMockDispatcherTrait, + apply, assert_apply_failed_with_refund, assert_deposited_event, + build_prefunded_apply_parameters_with_amount, build_prefunded_apply_parameters_with_token_address, build_prefunded_avnu, cheat_transfer_and_approve, deploy_4626_failure_mock, deploy_and_prefund_dummy_erc20_at, deploy_dummy_avnu, deploy_dummy_avnu_failure, deploy_dummy_avnu_false, deploy_earn_reporter, deploy_erc4626_deposit_mint_mock, deploy_mock_erc20_contract_at, dummy_apply_parameters, - dummy_apply_parameters_with_protocol, get_account_factory, get_event_by_selector, - get_position_owner, serialize_signature, setup_strategy_implementation_test_env, - validate_avnu_swap, + dummy_apply_parameters_with_protocol, get_account_factory, get_position_owner, + serialize_signature, setup_strategy_implementation_test_env, validate_avnu_swap, }; use strategy_implementation::utils::{ PROTOCOL_ENDUR, PROTOCOL_FORGE_YIELDS, PROTOCOL_NOON, PROTOCOL_TROVES, }; +use testing_utils::constants::APP_GOVERNOR; +use testing_utils::event_helpers::get_event_by_selector; #[test] diff --git a/strategy_implementation/src/test_utils.cairo b/strategy_implementation/src/test_utils.cairo index 88f675b..9e4d3c0 100644 --- a/strategy_implementation/src/test_utils.cairo +++ b/strategy_implementation/src/test_utils.cairo @@ -1,7 +1,3 @@ -// Re-export shared testing utilities from the testing_utils package. - -// Package-specific helpers - use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; use snforge_std::cheatcodes::events::Event; use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl}; @@ -25,14 +21,9 @@ use strategy_implementation::utils::{ PROTOCOL_AVNU, PROTOCOL_TROVES, Strategy, StrategyTrait, TokenTrait, deserialize_signature, strategy_from_protocol_and_token, }; -pub use testing_utils::account_factory_utils::{ - declare_primer_contract, eth_address_to_account, setup_account_factory_test_env, -}; -pub use testing_utils::constants::{APP_GOVERNOR, APP_ROLE_ADMIN, GOVERNANCE_ADMIN}; -pub use testing_utils::dummy_contracts::declare_dummy_eth_address_contract; -pub use testing_utils::event_helpers::{ - find_event_index_by_selector, get_event_by_selector, get_event_by_selector_n, -}; +use testing_utils::account_factory_utils::{eth_address_to_account, setup_account_factory_test_env}; +use testing_utils::constants::{APP_GOVERNOR, APP_ROLE_ADMIN, GOVERNANCE_ADMIN}; +use testing_utils::event_helpers::get_event_by_selector; #[derive(Drop, Copy)]