diff --git a/Cargo.lock b/Cargo.lock
index eed8fb4f9b..45a875bd35 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -430,6 +430,7 @@ dependencies = [
  "num-rational",
  "num-traits 0.2.19",
  "once_cell",
+ "paste",
  "phf",
  "pretty_assertions",
  "rand",
@@ -2643,9 +2644,9 @@ dependencies = [
 
 [[package]]
 name = "paste"
-version = "1.0.14"
+version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
 
 [[package]]
 name = "path-clean"
diff --git a/Cargo.toml b/Cargo.toml
index 103fa3da93..9722c3fd68 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -38,6 +38,7 @@ num-rational = { version = "0.4", features = ["serde"] }
 num-traits = "0.2"
 once_cell = "1.19.0"
 papyrus_storage = "0.4.0-dev.4"
+paste = "1.0.15"
 phf = { version = "0.11", features = ["macros"] }
 pretty_assertions = "1.2.1"
 pyo3 = "0.19.1"
diff --git a/crates/blockifier/Cargo.toml b/crates/blockifier/Cargo.toml
index 6baafab7da..8516535f71 100644
--- a/crates/blockifier/Cargo.toml
+++ b/crates/blockifier/Cargo.toml
@@ -38,6 +38,7 @@ num-integer.workspace = true
 num-rational.workspace = true
 num-traits.workspace = true
 once_cell.workspace = true
+paste.workspace = true
 phf.workspace = true
 rand = { workspace = true, optional = true }
 rstest = { workspace = true, optional = true }
diff --git a/crates/blockifier/src/test_utils/struct_impls.rs b/crates/blockifier/src/test_utils/struct_impls.rs
index 52cbd67adb..eedfcdc956 100644
--- a/crates/blockifier/src/test_utils/struct_impls.rs
+++ b/crates/blockifier/src/test_utils/struct_impls.rs
@@ -28,7 +28,7 @@ use crate::transaction::objects::{
     DeprecatedTransactionInfo, FeeType, TransactionFeeResult, TransactionInfo, TransactionResources,
 };
 use crate::versioned_constants::{
-    GasCosts, OsConstants, VersionedConstants, DEFAULT_CONSTANTS_JSON,
+    GasCosts, OsConstants, VersionedConstants, VERSIONED_CONSTANTS_LATEST_JSON,
 };
 
 impl CallEntryPoint {
@@ -109,11 +109,12 @@ impl TransactionResources {
 impl GasCosts {
     pub fn create_for_testing_from_subset(subset_of_os_constants: &str) -> Self {
         let subset_of_os_constants: Value = serde_json::from_str(subset_of_os_constants).unwrap();
-        let mut os_constants: Value = serde_json::from_str::<Value>(DEFAULT_CONSTANTS_JSON)
-            .unwrap()
-            .get("os_constants")
-            .unwrap()
-            .clone();
+        let mut os_constants: Value =
+            serde_json::from_str::<Value>(VERSIONED_CONSTANTS_LATEST_JSON)
+                .unwrap()
+                .get("os_constants")
+                .unwrap()
+                .clone();
         update_json_value(&mut os_constants, subset_of_os_constants);
         let os_constants: OsConstants = serde_json::from_value(os_constants).unwrap();
         os_constants.gas_costs
diff --git a/crates/blockifier/src/versioned_constants.rs b/crates/blockifier/src/versioned_constants.rs
index b80c7a1670..a975ab0e98 100644
--- a/crates/blockifier/src/versioned_constants.rs
+++ b/crates/blockifier/src/versioned_constants.rs
@@ -8,10 +8,12 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
 use indexmap::{IndexMap, IndexSet};
 use num_rational::Ratio;
 use once_cell::sync::Lazy;
+use paste::paste;
 use serde::de::Error as DeserializationError;
 use serde::{Deserialize, Deserializer};
 use serde_json::{Map, Number, Value};
 use strum::IntoEnumIterator;
+use strum_macros::{EnumCount, EnumIter};
 use thiserror::Error;
 
 use crate::execution::deprecated_syscalls::hint_processor::SyscallCounter;
@@ -26,18 +28,56 @@ use crate::transaction::transaction_types::TransactionType;
 #[path = "versioned_constants_test.rs"]
 pub mod test;
 
-pub(crate) const DEFAULT_CONSTANTS_JSON: &str =
-    include_str!("../resources/versioned_constants.json");
-static DEFAULT_CONSTANTS: Lazy<VersionedConstants> = Lazy::new(|| {
-    serde_json::from_str(DEFAULT_CONSTANTS_JSON)
-        .expect("Versioned constants JSON file is malformed")
-});
+/// Auto-generate getters for listed versioned constants versions.
+macro_rules! define_versioned_constants {
+    ($(($variant:ident, $path_to_json:expr)),* $(,)?) => {
+        /// Enum of all the Starknet versions supporting versioned constants.
+        #[derive(Clone, Debug, EnumCount, EnumIter, Hash, Eq, PartialEq)]
+        pub enum StarknetVersion {
+            $($variant,)*
+        }
+
+        // Static (lazy) instances of the versioned constants.
+        // For internal use only; for access to a static instance use the `StarknetVersion` enum.
+        paste! {
+            $(
+                pub(crate) const [<VERSIONED_CONSTANTS_ $variant:upper _JSON>]: &str =
+                    include_str!($path_to_json);
+                static [<VERSIONED_CONSTANTS_ $variant:upper>]: Lazy<VersionedConstants> = Lazy::new(|| {
+                    serde_json::from_str([<VERSIONED_CONSTANTS_ $variant:upper _JSON>])
+                        .expect(&format!("Versioned constants {} is malformed.", $path_to_json))
+                });
+            )*
+        }
+
+        /// API to access a static instance of the versioned constants.
+        impl From<StarknetVersion> for &'static VersionedConstants {
+            fn from(version: StarknetVersion) -> Self {
+                match version {
+                    $(
+                        StarknetVersion::$variant => {
+                           & paste! { [<VERSIONED_CONSTANTS_ $variant:upper>] }
+                        }
+                    )*
+                }
+            }
+        }
+    };
+}
+
+define_versioned_constants! {
+    (V0_13_0, "../resources/versioned_constants_13_0.json"),
+    (V0_13_1, "../resources/versioned_constants_13_1.json"),
+    (V0_13_1_1, "../resources/versioned_constants_13_1_1.json"),
+    (Latest, "../resources/versioned_constants.json"),
+}
 
 pub type ResourceCost = Ratio<u128>;
 
 /// Contains constants for the Blockifier that may vary between versions.
 /// Additional constants in the JSON file, not used by Blockifier but included for transparency, are
 /// automatically ignored during deserialization.
+/// Instances of this struct for specific Starknet versions can be selected by using the above enum.
 #[derive(Clone, Debug, Default, Deserialize)]
 pub struct VersionedConstants {
     // Limits.
@@ -73,10 +113,15 @@ pub struct VersionedConstants {
 }
 
 impl VersionedConstants {
+    /// Get the constants for the specified Starknet version.
+    pub fn get(version: StarknetVersion) -> &'static Self {
+        version.into()
+    }
+
     /// Get the constants that shipped with the current version of the Blockifier.
     /// To use custom constants, initialize the struct from a file using `try_from`.
     pub fn latest_constants() -> &'static Self {
-        &DEFAULT_CONSTANTS
+        Self::get(StarknetVersion::Latest)
     }
 
     /// Returns the initial gas of any transaction to run with.
diff --git a/crates/blockifier/src/versioned_constants_test.rs b/crates/blockifier/src/versioned_constants_test.rs
index db1fa7a6f1..ff6dd2d4d2 100644
--- a/crates/blockifier/src/versioned_constants_test.rs
+++ b/crates/blockifier/src/versioned_constants_test.rs
@@ -1,5 +1,5 @@
 use cairo_vm::types::builtin_name::BuiltinName;
-use glob::glob;
+use glob::{glob, Paths};
 use pretty_assertions::assert_eq;
 
 use super::*;
@@ -7,6 +7,11 @@ use super::*;
 // TODO: Test Starknet OS validation.
 // TODO: Add an unallowed field scenario for GasCost parsing.
 
+/// Returns all JSON files in the resources directory (should be all versioned constants files).
+fn all_jsons_in_dir() -> Paths {
+    glob(format!("{}/resources/*.json", env!("CARGO_MANIFEST_DIR")).as_str()).unwrap()
+}
+
 #[test]
 fn test_successful_gas_costs_parsing() {
     let json_data = r#"
@@ -70,7 +75,7 @@ fn get_json_value_without_defaults() -> serde_json::Value {
         "max_recursion_depth": 2
     }"#;
     // Fill the os constants with the gas cost values (do not have a default value).
-    let mut os_constants: Value = serde_json::from_str::<Value>(DEFAULT_CONSTANTS_JSON)
+    let mut os_constants: Value = serde_json::from_str::<Value>(VERSIONED_CONSTANTS_LATEST_JSON)
         .unwrap()
         .get("os_constants")
         .unwrap()
@@ -91,7 +96,7 @@ fn get_json_value_without_defaults() -> serde_json::Value {
 #[test]
 fn test_versioned_constants_base_overrides() {
     // Create a versioned constants copy with a modified value for `invoke_tx_max_n_steps`.
-    let mut versioned_constants_base_overrides = DEFAULT_CONSTANTS.clone();
+    let mut versioned_constants_base_overrides = VERSIONED_CONSTANTS_LATEST.clone();
     versioned_constants_base_overrides.invoke_tx_max_n_steps += 1;
 
     let result = VersionedConstants::get_versioned_constants(VersionedConstantsOverrides {
@@ -218,9 +223,13 @@ fn test_invalid_number() {
 
 #[test]
 fn test_old_json_parsing() {
-    let files = glob(format!("{}/resources/*.json", env!("CARGO_MANIFEST_DIR")).as_str()).unwrap();
-    for file in files.map(Result::unwrap) {
+    for file in all_jsons_in_dir().map(Result::unwrap) {
         serde_json::from_reader::<_, VersionedConstants>(&std::fs::File::open(&file).unwrap())
             .unwrap_or_else(|_| panic!("Versioned constants JSON file {file:#?} is malformed"));
     }
 }
+
+#[test]
+fn test_all_jsons_in_enum() {
+    assert_eq!(StarknetVersion::iter().count(), all_jsons_in_dir().count());
+}