Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/on-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
56 changes: 55 additions & 1 deletion Scarb.lock
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
# 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",
"testing_utils",
]

[[package]]
name = "contracts"
version = "0.1.0"
dependencies = [
"snforge_std",
"starkware_utils_testing",
]

[[package]]
name = "earn_reporter"
version = "0.1.0"
dependencies = [
"openzeppelin",
"openzeppelin_upgrades",
"snforge_std",
"starkware_utils",
"starkware_utils_testing",
"testing_utils",
]

[[package]]
name = "eth_712_account"
version = "0.1.0"
dependencies = [
"openzeppelin",
"snforge_std",
]

[[package]]
Expand Down Expand Up @@ -162,3 +190,29 @@ 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",
"testing_utils",
]

[[package]]
name = "testing_utils"
version = "0.1.0"
dependencies = [
"account_factory",
"contracts",
"openzeppelin",
"snforge_std",
"starkware_utils",
"starkware_utils_testing",
]
3 changes: 1 addition & 2 deletions Scarb.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["contracts"]
members = ["contracts", "eth_712_account", "account_factory", "earn_reporter", "strategy_implementation", "testing_utils"]

[workspace.package]
edition = "2024_07"
Expand All @@ -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"}
Expand Down
37 changes: 37 additions & 0 deletions account_factory/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[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
testing_utils = { path = "../testing_utils" }

[[target.starknet-contract]]
sierra = true

[[test]]
build-external-contracts = [
"contracts::primer::primer::Primer",
"testing_utils::dummy_contracts::DummyEthAddressContract",
"testing_utils::dummy_contracts::SecondDummyEthAddressContract",
]
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"
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ pub trait IAccountFactory<TContractState> {
#[starknet::contract]
pub mod AccountFactory {
use RolesComponent::InternalTrait as RolesInternalTrait;
use contracts::account_factory::account_factory::IAccountFactory;
use contracts::account_factory::utils::{
use account_factory::account_factory::IAccountFactory;
use account_factory::utils::{
IEthAccountInitializerDispatcher, IEthAccountInitializerDispatcherTrait, PRIMER_CLASS_HASH,
eth_address_to_account, is_deployed,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod account_factory;
#[cfg(test)]
pub mod test;
pub(crate) mod test;
pub mod utils;
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
use account_factory::account_factory::AccountFactory::{AccountClassHashChanged, AccountDeployed};
use account_factory::account_factory::{IAccountFactoryDispatcher, IAccountFactoryDispatcherTrait};
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 crate::account_factory::account_factory::AccountFactory::{
AccountClassHashChanged, AccountDeployed,
};
use crate::account_factory::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,
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(
Expand Down Expand Up @@ -286,4 +283,3 @@ fn test_change_account_class_hash_affects_only_new_users() {
"original account should keep its original class hash",
);
}

Original file line number Diff line number Diff line change
Expand Up @@ -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 =
0x279a9bb18604f4ae57633373d56656063203f236cc5aeceea8f2cf40f6336d7
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();

Expand All @@ -26,6 +26,7 @@ pub(crate) trait IEthAccountInitializer<TContractState> {
}

/// 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>) -> felt252 {
let mut state = PedersenTrait::new(0);
for value in data {
Expand Down Expand Up @@ -72,4 +73,3 @@ pub fn compute_contract_address(
pub fn is_deployed(addr: ContractAddress) -> bool {
get_class_hash_at_syscall(addr).unwrap_syscall() != Zero::zero()
}

32 changes: 13 additions & 19 deletions contracts/Scarb.toml
Original file line number Diff line number Diff line change
@@ -1,36 +1,30 @@
[package]
edition.workspace = true
name = "contracts"
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]
openzeppelin.workspace = true
openzeppelin_upgrades.workspace = true
starknet.workspace = true
starkware_utils.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]
assert_macros.workspace = true
snforge_std.workspace = true
starkware_utils_testing.workspace = true

[[target.starknet-contract]]
sierra = true

[scripts]
Comment thread
cursor[bot] marked this conversation as resolved.
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
unstable-add-statements-code-locations-debug-info = true
inlining-strategy = "avoid"

[profile.release.cairo]
inlining-strategy = 30
# Explicit release settings for deterministic Primer class hash
sierra-replace-ids = true

[[test]]
build-external-contracts = ["starkware_utils::erc20::erc20_mocks::DualCaseERC20Mock"]
name = "contracts_unittest"
[scripts]
test = "snforge test"
Comment thread
cursor[bot] marked this conversation as resolved.
3 changes: 0 additions & 3 deletions contracts/src/earn_reporter.cairo

This file was deleted.

8 changes: 2 additions & 6 deletions contracts/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
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;
mod test;
2 changes: 0 additions & 2 deletions contracts/src/primer.cairo
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
pub mod primer;
#[cfg(test)]
pub mod test;
39 changes: 25 additions & 14 deletions contracts/src/primer/test.cairo → contracts/src/test.cairo
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
use snforge_std::{ContractClassTrait, DeclareResultTrait, TokenImpl};
use starknet::get_contract_address;
use contracts::primer::primer::{IPrimerDispatcher, IPrimerDispatcherTrait};
use snforge_std::{ContractClassTrait, DeclareResultTrait};
use starknet::syscalls::get_class_hash_at_syscall;
use crate::primer::primer::{IPrimerDispatcher, IPrimerDispatcherTrait};
use crate::test_utils::declare_dummy_eth_address_contract;
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_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'.
Expand All @@ -14,16 +26,16 @@ fn test_primer_update_class_hash_invalid_caller() {

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(
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);
let test_class_hash = declare_dummy_upgrade_target();
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();
Expand All @@ -32,12 +44,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();
starkware_utils_testing::test_utils::cheat_caller_address_once(
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: 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");
}

Loading