Repository: OpenZeppelin/cairo-contracts (language: python)

Issue:
Upgrade starknet foundry to 0.30.0
**🧐 Motivation**
This enables some features like coverage that we want to use.

**📝 Details**
https://github.com/foundry-rs/starknet-foundry/releases/tag/v0.30.0




Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 44a37440f..5a32896ab 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## Unreleased
 
+### Added
+
+- `into_base_16_string_no_padding` function to the test helpers (#1137)
+
+### Changed
+
+- Bump scarb to v2.8.2 (#1137)
+- Bump snforge to 0.30.0 (#1137)
+- `declare_class`, `declare_and_deploy`, and `declare_and_deploy_at` will skip declaration if the contract is already declared (#1137)
+
 ## 0.16.0 (2024-08-30)
 
 ### Added
diff --git a/Scarb.lock b/Scarb.lock
index 2d8a6207c..517b346d8 100644
--- a/Scarb.lock
+++ b/Scarb.lock
@@ -137,7 +137,17 @@ dependencies = [
  "snforge_std",
 ]
 
+[[package]]
+name = "snforge_scarb_plugin"
+version = "0.2.0"
+source = "registry+https://scarbs.xyz/"
+checksum = "sha256:2e4ce3ebe3f49548bd26908391b5d78537a765d827df0d96c32aeb88941d0d67"
+
 [[package]]
 name = "snforge_std"
-version = "0.27.0"
-source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.27.0#2d99b7c00678ef0363881ee0273550c44a9263de"
+version = "0.30.0"
+source = "registry+https://scarbs.xyz/"
+checksum = "sha256:2f3c4846881813ac0f5d1460981249c9f5e2a6831e752beedf9b70975495b4ec"
+dependencies = [
+ "snforge_scarb_plugin",
+]
diff --git a/Scarb.toml b/Scarb.toml
index 70c4b56a0..e5b802347 100644
--- a/Scarb.toml
+++ b/Scarb.toml
@@ -21,8 +21,8 @@ version.workspace = true
 [workspace.package]
 version = "0.16.0"
 edition = "2023_11"
-cairo-version = "2.8.0"
-scarb-version = "2.8.0"
+cairo-version = "2.8.2"
+scarb-version = "2.8.2"
 authors = ["OpenZeppelin Community <maintainers@openzeppelin.org>"]
 description = "OpenZeppelin Contracts written in Cairo for Starknet, a decentralized ZK Rollup"
 documentation = "https://docs.openzeppelin.com/contracts-cairo"
@@ -39,8 +39,9 @@ keywords = [
 ]
 
 [workspace.dependencies]
-starknet = "2.8.0"
-snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.27.0" }
+assert_macros = "2.8.2"
+starknet = "2.8.2"
+snforge_std = "0.30.0"
 
 [dependencies]
 starknet.workspace = true
@@ -56,6 +57,7 @@ openzeppelin_upgrades = { path = "packages/upgrades" }
 openzeppelin_utils = { path = "packages/utils" }
 
 [dev-dependencies]
+assert_macros.workspace = true
 snforge_std.workspace = true
 openzeppelin_test_common = { path = "packages/test_common" }
 openzeppelin_testing = { path = "packages/testing" }
diff --git a/packages/access/Scarb.toml b/packages/access/Scarb.toml
index ab2a11fcf..5b1cc7a09 100644
--- a/packages/access/Scarb.toml
+++ b/packages/access/Scarb.toml
@@ -21,6 +21,7 @@ openzeppelin_introspection = { path = "../introspection" }
 openzeppelin_utils = { path = "../utils" }
 
 [dev-dependencies]
+assert_macros.workspace = true
 snforge_std.workspace = true
 openzeppelin_testing = { path = "../testing" }
 openzeppelin_test_common = { path = "../test_common" }
diff --git a/packages/account/Scarb.toml b/packages/account/Scarb.toml
index 6b1734a83..5ffc0d3de 100644
--- a/packages/account/Scarb.toml
+++ b/packages/account/Scarb.toml
@@ -21,6 +21,7 @@ openzeppelin_introspection = { path = "../introspection" }
 openzeppelin_utils = { path = "../utils" }
 
 [dev-dependencies]
+assert_macros.workspace = true
 snforge_std.workspace = true
 openzeppelin_testing = { path = "../testing" }
 openzeppelin_test_common = { path = "../test_common" }
diff --git a/packages/governance/Scarb.toml b/packages/governance/Scarb.toml
index 644641f1d..d4aa583c7 100644
--- a/packages/governance/Scarb.toml
+++ b/packages/governance/Scarb.toml
@@ -21,6 +21,7 @@ openzeppelin_access = { path = "../access" }
 openzeppelin_introspection = { path = "../introspection" }
 
 [dev-dependencies]
+assert_macros.workspace = true
 snforge_std.workspace = true
 openzeppelin_testing = { path = "../testing" }
 
diff --git a/packages/introspection/Scarb.toml b/packages/introspection/Scarb.toml
index 1ccc1aae8..bac107178 100644
--- a/packages/introspection/Scarb.toml
+++ b/packages/introspection/Scarb.toml
@@ -20,6 +20,7 @@ fmt.workspace = true
 starknet.workspace = true
 
 [dev-dependencies]
+assert_macros.workspace = true
 snforge_std.workspace = true
 
 [lib]
diff --git a/packages/merkle_tree/Scarb.toml b/packages/merkle_tree/Scarb.toml
index 39472084f..e0307a82b 100644
--- a/packages/merkle_tree/Scarb.toml
+++ b/packages/merkle_tree/Scarb.toml
@@ -17,5 +17,6 @@ keywords.workspace = true
 fmt.workspace = true
 
 [dev-dependencies]
+assert_macros.workspace = true
 starknet.workspace = true
 snforge_std.workspace = true
diff --git a/packages/presets/Scarb.toml b/packages/presets/Scarb.toml
index 1d1c033e2..34f42bfd7 100644
--- a/packages/presets/Scarb.toml
+++ b/packages/presets/Scarb.toml
@@ -25,6 +25,7 @@ openzeppelin_token = { path = "../token" }
 openzeppelin_upgrades = { path = "../upgrades" }
 
 [dev-dependencies]
+assert_macros.workspace = true
 snforge_std.workspace = true
 openzeppelin_testing = { path = "../testing" }
 openzeppelin_test_common = { path = "../test_common" }
diff --git a/packages/security/Scarb.toml b/packages/security/Scarb.toml
index eb7e70541..6d1e00e95 100644
--- a/packages/security/Scarb.toml
+++ b/packages/security/Scarb.toml
@@ -20,6 +20,7 @@ fmt.workspace = true
 starknet.workspace = true
 
 [dev-dependencies]
+assert_macros.workspace = true
 snforge_std.workspace = true
 openzeppelin_testing = { path = "../testing" }
 
diff --git a/packages/token/Scarb.toml b/packages/token/Scarb.toml
index 57734bfe1..8b01e1113 100644
--- a/packages/token/Scarb.toml
+++ b/packages/token/Scarb.toml
@@ -23,6 +23,7 @@ openzeppelin_introspection = { path = "../introspection" }
 openzeppelin_governance = { path = "../governance" }
 
 [dev-dependencies]
+assert_macros.workspace = true
 snforge_std.workspace = true
 openzeppelin_testing = { path = "../testing" }
 openzeppelin_test_common = { path = "../test_common" }
diff --git a/packages/upgrades/Scarb.toml b/packages/upgrades/Scarb.toml
index 6acd5002b..284bce89e 100644
--- a/packages/upgrades/Scarb.toml
+++ b/packages/upgrades/Scarb.toml
@@ -20,6 +20,7 @@ fmt.workspace = true
 starknet.workspace = true
 
 [dev-dependencies]
+assert_macros.workspace = true
 snforge_std.workspace = true
 openzeppelin_testing = { path = "../testing" }
 openzeppelin_test_common = { path = "../test_common" }
diff --git a/packages/utils/Scarb.toml b/packages/utils/Scarb.toml
index 1fe7d7efa..d22433360 100644
--- a/packages/utils/Scarb.toml
+++ b/packages/utils/Scarb.toml
@@ -20,6 +20,7 @@ fmt.workspace = true
 starknet.workspace = true
 
 [dev-dependencies]
+assert_macros.workspace = true
 snforge_std.workspace = true
 openzeppelin_testing = { path = "../testing" }
 


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index c7d113639..0ac13b10a 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -21,7 +21,7 @@ jobs:
         scarb-version: ${{ env.SCARB_VERSION }}
     - name: Extract foundry version
       run: |
-        FOUNDRY_VERSION=$(grep 'snforge_std = ' Scarb.toml | sed 's/snforge_std = .\+ tag = "v\(.*\)".*/\1/')
+        FOUNDRY_VERSION=$(grep 'snforge_std = ' Scarb.toml | sed 's/snforge_std = "\(.*\)"/\1/')
         echo "FOUNDRY_VERSION=$FOUNDRY_VERSION" >> "$GITHUB_ENV"
     - uses: foundry-rs/setup-snfoundry@v3
       with:
diff --git a/docs/modules/ROOT/pages/api/testing.adoc b/docs/modules/ROOT/pages/api/testing.adoc
index 17f09ec99..e5d017db8 100644
--- a/docs/modules/ROOT/pages/api/testing.adoc
+++ b/docs/modules/ROOT/pages/api/testing.adoc
@@ -73,8 +73,8 @@ following the Starknet Foundry emitted error format.
 [[testing-common-IntoBase16StringTrait]]
 ==== `[.contract-item-name]#++IntoBase16StringTrait++#` [.item-kind]#trait#
 
-A helper trait that enables a value to be represented as a `base16` string padded to 66 characters
-(including the `0x` prefix). The type of the value must implement `Into<T, felt252>` to be
+A helper trait that enables a value to be represented as a `base16`(hexadecimal) string padded to 66 characters
+(including the `0x` prefix). There's also a version with no padding for compatibility with Starknet Foundry `0.28.0` and above, where addresses and selectors are not padded properly. The type of the value must implement `Into<T, felt252>` to be
 convertible to `felt252`.
 
 Usage example:
@@ -118,7 +118,7 @@ A module containing utilities that simplify declaring and deploying contracts us
 [[testing-deployment-declare_class]]
 ==== `[.contract-item-name]#++declare_class++#++(contract_name: ByteArray) → ContractClass++` [.item-kind]#function#
 
-Declares a contract with a `snforge` `declare` call and unwraps the result.
+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`).
 
 [.contract-item]
 [[testing-deployment-deploy]]
@@ -155,13 +155,13 @@ deploy_another_at(alice_address, bob_address, array!['BOB_PUBKEY']);
 [[testing-deployment-declare_and_deploy]]
 ==== `[.contract-item-name]#++declare_and_deploy++#++(contract_name: ByteArray, calldata: Array<felt252>) → ContractAddress++` [.item-kind]#function#
 
-Combines the declaration of a class and the deployment of a contract into one function call.
+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`).
 
 [.contract-item]
 [[testing-deployment-declare_and_deploy_at]]
 ==== `[.contract-item-name]#++declare_and_deploy_at++#++(contract_name: ByteArray, target_address: ContractAddress, calldata: Array<felt252>)++` [.item-kind]#function#
 
-Combines the declaration of a class and the deployment of a contract at the given address into one function call.
+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`).
 
 [.contract]
 [[testing-events]]
diff --git a/packages/access/src/tests/test_dual_accesscontrol.cairo b/packages/access/src/tests/test_dual_accesscontrol.cairo
index d5b8057b3..8c1032266 100644
--- a/packages/access/src/tests/test_dual_accesscontrol.cairo
+++ b/packages/access/src/tests/test_dual_accesscontrol.cairo
@@ -68,7 +68,7 @@ fn test_dual_no_supports_interface() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_supports_interface_exists_and_panics() {
     let (snake_dispatcher, _) = setup_accesscontrol_panic();
     snake_dispatcher.supports_interface(IACCESSCONTROL_ID);
@@ -90,7 +90,7 @@ fn test_dual_no_has_role() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_has_role_exists_and_panics() {
     let (dispatcher, _) = setup_accesscontrol_panic();
     dispatcher.has_role(DEFAULT_ADMIN_ROLE, ADMIN());
@@ -112,7 +112,7 @@ fn test_dual_no_get_role_admin() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_get_role_admin_exists_and_panics() {
     let (snake_dispatcher, _) = setup_accesscontrol_panic();
     snake_dispatcher.get_role_admin(ROLE);
@@ -137,7 +137,7 @@ fn test_dual_no_grant_role() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_grant_role_exists_and_panics() {
     let (snake_dispatcher, _) = setup_accesscontrol_panic();
     snake_dispatcher.grant_role(ROLE, AUTHORIZED());
@@ -162,7 +162,7 @@ fn test_dual_no_revoke_role() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_revoke_role_exists_and_panics() {
     let (snake_dispatcher, _) = setup_accesscontrol_panic();
     snake_dispatcher.revoke_role(ROLE, AUTHORIZED());
@@ -187,7 +187,7 @@ fn test_dual_no_renounce_role() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_renounce_role_exists_and_panics() {
     let (snake_dispatcher, _) = setup_accesscontrol_panic();
     snake_dispatcher.renounce_role(DEFAULT_ADMIN_ROLE, ADMIN());
@@ -208,7 +208,7 @@ fn test_dual_hasRole() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_hasRole_exists_and_panics() {
     let (_, camel_dispatcher) = setup_accesscontrol_panic();
     camel_dispatcher.has_role(DEFAULT_ADMIN_ROLE, ADMIN());
@@ -225,7 +225,7 @@ fn test_dual_getRoleAdmin() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_getRoleAdmin_exists_and_panics() {
     let (_, camel_dispatcher) = setup_accesscontrol_panic();
     camel_dispatcher.get_role_admin(ROLE);
@@ -244,7 +244,7 @@ fn test_dual_grantRole() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_grantRole_exists_and_panics() {
     let (_, camel_dispatcher) = setup_accesscontrol_panic();
     camel_dispatcher.grant_role(ROLE, AUTHORIZED());
@@ -264,7 +264,7 @@ fn test_dual_revokeRole() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_revokeRole_exists_and_panics() {
     let (_, camel_dispatcher) = setup_accesscontrol_panic();
     camel_dispatcher.revoke_role(ROLE, AUTHORIZED());
@@ -283,7 +283,7 @@ fn test_dual_renounceRole() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_renounceRole_exists_and_panics() {
     let (_, camel_dispatcher) = setup_accesscontrol_panic();
     camel_dispatcher.renounce_role(DEFAULT_ADMIN_ROLE, ADMIN());
diff --git a/packages/access/src/tests/test_dual_ownable.cairo b/packages/access/src/tests/test_dual_ownable.cairo
index 19363d830..97d737032 100644
--- a/packages/access/src/tests/test_dual_ownable.cairo
+++ b/packages/access/src/tests/test_dual_ownable.cairo
@@ -69,7 +69,7 @@ fn test_dual_no_owner() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_owner_exists_and_panics() {
     let (dispatcher, _) = setup_ownable_panic();
     dispatcher.owner();
@@ -98,7 +98,7 @@ fn test_dual_no_transfer_ownership() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_transfer_ownership_exists_and_panics() {
     let (dispatcher, _) = setup_ownable_panic();
     dispatcher.transfer_ownership(NEW_OWNER());
@@ -123,7 +123,7 @@ fn test_dual_no_renounce_ownership() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_renounce_ownership_exists_and_panics() {
     let (dispatcher, _) = setup_ownable_panic();
     dispatcher.renounce_ownership();
@@ -146,7 +146,7 @@ fn test_dual_transferOwnership() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_transferOwnership_exists_and_panics() {
     let (_, camel_dispatcher) = setup_ownable_panic();
     camel_dispatcher.transfer_ownership(NEW_OWNER());
@@ -165,7 +165,7 @@ fn test_dual_renounceOwnership() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_renounceOwnership_exists_and_panics() {
     let (_, camel_dispatcher) = setup_ownable_panic();
     camel_dispatcher.renounce_ownership();
diff --git a/packages/account/src/tests/test_account.cairo b/packages/account/src/tests/test_account.cairo
index 188d69c88..9b906e756 100644
--- a/packages/account/src/tests/test_account.cairo
+++ b/packages/account/src/tests/test_account.cairo
@@ -1,5 +1,4 @@
 use core::num::traits::Zero;
-use core::starknet::SyscallResultTrait;
 use crate::AccountComponent::{InternalTrait, SRC6CamelOnlyImpl};
 use crate::AccountComponent::{PublicKeyCamelImpl, PublicKeyImpl};
 use crate::AccountComponent;
@@ -20,7 +19,7 @@ use snforge_std::{
     start_cheat_signature_global, start_cheat_transaction_version_global,
     start_cheat_transaction_hash_global
 };
-use snforge_std::{spy_events, declare, test_address, start_cheat_caller_address};
+use snforge_std::{spy_events, test_address, start_cheat_caller_address};
 use starknet::account::Call;
 
 //
@@ -46,7 +45,8 @@ fn setup(key_pair: StarkKeyPair) -> ComponentState {
 fn setup_dispatcher(
     key_pair: StarkKeyPair, data: SignedTransactionData
 ) -> (AccountABIDispatcher, felt252) {
-    let contract_class = declare("DualCaseAccountMock").unwrap_syscall();
+    let contract_class = utils::declare_class("DualCaseAccountMock");
+
     let calldata = array![key_pair.public_key];
     let address = utils::deploy(contract_class, calldata);
     let dispatcher = AccountABIDispatcher { contract_address: address };
diff --git a/packages/account/src/tests/test_dual_account.cairo b/packages/account/src/tests/test_dual_account.cairo
index fd26006ba..467f0878e 100644
--- a/packages/account/src/tests/test_dual_account.cairo
+++ b/packages/account/src/tests/test_dual_account.cairo
@@ -69,7 +69,7 @@ fn test_dual_no_set_public_key() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_set_public_key_exists_and_panics() {
     let (snake_dispatcher, _) = setup_account_panic();
     let new_public_key = KEY_PAIR_2().public_key;
@@ -93,7 +93,7 @@ fn test_dual_no_get_public_key() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_get_public_key_exists_and_panics() {
     let (snake_dispatcher, _) = setup_account_panic();
     snake_dispatcher.get_public_key();
@@ -121,7 +121,7 @@ fn test_dual_no_is_valid_signature() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_is_valid_signature_exists_and_panics() {
     let signature = array![];
     let (snake_dispatcher, _) = setup_account_panic();
@@ -145,7 +145,7 @@ fn test_dual_no_supports_interface() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_supports_interface_exists_and_panics() {
     let (snake_dispatcher, _) = setup_account_panic();
     snake_dispatcher.supports_interface(ISRC5_ID);
@@ -173,7 +173,7 @@ fn test_dual_setPublicKey() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_setPublicKey_exists_and_panics() {
     let (_, camel_dispatcher) = setup_account_panic();
     let new_public_key = KEY_PAIR_2().public_key;
@@ -191,7 +191,7 @@ fn test_dual_getPublicKey() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_getPublicKey_exists_and_panics() {
     let (_, camel_dispatcher) = setup_account_panic();
     camel_dispatcher.get_public_key();
@@ -211,7 +211,7 @@ fn test_dual_isValidSignature() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_isValidSignature_exists_and_panics() {
     let signature = array![];
 
diff --git a/packages/account/src/tests/test_dual_eth_account.cairo b/packages/account/src/tests/test_dual_eth_account.cairo
index f0289d0a4..c62495448 100644
--- a/packages/account/src/tests/test_dual_eth_account.cairo
+++ b/packages/account/src/tests/test_dual_eth_account.cairo
@@ -75,7 +75,7 @@ fn test_dual_no_set_public_key() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_set_public_key_exists_and_panics() {
     let (dispatcher, _) = setup_account_panic();
     dispatcher.set_public_key(KEY_PAIR().public_key, array![].span());
@@ -97,7 +97,7 @@ fn test_dual_no_get_public_key() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_get_public_key_exists_and_panics() {
     let (dispatcher, _) = setup_account_panic();
     dispatcher.get_public_key();
@@ -124,7 +124,7 @@ fn test_dual_no_is_valid_signature() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_is_valid_signature_exists_and_panics() {
     let signature = array![];
 
@@ -147,7 +147,7 @@ fn test_dual_no_supports_interface() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_supports_interface_exists_and_panics() {
     let (dispatcher, _) = setup_account_panic();
     dispatcher.supports_interface(ISRC5_ID);
@@ -176,7 +176,7 @@ fn test_dual_setPublicKey() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_setPublicKey_exists_and_panics() {
     let (_, dispatcher) = setup_account_panic();
     dispatcher.set_public_key(KEY_PAIR_2().public_key, array![].span());
@@ -192,7 +192,7 @@ fn test_dual_getPublicKey() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_getPublicKey_exists_and_panics() {
     let (_, dispatcher) = setup_account_panic();
     dispatcher.get_public_key();
@@ -211,7 +211,7 @@ fn test_dual_isValidSignature() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_isValidSignature_exists_and_panics() {
     let signature = array![];
 
diff --git a/packages/merkle_tree/src/tests/merkle_proof/test_with_pedersen.cairo b/packages/merkle_tree/src/tests/merkle_proof/test_with_pedersen.cairo
index 78c1a8c1c..8a1d430c4 100644
--- a/packages/merkle_tree/src/tests/merkle_proof/test_with_pedersen.cairo
+++ b/packages/merkle_tree/src/tests/merkle_proof/test_with_pedersen.cairo
@@ -102,7 +102,7 @@ fn test_invalid_merkle_multi_proof_flags() {
 }
 
 #[test]
-#[should_panic(expected: ("MerkleProof: invalid multi proof",))]
+#[should_panic(expected: "MerkleProof: invalid multi proof")]
 fn test_process_multi_proof_invalid_len_proof_flags_panics() {
     let leaves = LEAVES();
     let leaves_to_prove = [leaf_hash(*leaves.at(0)), leaf_hash(*leaves.at(1))].span();
@@ -115,7 +115,7 @@ fn test_process_multi_proof_invalid_len_proof_flags_panics() {
 }
 
 #[test]
-#[should_panic(expected: ("MerkleProof: invalid multi proof",))]
+#[should_panic(expected: "MerkleProof: invalid multi proof")]
 fn test_verify_multi_proof_invalid_len_proof_flags_panics() {
     let leaves = LEAVES();
     let leaves_to_prove = [leaf_hash(*leaves.at(0)), leaf_hash(*leaves.at(1))].span();
diff --git a/packages/merkle_tree/src/tests/merkle_proof/test_with_poseidon.cairo b/packages/merkle_tree/src/tests/merkle_proof/test_with_poseidon.cairo
index 5f1f2c867..da424b7f6 100644
--- a/packages/merkle_tree/src/tests/merkle_proof/test_with_poseidon.cairo
+++ b/packages/merkle_tree/src/tests/merkle_proof/test_with_poseidon.cairo
@@ -101,7 +101,7 @@ fn test_invalid_merkle_multi_proof_flags() {
 }
 
 #[test]
-#[should_panic(expected: ("MerkleProof: invalid multi proof",))]
+#[should_panic(expected: "MerkleProof: invalid multi proof")]
 fn test_process_multi_proof_invalid_len_proof_flags_panics() {
     let leaves = LEAVES();
     let leaves_to_prove = [leaf_hash(*leaves.at(0)), leaf_hash(*leaves.at(1))].span();
@@ -114,7 +114,7 @@ fn test_process_multi_proof_invalid_len_proof_flags_panics() {
 }
 
 #[test]
-#[should_panic(expected: ("MerkleProof: invalid multi proof",))]
+#[should_panic(expected: "MerkleProof: invalid multi proof")]
 fn test_verify_multi_proof_invalid_len_proof_flags_panics() {
     let leaves = LEAVES();
     let leaves_to_prove = [leaf_hash(*leaves.at(0)), leaf_hash(*leaves.at(1))].span();
diff --git a/packages/presets/src/tests/test_erc721.cairo b/packages/presets/src/tests/test_erc721.cairo
index cf0980567..2aecede3a 100644
--- a/packages/presets/src/tests/test_erc721.cairo
+++ b/packages/presets/src/tests/test_erc721.cairo
@@ -1121,15 +1121,10 @@ fn test_v2_missing_camel_selector() {
     v1.upgrade(v2_class_hash);
 
     let safe_dispatcher = IERC721CamelOnlySafeDispatcher { contract_address: v1.contract_address };
-    let mut panic_data = safe_dispatcher.ownerOf(TOKEN_1).unwrap_err();
-
+    let mut result = safe_dispatcher.ownerOf(TOKEN_1);
     let selector = selector!("ownerOf");
-    let expected_panic_message = format!(
-        "Entry point selector {} not found in contract {}",
-        selector.into_base_16_string(),
-        v1.contract_address.into_base_16_string()
-    );
-    assert_eq!(utils::panic_data_to_byte_array(panic_data), expected_panic_message);
+
+    utils::assert_entrypoint_not_found_error(result, selector, v1.contract_address);
 }
 
 #[test]
diff --git a/packages/test_common/Scarb.toml b/packages/test_common/Scarb.toml
index 4a6706034..f5417a9d7 100644
--- a/packages/test_common/Scarb.toml
+++ b/packages/test_common/Scarb.toml
@@ -16,6 +16,7 @@ keywords.workspace = true
 fmt.workspace = true
 
 [dependencies]
+assert_macros.workspace = true
 starknet.workspace = true
 snforge_std.workspace = true
 openzeppelin_upgrades = { path = "../upgrades" }
diff --git a/packages/testing/Scarb.toml b/packages/testing/Scarb.toml
index 2acc6c466..5da7bad77 100644
--- a/packages/testing/Scarb.toml
+++ b/packages/testing/Scarb.toml
@@ -16,6 +16,7 @@ keywords.workspace = true
 fmt.workspace = true
 
 [dependencies]
+assert_macros.workspace = true
 starknet.workspace = true
 snforge_std.workspace = true
 
diff --git a/packages/testing/src/common.cairo b/packages/testing/src/common.cairo
index dbd61b297..f0cfb2f8c 100644
--- a/packages/testing/src/common.cairo
+++ b/packages/testing/src/common.cairo
@@ -29,13 +29,26 @@ pub fn to_base_16_string(value: felt252) -> ByteArray {
     format!("0x{}", string)
 }
 
+/// Converts a `felt252` to a `base16`(hexadecimal) string without padding, but including the `0x`
+/// prefix.
+/// We need this because Starknet Foundry has a way of representing addresses and selectors that
+/// does not include 0's after `Ox`.
+pub fn to_base_16_string_no_padding(value: felt252) -> ByteArray {
+    let string = value.format_as_byte_array(16);
+    format!("0x{}", string)
+}
+
 /// A helper trait that enables any value that can be converted to `felt252` to be represented
-/// as a `base16` string padded to 66 characters (including the `0x` prefix).
+/// as a `base16` string(including the `0x` prefix).
 #[generate_trait]
 pub impl IntoBase16String<T, +Into<T, felt252>> of IntoBase16StringTrait<T> {
     fn into_base_16_string(self: T) -> ByteArray {
         to_base_16_string(self.into())
     }
+
+    fn into_base_16_string_no_padding(self: T) -> ByteArray {
+        to_base_16_string_no_padding(self.into())
+    }
 }
 
 /// Asserts that the syscall result of a call failed with an "Entrypoint not found" error,
@@ -46,15 +59,15 @@ pub fn assert_entrypoint_not_found_error<T, +Drop<T>>(
     if let Result::Err(panic_data) = result {
         let expected_panic_message = format!(
             "Entry point selector {} not found in contract {}",
-            selector.into_base_16_string(),
-            contract_address.into_base_16_string()
+            selector.into_base_16_string_no_padding(),
+            contract_address.into_base_16_string_no_padding()
         );
         let actual_panic_message = panic_data_to_byte_array(panic_data);
         assert!(
             actual_panic_message == expected_panic_message,
-            "Got unexpected panic message: ${actual_panic_message}"
+            "Got unexpected panic message: {actual_panic_message}"
         );
     } else {
-        panic!("${selector} call was expected to fail, but succeeded");
+        panic!("{selector} call was expected to fail, but succeeded");
     }
 }
diff --git a/packages/testing/src/deployment.cairo b/packages/testing/src/deployment.cairo
index fdaf7feeb..46ef37eb0 100644
--- a/packages/testing/src/deployment.cairo
+++ b/packages/testing/src/deployment.cairo
@@ -1,11 +1,17 @@
 use crate::panic_data_to_byte_array;
-use snforge_std::{ContractClass, ContractClassTrait};
+use snforge_std::{ContractClass, ContractClassTrait, DeclareResult};
 use starknet::ContractAddress;
 
-/// Declares a contract with a `snforge` `declare` call and unwraps the result.
+/// 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`)
 pub fn declare_class(contract_name: ByteArray) -> ContractClass {
     match snforge_std::declare(contract_name) {
-        Result::Ok(contract_class) => contract_class,
+        Result::Ok(declare_result) => match declare_result {
+            DeclareResult::Success(contract_class) => contract_class,
+            DeclareResult::AlreadyDeclared(contract_class) => contract_class,
+        },
         Result::Err(panic_data) => panic!("{}", panic_data_to_byte_array(panic_data))
     }
 }
@@ -38,6 +44,9 @@ pub fn deploy_another_at(
 }
 
 /// 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`)
 pub fn declare_and_deploy(contract_name: ByteArray, calldata: Array<felt252>) -> ContractAddress {
     let contract_class = declare_class(contract_name);
     deploy(contract_class, calldata)
@@ -45,6 +54,9 @@ pub fn declare_and_deploy(contract_name: ByteArray, calldata: Array<felt252>) ->
 
 /// 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`)
 pub fn declare_and_deploy_at(
     contract_name: ByteArray, target_address: ContractAddress, calldata: Array<felt252>
 ) {
diff --git a/packages/token/src/tests/erc1155/test_dual1155.cairo b/packages/token/src/tests/erc1155/test_dual1155.cairo
index 2b17750ce..cc15d9822 100644
--- a/packages/token/src/tests/erc1155/test_dual1155.cairo
+++ b/packages/token/src/tests/erc1155/test_dual1155.cairo
@@ -88,7 +88,7 @@ fn test_dual_no_uri() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_uri_exists_and_panics() {
     let (dispatcher, _) = setup_erc1155_panic();
     dispatcher.uri(TOKEN_ID);
@@ -113,7 +113,7 @@ fn test_dual_no_balance_of() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_balance_of_exists_and_panics() {
     let (dispatcher, _) = setup_erc1155_panic();
     dispatcher.balance_of(OWNER(), TOKEN_ID);
@@ -140,7 +140,7 @@ fn test_dual_no_balance_of_batch() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_balance_of_batch_exists_and_panics() {
     let (dispatcher, _) = setup_erc1155_panic();
     let (accounts, token_ids) = get_accounts_and_ids();
@@ -166,7 +166,7 @@ fn test_dual_no_safe_transfer_from() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_safe_transfer_from_exists_and_panics() {
     let (dispatcher, _) = setup_erc1155_panic();
     dispatcher.safe_transfer_from(OWNER(), RECIPIENT(), TOKEN_ID, TOKEN_VALUE, EMPTY_DATA());
@@ -196,7 +196,7 @@ fn test_dual_no_safe_batch_transfer_from() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_safe_batch_transfer_from_exists_and_panics() {
     let (dispatcher, _) = setup_erc1155_panic();
     let token_ids = array![TOKEN_ID, TOKEN_ID_2].span();
@@ -224,7 +224,7 @@ fn test_dual_no_is_approved_for_all() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_is_approved_for_all_exists_and_panics() {
     let (dispatcher, _) = setup_erc1155_panic();
     dispatcher.is_approved_for_all(OWNER(), OPERATOR());
@@ -250,7 +250,7 @@ fn test_dual_no_set_approval_for_all() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_set_approval_for_all_exists_and_panics() {
     let (dispatcher, _) = setup_erc1155_panic();
     dispatcher.set_approval_for_all(OPERATOR(), true);
@@ -272,7 +272,7 @@ fn test_dual_no_supports_interface() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_supports_interface_exists_and_panics() {
     let (dispatcher, _) = setup_erc1155_panic();
     dispatcher.supports_interface(IERC1155_ID);
@@ -291,7 +291,7 @@ fn test_dual_balanceOf() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_balanceOf_exists_and_panics() {
     let (_, dispatcher) = setup_erc1155_panic();
     dispatcher.balance_of(OWNER(), TOKEN_ID);
@@ -311,7 +311,7 @@ fn test_dual_balanceOfBatch() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_balanceOfBatch_exists_and_panics() {
     let (_, dispatcher) = setup_erc1155_panic();
     let (accounts, token_ids) = get_accounts_and_ids();
@@ -331,7 +331,7 @@ fn test_dual_safeTransferFrom() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_safeTransferFrom_exists_and_panics() {
     let (_, dispatcher) = setup_erc1155_panic();
     dispatcher.safe_transfer_from(OWNER(), RECIPIENT(), TOKEN_ID, TOKEN_VALUE, EMPTY_DATA());
@@ -353,7 +353,7 @@ fn test_dual_safeBatchTransferFrom() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_safeBatchTransferFrom_exists_and_panics() {
     let (_, dispatcher) = setup_erc1155_panic();
     let token_ids = array![TOKEN_ID, TOKEN_ID_2].span();
@@ -375,7 +375,7 @@ fn test_dual_isApprovedForAll() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_isApprovedForAll_exists_and_panics() {
     let (_, dispatcher) = setup_erc1155_panic();
     dispatcher.is_approved_for_all(OWNER(), OPERATOR());
@@ -395,7 +395,7 @@ fn test_dual_setApprovalForAll() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_setApprovalForAll_exists_and_panics() {
     let (_, dispatcher) = setup_erc1155_panic();
     dispatcher.set_approval_for_all(OPERATOR(), true);
diff --git a/packages/token/src/tests/erc1155/test_dual1155_receiver.cairo b/packages/token/src/tests/erc1155/test_dual1155_receiver.cairo
index eb54ffcb1..dc6c56108 100644
--- a/packages/token/src/tests/erc1155/test_dual1155_receiver.cairo
+++ b/packages/token/src/tests/erc1155/test_dual1155_receiver.cairo
@@ -63,7 +63,7 @@ fn test_dual_no_on_erc1155_received() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_on_erc1155_received_exists_and_panics() {
     let (dispatcher, _) = setup_erc1155_receiver_panic();
     dispatcher.on_erc1155_received(OPERATOR(), OWNER(), TOKEN_ID, TOKEN_VALUE, EMPTY_DATA());
@@ -89,7 +89,7 @@ fn test_dual_no_on_erc1155_batch_received() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_on_erc1155_batch_received_exists_and_panics() {
     let (dispatcher, _) = setup_erc1155_receiver_panic();
     let (token_ids, values) = get_ids_and_values();
@@ -111,7 +111,7 @@ fn test_dual_onERC1155Received() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_onERC1155Received_exists_and_panics() {
     let (_, dispatcher) = setup_erc1155_receiver_panic();
     dispatcher.on_erc1155_received(OPERATOR(), OWNER(), TOKEN_ID, TOKEN_VALUE, EMPTY_DATA());
@@ -130,7 +130,7 @@ fn test_dual_onERC1155BatchReceived() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_onERC1155BatchReceived_exists_and_panics() {
     let (_, dispatcher) = setup_erc1155_receiver_panic();
     let (token_ids, values) = get_ids_and_values();
diff --git a/packages/token/src/tests/erc1155/test_erc1155.cairo b/packages/token/src/tests/erc1155/test_erc1155.cairo
index 81043a52a..4901ab56f 100644
--- a/packages/token/src/tests/erc1155/test_erc1155.cairo
+++ b/packages/token/src/tests/erc1155/test_erc1155.cairo
@@ -1025,11 +1025,7 @@ fn test_update_wac_batch_from_non_zero_to_non_zero_account() {
 }
 
 #[test]
-#[should_panic(
-    expected: (
-        "Contract not deployed at address: 0x0000000000000000000000000000000000000000000000000000000000000000",
-    )
-)]
+#[should_panic(expected: "Contract not deployed at address: 0x0")]
 fn test_update_wac_from_non_zero_to_zero() {
     let (mut state, owner) = setup();
     let recipient = ZERO();
diff --git a/packages/token/src/tests/erc20/test_dual20.cairo b/packages/token/src/tests/erc20/test_dual20.cairo
index 89e1d265e..d1b926deb 100644
--- a/packages/token/src/tests/erc20/test_dual20.cairo
+++ b/packages/token/src/tests/erc20/test_dual20.cairo
@@ -69,7 +69,7 @@ fn test_dual_no_name() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_name_exists_and_panics() {
     let (dispatcher, _) = setup_erc20_panic();
     dispatcher.name();
@@ -92,7 +92,7 @@ fn test_dual_no_symbol() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_symbol_exists_and_panics() {
     let (dispatcher, _) = setup_erc20_panic();
     dispatcher.symbol();
@@ -115,7 +115,7 @@ fn test_dual_no_decimals() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_decimals_exists_and_panics() {
     let (dispatcher, _) = setup_erc20_panic();
     dispatcher.decimals();
@@ -144,7 +144,7 @@ fn test_dual_no_transfer() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_transfer_exists_and_panics() {
     let (dispatcher, _) = setup_erc20_panic();
     dispatcher.transfer(RECIPIENT(), VALUE);
@@ -176,7 +176,7 @@ fn test_dual_no_approve() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_approve_exists_and_panics() {
     let (dispatcher, _) = setup_erc20_panic();
     dispatcher.approve(SPENDER(), VALUE);
@@ -201,7 +201,7 @@ fn test_dual_no_total_supply() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_total_supply_exists_and_panics() {
     let (dispatcher, _) = setup_erc20_panic();
     dispatcher.total_supply();
@@ -222,7 +222,7 @@ fn test_dual_no_balance_of() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_balance_of_exists_and_panics() {
     let (dispatcher, _) = setup_erc20_panic();
     dispatcher.balance_of(OWNER());
@@ -248,7 +248,7 @@ fn test_dual_no_transfer_from() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_transfer_from_exists_and_panics() {
     let (dispatcher, _) = setup_erc20_panic();
     dispatcher.transfer_from(OWNER(), RECIPIENT(), VALUE);
@@ -267,7 +267,7 @@ fn test_dual_totalSupply() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_totalSupply_exists_and_panics() {
     let (_, dispatcher) = setup_erc20_panic();
     dispatcher.total_supply();
@@ -282,7 +282,7 @@ fn test_dual_balanceOf() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_balanceOf_exists_and_panics() {
     let (_, dispatcher) = setup_erc20_panic();
     dispatcher.balance_of(OWNER());
@@ -302,7 +302,7 @@ fn test_dual_transferFrom() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_transferFrom_exists_and_panics() {
     let (_, dispatcher) = setup_erc20_panic();
     dispatcher.transfer_from(OWNER(), RECIPIENT(), VALUE);
diff --git a/packages/token/src/tests/erc721/test_dual721.cairo b/packages/token/src/tests/erc721/test_dual721.cairo
index 7e6d8254e..8fabac436 100644
--- a/packages/token/src/tests/erc721/test_dual721.cairo
+++ b/packages/token/src/tests/erc721/test_dual721.cairo
@@ -84,7 +84,7 @@ fn test_dual_no_name() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_name_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_panic();
     dispatcher.name();
@@ -107,7 +107,7 @@ fn test_dual_no_symbol() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_symbol_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_panic();
     dispatcher.symbol();
@@ -137,7 +137,7 @@ fn test_dual_no_approve() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_approve_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_panic();
     dispatcher.approve(SPENDER(), TOKEN_ID);
@@ -162,7 +162,7 @@ fn test_dual_no_balance_of() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_balance_of_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_panic();
     dispatcher.balance_of(OWNER());
@@ -183,7 +183,7 @@ fn test_dual_no_owner_of() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_owner_of_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_panic();
     dispatcher.owner_of(TOKEN_ID);
@@ -205,7 +205,7 @@ fn test_dual_no_transfer_from() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_transfer_from_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_panic();
     dispatcher.transfer_from(OWNER(), RECIPIENT(), TOKEN_ID);
@@ -228,7 +228,7 @@ fn test_dual_no_safe_transfer_from() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_safe_transfer_from_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_panic();
     dispatcher.safe_transfer_from(OWNER(), RECIPIENT(), TOKEN_ID, DATA(true));
@@ -252,7 +252,7 @@ fn test_dual_no_get_approved() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_get_approved_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_panic();
     dispatcher.get_approved(TOKEN_ID);
@@ -278,7 +278,7 @@ fn test_dual_no_set_approval_for_all() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_set_approval_for_all_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_panic();
     dispatcher.set_approval_for_all(OPERATOR(), true);
@@ -304,7 +304,7 @@ fn test_dual_no_is_approved_for_all() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_is_approved_for_all_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_panic();
     dispatcher.is_approved_for_all(OWNER(), OPERATOR());
@@ -327,7 +327,7 @@ fn test_dual_no_token_uri() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_token_uri_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_panic();
     dispatcher.token_uri(TOKEN_ID);
@@ -349,7 +349,7 @@ fn test_dual_no_supports_interface() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_supports_interface_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_panic();
     dispatcher.supports_interface(IERC721_ID);
@@ -368,7 +368,7 @@ fn test_dual_balanceOf() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_balanceOf_exists_and_panics() {
     let (_, dispatcher) = setup_erc721_panic();
     dispatcher.balance_of(OWNER());
@@ -384,7 +384,7 @@ fn test_dual_ownerOf() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_ownerOf_exists_and_panics() {
     let (_, dispatcher) = setup_erc721_panic();
     dispatcher.owner_of(TOKEN_ID);
@@ -404,7 +404,7 @@ fn test_dual_transferFrom() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_transferFrom_exists_and_panics() {
     let (_, dispatcher) = setup_erc721_panic();
     dispatcher.transfer_from(OWNER(), RECIPIENT(), TOKEN_ID);
@@ -423,7 +423,7 @@ fn test_dual_safeTransferFrom() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_safeTransferFrom_exists_and_panics() {
     let (_, dispatcher) = setup_erc721_panic();
     dispatcher.safe_transfer_from(OWNER(), RECIPIENT(), TOKEN_ID, DATA(true));
@@ -443,7 +443,7 @@ fn test_dual_getApproved() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_getApproved_exists_and_panics() {
     let (_, dispatcher) = setup_erc721_panic();
     dispatcher.get_approved(TOKEN_ID);
@@ -463,7 +463,7 @@ fn test_dual_setApprovalForAll() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_setApprovalForAll_exists_and_panics() {
     let (_, dispatcher) = setup_erc721_panic();
     dispatcher.set_approval_for_all(OPERATOR(), true);
@@ -483,7 +483,7 @@ fn test_dual_isApprovedForAll() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_isApprovedForAll_exists_and_panics() {
     let (_, dispatcher) = setup_erc721_panic();
     dispatcher.is_approved_for_all(OWNER(), OPERATOR());
@@ -500,7 +500,7 @@ fn test_dual_tokenURI() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_tokenURI_exists_and_panics() {
     let (_, dispatcher) = setup_erc721_panic();
     dispatcher.token_uri(TOKEN_ID);
diff --git a/packages/token/src/tests/erc721/test_dual721_receiver.cairo b/packages/token/src/tests/erc721/test_dual721_receiver.cairo
index 4acffb5e4..bab5645c8 100644
--- a/packages/token/src/tests/erc721/test_dual721_receiver.cairo
+++ b/packages/token/src/tests/erc721/test_dual721_receiver.cairo
@@ -64,7 +64,7 @@ fn test_dual_no_on_erc721_received() {
 }
 
 #[test]
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_on_erc721_received_exists_and_panics() {
     let (dispatcher, _) = setup_erc721_receiver_panic();
     dispatcher.on_erc721_received(OPERATOR(), OWNER(), TOKEN_ID, DATA(true));
@@ -86,7 +86,7 @@ fn test_dual_onERC721Received() {
 
 #[test]
 #[ignore] // REASON: foundry entrypoint_not_found error message inconsistent with mainnet.
-#[should_panic(expected: ("Some error",))]
+#[should_panic(expected: "Some error")]
 fn test_dual_onERC721Received_exists_and_panics() {
     let (_, dispatcher) = setup_erc721_receiver_panic();
     dispatcher.on_erc721_received(OPERATOR(), OWNER(), TOKEN_ID, DATA(true));