Skip to content

feat: CW Union Transfer library #327

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

keyleu
Copy link
Contributor

@keyleu keyleu commented Apr 23, 2025

Counterpart of the EVM Union Transfer library but for Cosmwasm.

Works in a very similar way as the EVM one, using ABI encoded bytes in Cosmwasm. The main difference is that here the instruction goes in a batch of instructions (this is how it's currently used for btc.union.build) instead of sending the instruction directly, having, in the end, a batch with only 1 instruction.

Most parts have been unit tested but the e2e test can't be completed because the protocol for CW is only available on Babylon mainnet and we don't have an account that can upload contracts there yet. In any case, if required, an e2e test can be done there once we have that.

Summary by CodeRabbit

  • New Features
    • Introduced the Valence Union Transfer library, enabling fund transfers between CosmWasm and EVM chains using the Union protocol.
    • Added configuration options for flexible asset types (native or CW20), transfer amount (full or fixed), transfer timeout, and protocol-specific parameters.
    • Added contract entry points for instantiation, execution, and queries supporting ownership and configuration management.
    • Provided ABI-encoded instruction support for Union transfers with detailed serialization and decoding.
    • Integrated the library as a workspace dependency and added support in the program manager.
  • Documentation
    • Added comprehensive user documentation and flow diagrams for the Union Transfer library.
    • Updated schema files and documentation to reflect the new library and its configuration options.
  • Tests
    • Implemented integration tests covering contract instantiation, configuration validation, updates, and transfer execution.

@keyleu keyleu requested a review from bekauz April 23, 2025 10:51
Copy link
Contributor

coderabbitai bot commented Apr 23, 2025

Walkthrough

A new CosmWasm smart contract library, valence-union-transfer, has been introduced to facilitate asset transfers using the Union protocol within the Valence ecosystem. The library is fully integrated into the workspace, with corresponding configuration, schema, documentation, and comprehensive tests. The contract defines instantiation, execution, and query entry points, supports complex configuration for asset and protocol parameters, and provides ABI encoding for cross-chain instructions. The program manager and documentation have been updated to recognize and support this new library, including schema extensions and configuration options.

Changes

File(s) Change Summary
Cargo.toml, program-manager/Cargo.toml Added valence-union-transfer as a workspace dependency.
contracts/libraries/union-transfer/Cargo.toml, contracts/libraries/union-transfer/.cargo/config.toml Added manifest and Cargo config for new valence-union-transfer library with dependencies, features, and build aliases.
contracts/libraries/union-transfer/README.md, docs/src/libraries/cosmwasm/union_transfer.md Added documentation describing the purpose, configuration, and flow of the Union Transfer library.
contracts/libraries/union-transfer/schema/valence-union-transfer.json, program-manager/schema/valence-program-manager.json Added and extended JSON schemas for contract messages, configuration, and updates to support the new library.
contracts/libraries/union-transfer/src/lib.rs, contracts/libraries/union-transfer/src/contract.rs, contracts/libraries/union-transfer/src/msg.rs, contracts/libraries/union-transfer/src/state.rs, contracts/libraries/union-transfer/src/union.rs Implemented library modules: contract logic, message types, configuration, ABI encoding, and persistent state.
contracts/libraries/union-transfer/src/bin/schema.rs Added schema generator for contract API messages.
contracts/libraries/union-transfer/src/tests.rs Added integration tests for instantiation, configuration, and transfer logic.
docs/src/SUMMARY.md Added "Union Transfer" to the CosmWasm libraries documentation index.
program-manager/src/library.rs Added new enum variant for ValenceUnionTransfer configuration.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Processor
    participant UnionTransferLibrary
    participant zkGMContract
    participant EVMRecipient

    User->>Processor: Initiate transfer (function call)
    Processor->>UnionTransferLibrary: Execute Transfer
    UnionTransferLibrary->>UnionTransferLibrary: Validate config and balances
    UnionTransferLibrary->>zkGMContract: Send encoded transfer instruction (via IBC)
    zkGMContract->>EVMRecipient: Release/transfer assets on EVM chain
Loading

Poem

In the garden of code, a new path we lay,
For Union Transfers to travel and play.
Across chains they hop, with assets in tow,
Configured with care, where the protocols flow.
From CosmWasm fields to EVM's bright sun,
This rabbit approves—another great run!
🐇✨


🪧 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 sequence diagram to generate a sequence diagram of the changes in this 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
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: 5

🧹 Nitpick comments (13)
contracts/libraries/union-transfer/.cargo/config.toml (1)

1-3: Add Cargo aliases for build and schema generation.

The wasm and schema aliases streamline the build and schema-generation workflow for the Union Transfer library. Consider documenting these aliases in the repository’s CONTRIBUTING or README to surface them for other developers.

contracts/libraries/union-transfer/src/state.rs (1)

3-3: Add documentation for storage item
Consider adding a doc comment above COUNTER to clarify its purpose, for example:

/// Storage key for the transfer instruction salt counter.
pub const COUNTER: Item<u64> = Item::new("counter");
contracts/libraries/union-transfer/src/lib.rs (1)

5-6: Consider moving tests module declaration
For readability, you may want to place the #[cfg(test)] mod tests; after all pub mod exports so that test code is clearly separated from production modules.

docs/src/libraries/cosmwasm/union_transfer.md (1)

3-3: Fix grammar and improve clarity in documentation
Refine active voice and concise phrasing in two spots:

  • Change “allows to transfer funds” to “allows you to transfer funds” (or “allows transferring funds”).
  • Replace “take into consideration the amount of tokens” with “consider the number of tokens.”

Apply this diff:

- The **Valence Union Transfer** library allows to transfer funds over [Union](https://union.build/) from an **input account** ...
+ The **Valence Union Transfer** library allows you to transfer funds over [Union](https://union.build/) from an **input account** ...

...

- therefore the `quote_amount` value should take into consideration the amount of tokens that the filling party will receive.
+ therefore the `quote_amount` value should consider the number of tokens that the filling party will receive.

Also applies to: 43-43

🧰 Tools
🪛 LanguageTool

[grammar] ~3-~3: Did you mean “transferring”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun.
Context: ...Valence Union Transfer** library allows to transfer funds over [Union](https://union.build/...

(ALLOW_TO)

contracts/libraries/union-transfer/README.md (1)

3-3: Grammar tweak for a clearer opening sentence

The phrase “allows to transfer funds” is missing an object and sounds awkward. A small tweak improves readability:

-The **Valence Union Transfer** library allows to transfer funds over [Union](https://union.build/) from an **input account** on a source chain to an **output account** on a destination chain.
+The **Valence Union Transfer** library allows you to transfer funds over [Union](https://union.build/) from an **input account** on a source chain to an **output account** on a destination chain.
🧰 Tools
🪛 LanguageTool

[grammar] ~3-~3: Did you mean “transferring”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun.
Context: ...Valence Union Transfer** library allows to transfer funds over [Union](https://union.build/...

(ALLOW_TO)

contracts/libraries/union-transfer/src/tests.rs (3)

14-16: Constant name/value mismatch may confuse future maintainers

ONE_MILLION is set to 1_000_000_000_000, which is one trillion. Either rename or fix the value:

-const ONE_MILLION: u128 = 1_000_000_000_000_u128;
+// choose one of the following
+const ONE_TRILLION: u128 = 1_000_000_000_000_u128;
// or
-const ONE_MILLION: u128 = 1_000_000_u128;

112-143: OptionUpdate::Set(None) wipes a field – double‑check intent

transfer_timeout, batch_instruction_version, and transfer_instruction_version are wrapped in OptionUpdate::Set(...). When the supplied config carries None, the field is explicitly set to None (i.e. cleared). If the intended semantics were “leave unchanged when caller passes None”, use OptionUpdate::Keep instead.

Please verify to avoid unintentionally resetting contract state.


83-101: zkgm_contract in tests is a local CW address, not an EVM address

For realism and for tests to surface address‑format bugs, consider providing an EVM‑style hex string (as expected on mainnet) instead of self.input_addr:

-            self.input_addr.to_string(),
+            "0xe7c952d457121ba8f02df1b1d85b26de80a6f1ac".to_string(),

This mirrors production usage and prevents accidental coupling to the test account address.

contracts/libraries/union-transfer/src/contract.rs (3)

194-213: Salt encoding does unnecessary round‑tripping and allocates twice

You hash to [u8; 32], convert to a hex string, parse that back into Bytes, then stringify it again.
This can be simplified and made allocation‑free:

-    let send_msg = CosmosMsg::Wasm(WasmMsg::Execute {
-        contract_addr: cfg.zkgm_contract.to_string(),
-        msg: to_json_binary(&union::ExecuteMsg::Send {
-            /* … */
-            salt: Bytes::from_hex(hex::encode(salt))
-                .map_err(|_| LibraryError::ExecutionError("Can't encode the salt.".to_string()))?
-                .to_string(),
-            instruction: bytes_instruction.to_string(),
-        })?,
-        funds,
-    });
+    // keep salt in raw bytes – `Bytes` already implements `From<&[u8]>`
+    let send_msg = CosmosMsg::Wasm(WasmMsg::Execute {
+        contract_addr: cfg.zkgm_contract.to_string(),
+        msg: to_json_binary(&union::ExecuteMsg::Send {
+            /* … */
+            salt: Bytes::from(salt).to_string(),        // one allocation instead of three
+            instruction: bytes_instruction.to_string(),
+        })?,
+        funds,
+    });

This removes two conversions (hex::encode and Bytes::from_hex) and cuts memory usage.


132-137: Uint256 → U256 conversion can panic in edge cases

U256::from_be_bytes(…) panics if the value does not fit in 256 bits. While Uint256 is guaranteed
to be 256‑bit, a future refactor could change that invariant.
The safe idiom is U256::from_big_endian(quote_amount.to_be_bytes().as_slice()), which never panics.

Not blocking, but worth hardening.


108-130: Shadowed amount variable may confuse future maintainers

Inside the else branch you re‑declare let amount = amount.u128(); which shadows the outer Uint128
named amount. Later you still reference the outer variable.
Consider renaming:

-    let amount = amount.u128();
+    let native_amount_u128 = amount.u128();-    funds.push(coin(amount, denom));
+    funds.push(coin(native_amount_u128, denom));

This avoids accidental misuse of the wrong binding.

contracts/libraries/union-transfer/schema/valence-union-transfer.json (1)

70-87: Schema: missing description for critical fields

The JSON‑schema is thorough but some essential parameters (zkgm_contract, channel_id) lack explanatory
text while less important ones have it.
Describing these fields improves auto‑generated docs and front‑end validations.

program-manager/schema/valence-program-manager.json (1)

2946-2967: Add descriptive documentation for TransferAmount
Currently TransferAmount is defined without a description. For consistency and better schema-generated docs (similar to IbcTransferAmount), consider adding a description explaining "full_amount" vs a fixed amount object.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9b83779 and 19372aa.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (17)
  • Cargo.toml (1 hunks)
  • contracts/libraries/union-transfer/.cargo/config.toml (1 hunks)
  • contracts/libraries/union-transfer/Cargo.toml (1 hunks)
  • contracts/libraries/union-transfer/README.md (1 hunks)
  • contracts/libraries/union-transfer/schema/valence-union-transfer.json (1 hunks)
  • contracts/libraries/union-transfer/src/bin/schema.rs (1 hunks)
  • contracts/libraries/union-transfer/src/contract.rs (1 hunks)
  • contracts/libraries/union-transfer/src/lib.rs (1 hunks)
  • contracts/libraries/union-transfer/src/msg.rs (1 hunks)
  • contracts/libraries/union-transfer/src/state.rs (1 hunks)
  • contracts/libraries/union-transfer/src/tests.rs (1 hunks)
  • contracts/libraries/union-transfer/src/union.rs (1 hunks)
  • docs/src/SUMMARY.md (1 hunks)
  • docs/src/libraries/cosmwasm/union_transfer.md (1 hunks)
  • program-manager/Cargo.toml (1 hunks)
  • program-manager/schema/valence-program-manager.json (7 hunks)
  • program-manager/src/library.rs (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
contracts/libraries/union-transfer/src/union.rs (2)
contracts/libraries/union-transfer/src/tests.rs (1)
  • new (33-55)
contracts/libraries/union-transfer/src/msg.rs (2)
  • new (133-167)
  • new (338-372)
contracts/libraries/union-transfer/src/msg.rs (5)
packages/valence-macros/src/lib.rs (1)
  • valence_library_query (335-353)
contracts/libraries/union-transfer/src/tests.rs (2)
  • new (33-55)
  • update_config (112-143)
program-manager/src/library.rs (1)
  • new (60-67)
contracts/libraries/union-transfer/src/contract.rs (1)
  • update_config (234-241)
packages/library-base/src/state.rs (2)
  • load_config (28-38)
  • save_config (20-26)
🪛 LanguageTool
contracts/libraries/union-transfer/README.md

[grammar] ~3-~3: Did you mean “transferring”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun.
Context: ...Valence Union Transfer** library allows to transfer funds over [Union](https://union.build/...

(ALLOW_TO)

docs/src/libraries/cosmwasm/union_transfer.md

[grammar] ~3-~3: Did you mean “transferring”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun.
Context: ...Valence Union Transfer** library allows to transfer funds over [Union](https://union.build/...

(ALLOW_TO)


[style] ~43-~43: The phrase “take into consideration” may be wordy. To make your writing clearer, consider replacing it.
Context: ...erefore the quote_amount value should take into consideration the amount of tokens that the filling p...

(TAKE_INTO_CONSIDERATION)


[uncategorized] ~43-~43: ‘Amount of’ should usually only be used with uncountable or mass nouns. Consider using “number” if this is not the case.
Context: ...alue should take into consideration the amount of tokens that the filling party will r...

(AMOUNTOF_TO_NUMBEROF)

🔇 Additional comments (18)
docs/src/SUMMARY.md (1)

46-46:

✅ Verification successful

Add new Union Transfer documentation entry.

The new “Union Transfer” entry is correctly placed under the CosmWasm libraries section, matching the indentation and format of neighboring items. Ensure that docs/src/libraries/cosmwasm/union_transfer.md exists and is accessible.

Run:


🏁 Script executed:

fd "union_transfer.md" docs/src/libraries/cosmwasm

Length of output: 96


Union Transfer entry added — file exists and accessible

  • Confirmed docs/src/libraries/cosmwasm/union_transfer.md is present and correctly placed.
  • Documentation entry matches indentation and format of neighboring items.
program-manager/Cargo.toml (1)

47-47: Integrate Valence Union Transfer into program-manager dependencies.

Adding valence-union-transfer as a workspace dependency aligns with the new CosmWasm library crate. Confirm that the path and package name in contracts/libraries/union-transfer/Cargo.toml match this entry.

program-manager/src/library.rs (1)

100-100:

✅ Verification successful

Add ValenceUnionTransfer variant for new library.

The new ValenceUnionTransfer(valence_union_transfer::msg::LibraryConfig) entry integrates the Union Transfer library into the program manager. Ensure the manager_impl_library_configs macro generates the necessary handlers for this variant, and that the JSON schema at program-manager/schema/valence-program-manager.json is updated accordingly.

Run:


🏁 Script executed:

rg "ValenceUnionTransfer" -A3 program-manager/schema/valence-program-manager.json

Length of output: 504


🏁 Script executed:

#!/bin/bash
# Locate the invocation of the manager_impl_library_configs macro to verify it includes the new variant
rg "manager_impl_library_configs" -C3 -n program-manager/src

Length of output: 818


🏁 Script executed:

#!/bin/bash
# Extract the enum definition around the manager_impl_library_configs macro to verify the new variant inclusion
sed -n '50,150p' program-manager/src/library.rs

Length of output: 2952


All Verified: ValenceUnionTransfer Integrated Successfully
The LibraryConfig enum under the #[manager_impl_library_configs] macro now includes the ValenceUnionTransfer variant, and the JSON schema at program-manager/schema/valence-program-manager.json has been updated with both the create and update definitions for "ValenceUnionTransfer". No further changes required.

Cargo.toml (1)

91-91:

✅ Verification successful

Integrate valence-union-transfer into workspace dependencies.

Adding the new library under [workspace.dependencies] with features = ["library"] correctly wires it into the Cargo workspace. Verify that the path contracts/libraries/union-transfer contains a valid Cargo.toml with the library feature flag.

Run:


🏁 Script executed:

fd "Cargo.toml" contracts/libraries/union-transfer

Length of output: 96


🏁 Script executed:

grep -n '^\[features\]' -n contracts/libraries/union-transfer/Cargo.toml -A5

Length of output: 252


Workspace dependency integration verified

  • Confirmed that contracts/libraries/union-transfer/Cargo.toml defines a [features] section with library = [], satisfying the feature-flag requirement.
contracts/libraries/union-transfer/src/state.rs (1)

1-3: Storage counter definition looks correct
The COUNTER storage item is properly defined to track a unique u64 counter for generating salts.

contracts/libraries/union-transfer/src/lib.rs (1)

1-4: Module exports are correctly declared
The library entry point cleanly exposes contract, msg, state, and union modules. The public API surface aligns with the PR objectives.

contracts/libraries/union-transfer/src/bin/schema.rs (1)

1-5: Schema generation binary is implemented as expected
The main function correctly invokes write_api! with the appropriate message types, and imports are accurate. This will produce the JSON schema for instantiate, execute, and query interfaces.

contracts/libraries/union-transfer/Cargo.toml (1)

23-24: Verify serde and schemars derive features
To support #[derive(Serialize, Deserialize)] and JSON schema generation, ensure that the workspace dependencies for serde and schemars enable the derive feature. Without it, derive macros in your types (e.g., in msg.rs or state.rs) may fail to compile.

contracts/libraries/union-transfer/src/msg.rs (1)

169-193: channel_id and quote_amount are not sanity‑checked

do_validate rejects zero amount and transfer_timeout, but allows:

  • channel_id == 0
  • quote_amount == 0

Both likely indicate mis‑configuration. Consider adding similar guards to prevent accidental mis‑deployments.

program-manager/schema/valence-program-manager.json (9)

873-885: Introduce ValenceUnionTransfer to LibraryConfig oneOf
The new variant for "ValenceUnionTransfer" correctly references #/definitions/LibraryConfig14, aligning with the addition of the Union Transfer library. Ensure that this oneOf branch is also handled appropriately in program-manager/src/library.rs (the enum variant should match this name).


984-1007: Ensure LibraryConfig14 matches Rust contract schema
The LibraryConfig14 definition introduces all required fields for the Union Transfer library. Please verify that this JSON schema mirrors the Rust InstantiateMsg or LibraryConfig struct in the union-transfer contract. In particular, confirm that:

  • Fields marked optional here (batch_instruction_version, transfer_instruction_version, transfer_timeout) correspond to Option<u8>/Option<u64> in Rust.
  • Naming (e.g. zkgm_contract) matches the Rust field names exactly.

1442-1454: Add ValenceUnionTransfer to LibraryConfigUpdate oneOf
The update schema now includes a "ValenceUnionTransfer" branch pointing to #/definitions/LibraryConfigUpdate14. This looks correct—ensure that the program manager’s update logic recognizes and routes this variant.


1617-1736: Validate LibraryConfigUpdate14 against Rust update message
LibraryConfigUpdate14 defines all optional update wrappers for the Union Transfer library. Confirm that this JSON matches the Rust UpdateMsg or corresponding LibraryConfigUpdate struct:

  • Required keys (batch_instruction_version, transfer_instruction_version, transfer_timeout) align with the Rust update API.
  • Use of OptionUpdate_for_uint8/OptionUpdate_for_uint64 matches how numeric updates are represented in code.

2385-2411: Approve OptionUpdate_for_uint64 definition
The OptionUpdate_for_uint64 union correctly models a none vs set pattern for u64 updates. This will be used for fields like transfer_timeout.


2412-2438: Approve OptionUpdate_for_uint8 definition
OptionUpdate_for_uint8 is consistent with the uint8 update pattern and will apply to instruction version fields.


2972-2975: Uint256 definition appears consistent
The Uint256 type follows the established pattern of other Uint wrappers and includes a clear description. No issues found.


3190-3207: Approve UncheckedUnionCw20Config addition
UncheckedUnionCw20Config cleanly captures the CW20 variant with minter and token. This aligns with UncheckedUnionDenomConfig’s downstream reference.


3208-3236: Approve UncheckedUnionDenomConfig addition
The UncheckedUnionDenomConfig union properly supports both native and cw20 cases. Definitions and nesting look correct and consistent with other denom types.

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

🧹 Nitpick comments (2)
contracts/libraries/union-transfer/src/union.rs (2)

76-136: Consider enhancing the real instruction test with more assertions

While the test effectively validates the decoding of a real instruction, it relies heavily on debug prints rather than assertions for some fields. Adding assertions for all important fields would make the test more robust against regressions.

 // Extract and print important fields for verification
 println!("\nFungibleAssetOrder details:");
 println!("  Sender: {}", fungible_asset_order.sender);
+assert_eq!(fungible_asset_order.sender.to_string(), "0x62626e31657032756d6a366b6e3334673274746a616c73633572397738707437737634786a7537333472");
 println!("  Receiver: {}", fungible_asset_order.receiver);
+assert_eq!(fungible_asset_order.receiver.to_string(), "0xe7c952d457121ba8f02df1b1d85b26de80a6f1ac");
 println!("  Base token: {}", fungible_asset_order.baseToken);
+assert_eq!(fungible_asset_order.baseToken.to_string(), "0x7562626e"); // "ubbn"
 println!("  Base amount: {}", fungible_asset_order.baseAmount);
+assert_eq!(fungible_asset_order.baseAmount, U256::from(35000000));
 // Continue with other assertions...

93-98: Consider adding a test helper for instruction debugging

The debug printing code appears in multiple places. Consider extracting it to a test helper function to reduce duplication and make future maintenance easier.

+#[cfg(test)]
+fn print_instruction_details(instruction: &Instruction) {
+    println!("Instruction details:");
+    println!("  Version: {}", instruction.version);
+    println!("  Opcode: {}", instruction.opcode);
+    println!("  Operand length: {} bytes", instruction.operand.len());
+}

// Then in the test:
-// Print decoded instruction details for debugging
-println!("Instruction successfully decoded:");
-println!("  Version: {}", instruction.version);
-println!("  Opcode: {}", instruction.opcode);
-println!("  Operand length: {} bytes", instruction.operand.len());
+// Print decoded instruction details for debugging
+println!("Instruction successfully decoded:");
+print_instruction_details(&instruction);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between fc24a65 and 6209b63.

📒 Files selected for processing (1)
  • contracts/libraries/union-transfer/src/union.rs (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
contracts/libraries/union-transfer/src/union.rs (1)
Learnt from: keyleu
PR: timewave-computer/valence-protocol#327
File: contracts/libraries/union-transfer/src/union.rs:8-16
Timestamp: 2025-04-23T11:02:27.574Z
Learning: When using alloy_primitives::Bytes::from_hex() for processing hex strings in Cosmwasm contracts, additional validation at deserialization time is generally redundant as Bytes::from_hex() already validates hex string format.
🔇 Additional comments (4)
contracts/libraries/union-transfer/src/union.rs (4)

1-16: Clean implementation of execute message structure

The ExecuteMsg enum is well-structured with appropriate fields for IBC channel communication. Using String for salt and instruction aligns with the intention to handle hex-prefixed byte data, and the comment explains this design choice clearly.

Per the learnings from previous reviews, validation at deserialization time isn't necessary since Bytes::from_hex() already provides validation when these strings are processed later in the code.


18-42: Well-defined Solidity ABI structures for cross-chain communication

The use of the sol! macro to define Solidity-compatible structures is an excellent approach for cross-chain interoperability. The defined structures (Instruction, Batch, and FungibleAssetOrder) match the Union protocol's requirements and provide a clean interface for ABI encoding/decoding.


54-74: Complete serialization test with proper assertions

This test properly verifies that the ExecuteMsg::Send serializes to the expected JSON format. The assertion ensures the test will fail if the serialization format changes unexpectedly.


138-192: Comprehensive test for instruction building from configuration

This test thoroughly validates that a FungibleAssetOrder is correctly constructed from a Config object. The assertions verify key fields, ensuring the configuration transformation logic works as expected.

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.

1 participant