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

refactor: update staking contract config structure #134

Merged
merged 13 commits into from
Jan 30, 2025

Conversation

manu0466
Copy link
Contributor

Overview

This PR updates the Config structure used to store the staking contract configurations to improve future extensions.

closes: LSTS-81, LSTS-82

Checklist


  • Appropriate labels applied
  • Targeted PR against correct branch
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Wrote unit and integration
  • Updated relevant documentation

Copy link
Contributor

coderabbitai bot commented Jan 25, 2025

Walkthrough

This pull request introduces a comprehensive refactoring of the staking contract, focusing on enhancing configuration management and validation. The changes involve restructuring the configuration data types, introducing more granular and type-safe configurations for native and protocol chains, and implementing robust validation mechanisms. The modifications span across multiple files, including state management, message handling, migration logic, and test suites, with a primary goal of improving the contract's flexibility, modularity, and error handling.

Changes

File Change Summary
Cargo.toml Version updated from workspace reference to specific version "1.0.0"
src/contract.rs Enhanced validation for configuration parameters, updated instantiation and execute logic
src/error.rs Added TreasuryNotConfigured error variant
src/execute.rs Restructured configuration handling, updated method signatures
src/helpers.rs Added validation functions for denominations and address prefixes
src/ibc.rs Updated channel ID configuration access
src/lib.rs Added new types module
src/migrations/* Added new migration modules and state management for different versions
src/msg.rs Significant changes to message structures, added migration message variant
src/query.rs Updated configuration query response
src/state.rs Introduced new configuration structs for native and protocol chains
src/tests/* Updated test suites to reflect new configuration structures
src/types.rs Added "unsafe" configuration structs with validation methods
scripts/testnet/init-stake-contract.sh Updated contract initialization script

Sequence Diagram

sequenceDiagram
    participant Client
    participant Contract
    participant Storage

    Client->>Contract: Instantiate(native_chain_config, protocol_chain_config)
    Contract->>Contract: Validate Configurations
    alt Invalid Configuration
        Contract-->>Client: Error
    else Valid Configuration
        Contract->>Storage: Save Configuration
        Storage-->>Contract: Configuration Saved
        Contract-->>Client: Instantiation Success
    end

    Client->>Contract: UpdateConfig(new_config)
    Contract->>Contract: Validate New Configuration
    alt Invalid Update
        Contract-->>Client: Error
    else Valid Update
        Contract->>Storage: Update Configuration
        Storage-->>Contract: Configuration Updated
        Contract-->>Client: Update Success
    end
Loading

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6cc377f and 990784f.

📒 Files selected for processing (1)
  • contracts/staking/src/tests/update_config_tests.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • contracts/staking/src/tests/update_config_tests.rs
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Test Suite

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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
Contributor

@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: 2

🔭 Outside diff range comments (1)
contracts/staking/src/tests/test_helper.rs (1)

Line range hint 52-67: Add negative test cases.

The init() function only tests the happy path. Consider adding helper functions for negative test cases.

pub fn init_with_invalid_config() -> Result<OwnedDeps<MockStorage, MockApi, MockQuerier>, ContractError> {
    let mut deps = mock_dependencies();
    let mut msg = mock_init_msg();
    msg.native_chain_config.validators = vec![]; // Invalid empty validators
    let info = mock_info(OSMO3, &coins(1000, "uosmo"));
    
    instantiate(deps.as_mut(), mock_env(), info, msg).map(|_| deps)
}
🧹 Nitpick comments (18)
contracts/staking/src/types.rs (1)

15-22: Potential upper bound check on dao_treasury_fee.
Since dao_treasury_fee is represented as Uint128 and used as a fraction (x/100000), consider adding a constraint (e.g., ≤ 100000) to avoid misconfigurations that exceed 100%.

 pub struct UnsafeProtocolFeeConfig {
-    pub dao_treasury_fee: Uint128,
+    /// Must be <= 100000 to represent <= 100%
+    pub dao_treasury_fee: Uint128,
     pub treasury_address: Option<String>,
 }
contracts/staking/src/state.rs (2)

9-33: Ensure consistent usage of optional vs. mandatory fields.

Overall, the expanded Config struct is well-structured, separating chain and fee logic. However, consider whether you truly need a non-optional monitors vector and a mandatory stopped boolean. For instance, certain logic might benefit from an Option<Vec<Addr>> to differentiate between no monitors vs. an empty set. The stopped field could be replaced by a small enum if you plan to add partial or read-only modes in the future.


83-92: Use a more explicit representation for fees.

Storing fees as a plain Uint128 (interpreted as x/100000) might be confusing for future maintainers. Consider using a fraction or a typed struct that clarifies the base multiplier, or a Decimal type for immediate clarity.

contracts/staking/src/tests/query_tests.rs (1)

19-62: Thorough coverage of new config fields in tests.

The additions to get_config adequately validate all relevant fields in native_chain_config and protocol_chain_config. As a future enhancement, consider testing boundary conditions (e.g., empty validator lists, extremely large minimum_liquid_stake_amount) to ensure robust behavior.

contracts/staking/src/contract.rs (1)

168-172: Refactor update_config for modular changes.

Update messages can become unwieldy if too many fields are grouped together. Consider creating smaller specialized update functions (e.g., update_fee_config) to reduce potential mistakes and keep changes more targeted.

contracts/staking/src/execute.rs (1)

725-725: Blank line
Minor layout change, no functional effect.

contracts/staking/src/migrations/states/v0_4_18.rs (2)

28-28: Enhance documentation for fee calculation.

The comment about fee percentage calculation could be more explicit.

-    pub dao_treasury_fee: Uint128, // not using a fraction, fee percentage=x/100000
+    pub dao_treasury_fee: Uint128, // Fee percentage is calculated as (fee_value/100000)*100%. Example: 10000 = 10%

20-22: Consider consolidating oracle address fields.

Multiple optional oracle address fields suggest an evolving contract. Consider consolidating these into a more structured approach.

-    pub oracle_contract_address: Option<Addr>,
-    pub oracle_contract_address_v2: Option<Addr>,
-    pub oracle_address: Option<Addr>,
+    pub oracle_config: OracleConfig,

// Add this struct:
+#[cw_serde]
+pub struct OracleConfig {
+    pub legacy_address: Option<Addr>,      // Previously oracle_contract_address
+    pub current_address: Option<Addr>,     // Previously oracle_address
+    pub v2_address: Option<Addr>,          // Previously oracle_contract_address_v2
+}
contracts/staking/src/tests/test_helper.rs (1)

Line range hint 11-22: Organize test constants better.

Consider grouping related constants and adding documentation about their purpose.

+// Test addresses for Osmosis chain
 pub static OSMO1: &str = "osmo12z558dm3ew6avgjdj07mfslx80rp9sh8nt7q3w";
 pub static OSMO2: &str = "osmo13ftwm6z4dq6ugjvus2hf2vx3045ahfn3dq7dms";
 pub static OSMO3: &str = "osmo1sfhy3emrgp26wnzuu64p06kpkxd9phel8ym0ge";
 pub static OSMO4: &str = "osmo17x4zm0m0mxc428ykll3agmehfrxpr5hqpmsatd";
+
+// Test addresses for Celestia chain
 pub static CELESTIA1: &str = "celestia1sfhy3emrgp26wnzuu64p06kpkxd9phel74e0yx";
 pub static CELESTIA2: &str = "celestia1ztrhpdznu2xlwakd4yp3hg9lwyr3d46ayd30u2";
+
+// Test validator addresses
 pub static CELESTIAVAL1: &str = "celestiavaloper1463wx5xkus5hyugyecvlhv9qpxklz62kyhwcts";
contracts/staking/src/ibc.rs (2)

Line range hint 36-42: Reduce code duplication in channel validation.

The channel validation logic is duplicated between receive_ack and receive_timeout. Consider extracting it to a helper function.

+fn validate_source_channel(config: &Config, source_channel: &str) -> Result<Response, ContractError> {
+    if source_channel != config.protocol_chain_config.ibc_channel_id {
+        return Ok(Response::new()
+            .add_attribute("action", "ibc_receive")
+            .add_attribute("channel", source_channel)
+            .add_attribute("error", "received packet for different channel"));
+    }
+    Ok(Response::new().add_attribute("action", "ibc_receive"))
+}

Also applies to: 75-80


Line range hint 91-94: Enhance error attributes for timeout handling.

The timeout error attributes could be more informative by including the sequence number.

-    Ok(response.add_attribute("error", "ibc packet timed out"))
+    Ok(response
+        .add_attribute("error", "ibc packet timed out")
+        .add_attribute("sequence", sequence.to_string())
+        .add_attribute("channel", source_channel))
contracts/staking/src/tests/instantiate_tests.rs (2)

12-105: Consider reducing code duplication in test functions.

The test functions for invalid configurations follow a similar pattern. Consider introducing a helper function to reduce code duplication.

Example refactor:

fn test_invalid_config<F>(modify_config: F)
where
    F: FnOnce(&mut InstantiateMsg),
{
    let mut deps = mock_dependencies();
    let info = mock_info(OSMO3, &[]);
    let mut msg = mock_init_msg();
    
    modify_config(&mut msg);
    
    let res = crate::contract::instantiate(
        deps.as_mut(),
        cosmwasm_std::testing::mock_env(),
        info.clone(),
        msg,
    );
    assert!(res.is_err());
}

#[test]
fn invalid_native_chain_account_address_prefix_fails() {
    test_invalid_config(|msg| {
        msg.native_chain_config.account_address_prefix = "".to_string();
    });
}

203-259: Enhance test assertions with descriptive messages.

The test assertions in init_properly could be more descriptive to help identify failures quickly.

Example enhancement:

-    assert!(pending_batch.id == 1);
+    assert_eq!(pending_batch.id, 1, "First batch ID should be 1");

-    assert_eq!(
+    assert_eq!(
         NativeChainConfig {
             token_denom: "utia".to_string(),
             // ...
         },
         config.native_chain_config,
+        "Native chain config should match expected values"
     );
contracts/staking/src/helpers.rs (3)

8-41: Enhance address prefix validation.

The address prefix validation is good but could be more robust:

  1. Consider adding a maximum length check based on the Bech32 specification
  2. Consider validating against a list of known prefixes
 pub fn validate_address_prefix(hrp: &str) -> StdResult<String> {
-    if hrp.is_empty() || hrp.len() > 83 {
+    // As per Bech32 spec, HRP length should be 1-83 chars
+    const MIN_HRP_LENGTH: usize = 1;
+    const MAX_HRP_LENGTH: usize = 83;
+    
+    if hrp.len() < MIN_HRP_LENGTH || hrp.len() > MAX_HRP_LENGTH {
         return Err(StdError::generic_err("invalid address prefix length"));
     }

     let mut has_lower: bool = false;
     let mut has_upper: bool = false;
     for b in hrp.bytes() {
-        // Valid subset of ASCII
-        if !(33..=126).contains(&b) {
+        // As per Bech32 spec, HRP chars must be ASCII chars between 33-126
+        if !matches!(b, 33..=126) {
             return Err(StdError::generic_err(
                 "address prefix contains invalid chars",
             ));
         }

203-215: Strengthen denom validation.

The denom validation could be more comprehensive:

  1. Add a maximum length check
  2. Consider validating against a specific pattern
  3. Add validation for common prefixes like 'u' for micro
 pub fn validate_denom(denom: impl Into<String>) -> StdResult<String> {
     let denom: String = denom.into();
 
-    if denom.len() <= 3 {
-        return Err(StdError::generic_err("denom len is less than 3"));
+    const MIN_DENOM_LENGTH: usize = 3;
+    const MAX_DENOM_LENGTH: usize = 128;
+    
+    if denom.len() < MIN_DENOM_LENGTH {
+        return Err(StdError::generic_err(
+            format!("denom length must be at least {}", MIN_DENOM_LENGTH)
+        ));
+    }
+    if denom.len() > MAX_DENOM_LENGTH {
+        return Err(StdError::generic_err(
+            format!("denom length must not exceed {}", MAX_DENOM_LENGTH)
+        ));
     }
-    if !denom.chars().all(|c| c.is_ascii_alphabetic()) {
-        return Err(StdError::generic_err("denom must be alphabetic"));
+    
+    // Common prefix validation
+    if denom.starts_with('u') && denom.len() > 1 {
+        let unit = &denom[1..];
+        if !unit.chars().all(|c| c.is_ascii_alphabetic()) {
+            return Err(StdError::generic_err(
+                "micro unit must contain only alphabetic characters"
+            ));
+        }
+    } else if !denom.chars().all(|c| c.is_ascii_alphabetic()) {
+        return Err(StdError::generic_err(
+            "denom must contain only alphabetic characters"
+        ));
     }
 
     Ok(denom)

217-226: Improve IBC denom validation.

The IBC denom validation could be more flexible and informative:

  1. Add validation for the hash portion
  2. Consider supporting different IBC denom formats
  3. Provide more specific error messages
 pub fn validate_ibc_denom(ibc_denom: impl Into<String>) -> StdResult<String> {
     let ibc_denom: String = ibc_denom.into();
 
-    if ibc_denom.starts_with("ibc/") && ibc_denom.strip_prefix("ibc/").unwrap().len() == 64 {
-        Ok(ibc_denom)
-    } else {
-        Err(StdError::generic_err("ibc denom is invalid"))
+    const IBC_PREFIX: &str = "ibc/";
+    const HASH_LENGTH: usize = 64;
+    
+    if !ibc_denom.starts_with(IBC_PREFIX) {
+        return Err(StdError::generic_err(
+            format!("ibc denom must start with '{}'", IBC_PREFIX)
+        ));
+    }
+    
+    let hash = ibc_denom.strip_prefix(IBC_PREFIX).unwrap();
+    if hash.len() != HASH_LENGTH {
+        return Err(StdError::generic_err(
+            format!("ibc denom hash must be {} characters long", HASH_LENGTH)
+        ));
+    }
+    
+    if !hash.chars().all(|c| c.is_ascii_hexdigit()) {
+        return Err(StdError::generic_err(
+            "ibc denom hash must be a valid hex string"
+        ));
     }
+    
+    Ok(ibc_denom)
contracts/staking/src/tests/unstake_tests.rs (1)

220-220: Simplify batch state updates.

The batch state updates can be simplified by chaining the operations.

-    batch.update_status(BatchStatus::Pending, Some(env.block.time.seconds() - 1));
-    BATCHES.save(&mut deps.storage, 1, &batch).unwrap();
+    BATCHES.save(&mut deps.storage, 1, &batch.update_status(BatchStatus::Pending, Some(env.block.time.seconds() - 1))).unwrap();

Also applies to: 227-227, 233-233

contracts/staking/src/tests/update_config_tests.rs (1)

1-431: Comprehensive test coverage for configuration updates.

The test suite thoroughly covers configuration validation scenarios. However, consider adding the following test cases:

  1. Test for concurrent updates of multiple configurations
  2. Test for empty/null optional fields
  3. Test for maximum/minimum bounds of numeric fields

Example test case for concurrent updates:

#[test]
fn update_multiple_configs_properly() {
    let mut deps = init();
    let info = cosmwasm_std::testing::mock_info(OSMO3, &[]);

    let config_update_msg = crate::msg::ExecuteMsg::UpdateConfig {
        native_chain_config: Some(UnsafeNativeChainConfig {
            // ... native chain config fields
        }),
        protocol_chain_config: Some(UnsafeProtocolChainConfig {
            // ... protocol chain config fields
        }),
        protocol_fee_config: Some(UnsafeProtocolFeeConfig {
            // ... protocol fee config fields
        }),
        batch_period: Some(100u64),
        monitors: Some(vec![OSMO1.to_string()]),
    };

    let res = crate::contract::execute(
        deps.as_mut(),
        cosmwasm_std::testing::mock_env(),
        info.clone(),
        config_update_msg,
    );
    assert!(res.is_ok());

    let config = CONFIG.load(&deps.storage).unwrap();
    // Assert all configurations are updated correctly
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0d118b6 and 6cc377f.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (29)
  • contracts/staking/Cargo.toml (1 hunks)
  • contracts/staking/src/contract.rs (8 hunks)
  • contracts/staking/src/error.rs (1 hunks)
  • contracts/staking/src/execute.rs (19 hunks)
  • contracts/staking/src/helpers.rs (2 hunks)
  • contracts/staking/src/ibc.rs (2 hunks)
  • contracts/staking/src/lib.rs (1 hunks)
  • contracts/staking/src/migrations/mod.rs (1 hunks)
  • contracts/staking/src/migrations/states/mod.rs (1 hunks)
  • contracts/staking/src/migrations/states/v0_4_18.rs (1 hunks)
  • contracts/staking/src/migrations/states/v0_4_20.rs (1 hunks)
  • contracts/staking/src/migrations/v0_4_20.rs (2 hunks)
  • contracts/staking/src/migrations/v1_0_0.rs (1 hunks)
  • contracts/staking/src/msg.rs (5 hunks)
  • contracts/staking/src/query.rs (1 hunks)
  • contracts/staking/src/state.rs (1 hunks)
  • contracts/staking/src/tests/circuit_breaker_tests.rs (2 hunks)
  • contracts/staking/src/tests/helper_tests.rs (1 hunks)
  • contracts/staking/src/tests/instantiate_tests.rs (1 hunks)
  • contracts/staking/src/tests/mod.rs (1 hunks)
  • contracts/staking/src/tests/query_tests.rs (1 hunks)
  • contracts/staking/src/tests/reward_tests.rs (4 hunks)
  • contracts/staking/src/tests/stake_tests.rs (1 hunks)
  • contracts/staking/src/tests/test_helper.rs (2 hunks)
  • contracts/staking/src/tests/unstake_tests.rs (2 hunks)
  • contracts/staking/src/tests/update_config_tests.rs (1 hunks)
  • contracts/staking/src/tests/withdraw_tests.rs (4 hunks)
  • contracts/staking/src/types.rs (1 hunks)
  • scripts/testnet/init-stake-contract.sh (2 hunks)
✅ Files skipped from review due to trivial changes (4)
  • contracts/staking/src/lib.rs
  • contracts/staking/src/tests/mod.rs
  • contracts/staking/src/migrations/states/mod.rs
  • contracts/staking/src/tests/helper_tests.rs
🧰 Additional context used
📓 Learnings (1)
contracts/staking/src/msg.rs (1)
Learnt from: manu0466
PR: milkyway-labs/milkyway-contracts#129
File: contracts/treasury/src/msg.rs:73-73
Timestamp: 2024-11-12T02:30:53.601Z
Learning: The `MigrateMsg` in `contracts/treasury/src/msg.rs` is intentionally designed as a struct instead of an enum due to the lack of specific migration logic that needs to be enforced.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Test Suite
🔇 Additional comments (68)
contracts/staking/src/migrations/v1_0_0.rs (5)

13-20: Ensure consistent migration parameter order in MigrateMsg.
All parameters in the migration function align with the new MigrateMsg::V0_4_20ToV1_0_0 fields. Confirm that no parameter ordering mismatches exist between the message variant and this function signature, which might cause confusion or potential runtime deserialization issues.


21-23: Good practice: version check.
It’s good to see you verifying the contract version before proceeding with migration. This ensures that the migration occurs only if the existing stored version matches the expected FROM_VERSION.


24-30: Comprehensive validation of prefixes and denom.
The validations for address prefixes and the native token denomination reduce the risk of invalid contract states. Well done.

Also applies to: 31-32


34-61: Validating old configuration's addresses.
Ensuring that old addresses align with newly supplied prefixes mitigates potential address format conflicts after migration. This thorough validation step is crucial for preventing errors during contract upgrades.


63-93: Migration logic properly translates old config to new config.
The creation of Config using NativeChainConfig, ProtocolChainConfig, and ProtocolFeeConfig is handled cleanly. This approach avoids data loss while allowing extension of future fields.

Also applies to: 95-101

contracts/staking/src/types.rs (3)

24-35: Validation method ensures seamless safe struct conversion.
The logic for converting the treasury_address into a validated address is robust. Keeping the validation here centralizes correctness checks and clarifies the code flow for external references.


37-63: Clear separation of concerns in UnsafeNativeChainConfig.
By requiring explicit calls to validate(), you decouple raw input handling from secure data usage. This pattern fosters safer expansions of chain-specific logic.


81-125: IBC channel ID format check is valuable.
Validating that the ibc_channel_id starts with "channel-" and parsing the numeric suffix prevents accidental misuse of incorrectly formatted channel IDs. This is a good safeguard.

contracts/staking/src/msg.rs (4)

16-24: Enhanced instantiation with structured configs.
Embedding UnsafeNativeChainConfig, UnsafeProtocolChainConfig, and UnsafeProtocolFeeConfig in InstantiateMsg promotes a clearer and more extensible approach, reducing the risk of misconfigured fields at instantiation.


51-55: Partial updates with optional fields.
Allowing selective updates to each config category via Option<T> is convenient and flexible. However, ensure that partial updates do not revert unchanged fields to defaults. Properly handle None to preserve existing values.


76-81: Consistent ConfigResponse refactor.
Refactoring to return the new NativeChainConfig, ProtocolChainConfig, and ProtocolFeeConfig makes it simpler for consumers to retrieve the entire config in a unified structure.


175-183: Comprehensive migration variant.
The V0_4_20ToV1_0_0 variant lines up well with the parameters in your migration function. This ensures a straightforward upgrade path for both user expectations and on-chain transformations.

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

35-61: Validate minimum requirements and edge cases for NativeChainConfig.

The fields in NativeChainConfig appear properly typed. However, consider clarifying or enforcing constraints, such as ensuring validators is not empty to avoid issues with distributing delegations. You might also want to confirm that unbonding_period is non-zero or within an acceptable range.


63-78: Confirm the intended usage of oracle_address.

Allowing oracle_address to be None gives flexibility. However, if the contract logic relies on an oracle for rate calculation or redemption, ensure that all code paths handle the case where oracle_address is None. This would avoid panic paths or unexpected reverts.

contracts/staking/src/tests/query_tests.rs (1)

8-12: Imports look appropriate.

Adding CELESTIA1, CELESTIA2, and OSMO4 as reused constants is consistent with the test harness. Including Addr from cosmwasm_std looks correct for the new usage in test checks.

contracts/staking/src/contract.rs (6)

Line range hint 5-26: Import and usage alignment confirmed.

The added imports (validate_addresses, validate_denom, Config, State, etc.) consistently reflect the newly introduced validation and state management logic. No issues spotted.


58-75: Validate and construct new Config accurately during instantiation.

Using validate() methods on all config structures is a good defensive design. Ensure these validations include checks for required prefixes, acceptable denom formats, and that liquid_stake_token_denom is sanitized. The default stopped = true approach is suitable for a “safe by default” design.


136-136: Inevitably coupling must_pay with protocol_chain_config.ibc_token_denom.

Confirm that the entire flow of tokens in the contract now expects IBC-based tokens rather than the older native_token_denom. Be sure to remove any remaining references to the old denom to avoid confusion.


159-163: Ensure partial config updates are consistent.

When updating the config, confirm that none of these new fields inadvertently reset existing fields to defaults (e.g., overwriting addresses to None or blank). Proper null checks or a partial update pattern might help preserve existing configurations that are not being updated.


262-262: Safe migration logic to prevent downgrades.

The safeguard ensures no unintended rollback in contract versions. Confirm that integrators are aware they cannot revert to older contract states.


275-287: Migration to v1.0.0 is well-defined.

Migrating to the new config structure is clearly laid out, carrying forward the essential prefix and denom details. Double-check that older deployments will seamlessly transition if they have partial or missing fields.

contracts/staking/src/execute.rs (31)

1-1: Imports for new config structures and utilities
These additional imports align well with the updated configuration approach. No issues detected.

Also applies to: 10-10, 14-14, 16-16


36-36: Check for empty ibc_channel_id
This early return provides clear error handling. Looks good.


41-41: Referencing config.protocol_chain_config.ibc_token_denom
Straightforward usage. No concerns.


49-49: Ensure staker_address is valid
This line references config.native_chain_config.staker_address. Consider validating non-emptiness similarly to ibc_channel_id if there's a possibility it could be missing.


51-51: Use of config.protocol_chain_config.ibc_channel_id
Consistent with the earlier check at line 36.


110-115: Unwrapping the optional oracle_address
Calling .unwrap() may panic if oracle_address is unexpectedly None. Confirm in upstream logic that an oracle address is always set before reaching this code.


164-164: Check minimum liquid stake amount
The validation logic looks correct for comparing the sent amount with the minimum requirement.

Also applies to: 166-166, 167-167


391-391: Use of native_chain_config.unbonding_period
Correctly calculates the expected time for native chain unbonding.


450-450: Cloning IBC token denom
Sufficient for constructing the message. No performance concerns.


475-478: Validate new validator address
Passing config.native_chain_config.validator_address_prefix to validate_address is correct.


482-482: Avoid duplicate validators
The check ensures no repeated entries. Implementation is solid.


493-496: Add new validator
Straightforward addition to the validators vector.


516-519: Validate address for removal
Reuses the same prefix logic as adding a validator, which is consistent.


523-523: Find position of validator
The .position(...) callback is properly used to locate the validator.


529-529: Remove validator from list
Implementation is consistent and error handling is already present if not found.


708-710: Expanding update_config signature
Accepting Option<UnsafeNativeChainConfig>, Option<UnsafeProtocolChainConfig>, and Option<UnsafeProtocolFeeConfig> promotes flexible partial updates.


712-712: Addition of monitors
Allowing an optional list of addresses broadens monitoring capabilities.


722-723: Update protocol chain config
Properly validated upon assignment.


727-727: Update protocol fee config
The .validate method ensures correctness relative to the protocol chain config.


730-734: Validate monitor addresses
Ensures each monitor address uses the correct prefix.


737-738: Update batch_period
Straightforward assignment.


757-759: Derive intermediate sender
Deploys newly structured fields from protocol_chain_config and native_chain_config.


775-775: Find correct IBC coin
Matches the token denom from config.


797-797: Fee handling logic
Falls back to the contract’s total_fees if treasury_address is unset.


1023-1031: Ensure treasury is configured before withdrawal
The unwrap is safe thanks to the preceding is_none() check.


1037-1037: Cloning treasury address
No concerns.


1039-1039: Setting denom in send_msg
Uses config-provided IBC denom. No issues.


1046-1046: Attach receiver attribute
Useful for traceability.


839-841: Intermediate sender for receive_unstaked_tokens
Again leverages protocol_chain_config and native_chain_config. Consistent usage.


857-857: Locate IBC coin for unstaked tokens
Same approach as in reward logic. No issues.


904-904: Check monitors for circuit_breaker
Allows either admin or a monitor to halt the contract. No concerns.

contracts/staking/src/migrations/mod.rs (1)

1-1: Addition of new migration modules
Introducing states and v1_0_0 mirrors the versioning approach. Looks well-structured.

Also applies to: 3-3

contracts/staking/src/migrations/states/v0_4_20.rs (1)

1-27: New file defining v0_4_20::Config
A comprehensive configuration setup that includes addresses, token denoms, periods, and flags. The usage of cw_serde and Item<Config> is consistent with standard patterns.

contracts/staking/src/migrations/v0_4_20.rs (1)

Line range hint 18-34: Add validation during migration.

The migration copies fields directly without validation. Consider adding validation for critical fields like addresses and denominations.

Example validation:

fn validate_migration_config(config: &Config) -> ContractResult<()> {
    validate_address(&config.treasury_address)?;
    validate_denom(&config.native_token_denom)?;
    // Add more validations
    Ok(())
}
contracts/staking/src/error.rs (1)

136-137: LGTM! The new error variant is well-defined.

The TreasuryNotConfigured error variant is clear, follows the established pattern, and enhances configuration validation.

contracts/staking/src/tests/circuit_breaker_tests.rs (1)

65-67: LGTM! Configuration access patterns updated correctly.

The changes properly reflect the new configuration structure, maintaining the same test logic while using the reorganized config fields.

Also applies to: 74-74, 86-86

contracts/staking/src/tests/reward_tests.rs (2)

29-31: LGTM! Configuration access updated correctly in receive_rewards.

The changes properly reflect the new configuration structure for sender derivation, token denomination, and treasury handling.

Also applies to: 50-50, 58-58, 65-65


112-114: LGTM! Configuration access updated correctly in receive_rewards_and_send_fees_to_treasury.

The changes properly reflect the new configuration structure while maintaining the same test coverage and assertions.

Also applies to: 122-122, 148-152

contracts/staking/src/query.rs (1)

19-21: LGTM! Config response structure updated appropriately.

The changes properly reflect the new configuration structure, improving modularity while maintaining the same query functionality.

Also applies to: 23-23

contracts/staking/src/tests/instantiate_tests.rs (1)

1-11: LGTM! Well-organized imports.

The imports are properly organized and include all necessary dependencies for testing.

contracts/staking/src/tests/withdraw_tests.rs (1)

84-84: LGTM! Consistent configuration access.

The changes correctly update the token denomination access to use protocol_chain_config.ibc_token_denom from the new configuration structure.

Also applies to: 125-125, 202-202, 243-243

contracts/staking/src/tests/stake_tests.rs (1)

1-293: LGTM! Improved code formatting.

The changes improve code readability through consistent formatting and proper indentation.

contracts/staking/src/tests/unstake_tests.rs (3)

204-206: LGTM: Configuration access aligned with new structure.

The configuration access has been correctly updated to use the new nested structure, properly accessing the required fields from their respective config sections.


214-214: LGTM: Token denom access updated.

The token denom is now correctly accessed from the protocol chain configuration.


405-421: LGTM: Configuration setup for receive_unstaked_tokens test.

The test configuration setup has been properly updated to use the new nested configuration structure.

scripts/testnet/init-stake-contract.sh (2)

81-81: LGTM: Initialization message updated for new config structure.

The initialization message correctly reflects the new nested configuration structure.


92-93: Verify oracle configuration update.

The configuration update correctly includes the oracle address, but consider adding validation for the oracle contract's existence before updating.

contracts/staking/Cargo.toml Show resolved Hide resolved
@milkyway-labs milkyway-labs deleted a comment from coderabbitai bot Jan 25, 2025
Copy link
Contributor

@rustcandy rustcandy left a comment

Choose a reason for hiding this comment

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

Looks good to me overall. Just a few comments

contracts/staking/src/tests/update_config_tests.rs Outdated Show resolved Hide resolved
contracts/staking/src/tests/update_config_tests.rs Outdated Show resolved Hide resolved
contracts/staking/src/migrations/v1_0_0.rs Show resolved Hide resolved
@manu0466 manu0466 changed the title refactor: update staking contrac config structure refactor: update staking contract config structure Jan 28, 2025
@manu0466 manu0466 requested a review from rustcandy January 28, 2025 15:20
@RiccardoM RiccardoM merged commit e56da75 into main Jan 30, 2025
2 checks passed
@RiccardoM RiccardoM deleted the manuel/config-refactor branch January 30, 2025 13:13
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.

3 participants