Critical | Prioritize reserve asset transfer over teleport | Using teleports from multiple origins as default token transfer method requires bilateral trust in issuance management and increases risk | Prioritize Reserve Asset transfers and use trusted reserves like Asset Hub; carefully configure xcm-executor permissions |
Critical | Use appropriate origin checks | Open access on extrinsics without checks may allow unauthorized actions that can compromise security | Add access control checks to limit access to specific users or roles |
Critical | Avoid unbounded iteration | Unbounded iterations over large data structures can lead to resource exhaustion and potential denial of service | Implement limits or use a bounded storage map for these iterations |
Critical | Unchecked input data | Lack of input validation can lead to unexpected behaviors and potential vulnerabilities | Validate input data before processing to ensure safe and predictable behavior |
Critical | Avoid unwrap usage inside runtime | Using unwrap() or expect without proper error handling can lead to runtime panics and crashes | Handle errors gracefully with Result or Option types to prevent panics |
Critical | Use benchmarking for accurate dynamic weights | Using hardcoded weights for extrinsics can lead to inaccurate resource estimations and performance issues. | Implement benchmarking to dynamically assess the weights of functions, ensuring they accurately reflect execution costs |
High | Make proper usage of XCM Junctions | Misuse of junction types (especially GeneralIndex) for purposes beyond their intended entity representation can lead to incorrect path routing | Use junctions strictly for their intended purpose of representing entities in Location paths; propose RFCs for new needs |
High | Properly setup XCM Barrier | Improperly configured XCM executor barriers can allow unauthorized free execution from any origin | Implement restrictive barriers with explicit authorization for unpaid execution and clear documentation of intended uses |
High | Ensure consistent asset registration by adhering to host chain schema | Inconsistent asset registration schemas across chains can lead to integration issues and complications in cross-chain asset handling | Study and follow the host chain's established schema for asset registration to maintain consistency |
High | Benchmark Extrinsic Worst-case Scenario | Without benchmarks for worst-case scenarios, execution weights may be underestimated | Benchmark worst-case paths and update extrinsics to reflect these cases accurately |
High | Keep dependencies up to date | Using outdated libraries may lead to security and compatibility issues | Regularly update dependencies to the latest stable versions for improved security and compatibility |
High | Avoid the usage of pseudo random numbers | Using non-deterministic methods for selection can introduce manipulation opportunities | Adopt deterministic selection methods to ensure fairness |
High | Use safe arithmetic operations | Unchecked arithmetic operations can lead to overflow errors | Use safe math functions such as checked_add to prevent overflows |
High | Be careful with storage growth | Allowing unlimited entries in storage structures can lead to overflow and performance issues | Use bounded storage collections to prevent uncontrolled growth |
High | Prevent inconsistent state by distributing finalization costs | Relying on a single transaction to finalize multiple operations can lead to errors if it fails | Use a claim-based or distributed finalization approach to avoid reliance on a single transaction |
High | Use atomic operations to prevent state inconsistencies | Modifying multiple resources without transactional integrity may leave the system in an inconsistent state | Implement rollback mechanisms to ensure consistency in case of failure |
High | Avoid redundant storage access in mutations | Using both try_mutate and insert leads to unnecessary storage accesses | Use try_mutate or try_mutate_exists to read, modify, and write in a single step |
High | Prevent unnecessary reads and writes in storage access | Frequent reads and writes to storage without optimization can degrade performance | Use efficient storage access methods such as try_mutate to combine reads and writes |
High | Implement try-state Hook | The absence of try-state hooks prevents runtime sanity checks, making it harder to ensure that the storage state is sensible after upgrades | Implement the try-state hook to perform thorough state checks without altering storage |
Medium | Implement proper XCM fee management | Using the FeeManager unit type without consideration leads to unintended fee burning rather than proper fee handling | Implement proper FeeManager that either deposits or distributes fees, with clear handling of fee-exempt locations |
Medium | Avoid unrestricted XCM Execution | Allowing arbitrary users to send unrestricted XCM instructions, especially Transact operations, can create security vulnerabilities | Disable or strictly limit XCM execution permissions unless specifically required; restrict to privileged users |
Medium | Remove deprecated storage getters | Using deprecated storage getters may lead to compatibility issues in future versions | Replace deprecated getters with the recommended methods in updated frameworks |
Medium | Avoid hardcoded parameters and values | Hardcoding parameters can reduce flexibility and adaptability to different environments | Use configurable parameters to enhance adaptability |
Medium | Include tests for edge cases | Omitting tests for boundary cases can lead to unhandled conditions and bugs | Include tests for boundary conditions to improve reliability |
Medium | Include extrinsic documentation | Extrinsics without documentation can lead to misunderstandings regarding usage permissions and error handling | Provide detailed documentation for each extrinsic, including functionality and parameters |
Medium | Include error documentation | Lack of documentation on error variants can make debugging difficult and slow | Document each error variant with its cause and handling details for easier troubleshooting |
Medium | Provide event documentation | Events emitted by the runtime lack proper documentation, making it harder for users to understand their purpose | Provide detailed comments for each event to explain its purpose and usage |
Medium | Provide pallet configuration documentation | Pallet configuration items that lack documentation can confuse developers and users | Document each pallet configuration item with a brief description of its purpose and constraints |
Medium | Modularize large files | Large files reduce readability and make navigation difficult for developers | Provide detailed comments for each event to explain its purpose and usage |
Medium | Break down complex functions | Complex functions are harder to test, understand, and maintain, increasing the risk of errors | Apply the single responsibility principle to simplify functions and improve readability |
Medium | Enhance performance with efficient data structures | Choosing inefficient data structures can lead to slowdowns and increased resource usage | Use search-efficient data structures like HashSet or BTreeSet for frequent lookups |
Medium | Define constants to replace magic numbers | Magic numbers make code hard to understand and maintain due to lack of context | Define constants with descriptive names for better readability |
Medium | Implement Proper Interface Segregation | Overloaded interfaces make code harder to maintain and test due to complex dependencies | Separate interfaces into smaller, focused traits to improve modularity |
Medium | Make BoundedVec size configurable | Hardcoded BoundedVec sizes limit flexibility and adaptability | Use configurable parameters for vector sizes to enhance flexibility |
Medium | Enhance logging in migration scripts | Insufficient logging in migration scripts makes tracing progress and debugging harder | Add descriptive logs to migration scripts to track steps and conditions |
Medium | Avoid redundant data structures | Storing the same data in multiple locations increases complexity and risks inconsistencies | Use a single structure as the primary source for data, and avoid duplicating fields across storage structures |
Medium | Implement tests for all error cases | Lack of tests for error cases in extrinsics can lead to unhandled scenarios and unpredictable behavior | Add tests that verify expected errors are emitted when invalid inputs or conditions are encountered |
Medium | Avoid resource intensive execution inside hooks | Performing complex or large computations in hooks like on_finalize can slow block execution and reduce network performance | Distribute computations across extrinsics or allow users to manually trigger them outside of hooks. |
Medium | Transition away from Currency trait | Using the deprecated Currency trait limits compatibility and functionality in future Substrate updates | Replace Currency with fungible traits, like Inspect and Mutate , for modular, future-proof balance management |
Low | Use appropriate naming conventions | Inconsistent naming conventions reduce code readability | Adopt consistent, descriptive naming conventions across the codebase |
Low | Avoid unnecessary cloning | Redundant code and cloning increase code size and decrease efficiency | Remove unused code and optimize cloning operations |
Low | Avoid hardcoded error messages | Hardcoded error messages make localization and updates difficult | Centralize error messages for easier updates and localization |
Low | Adopt enumerations for optional input | Using basic types instead of enums can lead to errors and reduces readability | Use enums to represent distinct categories for better readability and robustness |
Low | Implement descriptive logging | Minimal logging lacks context, making troubleshooting difficult | Include context and relevant details in log messages |
Low | Remove unnecessary return values | Returning values that are not modified or needed increases code complexity | Remove unnecessary return values for simplicity |
Low | Avoid repetitive generic type instantiation | Defining complex generic types repeatedly increases verbosity and reduces maintainability | Use a type alias for specific instances of generic types to avoid duplication and enhance code readability |
Low | Update benchmarks with deprecated syntax | Deprecated benchmarking syntax can lead to compatibility issues and lacks support for newer features | Use the updated #[benchmarks] module syntax to improve maintainability, readability, and future compatibility |
Low | Expose runtime APIs for key functionalities | Failing to expose useful internal functions via runtime APIs limits client access and reduces system usability | Implement Runtime APIs to expose key functions, enabling users and clients to access essential data |
Low | Avoid unused code | Unused code can clutter a codebase, making it more difficult to read, maintain, and optimize. | Regularly remove unused functions, variables, and redundant logic to keep code clean and efficient |
Informational | Use proper naming criteria | Using commonly used terminology (like "foreign") can cause confusion and misunderstandings, especially when integrating with existing systems | Research ecosystem terminology and choose unique, clear names that avoid overlap with existing well-known terms |
Informational | Maintain consistent documentation standards | Inconsistent documentation across modules creates knowledge gaps | Establish a consistent documentation standard across the codebase |
Informational | Avoid typographical errors | Typos reduce professionalism and may confuse readers | Perform proofreading to catch typos and improve clarity |
Informational | Make backend logic Frontend-Agnostic | Frontend-specific values in backend code may lead to conflicts with backend design | Ensure backend remains frontend-agnostic to avoid inconsistencies |