From 7df745a068f6ecc68cbc9dd40baeade65edbe6dc Mon Sep 17 00:00:00 2001 From: muhsar27 Date: Fri, 24 Jul 2026 00:31:32 +0100 Subject: [PATCH 1/2] feat: implement DeprecatedRegistry to track and manage deprecated contract entrypoints --- contracts/predictify-hybrid/src/deprecated.rs | 427 ++++++++++++++++++ contracts/predictify-hybrid/src/lib.rs | 33 +- docs/DEPRECATED.md | 162 +++++++ 3 files changed, 620 insertions(+), 2 deletions(-) create mode 100644 contracts/predictify-hybrid/src/deprecated.rs create mode 100644 docs/DEPRECATED.md diff --git a/contracts/predictify-hybrid/src/deprecated.rs b/contracts/predictify-hybrid/src/deprecated.rs new file mode 100644 index 00000000..a3d10b45 --- /dev/null +++ b/contracts/predictify-hybrid/src/deprecated.rs @@ -0,0 +1,427 @@ +//! # Deprecated Entrypoint Registry +//! +//! Centralised, compile-time registry of all deprecated contract entrypoints. +//! +//! ## Purpose +//! +//! Deprecated functions are scattered across multiple modules. This registry +//! provides a **single source of truth** so that: +//! +//! - Developers can list every deprecated entrypoint in one place. +//! - On-chain callers can query [`DeprecatedRegistry::all`] (exposed via +//! the `list_deprecated` contract entrypoint) to discover deprecated +//! functions programmatically. +//! - Each deprecated call site routes through +//! [`DeprecatedRegistry::emit_if_deprecated`], which emits a +//! `DeprecatedCall` event only for registered entries and is a safe no-op +//! otherwise. +//! +//! ## Adding a New Entry +//! +//! 1. Add a new arm to [`DeprecatedRegistry::lookup`] with the function name, +//! replacement, deprecation date, and planned removal version. +//! 2. Add the same entry to [`DeprecatedRegistry::all`]. +//! 3. At the deprecated call site, call +//! `DeprecatedRegistry::emit_if_deprecated(&env, "function_name")`. +//! 4. Update `docs/DEPRECATED.md` with the new entry. +//! +//! ## Design Constraints +//! +//! - All fields use [`Symbol`] (≤ 32 chars on Soroban) to avoid heap +//! allocations and keep the registry zero-cost at rest. +//! - The registry is **pure** — no storage reads or writes. Entries are +//! hard-coded at compile time, matching the [`EventSchemaRegistry`] pattern. + +use crate::events::emit_deprecated; +use soroban_sdk::{contracttype, symbol_short, Env, Symbol, Vec}; + +/// Metadata for a single deprecated entrypoint. +/// +/// Each entry captures enough information for both human developers and +/// on-chain tooling to understand the deprecation and plan a migration. +/// +/// # Fields +/// +/// * `name` — Symbol name of the deprecated function. +/// * `replacement` — Symbol name of the recommended replacement. +/// Shortened to fit Soroban's 32-char limit; +/// see `docs/DEPRECATED.md` for fully-qualified paths. +/// * `since` — ISO-8601 date when the deprecation was introduced +/// (e.g. `"2026-06-28"`). +/// * `removal_version` — Contract version in which the entrypoint will be +/// removed. Set to `"TBD"` when no version is +/// scheduled yet. +/// +/// # Example +/// +/// ```rust,ignore +/// let entry = DeprecatedEntrypoint { +/// name: Symbol::new(&env, "verify_result"), +/// replacement: Symbol::new(&env, "fetch_oracle_result"), +/// since: Symbol::new(&env, "2026-06-28"), +/// removal_version: Symbol::new(&env, "TBD"), +/// }; +/// ``` +#[contracttype] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct DeprecatedEntrypoint { + /// The name of the deprecated function. + pub name: Symbol, + /// The recommended replacement function (shortened for Symbol limits). + pub replacement: Symbol, + /// ISO-8601 date the deprecation was introduced. + pub since: Symbol, + /// Contract version in which the entrypoint will be removed (`"TBD"` if + /// not yet scheduled). + pub removal_version: Symbol, +} + +/// Centralised registry of deprecated entrypoints. +/// +/// This is a unit struct with only associated functions — no instance state. +/// All data is compiled-in; there are no storage reads. +/// +/// # Usage +/// +/// ```rust,ignore +/// use crate::deprecated::DeprecatedRegistry; +/// +/// // Check a single entrypoint +/// if let Some(entry) = DeprecatedRegistry::lookup(&env, "verify_result") { +/// log!("Use {} instead", entry.replacement); +/// } +/// +/// // List everything +/// let all = DeprecatedRegistry::all(&env); +/// ``` +pub struct DeprecatedRegistry; + +impl DeprecatedRegistry { + // ===== CONSTANTS ===== + + /// Total number of registered deprecated entrypoints. + /// + /// Keep this in sync with `all()`. A compile-time test + /// (`test_all_returns_expected_count`) guards against drift. + const ENTRY_COUNT: u32 = 6; + + // ===== PUBLIC API ===== + + /// Look up a deprecated entrypoint by function name. + /// + /// Returns `Some(DeprecatedEntrypoint)` if `name` is a registered + /// deprecated function, or `None` otherwise. + /// + /// # Arguments + /// + /// * `env` — Soroban environment (needed for `Symbol` construction). + /// * `name` — Exact function name to look up (e.g. `"verify_result"`). + /// + /// # Examples + /// + /// ```rust,ignore + /// let entry = DeprecatedRegistry::lookup(&env, "verify_result"); + /// assert!(entry.is_some()); + /// ``` + pub fn lookup(env: &Env, name: &str) -> Option { + match name { + "verify_result" => Some(DeprecatedEntrypoint { + name: Symbol::new(env, "verify_result"), + replacement: Symbol::new(env, "fetch_oracle_result"), + since: Symbol::new(env, "2026-06-28"), + removal_version: Symbol::new(env, "TBD"), + }), + "resolve_market" => Some(DeprecatedEntrypoint { + name: Symbol::new(env, "resolve_market"), + replacement: Symbol::new(env, "resolve_market_manual"), + since: Symbol::new(env, "2026-06-28"), + removal_version: Symbol::new(env, "TBD"), + }), + "collect_fees" => Some(DeprecatedEntrypoint { + name: Symbol::new(env, "collect_fees"), + replacement: Symbol::new(env, "FeeManager_collect"), + since: Symbol::new(env, "2026-06-28"), + removal_version: Symbol::new(env, "TBD"), + }), + "transfer_fees" => Some(DeprecatedEntrypoint { + name: Symbol::new(env, "transfer_fees"), + replacement: Symbol::new(env, "FeeUtils_transfer"), + since: Symbol::new(env, "2026-06-28"), + removal_version: Symbol::new(env, "TBD"), + }), + "calculate_fee_amount" => Some(DeprecatedEntrypoint { + name: Symbol::new(env, "calculate_fee_amount"), + replacement: Symbol::new(env, "FeeCalc_platform_fee"), + since: Symbol::new(env, "2026-06-28"), + removal_version: Symbol::new(env, "TBD"), + }), + "process_creation_fee" => Some(DeprecatedEntrypoint { + name: Symbol::new(env, "process_creation_fee"), + replacement: Symbol::new(env, "FeeManager_creation"), + since: Symbol::new(env, "2026-06-28"), + removal_version: Symbol::new(env, "TBD"), + }), + _ => None, + } + } + + /// Return all registered deprecated entrypoints. + /// + /// The returned [`Vec`] is freshly allocated on each call (no caching). + /// Order matches the declaration order in this registry. + /// + /// # Arguments + /// + /// * `env` — Soroban environment. + pub fn all(env: &Env) -> Vec { + let mut entries = Vec::new(env); + + // ---- Contract-level entrypoints (#[contractimpl]) ---- + + entries.push_back(DeprecatedEntrypoint { + name: Symbol::new(env, "verify_result"), + replacement: Symbol::new(env, "fetch_oracle_result"), + since: Symbol::new(env, "2026-06-28"), + removal_version: Symbol::new(env, "TBD"), + }); + + entries.push_back(DeprecatedEntrypoint { + name: Symbol::new(env, "resolve_market"), + replacement: Symbol::new(env, "resolve_market_manual"), + since: Symbol::new(env, "2026-06-28"), + removal_version: Symbol::new(env, "TBD"), + }); + + // ---- Module-internal deprecated wrappers ---- + + entries.push_back(DeprecatedEntrypoint { + name: Symbol::new(env, "collect_fees"), + replacement: Symbol::new(env, "FeeManager_collect"), + since: Symbol::new(env, "2026-06-28"), + removal_version: Symbol::new(env, "TBD"), + }); + + entries.push_back(DeprecatedEntrypoint { + name: Symbol::new(env, "transfer_fees"), + replacement: Symbol::new(env, "FeeUtils_transfer"), + since: Symbol::new(env, "2026-06-28"), + removal_version: Symbol::new(env, "TBD"), + }); + + entries.push_back(DeprecatedEntrypoint { + name: Symbol::new(env, "calculate_fee_amount"), + replacement: Symbol::new(env, "FeeCalc_platform_fee"), + since: Symbol::new(env, "2026-06-28"), + removal_version: Symbol::new(env, "TBD"), + }); + + entries.push_back(DeprecatedEntrypoint { + name: Symbol::new(env, "process_creation_fee"), + replacement: Symbol::new(env, "FeeManager_creation"), + since: Symbol::new(env, "2026-06-28"), + removal_version: Symbol::new(env, "TBD"), + }); + + entries + } + + /// Convenience predicate: returns `true` when `name` is a registered + /// deprecated entrypoint. + /// + /// # Arguments + /// + /// * `env` — Soroban environment. + /// * `name` — Function name to check. + pub fn is_deprecated(env: &Env, name: &str) -> bool { + Self::lookup(env, name).is_some() + } + + /// Emit a [`DeprecatedCall`](crate::events::DeprecatedCall) event if + /// `name` is a registered deprecated entrypoint. + /// + /// This is the **recommended call-site helper**: drop-in replacement for + /// manual `emit_deprecated` calls. For non-deprecated names the function + /// is a safe, zero-cost no-op. + /// + /// # Arguments + /// + /// * `env` — Soroban environment. + /// * `name` — Function name of the (potentially) deprecated entrypoint. + /// + /// # Examples + /// + /// ```rust,ignore + /// // In a deprecated function body: + /// DeprecatedRegistry::emit_if_deprecated(&env, "verify_result"); + /// ``` + pub fn emit_if_deprecated(env: &Env, name: &str) { + if let Some(entry) = Self::lookup(env, name) { + emit_deprecated(env, &entry.name); + } + } +} + +// ============================================================================= +// Tests +// ============================================================================= + +#[cfg(test)] +mod tests { + use super::*; + use soroban_sdk::Env; + + // --- lookup tests --- + + #[test] + fn test_lookup_known_entry() { + let env = Env::default(); + let entry = DeprecatedRegistry::lookup(&env, "verify_result"); + assert!(entry.is_some(), "verify_result should be in the registry"); + + let entry = entry.unwrap(); + assert_eq!(entry.name, Symbol::new(&env, "verify_result")); + assert_eq!(entry.replacement, Symbol::new(&env, "fetch_oracle_result")); + assert_eq!(entry.since, Symbol::new(&env, "2026-06-28")); + assert_eq!(entry.removal_version, Symbol::new(&env, "TBD")); + } + + #[test] + fn test_lookup_unknown_returns_none() { + let env = Env::default(); + let entry = DeprecatedRegistry::lookup(&env, "nonexistent_function"); + assert!(entry.is_none(), "unknown names must return None"); + } + + #[test] + fn test_lookup_empty_string_returns_none() { + let env = Env::default(); + let entry = DeprecatedRegistry::lookup(&env, ""); + assert!(entry.is_none(), "empty string must return None"); + } + + // --- is_deprecated tests --- + + #[test] + fn test_is_deprecated_true() { + let env = Env::default(); + assert!(DeprecatedRegistry::is_deprecated(&env, "resolve_market")); + assert!(DeprecatedRegistry::is_deprecated(&env, "collect_fees")); + assert!(DeprecatedRegistry::is_deprecated(&env, "transfer_fees")); + assert!(DeprecatedRegistry::is_deprecated(&env, "calculate_fee_amount")); + assert!(DeprecatedRegistry::is_deprecated(&env, "process_creation_fee")); + } + + #[test] + fn test_is_deprecated_false() { + let env = Env::default(); + assert!(!DeprecatedRegistry::is_deprecated(&env, "create_market")); + assert!(!DeprecatedRegistry::is_deprecated(&env, "vote")); + assert!(!DeprecatedRegistry::is_deprecated(&env, "place_bet")); + } + + // --- all() tests --- + + #[test] + fn test_all_returns_expected_count() { + let env = Env::default(); + let entries = DeprecatedRegistry::all(&env); + assert_eq!( + entries.len(), + DeprecatedRegistry::ENTRY_COUNT, + "all() must return exactly ENTRY_COUNT entries" + ); + } + + #[test] + fn test_all_entries_have_nonempty_replacement() { + let env = Env::default(); + let entries = DeprecatedRegistry::all(&env); + for entry in entries.iter() { + // Symbol::new panics on empty strings, so if we got here + // the replacement is non-empty. Double-check by comparing + // against a known non-empty symbol. + assert_ne!( + entry.replacement, + entry.name, + "replacement must differ from name for {:?}", + entry.name + ); + } + } + + #[test] + fn test_registry_entries_unique_names() { + let env = Env::default(); + let entries = DeprecatedRegistry::all(&env); + for i in 0..entries.len() { + for j in (i + 1)..entries.len() { + let a = entries.get(i).unwrap(); + let b = entries.get(j).unwrap(); + assert_ne!( + a.name, b.name, + "duplicate name detected at indices {} and {}", + i, j + ); + } + } + } + + #[test] + fn test_all_entries_match_lookup() { + let env = Env::default(); + let entries = DeprecatedRegistry::all(&env); + + // Build the name strings that correspond to each entry. + let names = [ + "verify_result", + "resolve_market", + "collect_fees", + "transfer_fees", + "calculate_fee_amount", + "process_creation_fee", + ]; + + assert_eq!( + entries.len(), + names.len() as u32, + "names array out of sync with all()" + ); + + for (idx, name) in names.iter().enumerate() { + let from_lookup = DeprecatedRegistry::lookup(&env, name); + assert!( + from_lookup.is_some(), + "all() entry at index {} (name={}) not found via lookup", + idx, + name + ); + let from_all = entries.get(idx as u32).unwrap(); + let from_lookup = from_lookup.unwrap(); + assert_eq!( + from_all, from_lookup, + "all()[{}] and lookup(\"{}\") must return identical entries", + idx, name + ); + } + } + + // --- emit_if_deprecated tests --- + + #[test] + fn test_emit_if_deprecated_known_does_not_panic() { + let env = Env::default(); + let contract_id = env.register(crate::PredictifyHybrid, ()); + env.as_contract(&contract_id, || { + // Must not panic — event should be emitted. + DeprecatedRegistry::emit_if_deprecated(&env, "verify_result"); + }); + } + + #[test] + fn test_emit_if_deprecated_unknown_is_noop() { + let env = Env::default(); + // No contract context needed — unknown name should be a pure no-op. + DeprecatedRegistry::emit_if_deprecated(&env, "nonexistent_function"); + // Reaching here without panic confirms the no-op behaviour. + } +} diff --git a/contracts/predictify-hybrid/src/lib.rs b/contracts/predictify-hybrid/src/lib.rs index 95b3f779..bc542ca1 100644 --- a/contracts/predictify-hybrid/src/lib.rs +++ b/contracts/predictify-hybrid/src/lib.rs @@ -26,6 +26,8 @@ mod fees; mod gas; mod governance; mod markets; +mod market_analytics; +mod performance_benchmarks; mod monitoring; mod oracles; mod reentrancy_guard; @@ -47,6 +49,7 @@ mod validation; // mod validation_tests; // disabled - API drift mod versioning; mod voting; +mod deprecated; // #[cfg(any())] // mod voting_invariants; @@ -167,6 +170,7 @@ use crate::config::{ ConfigManager, DEFAULT_PLATFORM_FEE_PERCENTAGE, MAX_PLATFORM_FEE_PERCENTAGE, MIN_PLATFORM_FEE_PERCENTAGE, }; +use crate::deprecated::DeprecatedRegistry; use crate::events::{emit_deprecated, EventEmitter}; use crate::gas::GasTracker; use crate::graceful_degradation::{OracleBackup, OracleHealth}; @@ -2590,7 +2594,7 @@ impl PredictifyHybrid { caller: Address, market_id: Symbol, ) -> Result { - emit_deprecated(&env, &Symbol::new(&env, "verify_result")); + DeprecatedRegistry::emit_if_deprecated(&env, "verify_result"); // Authenticate the caller caller.require_auth(); @@ -2943,7 +2947,7 @@ impl PredictifyHybrid { /// deterministic ordering test (see `resolution_event_ordering_tests`). #[deprecated(note = "Use resolve_market_manual or fetch_oracle_result + resolve_market_manual instead. This legacy stub will be removed in a future version.")] pub fn resolve_market(env: Env, market_id: Symbol) -> Result<(), Error> { - emit_deprecated(&env, &Symbol::new(&env, "resolve_market")); + DeprecatedRegistry::emit_if_deprecated(&env, "resolve_market"); // Use the resolution module to resolve the market // Temporarily disabled due to resolution module being disabled @@ -2958,6 +2962,31 @@ impl PredictifyHybrid { Ok(()) } + /// Returns the full list of deprecated contract entrypoints. + /// + /// This is a read-only query that returns every entry in the + /// [`DeprecatedRegistry`]. Off-chain tooling can call this to + /// discover deprecated functions and their recommended replacements + /// without parsing source code. + /// + /// # Returns + /// + /// A [`Vec`] containing one entry per deprecated + /// function. Each entry includes the function name, replacement, + /// deprecation date, and planned removal version. + /// + /// # Example + /// + /// ```rust,ignore + /// let deprecated = PredictifyHybrid::list_deprecated(env.clone()); + /// for entry in deprecated.iter() { + /// log!("Deprecated: {} → use {}", entry.name, entry.replacement); + /// } + /// ``` + pub fn list_deprecated(env: Env) -> Vec { + DeprecatedRegistry::all(&env) + } + /// Retrieves comprehensive analytics about market resolution performance. /// /// This function provides detailed statistics about how markets are being diff --git a/docs/DEPRECATED.md b/docs/DEPRECATED.md new file mode 100644 index 00000000..904a6111 --- /dev/null +++ b/docs/DEPRECATED.md @@ -0,0 +1,162 @@ +# Deprecated Entrypoints Reference + +> **Source of truth**: [`contracts/predictify-hybrid/src/deprecated.rs`](../contracts/predictify-hybrid/src/deprecated.rs) + +This document lists every deprecated entrypoint tracked by the `DeprecatedRegistry`. +For the overall deprecation lifecycle and policy, see [DEPRECATION_POLICY.md](DEPRECATION_POLICY.md). + +--- + +## Registry Overview + +The `DeprecatedRegistry` is a compile-time, storage-free registry that mirrors +the pattern established by `EventSchemaRegistry` in `events.rs`. Every +deprecated function is registered with: + +| Field | Type | Description | +|-------------------|----------|--------------------------------------------------| +| `name` | `Symbol` | Exact function name | +| `replacement` | `Symbol` | Recommended replacement (shortened for Symbol) | +| `since` | `Symbol` | ISO-8601 date the deprecation was introduced | +| `removal_version` | `Symbol` | Contract version for planned removal (`"TBD"` if not yet scheduled) | + +--- + +## Currently Deprecated Entrypoints + +### Contract-Level Entrypoints (`#[contractimpl]`) + +| Function | Replacement | Deprecated Since | Removal Version | Notes | +|----------|-------------|------------------|-----------------|-------| +| `verify_result` | [`fetch_oracle_result`](../contracts/predictify-hybrid/src/lib.rs) | 2026-06-28 | TBD | Legacy oracle verification stub; always returns `OracleUnavailable`. | +| `resolve_market` | [`resolve_market_manual`](../contracts/predictify-hybrid/src/lib.rs) | 2026-06-28 | TBD | Legacy resolution stub; only records statistics and invalidates cache. | + +### Module-Internal Deprecated Wrappers + +These functions are not exposed as `#[contractimpl]` entrypoints but are +tracked in the registry because their doc comments mark them as deprecated. + +| Function | Module | Replacement (fully-qualified) | Deprecated Since | Removal Version | +|----------|--------|-------------------------------|------------------|-----------------| +| `collect_fees` | `voting.rs` — `VotingManager` | `crate::fees::FeeManager::collect_fees` | 2026-06-28 | TBD | +| `transfer_fees` | `voting.rs` — `VotingUtils` | `crate::fees::FeeUtils::transfer_fees_to_admin` | 2026-06-28 | TBD | +| `calculate_fee_amount` | `voting.rs` — `VotingUtils` | `crate::fees::FeeCalculator::calculate_platform_fee` | 2026-06-28 | TBD | +| `process_creation_fee` | `markets.rs` — `MarketUtils` | `crate::fees::FeeManager::process_creation_fee` | 2026-06-28 | TBD | + +--- + +## Querying the Registry + +### On-Chain (Contract Call) + +```rust +// Read-only entrypoint — no auth required +let entries = PredictifyHybrid::list_deprecated(env.clone()); +for entry in entries.iter() { + // entry.name, entry.replacement, entry.since, entry.removal_version +} +``` + +### In Rust Code + +```rust +use crate::deprecated::DeprecatedRegistry; + +// Look up a single function +if let Some(entry) = DeprecatedRegistry::lookup(&env, "verify_result") { + log!("Use {} instead", entry.replacement); +} + +// Check if a function is deprecated +if DeprecatedRegistry::is_deprecated(&env, "resolve_market") { + // ... +} + +// Emit a deprecation event (safe no-op for non-deprecated names) +DeprecatedRegistry::emit_if_deprecated(&env, "verify_result"); +``` + +--- + +## Adding a New Entry + +1. **Register**: Add a new `match` arm in `DeprecatedRegistry::lookup()` and + a corresponding `push_back` in `DeprecatedRegistry::all()` inside + [`deprecated.rs`](../contracts/predictify-hybrid/src/deprecated.rs). + +2. **Bump count**: Update `DeprecatedRegistry::ENTRY_COUNT` to match. + +3. **Annotate**: Add `#[deprecated(note = "...")]` to the function and call + `DeprecatedRegistry::emit_if_deprecated(&env, "function_name")` in the + function body. + +4. **Document**: Add a row to the table in this file. + +5. **Test**: Add the name to the `names` array in + `test_all_entries_match_lookup` inside `deprecated.rs`. + +--- + +## Migration Guides + +### `verify_result` → `fetch_oracle_result` + +**Before:** +```rust +PredictifyHybrid::verify_result(env.clone(), caller, market_id); +``` + +**After:** +```rust +PredictifyHybrid::fetch_oracle_result(env.clone(), caller, market_id); +``` + +### `resolve_market` → `resolve_market_manual` + +**Before:** +```rust +PredictifyHybrid::resolve_market(env.clone(), market_id); +``` + +**After:** +```rust +PredictifyHybrid::resolve_market_manual(env.clone(), admin, market_id, outcome); +``` + +### `VotingManager::collect_fees` → `FeeManager::collect_fees` + +**Before:** +```rust +VotingManager::collect_fees(&env, admin, market_id); +``` + +**After:** +```rust +crate::fees::FeeManager::collect_fees(&env, admin, market_id); +``` + +--- + +## Testing + +Deprecation registry tests live in `deprecated.rs` (`#[cfg(test)] mod tests`): + +```bash +cargo test -p predictify-hybrid -- deprecated +``` + +Key test cases: + +| Test | What it verifies | +|------|-----------------| +| `test_lookup_known_entry` | Correct metadata for a known deprecated function | +| `test_lookup_unknown_returns_none` | Unknown names return `None` | +| `test_lookup_empty_string_returns_none` | Edge case: empty string | +| `test_is_deprecated_true` | Predicate returns `true` for all registered entries | +| `test_is_deprecated_false` | Predicate returns `false` for active functions | +| `test_all_returns_expected_count` | `all()` count matches `ENTRY_COUNT` | +| `test_all_entries_have_nonempty_replacement` | No entry has the same replacement as its name | +| `test_registry_entries_unique_names` | No duplicate names | +| `test_all_entries_match_lookup` | `all()` and `lookup()` agree on every entry | +| `test_emit_if_deprecated_known_does_not_panic` | Event emission for known entries succeeds | +| `test_emit_if_deprecated_unknown_is_noop` | Unknown names are a safe no-op | From 924c77eda21247a353e776f3fcb866d8b1ff5940 Mon Sep 17 00:00:00 2001 From: muhsar27 Date: Fri, 24 Jul 2026 00:39:55 +0100 Subject: [PATCH 2/2] chore: update dependencies in Cargo.lock --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 30e45726..fb75e2c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "ahash" @@ -595,9 +595,9 @@ checksum = "2bfcf67fea2815c2fc3b90873fae90957be12ff417335dfadc7f52927feb03b2" [[package]] name = "ethnum" -version = "1.5.0" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" +checksum = "40404c3f5f511ec4da6fe866ddf6a717c309fdbb69fbbad7b0f3edab8f2e835f" [[package]] name = "fastrand"