Testing

This crate provides various helper functions for declaring, deploying, and testing smart contracts using the snforge toolchain from Starknet Foundry.

use openzeppelin_testing;

The module isn’t part of the openzeppelin package and to be accessible has to be added as a separate dependency in Scarb.toml:

[dev-dependencies]
openzeppelin_testing = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.17.0" }

Test Utilities

common

A module providing common test helpers.

use openzeppelin_testing::common;

Functions

panic_data_to_byte_array(panic_data: Array<felt252>) → ByteArray function

Converts panic data into a string (ByteArray).

panic_data is expected to be a valid serialized ByteArray with an extra felt252 at the beginning, which is the BYTE_ARRAY_MAGIC.

to_base_16_string(value: felt252) → ByteArray function

Converts a felt252 to a base16 string padded to 66 characters (including the 0x prefix).

to_base_16_string_no_padding(value: felt252) → ByteArray function

Converts a felt252 to a base16 (hexadecimal) string without padding, but including the 0x prefix.

assert_entrypoint_not_found_error<T, +Drop<T>>(result: SyscallResult<T>, selector: felt252, contract_address: ContractAddress) function

Asserts that the syscall result of a call failed with an "Entrypoint not found" error, following the Starknet Foundry emitted error format.

Traits

IntoBase16StringTrait trait

A helper trait that enables a value to be represented as a base16(hexadecimal) string padded to 66 characters (including the 0x prefix). The type of the value must implement Into<T, felt252> to be convertible to felt252.

Usage example:

use openzeppelin_testing::common::IntoBase16String;

let expected_panic_message = format!(
    "Entry point selector {} not found in contract {}",
    selector.into_base_16_string(),
    contract_address.into_base_16_string()
);
The no-padding version can be used in the same way by calling selector.into_base_16_string_no_padding().

deployment

use openzeppelin_testing::deployment;

A module containing utilities that simplify declaring and deploying contracts using the snforge toolchain.

Functions

declare_class(contract_name: ByteArray) → ContractClass function

Declares a contract with a snforge_std::declare call and unwraps the result. This function will skip declaration and just return the ContractClass if the contract is already declared (the result of snforge_std::declare call is of type DeclareResult::AlreadyDeclared).

deploy(contract_class: ContractClass, calldata: Array<felt252>) → ContractAddress function

Deploys an instance of a contract and unwraps the result.

deploy_at(contract_class: ContractClass, target_address: ContractAddress, calldata: Array<felt252>) function

Deploys an instance of a contract at a given address.

deploy_another_at(existing: ContractAddress, target_address: ContractAddress, calldata: Array<felt252>) function

Deploys a contract using the class hash from another already-deployed contract.

Note that currently, snforge does not support redeclaring a contract class. Consequently, there is no direct method to deploy a second instance of a contract if neither its ContractClass nor its class_hash is available in the context. This helper function provides a solution by retrieving the class hash from an existing contract and using it to facilitate the deployment.

use openzeppelin_testing::deploy_another_at;

let alice_address = setup_account(array!['ALICE_PUBKEY']);
let bob_address = contract_address_const::<'BOB'>();
deploy_another_at(alice_address, bob_address, array!['BOB_PUBKEY']);

declare_and_deploy(contract_name: ByteArray, calldata: Array<felt252>) → ContractAddress function

Combines the declaration of a class and the deployment of a contract into one function call. This function will skip declaration if the contract is already declared (the result of snforge_std::declare call is of type DeclareResult::AlreadyDeclared).

declare_and_deploy_at(contract_name: ByteArray, target_address: ContractAddress, calldata: Array<felt252>) function

Combines the declaration of a class and the deployment of a contract at the given address into one function call. This function will skip declaration if the contract is already declared (the result of snforge_std::declare call is of type DeclareResult::AlreadyDeclared).

events

use openzeppelin_testing::events;
use openzeppelin_testing::events::EventSpyExt;

A module offering an extended set of functions for handling emitted events, enhancing the default event utilities provided by snforge. These functions are accessible via the EventSpyExt trait implemented on the EventSpy struct.

Functions

assert_only_event<T, +starknet::Event<T>, +Drop<T>>(ref self: EventSpy, from_address: ContractAddress, expected_event: T) function

Ensures that from_address has emitted only the expected_event and no additional events.

assert_emitted_single<T, +starknet::Event<T>, +Drop<T>>(ref self: EventSpy, from_address: ContractAddress, expected_event: T) function

Ensures that from_address has emitted the expected_event.

drop_event(ref self: EventSpy) function

Removes a single event from the queue. If the queue is empty, the function will panic.

drop_n_events(ref self: EventSpy, number_to_drop: u32) function

Removes number_to_drop events from the queue. If the queue is empty, the function will panic.

drop_all_events(ref self: EventSpy) function

Removes all events remaining on the queue. If the queue is empty already, the function will do nothing.

assert_no_events_left(ref self: EventSpy) function

Ensures that there are no events remaining on the queue.

assert_no_events_left_from(ref self: EventSpy, from_address: ContractAddress) function

Ensures that there are no events emitted from the given address remaining on the queue.

count_events_from(ref self: EventSpy, from_address: ContractAddress) → u32 function

Counts the number of remaining events emitted from the given address.

signing

use openzeppelin_testing::signing;

A module offering utility functions for easier management of key pairs and signatures.

Functions

get_stark_keys_from(private_key: felt252) → StarkKeyPair function

Builds a Stark key pair from a private key represented by a felt252 value.

get_secp256k1_keys_from(private_key: u256) → Secp256k1KeyPair function

Builds a Secp256k1 key pair from a private key represented by a u256 value.

Traits

SerializedSigning trait

A helper trait that facilitates signing and converting the result signature into a serialized format.

Usage example:

use openzeppelin_testing::signing::{
    StarkKeyPair, get_stark_keys_from, StarkSerializedSigning
};

let key_pair = get_stark_keys_from('SECRET_KEY');
let serialized_signature = key_pair.serialized_sign('TX_HASH');