Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(torii): index whitelisted ERC20/ERC721 tokens #2277

Closed
wants to merge 25 commits into from

Conversation

lambda-0x
Copy link
Contributor

@lambda-0x lambda-0x commented Aug 8, 2024

Description

Related issue

Tests

  • Yes
  • No, because they aren't needed
  • No, because I need help

Added to documentation?

  • README.md
  • Dojo Book
  • No documentation needed

Checklist

  • I've formatted my code (scripts/prettier.sh, scripts/rust_fmt.sh, scripts/cairo_fmt.sh)
  • I've linted my code (scripts/clippy.sh, scripts/docs.sh)
  • I've commented my code
  • I've requested a review after addressing the comments

Summary by CodeRabbit

  • New Features

    • Added support for dynamic ERC contract indexing via a new command-line argument, enabling users to specify ERC contract addresses.
    • Introduced a new configuration file for defining ERC token contracts, enhancing application configurability.
    • Implemented new scripts to facilitate the deployment of ERC20 tokens on the StarkNet blockchain.
    • Enhanced the GraphQL API with new object types for querying ERC token balances and transfers.
  • Bug Fixes

    • Improved error handling in various methods related to ERC token processing and event fetching.
  • Documentation

    • Updated documentation to reflect new features and configuration options for ERC contracts.
  • Chores

    • Introduced new SQL migration scripts to establish tables for managing ERC contracts, balances, and transfers.

@lambda-0x lambda-0x marked this pull request as ready for review August 18, 2024 20:52
@lambda-0x lambda-0x requested a review from Larkooo August 18, 2024 20:52
Copy link

coderabbitai bot commented Aug 18, 2024

Walkthrough

Ohayo, sensei! The recent changes to the Torii application significantly enhance its capabilities for handling ERC contracts. Users can now dynamically index ERC20 and ERC721 tokens through a new command-line argument, alongside improved database schemas and GraphQL integration. These updates greatly enhance the application’s configurability and robustness, enabling seamless interaction with Ethereum standards.

Changes

Files Change Summary
bin/torii/src/main.rs Added erc_contracts command-line argument for dynamic contract indexing and modified main to handle this functionality.
bin/torii/torii.toml Introduced structured configuration for defining ERC20 and ERC721 contracts, enhancing configuration management.
crates/katana/scripts/deploy-erc20.sh New script for deploying ERC20 tokens on the StarkNet blockchain, simplifying the deployment process.
crates/torii/core/Cargo.toml Added toml crate as a workspace member for improved TOML file management.
crates/torii/core/src/engine.rs Enhanced Engine struct to include ERC token mapping and refactored event fetching to an asynchronous model for better performance.
crates/torii/core/src/processors/* Introduced event processors for managing ERC20 and ERC721 transfers with validation and logging functionalities.
crates/torii/core/src/sql.rs Updated Sql struct to manage ERC contract registrations and handle token transfers with new methods for both ERC20 and ERC721.
crates/torii/core/src/types.rs Added ToriiConfig and ErcContract structs for ERC contract configurations, along with an ErcType enum for contract types.
crates/torii/graphql/src/constants.rs Introduced new constants for ERC balance and token types to enhance GraphQL schema definitions.
crates/torii/graphql/src/mapping.rs Added static references for ERC token mappings to improve data access within the GraphQL layer.
crates/torii/graphql/src/object/erc/* New modules to handle ERC balances and tokens, including resolvers for fetching balance data via GraphQL queries.
crates/torii/graphql/src/schema.rs Updated GraphQL schema to integrate new ERC balance and token object types.
crates/torii/migrations/20240803102207_add_erc.sql New SQL migration script to create essential tables for managing ERC contracts, balances, and transfer records.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant Config
    participant Database
    participant GraphQL

    User->>CLI: Start application with erc_contracts
    CLI->>Config: Load ERC contracts from argument
    Config->>Database: Register contracts
    Database-->>Config: Confirmation of registration
    CLI-->>User: Application ready

    User->>GraphQL: Query for ERC balance
    GraphQL->>Database: Fetch balance data
    Database-->>GraphQL: Return balance info
    GraphQL-->>User: Display balance
Loading

Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 6dee6c8 and 1240bdf.

Files selected for processing (1)
  • crates/torii/migrations/20240803102207_add_erc.sql (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • crates/torii/migrations/20240803102207_add_erc.sql

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Outside diff range, codebase verification and nitpick comments (22)
crates/katana/scripts/deploy-erc20.sh (1)

1-1: Add a shebang for clarity and portability.

Consider adding a shebang (e.g., #!/bin/bash) at the top of the script to specify the shell environment.

+#!/bin/bash
starkli deploy --account account.json --keystore signer.json --keystore-password "" 0x02a8846878b6ad1f54f6ba46f5f40e11cee755c677f130b2c4b60566c9003f1f 0x626c6f62 0x424c42 0x8 u256:10000000000 0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828c
Tools
Shellcheck

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)

bin/torii/torii.toml (1)

6-8: Consider adding comments for clarity.

Adding comments to explain the purpose of each field in the configuration can improve readability and maintainability.

erc_contracts = [
    { type = "ERC20", contract_address = "0x07fc13cc1f43f0b0519f84df8bf13bea4d9fd5ce2d748c3baf27bf90a565f60a", start_block = 0 } # Example ERC20 contract
]
crates/torii/core/src/processors/erc20_transfer.rs (3)

1-7: Ensure appropriate error handling and logging.

The imports used are relevant and necessary for the functionality. However, consider adding more detailed error handling and logging to capture potential issues during event processing. This will aid in debugging and monitoring.


26-34: Validate event structure carefully.

The validate method checks the structure of the event. Ensure that this validation logic aligns with the expected format of ERC20 transfer events. Consider logging validation failures for better traceability.


36-57: Review the process method for completeness.

The process method handles the core logic of processing an ERC20 transfer. Ensure that all necessary steps, such as updating the database and logging the transfer, are correctly implemented. Consider adding more detailed logging for successful and failed operations.

crates/torii/core/src/processors/erc20_legacy_transfer.rs (3)

1-7: Ensure appropriate error handling and logging.

Similar to the erc20_transfer.rs file, consider enhancing error handling and logging to capture potential issues during the processing of legacy events.


26-34: Validate event structure carefully.

The validate method checks for a specific structure in legacy events. Ensure this aligns with the expected format of legacy ERC20 transfer events. Consider logging validation failures for better traceability.


36-57: Review the process method for completeness.

The process method should handle all necessary steps for processing a legacy ERC20 transfer. Ensure that differences from the standard ERC20 processing are correctly implemented and logged.

crates/torii/core/src/processors/erc721_transfer.rs (3)

1-7: Ensure appropriate error handling and logging.

As with the other processor files, consider enhancing error handling and logging to capture potential issues during the processing of ERC721 events.


26-34: Validate event structure carefully.

The validate method checks for a specific structure in ERC721 events. Ensure this aligns with the expected format of ERC721 transfer events. Consider logging validation failures for better traceability.


37-58: Review the process method for completeness.

The process method should handle all necessary steps for processing an ERC721 transfer. Ensure that differences from ERC20 processing are correctly implemented and logged.

crates/torii/core/src/types.rs (3)

89-93: Add documentation for ToriiConfig.

The ToriiConfig struct is well-defined, but adding documentation comments would improve clarity and maintainability.

+ /// Configuration for Torii, including ERC contracts to index.
pub struct ToriiConfig {

103-108: Add documentation for ErcContract.

The ErcContract struct is well-defined, but adding documentation comments would improve clarity and maintainability.

+ /// Represents an ERC contract with its address, start block, and type.
pub struct ErcContract {

110-115: Add documentation for ErcType.

The ErcType enum is well-defined, but adding documentation comments would improve clarity and maintainability.

+ /// Enum representing the type of ERC contract, either ERC20 or ERC721.
pub enum ErcType {
crates/torii/graphql/src/object/erc/erc_balance.rs (3)

15-16: Add documentation for ErcBalanceObject.

The ErcBalanceObject struct is defined but lacks documentation. Adding comments would improve clarity and maintainability.

+ /// Represents a GraphQL object for ERC balance.
pub struct ErcBalanceObject;

58-100: Optimize the SQL query in fetch_erc_balances.

The fetch_erc_balances function uses a SQL query that joins multiple tables. Ensure that the necessary indexes are present on the database to optimize this query.

Consider adding indexes on balances.account_address, tokens.id, and contracts.contract_address to improve query performance.


110-119: Add documentation for BalanceQueryResultRaw.

The BalanceQueryResultRaw struct is defined but lacks documentation. Adding comments would improve clarity and maintainability.

+ /// Represents a raw query result for ERC balance.
struct BalanceQueryResultRaw {
crates/torii/graphql/src/schema.rs (2)

13-14: Add documentation for new imports.

The new imports for ErcBalanceObject and ErcTokenObject are correct, but adding documentation comments would improve clarity.

+ // Importing ERC objects for GraphQL schema.
use crate::object::erc::erc_balance::ErcBalanceObject;
use crate::object::erc::erc_token::ErcTokenObject;

33-33: Clarify the comment about QUERY_TYPE_NAME.

The comment questioning the necessity of providing QUERY_TYPE_NAME is useful, but consider clarifying it further or addressing it in a separate issue if needed.

//? why we need to provide QUERY_TYPE_NAME object here when its already passed to Schema?
+ // Consider investigating this further or documenting the reason.
crates/torii/graphql/src/mapping.rs (2)

146-150: Add documentation for ERC_BALANCE_TYPE_MAPPING.

The ERC_BALANCE_TYPE_MAPPING is defined but lacks documentation. Adding comments would improve clarity and maintainability.

+ /// Mapping for ERC balance type in GraphQL.
pub static ref ERC_BALANCE_TYPE_MAPPING: TypeMapping = IndexMap::from([

152-157: Add documentation for ERC_TOKEN_TYPE_MAPPING.

The ERC_TOKEN_TYPE_MAPPING is defined but lacks documentation. Adding comments would improve clarity and maintainability.

+ /// Mapping for ERC token type in GraphQL.
pub static ref ERC_TOKEN_TYPE_MAPPING: TypeMapping = IndexMap::from([
bin/torii/src/main.rs (1)

123-126: Add documentation for erc_contracts argument.

The erc_contracts argument is well-defined, but adding documentation comments would improve clarity and maintainability.

+ /// Optional list of ERC contract addresses to index, specified in the format `erc_type:address:start_block`.
#[arg(long, value_parser = parse_erc_contracts)]

crates/torii/migrations/20240803102207_add_erc.sql Outdated Show resolved Hide resolved
crates/torii/core/src/types.rs Show resolved Hide resolved
crates/torii/core/src/types.rs Show resolved Hide resolved
Comment on lines +32 to +55
impl ResolvableObject for ErcBalanceObject {
fn resolvers(&self) -> Vec<Field> {
let account_address = "account_address";
let argument = InputValue::new(
account_address.to_case(Case::Camel),
TypeRef::named_nn(TypeRef::STRING),
);

let field = Field::new(self.name().0, TypeRef::named_list(self.type_name()), move |ctx| {
FieldFuture::new(async move {
let mut conn = ctx.data::<Pool<Sqlite>>()?.acquire().await?;
let address: String = extract::<String>(
ctx.args.as_index_map(),
&account_address.to_case(Case::Camel),
)?;

let erc_balances = fetch_erc_balances(&mut conn, &address).await?;

Ok(Some(Value::List(erc_balances)))
})
})
.argument(argument);
vec![field]
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure proper error handling in resolvers.

The resolvers method in ResolvableObject for ErcBalanceObject should ensure that errors are properly logged or handled, especially when fetching balances.

let field = Field::new(self.name().0, TypeRef::named_list(self.type_name()), move |ctx| {
    FieldFuture::new(async move {
        let mut conn = ctx.data::<Pool<Sqlite>>()?.acquire().await?;
        let address: String = extract::<String>(
            ctx.args.as_index_map(),
            &account_address.to_case(Case::Camel),
        )?;

        match fetch_erc_balances(&mut conn, &address).await {
            Ok(erc_balances) => Ok(Some(Value::List(erc_balances))),
            Err(e) => {
                warn!("Failed to fetch ERC balances: {}", e);
                Err(e.into())
            }
        }
    })
})
.argument(argument);

bin/torii/src/main.rs Show resolved Hide resolved
bin/torii/src/main.rs Show resolved Hide resolved
bin/torii/src/main.rs Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range, codebase verification and nitpick comments (1)
crates/torii/core/src/sql.rs (1)

Ohayo, sensei! I've reviewed the handle_erc20_transfer function, which manages ERC20 token transfers, including fetching token details and updating balances. While the logic seems correct, the error handling could be improved to avoid potential panics caused by unwrap calls. Consider using more robust error handling strategies to ensure the function handles unexpected data gracefully.

  • Improve error handling: Replace unwrap calls with proper error handling to avoid potential panics.
Analysis chain

Line range hint 255-437: Verify ERC20 transfer handling logic and error handling.

The handle_erc20_transfer method includes logic for fetching token details and updating balances. Ensure the transfer handling logic is correct and robust against errors.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the transfer handling logic and error handling in `handle_erc20_transfer`.

# Test: Check for method usage and error handling. Expect: Correct transfer logic and robust error handling.
rg --type rust 'pub async fn handle_erc20_transfer'

Length of output: 142


Script:

#!/bin/bash
# Extract the implementation of `handle_erc20_transfer` for detailed analysis.
ast-grep --lang rust --pattern 'pub async fn handle_erc20_transfer<P: Provider + Sync>($_) {
  $$$
}' crates/torii/core/src/sql.rs

Length of output: 132


Script:

#!/bin/bash
# Use `rg` to search for the `handle_erc20_transfer` function and include surrounding lines for context.
rg --type rust 'pub async fn handle_erc20_transfer' -A 50 crates/torii/core/src/sql.rs

Length of output: 1960


Script:

#!/bin/bash
# Continue retrieving more lines to capture the complete implementation of the `handle_erc20_transfer` function.
rg --type rust 'pub async fn handle_erc20_transfer' -A 100 crates/torii/core/src/sql.rs

Length of output: 4053


Script:

#!/bin/bash
# Retrieve additional lines to capture the complete implementation of the `handle_erc20_transfer` function.
rg --type rust 'pub async fn handle_erc20_transfer' -A 150 crates/torii/core/src/sql.rs

Length of output: 6383

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range, codebase verification and nitpick comments (8)
crates/torii/graphql/src/tests/metadata_test.rs (1)

105-105: Check for potential configuration needs with HashMap.

Adding a HashMap::default() might suggest future configurability. Ensure that any necessary configurations are planned or documented.

crates/torii/grpc/src/server/tests/entities_test.rs (1)

112-112: Ensure HashMap::default() is necessary in Engine::new.

The inclusion of HashMap::default() in Engine::new suggests future configurability. Verify its necessity and document any potential configurations.

crates/torii/graphql/src/tests/mod.rs (1)

366-366: Ensure HashMap::default() is necessary in Engine::new.

The inclusion of HashMap::default() in Engine::new suggests future configurability. Verify its necessity and document any potential configurations.

crates/torii/core/src/sql_test.rs (2)

122-122: Check for potential configuration needs with HashMap.

Adding a HashMap::default() might suggest future configurability. Ensure that any necessary configurations are planned or documented.


281-281: Ensure HashMap::default() usage is appropriate.

The addition of HashMap::default() should be reviewed to confirm its necessity and appropriateness in the context of the test.

crates/torii/graphql/src/tests/subscription_test.rs (3)

151-151: Check for potential configuration needs with HashMap.

Adding a HashMap::default() might suggest future configurability. Ensure that any necessary configurations are planned or documented.


256-256: Ensure HashMap::default() usage is appropriate.

The addition of HashMap::default() should be reviewed to confirm its necessity and appropriateness in the context of the test.


385-385: Check for potential configuration needs with HashMap.

Adding a HashMap::default() might suggest future configurability. Ensure that any necessary configurations are planned or documented.

Copy link

codecov bot commented Aug 19, 2024

Codecov Report

Attention: Patch coverage is 15.55270% with 657 lines in your changes missing coverage. Please review.

Project coverage is 66.38%. Comparing base (4f76fd7) to head (1240bdf).
Report is 92 commits behind head on main.

Files with missing lines Patch % Lines
crates/torii/core/src/sql.rs 1.75% 336 Missing ⚠️
...rates/torii/graphql/src/object/erc/erc_transfer.rs 21.55% 91 Missing ⚠️
crates/torii/graphql/src/object/erc/erc_balance.rs 25.60% 61 Missing ⚠️
bin/torii/src/main.rs 0.00% 48 Missing ⚠️
...rates/torii/core/src/processors/erc721_transfer.rs 0.00% 34 Missing ⚠️
...torii/core/src/processors/erc20_legacy_transfer.rs 0.00% 26 Missing ⚠️
crates/torii/core/src/processors/erc20_transfer.rs 0.00% 26 Missing ⚠️
crates/torii/core/src/types.rs 0.00% 19 Missing ⚠️
crates/torii/core/src/engine.rs 80.30% 13 Missing ⚠️
crates/torii/graphql/src/object/erc/erc_token.rs 66.66% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2277      +/-   ##
==========================================
+ Coverage   66.18%   66.38%   +0.20%     
==========================================
  Files         352      358       +6     
  Lines       46739    47005     +266     
==========================================
+ Hits        30933    31205     +272     
+ Misses      15806    15800       -6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add erc721_legacy_transfer

Copy link
Contributor Author

@lambda-0x lambda-0x Aug 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it wont be possible to add it with current implementation because both erc20_legacy_transer and erc721_legacy_transfer would have same event format data which would make it not possible to distinguish between them.

i.e.  

erc20_legacy_transfer:

key: [hash("Transfer")]
data: [from, to, value.0, value.1]

erc721_legacy_transfer:

key: [hash("Transfer")]
data: [from, to, token_id.0, token_id.1]

if we want to support this we would need to change how event proccessor are selected in the engine

crates/torii/core/src/sql.rs Show resolved Hide resolved
crates/torii/core/src/sql.rs Show resolved Hide resolved
Copy link
Collaborator

@glihm glihm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work @lambda-0x on this, some comments and general note on formatting. 👍

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should definitely start to have a sql module and splitting up the code for easier addition/maintenance. :)

);
}

// Update balances in erc20_balance table
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the manipulation of balances here. Because until we reach head of the chain, the balance will not be accurate.

Or do we assume that we should reach the head of the chain pretty quickly, and then it's fine to keep updating the balances?

From a client perspective, let's take Controller as an example, we may want to query the current balance with regular interval when it's needed. In this case, using the balance in the DB makes little sense? Or once again we assume we should be quickly in the head of chain, and pulling data from the DB or the chain should return the same result.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we assume that we should reach the head of the chain pretty quickly

yeah thats the assumption we make

say we only provide the info of which tokens are owned by user for that also we would need to index all the transfer events anyways and if we are lagging behind in indexing controller might not get info about some of the token.

so even by not keeping the balance we dont fully solve that issue. and not to mention that if user has large amount of tokens controller would need to make a rpc call to get balance for each of them.

self.query_queue.enqueue(
update_query,
vec![
Argument::String(format!("{:#x}:{:#x}", from, contract_address)),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed with you @lambda-0x and also with @Larkooo earlier, we should have more consistency on formatting the Felt with {:#066x} or 0x{:064x}.

We may have in Dojo a trait we implement for Felt to have the whole stack formatting the same way?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i did a sanity check on the Felt type from starknet-core and looks like it differs from std implementation of printing hex values, so doing {:#064x} does actually print 0x{64 characters padded with 0}. so we might not need to change the implementation unless i misunderstood your point.

image

@glihm
Copy link
Collaborator

glihm commented Sep 16, 2024

@lambda-0x ideally rebased after #2423 is merged (or next release we should be tonight).

@lambda-0x
Copy link
Contributor Author

lambda-0x commented Sep 18, 2024

superseded by #2442

@lambda-0x lambda-0x closed this Sep 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants