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

F/swap routes fix #19

Merged
merged 10 commits into from
Nov 8, 2024
Merged

F/swap routes fix #19

merged 10 commits into from
Nov 8, 2024

Conversation

maxrobot
Copy link
Contributor

@maxrobot maxrobot commented Oct 31, 2024

In this PR added is:

  • pagination for the queries
  • bump of deps

Off-topic:

  • removed some of the tests as they used useless numbers

Summary by CodeRabbit

Release Notes

  • New Features

    • Pagination implemented for the get_all_routes function.
    • Added new documentation for administrative functionalities related to Swap contracts.
  • Improvements

    • Updated Rust toolchain version to 1.78.0 for enhanced performance and features.
    • Streamlined error handling and improved readability in various contract functions and tests.
    • Enhanced functionality for managing swap routes with new parameters for pagination.
  • Bug Fixes

    • Adjusted expected error messages in authorization tests to reflect updated behavior.
  • Chores

    • Removed deprecated files and streamlined project structure for better organization.

Copy link

coderabbitai bot commented Oct 31, 2024

Walkthrough

The pull request introduces several updates across multiple files related to a Rust project. Key changes include the upgrade of the Rust toolchain version to 1.78.0 in workflow and configuration files, restructuring of dependencies in Cargo.toml, and the addition of a new documentation file. Several files related to testing and contract functionality have been modified for improved readability and organization, with updates to function signatures and error handling. Additionally, some files have been deleted, indicating a shift in project structure and dependency management.

Changes

File Path Change Summary
.github/workflows/rust.yaml Updated Rust toolchain version from 1.74.0 to 1.78.0 in test and lints jobs.
Cargo.toml Restructured workspace settings; added dependencies; removed specific package configuration.
Changelog.md Updated version from 1.0.2 to 1.1.0; added new entry for pagination in get_all_routes.
Makefile.toml Deleted file containing task definitions for managing the Rust project.
contracts/swap/.gitignore Deleted file listing patterns to ignore in Git.
contracts/swap/.gitpod.Dockerfile Deleted Dockerfile for Gitpod workspace setup.
contracts/swap/.gitpod.yml Deleted Gitpod workspace configuration file.
contracts/swap/Cargo.toml Updated package version to 1.1.0; shifted to workspace dependencies.
contracts/swap/rustfmt.toml Deleted configuration file for Rust code formatting.
contracts/swap/src/contract.rs Modified imports, streamlined execute and migrate functions, updated query return type.
contracts/swap/src/msg.rs Updated serialization attributes to cw_serde; added pagination parameters to GetAllRoutes.
contracts/swap/src/queries.rs Improved code formatting and simplified expressions.
contracts/swap/src/state.rs Added DEFAULT_LIMIT constant; updated get_all_swap_routes to accept pagination parameters.
contracts/swap/src/swap.rs Restructured imports; streamlined error handling in swap functions.
contracts/swap/src/testing/authz_tests.rs Organized imports; updated error handling in tests.
contracts/swap/src/testing/config_tests.rs Updated usage of mock_info to message_info in tests.
contracts/swap/src/testing/integration_logic_tests.rs Deleted file containing integration tests for swap functionality.
contracts/swap/src/testing/integration_realistic_tests_exact_quantity.rs Improved code formatting within tests.
contracts/swap/src/testing/migration_test.rs Updated test logic for contract migration to version 101.
contracts/swap/src/testing/mod.rs Removed integration_logic_tests module from imports.
contracts/swap/src/testing/queries_tests.rs Updated usage of message_info in tests; modified assertions for clarity.
contracts/swap/src/testing/test_utils.rs Consolidated imports and updated function signatures for clarity.
contracts/swap/src/types.rs Updated serialization attributes to cw_serde for multiple structs and enums.
docs/admin.md New documentation file outlining administrative functionalities for managing Swap contracts.
rust-toolchain.toml Updated Rust toolchain version from 1.73.0 to 1.78.0.
contracts/swap/src/admin.rs Reformatted function signatures for readability; error handling remains unchanged.
contracts/swap/src/helpers.rs Reformatted function signatures for improved readability; logic remains unchanged.
contracts/swap/src/testing/integration_realistic_tests_min_quantity.rs Improved code formatting within tests.
contracts/swap/src/testing/storage_tests.rs Enhanced code readability through formatting adjustments.
contracts/swap/src/testing/swap_tests.rs Streamlined imports and assertions for improved clarity.

Poem

In the land of code where rabbits play,
New tools and paths have come our way.
With upgrades and changes, we hop with glee,
A brighter future for you and me! 🐰✨
Dependencies shift, and tests align,
In the garden of Rust, our projects shine!


🪧 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>, please review it.
    • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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 using 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.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

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: 12

🧹 Outside diff range and nitpick comments (12)
Changelog.md (1)

23-24: Consider adding the specific version of serde-json-wasm.

While the changelog entry about bumping serde-json-wasm is good, it would be more helpful to include the specific version numbers for future reference.

 - Added pagination to `get_all_routes`
-- Bump version of `serde-json-wasm`
+- Bump version of `serde-json-wasm` from X.Y.Z to A.B.C
contracts/swap/src/msg.rs (1)

66-69: Add documentation for pagination parameters.

The pagination implementation follows CosmWasm patterns, but could benefit from documentation explaining:

  • The format of start_after tuple (presumably source_denom, target_denom)
  • The default and maximum values for limit

Add documentation like this:

    GetAllRoutes {
+       /// Optional pagination cursor, where (source_denom, target_denom) tuple
+       /// represents the last route from the previous query
        start_after: Option<(String, String)>,
+       /// Optional limit for the number of routes to return.
+       /// If not specified, a reasonable default will be used.
        limit: Option<u32>,
    },
contracts/swap/src/state.rs (1)

43-58: LGTM: Well-implemented pagination with a minor suggestion.

The pagination implementation follows best practices and handles edge cases correctly. Consider adding a comment explaining the sorting order of the routes for better maintainability.

 pub fn get_all_swap_routes(
     storage: &dyn Storage,
     start_after: Option<(String, String)>,
     limit: Option<u32>,
 ) -> StdResult<Vec<SwapRoute>> {
     let limit = limit.unwrap_or(DEFAULT_LIMIT) as usize;
 
     let start_bound = start_after
         .as_ref()
         .map(|(s, t)| Bound::inclusive((s.clone(), t.clone())));
 
+    // Routes are sorted by (source_denom, target_denom) in ascending order
     let routes = SWAP_ROUTES
         .range(storage, start_bound, None, Order::Ascending)
         .take(limit)
         .map(|item| item.map(|(_, route)| route))
         .collect::<StdResult<Vec<SwapRoute>>>()?;
contracts/swap/src/testing/authz_tests.rs (1)

38-38: Consider breaking long lines for better readability

While condensing these initialization calls improves vertical space usage, the resulting lines are quite long. Consider breaking them at logical points if they exceed your project's line length guidelines.

-    let contr_addr = init_self_relaying_contract_and_get_address(&wasm, &owner, &[str_coin("1_000", USDT, Decimals::Six)]);
+    let contr_addr = init_self_relaying_contract_and_get_address(
+        &wasm,
+        &owner,
+        &[str_coin("1_000", USDT, Decimals::Six)]
+    );

Also applies to: 54-55

contracts/swap/src/testing/migration_test.rs (2)

10-10: Consider splitting the long import line for better readability.

The import line is quite long and imports multiple types. Consider splitting it into multiple lines for better readability.

-use injective_std::types::cosmwasm::wasm::v1::{MsgMigrateContract, MsgMigrateContractResponse, QueryContractInfoRequest, QueryContractInfoResponse};
+use injective_std::types::cosmwasm::wasm::v1::{
+    MsgMigrateContract,
+    MsgMigrateContractResponse,
+    QueryContractInfoRequest,
+    QueryContractInfoResponse,
+};

Line range hint 36-48: Improve error handling and add documentation for initial funds.

  1. The code uses multiple unwrap() calls which could panic. Consider using proper error handling.
  2. The purpose of initializing with 1000 USDT should be documented.
 let swap_v101_address: String = wasm
     .instantiate(
         swap_v101_code_id,
         &V101InstantiateMsg {
             admin: Addr::unchecked(owner.address()),
             fee_recipient: FeeRecipient::SwapContract,
         },
         Some(&owner.address()),
         Some("swap-contract"),
+        // Initialize with 1000 USDT for <document purpose here>
         &[str_coin("1_000", USDT, Decimals::Six)],
         &owner,
     )
-    .unwrap()
+    .expect("Failed to instantiate swap contract")
     .data
     .address;
.github/workflows/rust.yaml (1)

Line range hint 64-64: Fix inconsistent toolchain version in test step.

The test step is still using toolchain version 1.74.0 while other steps have been updated to 1.78.0. This inconsistency could lead to different behavior between linting and testing environments.

Apply this diff to maintain consistency:

-          toolchain: 1.74.0
+          toolchain: 1.78.0
🧰 Tools
🪛 actionlint

33-33: the runner of "actions-rs/toolchain@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

contracts/swap/src/swap.rs (1)

78-78: Enhance insufficient funds error message

Consider adding more context to help users understand the exact shortfall.

-            return Err(ContractError::InsufficientFundsProvided(fp_coins, required_input));
+            return Err(ContractError::InsufficientFundsProvided(
+                fp_coins,
+                required_input,
+                format!("Required {} {}, but only {} {} provided", 
+                    required_input, 
+                    source_denom,
+                    fp_coins,
+                    source_denom
+                )
+            ));
contracts/swap/src/testing/queries_tests.rs (1)

533-533: Enhance pagination test coverage.

While the basic pagination test is good, consider adding more test cases to verify:

  • Different page sizes
  • Using start_after parameter
  • Edge cases (empty results, last page)
  • Consistency of results across multiple paginated requests

Example test cases:

// Test with start_after parameter
let second_page = get_all_swap_routes(deps.as_ref().storage, Some("eth_inj".to_string()), Some(1u32));
assert_eq!(second_page.unwrap(), vec![eth_usdt_route]);

// Test with larger page size
let larger_page = get_all_swap_routes(deps.as_ref().storage, None, Some(2u32));
assert_eq!(larger_page.unwrap(), vec![eth_inj_route, eth_usdt_route]);

// Test last page
let last_page = get_all_swap_routes(deps.as_ref().storage, Some("eth_usdt".to_string()), Some(2u32));
assert_eq!(last_page.unwrap(), vec![usdt_inj_route]);

Also applies to: 610-611

contracts/swap/src/testing/test_utils.rs (1)

984-986: Add documentation for the approximate equality function.

Consider adding documentation to explain the purpose and usage of this utility function, including what the max_diff parameter represents.

+/// Compares two FPDecimal values for approximate equality within a maximum difference.
+/// 
+/// # Arguments
+/// * `first` - First FPDecimal value to compare
+/// * `second` - Second FPDecimal value to compare
+/// * `max_diff` - Maximum allowed absolute difference between the values
+/// 
+/// # Returns
+/// `true` if the absolute difference between the values is less than or equal to `max_diff`
 pub fn are_fpdecimals_approximately_equal(first: FPDecimal, second: FPDecimal, max_diff: FPDecimal) -> bool {
     (first - second).abs() <= max_diff
 }
contracts/swap/src/testing/integration_realistic_tests_exact_quantity.rs (2)

Line range hint 1116-1124: Consider extracting common balance check logic.

The balance check logic with max diff assertions is repeated across all test templates. This could be extracted into a helper function for better maintainability and reduced code duplication.

Consider creating a helper function:

fn assert_balance_within_max_diff(
    actual: FPDecimal,
    expected: FPDecimal,
    max_diff: FPDecimal,
    token: &str,
    decimals: Decimals,
) {
    assert!(
        are_fpdecimals_approximately_equal(actual, expected, max_diff),
        "Contract balance changed too much. Actual balance: {} {}, previous balance: {} {}. Max diff: {} {}",
        actual.scaled(decimals.get_decimals().neg()),
        token,
        expected.scaled(decimals.get_decimals().neg()),
        token,
        max_diff.scaled(decimals.get_decimals().neg()),
        token
    );
}

Also applies to: 1238-1246, 1359-1367


1115-1115: Document magic numbers in comments.

The comments mention specific USDT amounts (0.7, 0.82) allowed for contract earnings, but don't explain how these values were determined. Consider adding more detailed documentation about the calculation of these thresholds.

Add more detailed comments explaining the threshold calculations:

-    // contract is allowed to earn extra 0.7 USDT from the swap of ~$8150 worth of ETH
+    // Contract fee calculation:
+    // - Swap value: ~$8150 worth of ETH
+    // - Expected fee: 0.1% of swap value = $8.15
+    // - Maximum allowed fee in USDT (considering price impact): 0.7 USDT

Also applies to: 1237-1237, 1358-1358

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between bf8dad9 and 436d29d.

⛔ Files ignored due to path filters (3)
  • Cargo.lock is excluded by !**/*.lock
  • contracts/swap/src/testing/test_artifacts/swap-contract-v100.wasm is excluded by !**/*.wasm
  • contracts/swap/src/testing/test_artifacts/swap_contract-v101.wasm is excluded by !**/*.wasm
📒 Files selected for processing (25)
  • .github/workflows/rust.yaml (3 hunks)
  • Cargo.toml (1 hunks)
  • Changelog.md (1 hunks)
  • Makefile.toml (0 hunks)
  • contracts/swap/.gitignore (0 hunks)
  • contracts/swap/.gitpod.Dockerfile (0 hunks)
  • contracts/swap/.gitpod.yml (0 hunks)
  • contracts/swap/Cargo.toml (2 hunks)
  • contracts/swap/rustfmt.toml (0 hunks)
  • contracts/swap/src/contract.rs (5 hunks)
  • contracts/swap/src/msg.rs (3 hunks)
  • contracts/swap/src/queries.rs (19 hunks)
  • contracts/swap/src/state.rs (2 hunks)
  • contracts/swap/src/swap.rs (12 hunks)
  • contracts/swap/src/testing/authz_tests.rs (5 hunks)
  • contracts/swap/src/testing/config_tests.rs (5 hunks)
  • contracts/swap/src/testing/integration_logic_tests.rs (0 hunks)
  • contracts/swap/src/testing/integration_realistic_tests_exact_quantity.rs (61 hunks)
  • contracts/swap/src/testing/migration_test.rs (5 hunks)
  • contracts/swap/src/testing/mod.rs (0 hunks)
  • contracts/swap/src/testing/queries_tests.rs (22 hunks)
  • contracts/swap/src/testing/test_utils.rs (39 hunks)
  • contracts/swap/src/types.rs (6 hunks)
  • docs/admin.md (1 hunks)
  • rust-toolchain.toml (1 hunks)
💤 Files with no reviewable changes (7)
  • Makefile.toml
  • contracts/swap/.gitignore
  • contracts/swap/.gitpod.Dockerfile
  • contracts/swap/.gitpod.yml
  • contracts/swap/rustfmt.toml
  • contracts/swap/src/testing/integration_logic_tests.rs
  • contracts/swap/src/testing/mod.rs
✅ Files skipped from review due to trivial changes (3)
  • contracts/swap/src/queries.rs
  • docs/admin.md
  • rust-toolchain.toml
🧰 Additional context used
🪛 actionlint
.github/workflows/rust.yaml

131-131: the runner of "actions-rs/cargo@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🔇 Additional comments (40)
contracts/swap/Cargo.toml (3)

5-5: LGTM: Version bump follows semantic versioning.

The version increment from 1.0.2 to 1.1.0 appropriately reflects the addition of pagination feature as a minor version bump.


23-34: LGTM: Clean workspace dependency management.

Moving to workspace-level dependency management is a good practice that will:

  • Ensure consistent versions across the workspace
  • Simplify dependency updates
  • Reduce potential version conflicts

37-40: Verify the impact of testing framework changes.

The switch to injective-specific testing tools might affect existing tests. Let's verify the test coverage hasn't decreased.

✅ Verification successful

Based on the test files and dependencies shown, I can provide a final response:

Testing framework changes have been properly implemented

The codebase has successfully migrated to injective-specific testing tools:

  • All tests use injective-test-tube, injective-testing, and injective-std for integration testing
  • Unit tests use injective-cosmwasm mock infrastructure
  • No active usage of cw-multi-test in test code, only appears as transitive dependency
  • Comprehensive test coverage maintained with both unit and integration tests covering core swap functionality
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any orphaned or broken test imports after the testing framework change

# Look for any remaining old test framework usage that might cause conflicts
rg -l "cw-multi-test|cosmos-sdk-proto" 

# Check for any test files that might need updates
fd -e rs --type f . | rg "test" | xargs rg "use (cw_multi_test|cosmos_sdk_proto)"

Length of output: 133


Script:

#!/bin/bash
# Let's verify the test coverage and framework usage more comprehensively

# Check for test files and their imports
fd -e rs "test" | xargs cat

# Check Cargo.lock for any remaining old dependencies
rg "cw-multi-test|cosmos-sdk-proto|cosmwasm-std" Cargo.lock

# Look for test attributes and test modules
ast-grep --pattern 'mod $_ {
  #[cfg(test)]
  $$$
}'

Length of output: 186941

Cargo.toml (3)

5-6: LGTM: Good choice using Rust 2021 edition.

The upgrade to Rust 2021 edition aligns well with the toolchain update and brings several improvements in cargo resolution and language features.


Line range hint 27-37: LGTM: Good cleanup of profile configuration.

The removal of package-specific overrides while maintaining strong security settings (overflow checks, panic=abort) in the release profile is a good improvement.


8-25: Consider pinning more dependency versions for better reproducibility.

While critical dependencies like injective-cosmwasm and test-tube-inj are correctly pinned, consider using exact versions for other dependencies to ensure consistent builds.

Additionally, verify the compatibility between these dependency versions:

✅ Verification successful

Based on the results, I can now generate the final response:

Dependency versions appear compatible and well-structured

The workspace dependencies are properly configured:

  • No dependency conflicts or warnings were detected
  • All injective-related packages in contracts correctly use workspace inheritance
  • Version combinations are compatible:
    • injective-cosmwasm (0.3.0) and injective-math (0.3.0) are aligned
    • injective-std (1.13.0) and injective-test-tube (1.13.2) are in the same major version

While pinning more versions could improve reproducibility, the current setup is sound and follows good practices with workspace inheritance.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for potential dependency conflicts and verify versions
# Test: Look for any dependency resolution warnings or conflicts
cargo check 2>&1 | grep -i "warning.*dependency\|conflict"

# Test: Verify injective-related package versions are compatible
rg "injective-" -A 1 $(fd -t f "Cargo.toml$")

Length of output: 1026

contracts/swap/src/msg.rs (3)

1-4: LGTM! Using cw_serde follows CosmWasm best practices.

The change to use cw_serde macro simplifies serialization by automatically deriving common traits.


6-7: LGTM! Consistent use of cw_serde across all message types.

The change uniformly applies cw_serde to all contract message types, improving code consistency and maintainability.

Also applies to: 12-13, 18-19, 21-22, 50-51


66-69: Verify pagination implementation details.

Please ensure:

  1. A maximum limit is enforced in the contract implementation
  2. Pagination functionality is covered by tests

Let's check the implementation and tests:

contracts/swap/src/state.rs (1)

3-4: LGTM: Appropriate imports and pagination limit.

The addition of Bound import and DEFAULT_LIMIT constant (100) are appropriate for implementing pagination functionality.

Also applies to: 12-12

contracts/swap/src/types.rs (4)

1-11: LGTM! Good use of cw_serde macro

The switch to cw_serde is a positive change as it's the recommended approach in CosmWasm for handling serialization/deserialization. The enum structure is clean and well-defined.


Line range hint 33-107: LGTM! Well-structured types with clear responsibilities

The types are well-organized with good separation of concerns. The SwapRoute implementation elegantly handles bidirectional routing by reversing steps when needed.


108-114: Verify pagination implementation for routes query

The PR objectives mention adding pagination for queries, but I don't see any pagination-related types in this file. We should verify where the pagination parameters are defined.

#!/bin/bash
# Look for pagination-related types and parameters
rg -A 5 "start_after|limit.*Option<|pagination" 

# Check if pagination is implemented in query messages
ast-grep --pattern 'struct $QueryMsg {
  $$$
  start_after: $type,
  limit: $type,
  $$$
}'

Line range hint 12-31: Verify FPDecimal to Coin conversion behavior

The removal of .into() in the conversion from FPCoin to Coin needs verification. Let's ensure that Coin::new can properly handle FPDecimal values directly.

contracts/swap/src/testing/config_tests.rs (5)

1-1: LGTM: Updated to use message_info instead of deprecated mock_info

The change aligns with modern testing practices in the Cosmos ecosystem.


20-20: LGTM: Improved readability with consolidated config save

The single-line save operation is more concise and clearer.


Line range hint 37-54: LGTM: Improved address comparison reliability

The addition of .to_string() ensures consistent string-based comparisons of addresses in the event attributes, preventing potential false negatives in tests.


66-71: LGTM: Consistent updates with the admin test

The changes mirror those in the admin test, maintaining consistency across test cases.


Line range hint 1-80: Verify config changes don't affect pagination functionality

While these config tests look good, let's verify there are no pagination-related config parameters that should be added given the PR's main objective.

✅ Verification successful

Based on the search results, I can see that pagination is already properly implemented in the codebase:

  1. DEFAULT_LIMIT constant is defined in state.rs
  2. Pagination parameters (limit, start_after) are present in both msg.rs and handled in contract.rs
  3. The config structure in the test focuses only on admin and fee_recipient which are unrelated to pagination

No pagination-related config parameters needed

The config changes are correctly scoped to administrative controls (admin and fee_recipient). Pagination is handled separately through query parameters and doesn't require any configuration settings, following common patterns where pagination is controlled by API consumers rather than contract configuration.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if there are any pagination-related configurations or types in the codebase
rg -i "pagination|page_size|limit" --type rust

Length of output: 4764

contracts/swap/src/testing/authz_tests.rs (4)

5-7: LGTM! Import organization improves readability

The consolidation of imports, particularly the injective_std related ones, enhances code organization.

Also applies to: 11-14


76-76: LGTM! Message encoding is correct

The duplicate execution properly tests the authorization behavior with increasing sequence numbers.

Also applies to: 87-87


92-92: Verify authorization behavior change

The error message assertion has changed from checking "failed to update grant with key" to "failed to get grant with given granter". This suggests a modification in the underlying authorization behavior that should be verified.

#!/bin/bash
# Search for related authorization error handling
rg -A 3 "failed to (update|get) grant" --type rust

62-62: Verify route market compatibility

The test sets up a route from ETH to ATOM through USDT markets, but there's no explicit validation that these markets form a valid route (i.e., compatible quote/base assets).

contracts/swap/src/testing/migration_test.rs (4)

Line range hint 50-65: LGTM! Thorough contract verification.

The verification checks all essential contract properties: address, code ID, creator, and label.


Line range hint 81-98: LGTM! Comprehensive post-migration verification.

The code properly verifies the contract state after migration and includes an additional functional test to ensure the contract works correctly after migration.


73-76: Verify if empty migration message is intended.

The migration uses an empty message (MigrateMsg {}). Please verify if this is intentional and if any state migration is needed between v101 and v110.

#!/bin/bash
# Search for MigrateMsg usage and implementation
ast-grep --pattern 'struct MigrateMsg {
  $$$
}'

14-14: Verify version naming consistency.

The type alias V101InstantiateMsg suggests this was previously a v100->v101 migration test, but the code now tests v101->v110 migration. Consider renaming this type alias to match the current test scenario.

✅ Verification successful

Type alias naming is consistent with test implementation

After reviewing the test file content, the type alias V101InstantiateMsg is correctly named as it represents the instantiate message for the v1.0.1 contract version that's being migrated. This is evidenced by:

  • The test loads swap-contract-v101.wasm bytecode
  • Uses V101InstantiateMsg to instantiate that v1.0.1 contract
  • Then migrates it to v1.1.0 (code stored via "swap_contract")

The naming convention accurately reflects the source version being tested in the migration.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any other v101/v110 version references
rg -i "v10[0-9]|v110" --type rust

Length of output: 50


Script:

#!/bin/bash
# Let's check the content of the migration test file to understand the context better
cat contracts/swap/src/testing/migration_test.rs

# Also search for any migration-related types and messages
ast-grep --pattern 'type V$_ = $_'

Length of output: 3481

.github/workflows/rust.yaml (1)

36-38: LGTM on toolchain updates.

The Rust toolchain version updates to 1.78.0 in these sections are consistent and align with the PR's objective of updating dependencies.

Also applies to: 101-103

contracts/swap/src/contract.rs (5)

1-12: LGTM! Well-organized imports.

The imports are logically grouped and follow Rust best practices by using explicit imports.


Line range hint 44-64: LGTM! Clean and well-structured execute handlers.

The match arms are well-organized with admin functions grouped together. The code is concise and maintains clear error handling.


104-104: LGTM! Pagination implementation.

The GetAllRoutes query now properly supports pagination with start_after and limit parameters, aligning with the PR objectives.


77-77: LGTM! Consistent error handling.

The change to Result<Binary, StdError> aligns with Rust and CosmWasm best practices for error handling in query functions.


117-136: Verify migration path support requirements.

The migration function only supports upgrading from version "1.0.1". Please verify if support for older versions is required.

✅ Verification successful

Let me gather more information about the contract versions and migration paths.


Let me check the Cargo.toml for version information and test directory structure.


Let me check the migration test implementation for more details about the migration path.


Migration path support is correctly implemented

The migration implementation is appropriate and doesn't need modification. Here's why:

  • Current contract version is 1.1.0 (from Cargo.toml)
  • Migration path from 1.0.1 is explicitly tested with a test artifact (swap-contract-v101.wasm)
  • The migration test verifies both the upgrade process and post-migration functionality
  • No older versions exist that would require migration support

The strict version check in the migration function is intentional and matches the tested upgrade path.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for existing deployments that might need migration support
echo "Checking for version references in tests and documentation..."
rg -A 2 "contract_version|set_contract_version" 

echo "Checking for migration-related test cases..."
rg -A 5 "test.*migrat"

Length of output: 2725


Script:

#!/bin/bash
# Check contract version constants and related files
echo "Checking contract version constants..."
rg -A 2 "CONTRACT_VERSION|CONTRACT_NAME"

echo "Checking changelog or release history..."
fd -g "CHANGELOG*" -x cat {}

echo "Checking test artifacts directory..."
fd -g "*.wasm" -p "test_artifacts"

Length of output: 1519


Script:

#!/bin/bash
# Check Cargo.toml for version info
echo "Checking Cargo.toml..."
fd -g "Cargo.toml" -x cat {}

echo "Checking test directory structure..."
fd -t d "testing"
fd -t f -p "testing"

Length of output: 3310


Script:

#!/bin/bash
# Check migration test implementation
echo "Checking migration test content..."
cat contracts/swap/src/testing/migration_test.rs

echo "Checking contract error definitions..."
rg -A 2 "MigrationError"

Length of output: 4014

contracts/swap/src/swap.rs (2)

1-18: LGTM: Well-organized imports

The imports are logically grouped and follow Rust conventions. The new imports (prost::Message and injective_std types) appropriately support the protobuf message parsing functionality.


Line range hint 158-273: Verify test coverage for error cases

The changes to error handling are significant. Let's verify that tests cover these scenarios:

  1. Market not found cases
  2. Missing message responses
  3. Invalid protobuf messages
✅ Verification successful

Test coverage for error cases is comprehensive

The test files reveal extensive coverage of error cases and edge scenarios:

  1. Market-related error cases:
  • Tests with realistic market parameters from mainnet
  • Tests for different market pairs and quote assets
  • Buffer insufficiency scenarios
  1. Message response handling:
  • Tests for atomic order execution
  • Tests for swap execution with minimum output quantities
  • Tests for handling execution failures
  1. Protobuf message handling:
  • Tests with realistic decimal values and scaling factors
  • Tests for handling price/quantity/fee calculations

The test suite includes both unit tests and integration tests with realistic values, covering the error paths mentioned in the review comment.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for relevant test cases
echo "Searching for market-related test cases..."
rg -l "query_spot_market" contracts/swap/src/testing/

echo "Searching for reply handling test cases..."
rg -l "handle_atomic_order_reply" contracts/swap/src/testing/

echo "Checking test coverage for error cases..."
rg "ContractError::" contracts/swap/src/testing/

Length of output: 447


Script:

#!/bin/bash
# Let's first check if there's a test directory with a different path
fd -t d "test" contracts/swap/

# Let's also check for any test files directly
fd -e rs "test" contracts/swap/

# Let's search in the entire contract directory for test cases
rg -l "mod tests" contracts/swap/

# Let's also check for any test-related imports
rg -l "#\\[test\\]" contracts/swap/

Length of output: 1254


Script:

#!/bin/bash
# Let's check the content of swap_tests.rs and integration tests for error cases
echo "=== Checking swap_tests.rs for error handling ==="
rg "ContractError::" contracts/swap/src/testing/swap_tests.rs -B 2 -A 2

echo "=== Checking integration tests for error handling ==="
rg "ContractError::" contracts/swap/src/testing/integration_realistic_tests_min_quantity.rs -B 2 -A 2
rg "ContractError::" contracts/swap/src/testing/integration_realistic_tests_exact_quantity.rs -B 2 -A 2

echo "=== Checking for market-related test cases ==="
rg "query_spot_market" contracts/swap/src/testing/swap_tests.rs -B 2 -A 2

echo "=== Checking for reply handling test cases ==="
rg "handle_atomic_order_reply" contracts/swap/src/testing/swap_tests.rs -B 2 -A 2

Length of output: 865


Script:

#!/bin/bash
# Let's try a different approach to check test content
echo "=== Checking test content for error cases ==="
cat contracts/swap/src/testing/swap_tests.rs

echo "=== Checking integration test content ==="
cat contracts/swap/src/testing/integration_realistic_tests_min_quantity.rs

Length of output: 48338

contracts/swap/src/testing/queries_tests.rs (3)

4-4: LGTM! Import changes improve test reliability.

The switch from mock_info to message_info and the reorganized imports enhance the testing framework.

Also applies to: 17-18


35-35: LGTM! Consistent usage of message_info across test functions.

The systematic replacement of mock_info with message_info improves test reliability by using the more appropriate testing utility.

Also applies to: 110-110, 184-184, 255-255, 332-332, 436-436, 525-525, 547-547


87-89: LGTM! Well-structured assertions with clear error messages.

The assertions are well-formatted with:

  • Appropriate use of are_fpdecimals_approximately_equal for floating-point comparisons
  • Descriptive error messages that aid in debugging
  • Consistent formatting across all test cases

Also applies to: 94-96, 161-165, 168-172, 232-236, 239-243, 307-311, 314-318, 382-385, 405-407, 418-421, 486-489, 505-507, 510-513

contracts/swap/src/testing/test_utils.rs (1)

Line range hint 1-991: Overall code structure and implementation look good.

The test utilities are well-organized and provide comprehensive helper functions for testing the swap contract functionality. The test cases cover various scenarios and edge cases.

contracts/swap/src/testing/integration_realistic_tests_exact_quantity.rs (1)

977-982: 🛠️ Refactor suggestion

Simplify error message assertion.

The multi-line assertion can be simplified for better readability.

Consider consolidating the assertion:

-    assert!(
-        execute_result
-            .to_string()
-            .contains("Provided amount of 608000000000000000000 is below required amount of 609714000000000000000"),
-        "wrong error message"
-    );
+    assert!(execute_result.to_string().contains("Provided amount of 608000000000000000000 is below required amount of 609714000000000000000"), "wrong error message");

Likely invalid or redundant comment.

@@ -16,10 +16,11 @@ All notable changes to this project will be documented in this file.

-

## [1.0.2] - 2024-03-19
## [1.1.0] - 2024-10-30
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Update the release date to the actual release date.

The release date is set to 2024-10-30, which is in the future. This could cause confusion for users tracking the changelog. Consider updating it to the actual release date when merging this PR.

-## [1.1.0] - 2024-10-30
+## [1.1.0] - 2024-10-XX
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## [1.1.0] - 2024-10-30
## [1.1.0] - 2024-10-XX

serde = { version = "1.0.137", default-features = false, features = [ "derive" ] }
serde-json-wasm = "1.0.1"
thiserror = { version = "1.0.31" }
cosmwasm-schema = { workspace = true }
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Consider moving cosmwasm-schema to dev-dependencies.

cosmwasm-schema is typically used only during development for generating JSON schema files and is not needed at runtime.

Apply this change:

[dependencies]
-cosmwasm-schema    = { workspace = true }

[dev-dependencies]
+cosmwasm-schema    = { workspace = true }

Committable suggestion was skipped due to low confidence.

Comment on lines 43 to 58
pub fn get_all_swap_routes(
storage: &dyn Storage,
start_after: Option<(String, String)>,
limit: Option<u32>,
) -> StdResult<Vec<SwapRoute>> {
let limit = limit.unwrap_or(DEFAULT_LIMIT) as usize;

let start_bound = start_after
.as_ref()
.map(|(s, t)| Bound::inclusive((s.clone(), t.clone())));

let routes = SWAP_ROUTES
.range(storage, None, None, Order::Ascending)
.map(|item| item.unwrap().1)
.collect();
.range(storage, start_bound, None, Order::Ascending)
.take(limit)
.map(|item| item.map(|(_, route)| route)) // Extract the `SwapRoute` from each item
.collect::<StdResult<Vec<SwapRoute>>>()?;
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Pagination implementation needs additional test coverage

The current test coverage only verifies the limit parameter with a basic test case. The start_after parameter is not tested, which could lead to undiscovered issues with cursor-based pagination. Key improvements needed:

  • Add test cases for start_after parameter in pagination
  • Add test cases for edge cases (e.g., non-existent start_after values)
  • Add test cases combining both start_after and limit parameters
🔗 Analysis chain

Verify pagination implementation in query handlers and tests.

Let's verify that the pagination parameters are properly handled in the corresponding query handlers and tests.


Based on the results, I can see that both the query handler and test coverage for pagination are implemented. Let me verify the completeness of pagination testing by checking if there are tests for the start_after parameter.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check query handler implementation and test coverage for pagination

# Check query handler implementation
echo "Checking query handler implementation..."
rg -A 10 "GetAllRoutes" contracts/swap/src/contract.rs

# Check test coverage
echo "Checking test coverage..."
rg -A 10 "get_all_swap_routes" contracts/swap/src/testing

Length of output: 3798


Script:

#!/bin/bash
# Check for start_after parameter testing
rg -B 5 -A 15 "start_after" contracts/swap/src/testing/queries_tests.rs

Length of output: 71

let wasm_byte_code =
std::fs::read("../../contracts/swap/src/testing/test_artifacts/swap-contract-v100.wasm")
.unwrap();
let wasm_byte_code = std::fs::read("../../contracts/swap/src/testing/test_artifacts/swap-contract-v101.wasm").unwrap();
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider using a more robust path resolution method.

The hardcoded path to the test artifact might break in different environments or when the project structure changes. Consider using environment variables or a path relative to the test file's location.

-let wasm_byte_code = std::fs::read("../../contracts/swap/src/testing/test_artifacts/swap-contract-v101.wasm").unwrap();
+let wasm_byte_code = std::fs::read(
+    std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
+        .join("src/testing/test_artifacts/swap-contract-v101.wasm")
+).unwrap();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let wasm_byte_code = std::fs::read("../../contracts/swap/src/testing/test_artifacts/swap-contract-v101.wasm").unwrap();
let wasm_byte_code = std::fs::read(
std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("src/testing/test_artifacts/swap-contract-v101.wasm")
).unwrap();

Comment on lines +126 to 135
toolchain: 1.78.0
command: fmt
args: --all -- --check

- name: Run cargo clippy
uses: actions-rs/cargo@v1
with:
toolchain: 1.74.0
toolchain: 1.78.0
command: clippy
args: --tests -- -D warnings
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Update the actions-rs/cargo action version.

The current version of actions-rs/cargo@v1 is outdated and may have compatibility issues with the latest GitHub Actions runners.

Consider updating to a newer version of the action or switching to alternative maintained actions. For example:

-      - name: Run cargo fmt
-        uses: actions-rs/cargo@v1
+      - name: Run cargo fmt
+        uses: dtolnay/rust-toolchain@stable
+      - run: cargo fmt --all -- --check

-      - name: Run cargo clippy
-        uses: actions-rs/cargo@v1
+      - name: Run cargo clippy
+        uses: dtolnay/rust-toolchain@stable
+      - run: cargo clippy --tests -- -D warnings

This change uses the more actively maintained dtolnay/rust-toolchain action.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
toolchain: 1.78.0
command: fmt
args: --all -- --check
- name: Run cargo clippy
uses: actions-rs/cargo@v1
with:
toolchain: 1.74.0
toolchain: 1.78.0
command: clippy
args: --tests -- -D warnings
toolchain: 1.78.0
command: fmt
args: --all -- --check
- name: Run cargo clippy
uses: dtolnay/rust-toolchain@stable
- run: cargo clippy --tests -- -D warnings
```
Note: The suggestion shows only the visible part of the code snippet, but the complete change would also need to update the cargo fmt section above in a similar manner. The full implementation would look like:
```suggestion
- name: Run cargo fmt
uses: dtolnay/rust-toolchain@stable
- run: cargo fmt --all -- --check
- name: Run cargo clippy
uses: dtolnay/rust-toolchain@stable
- run: cargo clippy --tests -- -D warnings
🧰 Tools
🪛 actionlint

131-131: the runner of "actions-rs/cargo@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.query_spot_market(&first_market_id)?
.market
.expect("market should be available");
let first_market = querier.query_spot_market(&first_market_id)?.market.expect("market should be available");
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical: Replace .expect() with proper error handling

Using .expect() in a smart contract can cause a panic, which should be avoided. Instead, handle the None case gracefully with a proper error return.

Replace with proper error handling:

-        let first_market = querier.query_spot_market(&first_market_id)?.market.expect("market should be available");
+        let first_market = querier.query_spot_market(&first_market_id)?.market.ok_or_else(|| 
+            ContractError::CustomError { 
+                val: format!("Market {} not found", first_market_id) 
+            }
+        )?;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let first_market = querier.query_spot_market(&first_market_id)?.market.expect("market should be available");
let first_market = querier.query_spot_market(&first_market_id)?.market.ok_or_else(||
ContractError::CustomError {
val: format!("Market {} not found", first_market_id)
}
)?;

Comment on lines +260 to +273
pub fn parse_market_order_response(msg: Reply) -> StdResult<MsgCreateSpotMarketOrderResponse> {
let binding = msg.result.into_result().map_err(ContractError::SubMsgFailure).unwrap();

let first_messsage = binding.msg_responses.first();

let order_response = MsgCreateSpotMarketOrderResponse::decode(first_messsage.unwrap().value.as_slice())
.map_err(|err| ContractError::ReplyParseFailure {
id: msg.id,
err: err.to_string(),
})
.unwrap();

Ok(order_response)
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical: Replace unwrap() calls with proper error handling

The parse_market_order_response function contains multiple unwrap() calls that could cause panics. This is unsafe in a smart contract environment.

Refactor to handle errors properly:

 pub fn parse_market_order_response(msg: Reply) -> StdResult<MsgCreateSpotMarketOrderResponse> {
-    let binding = msg.result.into_result().map_err(ContractError::SubMsgFailure).unwrap();
-
-    let first_messsage = binding.msg_responses.first();
-
-    let order_response = MsgCreateSpotMarketOrderResponse::decode(first_messsage.unwrap().value.as_slice())
-        .map_err(|err| ContractError::ReplyParseFailure {
-            id: msg.id,
-            err: err.to_string(),
-        })
-        .unwrap();
-
-    Ok(order_response)
+    let binding = msg.result.into_result().map_err(ContractError::SubMsgFailure)?;
+
+    let first_message = binding.msg_responses.first().ok_or_else(|| 
+        ContractError::CustomError {
+            val: "No message responses in reply".to_string()
+        }
+    )?;
+
+    MsgCreateSpotMarketOrderResponse::decode(first_message.value.as_slice())
+        .map_err(|err| ContractError::ReplyParseFailure {
+            id: msg.id,
+            err: err.to_string(),
+        })
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn parse_market_order_response(msg: Reply) -> StdResult<MsgCreateSpotMarketOrderResponse> {
let binding = msg.result.into_result().map_err(ContractError::SubMsgFailure).unwrap();
let first_messsage = binding.msg_responses.first();
let order_response = MsgCreateSpotMarketOrderResponse::decode(first_messsage.unwrap().value.as_slice())
.map_err(|err| ContractError::ReplyParseFailure {
id: msg.id,
err: err.to_string(),
})
.unwrap();
Ok(order_response)
}
pub fn parse_market_order_response(msg: Reply) -> StdResult<MsgCreateSpotMarketOrderResponse> {
let binding = msg.result.into_result().map_err(ContractError::SubMsgFailure)?;
let first_message = binding.msg_responses.first().ok_or_else(||
ContractError::CustomError {
val: "No message responses in reply".to_string()
}
)?;
MsgCreateSpotMarketOrderResponse::decode(first_message.value.as_slice())
.map_err(|err| ContractError::ReplyParseFailure {
id: msg.id,
err: err.to_string(),
})
}

actual, expected,
"failed to convert integer with 18 decimal to dec"
);
assert_eq!(actual, expected, "failed to convert integer with 18 decimal to dec");
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect error message in test.

The error message mentions "18 decimal" but the test is actually checking for 6 decimals.

-        assert_eq!(actual, expected, "failed to convert integer with 18 decimal to dec");
+        assert_eq!(actual, expected, "failed to convert integer with 6 decimal to dec");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
assert_eq!(actual, expected, "failed to convert integer with 18 decimal to dec");
assert_eq!(actual, expected, "failed to convert integer with 6 decimal to dec");

Comment on lines +278 to +334
pub fn launch_realistic_inj_usdt_spot_market(exchange: &Exchange<InjectiveTestApp>, signer: &SigningAccount) -> String {
launch_spot_market_custom(
exchange,
signer,
INJ_2,
USDT,
dec_to_proto(FPDecimal::must_from_str("0.000000000000001")).as_str(),
dec_to_proto(FPDecimal::must_from_str("1000000000000000")).as_str(),
"INJ2/USDT".to_string(),
INJ_2.to_string(),
USDT.to_string(),
"0.000000000000001".to_string(),
"1000000000000000".to_string(),
)
}

pub fn launch_realistic_weth_usdt_spot_market(
exchange: &Exchange<InjectiveTestApp>,
signer: &SigningAccount,
) -> String {
launch_custom_spot_market(
pub fn launch_realistic_weth_usdt_spot_market(exchange: &Exchange<InjectiveTestApp>, signer: &SigningAccount) -> String {
launch_spot_market_custom(
exchange,
signer,
ETH,
USDT,
dec_to_proto(FPDecimal::must_from_str("0.0000000000001")).as_str(),
dec_to_proto(FPDecimal::must_from_str("1000000000000000")).as_str(),
"ETH/USDT".to_string(),
ETH.to_string(),
USDT.to_string(),
"0.0000000000001".to_string(),
"1000000000000000".to_string(),
)
}

pub fn launch_realistic_atom_usdt_spot_market(
exchange: &Exchange<InjectiveTestApp>,
signer: &SigningAccount,
) -> String {
launch_custom_spot_market(
pub fn launch_realistic_atom_usdt_spot_market(exchange: &Exchange<InjectiveTestApp>, signer: &SigningAccount) -> String {
launch_spot_market_custom(
exchange,
signer,
ATOM,
USDT,
dec_to_proto(FPDecimal::must_from_str("0.001")).as_str(),
dec_to_proto(FPDecimal::must_from_str("10000")).as_str(),
"ATOM/USDT".to_string(),
ATOM.to_string(),
USDT.to_string(),
"0.001".to_string(),
"10000".to_string(),
)
}

pub fn launch_realistic_usdt_usdc_spot_market(
exchange: &Exchange<InjectiveTestApp>,
signer: &SigningAccount,
) -> String {
launch_custom_spot_market(
pub fn launch_realistic_usdt_usdc_spot_market(exchange: &Exchange<InjectiveTestApp>, signer: &SigningAccount) -> String {
launch_spot_market_custom(
exchange,
signer,
USDT,
USDC,
dec_to_proto(FPDecimal::must_from_str("0.0001")).as_str(),
dec_to_proto(FPDecimal::must_from_str("100")).as_str(),
"USDT/USDC".to_string(),
USDT.to_string(),
USDC.to_string(),
"0.0001".to_string(),
"100".to_string(),
)
}

pub fn launch_realistic_ninja_inj_spot_market(
exchange: &Exchange<InjectiveTestApp>,
signer: &SigningAccount,
) -> String {
launch_custom_spot_market(
pub fn launch_realistic_ninja_inj_spot_market(exchange: &Exchange<InjectiveTestApp>, signer: &SigningAccount) -> String {
launch_spot_market_custom(
exchange,
signer,
NINJA,
INJ_2,
dec_to_proto(FPDecimal::must_from_str("1000000")).as_str(),
dec_to_proto(FPDecimal::must_from_str("10000000")).as_str(),
"NINJA/INJ2".to_string(),
NINJA.to_string(),
INJ_2.to_string(),
"1000000".to_string(),
"10000000".to_string(),
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider parameterizing market configuration values.

The market launch functions (launch_realistic_*_spot_market) contain hardcoded values for tick sizes. Consider extracting these values into constants or making them configurable parameters for better reusability and maintainability.

-pub fn launch_realistic_inj_usdt_spot_market(exchange: &Exchange<InjectiveTestApp>, signer: &SigningAccount) -> String {
+pub fn launch_realistic_inj_usdt_spot_market(
+    exchange: &Exchange<InjectiveTestApp>,
+    signer: &SigningAccount,
+    min_price_tick_size: Option<String>,
+    min_quantity_tick_size: Option<String>,
+) -> String {
     launch_spot_market_custom(
         exchange,
         signer,
         "INJ2/USDT".to_string(),
         INJ_2.to_string(),
         USDT.to_string(),
-        "0.000000000000001".to_string(),
-        "1000000000000000".to_string(),
+        min_price_tick_size.unwrap_or_else(|| "0.000000000000001".to_string()),
+        min_quantity_tick_size.unwrap_or_else(|| "1000000000000000".to_string()),
     )
}

Committable suggestion was skipped due to low confidence.

@@ -618,15 +489,11 @@ fn it_swaps_inj_to_get_very_high_exact_amount_of_eth() {
)
.unwrap();

let expected_difference =
human_to_dec(inj_to_swap, Decimals::Eighteen) - query_result.result_quantity;
let expected_difference = human_to_dec(inj_to_swap, Decimals::Eighteen) - query_result.result_quantity;
let swapper_inj_balance_after = query_bank_balance(&bank, INJ_2, swapper.address().as_str());
let swapper_atom_balance_after = query_bank_balance(&bank, ETH, swapper.address().as_str());
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix misleading variable name.

The variable name swapper_atom_balance_after is used to store ETH balance, which is misleading. Consider renaming it to swapper_eth_balance_after to match the actual token being checked.

Apply this change across similar instances in other test cases for consistency:

-let swapper_atom_balance_after = query_bank_balance(&bank, ETH, swapper.address().as_str());
+let swapper_eth_balance_after = query_bank_balance(&bank, ETH, swapper.address().as_str());
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let swapper_atom_balance_after = query_bank_balance(&bank, ETH, swapper.address().as_str());
let swapper_eth_balance_after = query_bank_balance(&bank, ETH, swapper.address().as_str());

jbernal87
jbernal87 previously approved these changes Nov 5, 2024
Copy link
Contributor

@jbernal87 jbernal87 left a comment

Choose a reason for hiding this comment

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

LGTM just fix lints and broken tests

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: 1

🧹 Outside diff range and nitpick comments (4)
contracts/swap/src/testing/swap_tests.rs (1)

Line range hint 1-45: Missing tests for pagination functionality.

According to the PR objectives and AI summary, the get_all_swap_routes function has been updated to support pagination with new start_after and limit parameters. However, this test file doesn't include any tests to verify the pagination functionality.

Would you like me to help generate test cases that cover:

  • Pagination with different limit values
  • Pagination with different start_after values
  • Edge cases (empty results, last page, etc.)
  • Validation of limit bounds
contracts/swap/src/state.rs (1)

12-12: Consider adding documentation for DEFAULT_LIMIT

The constant value is reasonable, but adding a doc comment explaining the rationale for 100 would improve maintainability.

+/// Default maximum number of swap routes to return in a single query.
 pub const DEFAULT_LIMIT: u32 = 100u32;
contracts/swap/src/admin.rs (2)

94-94: Consider optimizing the route duplication check.

The current implementation could be more efficient:

  1. Avoid unnecessary clone() by collecting directly into HashSet
  2. Use a more idiomatic error message format

Consider this optimization:

-    if route.clone().into_iter().collect::<HashSet<MarketId>>().len() < route.len() {
+    let unique_steps: HashSet<_> = route.iter().collect();
+    if unique_steps.len() < route.len() {
         return Err(ContractError::CustomError {
-            val: "Route cannot have duplicate steps!".to_string(),
+            val: "route contains duplicate market IDs".to_string(),
         });
     }

For the market query error:

-        let market = querier.query_spot_market(market_id)?.market.ok_or(CustomError {
-            val: format!("Market {} not found", market_id.as_str()).to_string(),
-        })?;
+        let market = querier.query_spot_market(market_id)?.market
+            .ok_or_else(|| CustomError {
+                val: format!("market not found: {}", market_id)
+            })?;

Also applies to: 120-122


138-138: Consider more robust error handling for market denom validation.

While the unwrap() calls are safe due to the prior empty check, we can make the code more robust and idiomatic.

Consider this pattern-matching approach:

-    ensure!(
-        denoms.first().unwrap().quote_denom == route.source_denom || denoms.first().unwrap().base_denom == route.source_denom,
-        CustomError {
-            val: "Source denom not found in first market".to_string()
-        }
-    );
+    let first_market = denoms.first().ok_or_else(|| CustomError {
+        val: "no markets in route".to_string()
+    })?;
+    ensure!(
+        first_market.quote_denom == route.source_denom || first_market.base_denom == route.source_denom,
+        CustomError {
+            val: "source denom not found in first market".to_string()
+        }
+    );

-    ensure!(
-        denoms.last().unwrap().quote_denom == route.target_denom || denoms.last().unwrap().base_denom == route.target_denom,
-        CustomError {
-            val: "Target denom not found in last market".to_string()
-        }
-    );
+    let last_market = denoms.last().ok_or_else(|| CustomError {
+        val: "no markets in route".to_string()
+    })?;
+    ensure!(
+        last_market.quote_denom == route.target_denom || last_market.base_denom == route.target_denom,
+        CustomError {
+            val: "target denom not found in last market".to_string()
+        }
+    );

Also applies to: 144-144

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 436d29d and 851e199.

📒 Files selected for processing (7)
  • .github/workflows/rust.yaml (4 hunks)
  • contracts/swap/src/admin.rs (6 hunks)
  • contracts/swap/src/helpers.rs (3 hunks)
  • contracts/swap/src/state.rs (2 hunks)
  • contracts/swap/src/testing/integration_realistic_tests_min_quantity.rs (46 hunks)
  • contracts/swap/src/testing/storage_tests.rs (24 hunks)
  • contracts/swap/src/testing/swap_tests.rs (3 hunks)
✅ Files skipped from review due to trivial changes (3)
  • contracts/swap/src/helpers.rs
  • contracts/swap/src/testing/integration_realistic_tests_min_quantity.rs
  • contracts/swap/src/testing/storage_tests.rs
🧰 Additional context used
🪛 actionlint
.github/workflows/rust.yaml

131-131: the runner of "actions-rs/cargo@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🔇 Additional comments (8)
contracts/swap/src/testing/swap_tests.rs (1)

9-9: LGTM: Code formatting improvements look good.

The consolidation of imports and formatting changes improve readability while maintaining the same functionality.

Also applies to: 22-22, 43-43

contracts/swap/src/state.rs (2)

3-4: LGTM: Required imports for pagination

The added imports are necessary and correctly specified for implementing the pagination functionality.


37-46: Add input validation for limit parameter

While the pagination implementation is solid, consider adding validation for the limit parameter to prevent potential performance issues with very large values.

 pub fn get_all_swap_routes(storage: &dyn Storage, start_after: Option<(String, String)>, limit: Option<u32>) -> StdResult<Vec<SwapRoute>> {
-    let limit = limit.unwrap_or(DEFAULT_LIMIT) as usize;
+    let limit = limit.unwrap_or(DEFAULT_LIMIT);
+    if limit > 1000 {
+        return Err(StdError::generic_err("limit cannot exceed 1000"));
+    }
+    let limit = limit as usize;

Additionally, the previous review comment about test coverage for pagination remains valid. Please ensure comprehensive testing of the start_after parameter.

.github/workflows/rust.yaml (2)

36-36: LGTM: Consistent toolchain version updates.

The Rust toolchain version has been consistently updated to 1.78.0 across all jobs and steps. This update aligns with the PR objective of updating dependencies.

Also applies to: 65-65, 101-101, 126-126, 133-133


126-135: Previous warning about outdated actions-rs/cargo action still applies.

The current version of actions-rs/cargo@v1 remains outdated and may have compatibility issues with the latest GitHub Actions runners, as confirmed by the actionlint tool.

#!/bin/bash
# Description: Verify if the repository is using other outdated actions-rs actions
# that might need similar updates

rg -l 'uses:\s+actions-rs/[^@]+@v1' .github/
🧰 Tools
🪛 actionlint

131-131: the runner of "actions-rs/cargo@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

contracts/swap/src/admin.rs (3)

6-6: LGTM! Good use of validation macros.

The addition of ensure and ensure_eq macros from cosmwasm_std improves error handling readability.


10-10: LGTM! Improved function signature formatting.

The reformatted signatures enhance code readability while maintaining the same functionality.

Also applies to: 21-21


46-46: LGTM! Clean formatting.

The simplified attribute push improves code readability.

Comment on lines +25 to +29
pub fn read_swap_route(storage: &dyn Storage, source_denom: &str, target_denom: &str) -> StdResult<SwapRoute> {
let key = route_key(source_denom, target_denom);
SWAP_ROUTES.load(storage, key).map_err(|_| {
StdError::generic_err(format!(
"No swap route not found from {source_denom} to {target_denom}",
))
})
SWAP_ROUTES
.load(storage, key)
.map_err(|_| StdError::generic_err(format!("No swap route not found from {source_denom} to {target_denom}",)))
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix typo in error message

There's a double negative in the error message that should be fixed.

-        .map_err(|_| StdError::generic_err(format!("No swap route not found from {source_denom} to {target_denom}",)))
+        .map_err(|_| StdError::generic_err(format!("No swap route found from {source_denom} to {target_denom}")))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn read_swap_route(storage: &dyn Storage, source_denom: &str, target_denom: &str) -> StdResult<SwapRoute> {
let key = route_key(source_denom, target_denom);
SWAP_ROUTES.load(storage, key).map_err(|_| {
StdError::generic_err(format!(
"No swap route not found from {source_denom} to {target_denom}",
))
})
SWAP_ROUTES
.load(storage, key)
.map_err(|_| StdError::generic_err(format!("No swap route not found from {source_denom} to {target_denom}",)))
pub fn read_swap_route(storage: &dyn Storage, source_denom: &str, target_denom: &str) -> StdResult<SwapRoute> {
let key = route_key(source_denom, target_denom);
SWAP_ROUTES
.load(storage, key)
.map_err(|_| StdError::generic_err(format!("No swap route found from {source_denom} to {target_denom}")))

@jbernal87 jbernal87 self-requested a review November 8, 2024 10:05
@jbernal87 jbernal87 merged commit a2a4ba4 into master Nov 8, 2024
2 checks passed
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