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

Prevent from sending tokens when calling a non-payable function on Od… #459

Conversation

kpob
Copy link
Contributor

@kpob kpob commented May 27, 2024

…raVm

Summary by CodeRabbit

  • New Features

    • Introduced a check for non-payable entry points when calling contracts, ensuring transactions with tokens are handled correctly.
    • Added a new is_payable attribute to entry points, allowing differentiation between payable and non-payable functions.
  • Bug Fixes

    • Ensured the cargo purse is empty before setting keys in proxy calls, preventing invalid purse errors.
  • Tests

    • Added tests for calling non-payable functions with tokens to validate proper handling and balance adjustments.
  • Refactor

    • Simplified error handling and result processing in contract calls for improved code maintainability and readability.
  • Chores

    • Reorganized imports and updated function calls to align with new features and refactorings.

@kpob kpob linked an issue May 27, 2024 that may be closed by this pull request
Copy link
Contributor

coderabbitai bot commented May 27, 2024

Walkthrough

The changes introduce a new is_payable attribute to entry points, ensuring that non-payable functions cannot be called with tokens. This affects various files by adding checks, updating function signatures, and modifying test cases to accommodate the new attribute. Additionally, a new test function ensures proper handling of non-payable functions with tokens, and error handling improvements are made in the VM.

Changes

File(s) Change Summary
core/src/contract_container.rs Added is_payable check in call method; updated imports.
core/src/entry_point_callback.rs Introduced is_payable attribute to EntryPoint struct; added new_payable constructor.
examples/src/features/native_token.rs Added test_call_non_payable_function_with_tokens function.
odra-macros/src/.../deployer_item.rs
odra-macros/src/.../deployer_utils.rs
odra-macros/src/.../test_parts.rs
odra-macros/src/utils/expr.rs
Updated entry point creation to handle is_payable attribute.
odra-casper/proxy-caller/.../proxy_caller.rs
odra-casper/proxy-caller/.../proxy_caller_with_return.rs
Added ensure_cargo_purse_is_empty function call.
odra-casper/proxy-caller/src/lib.rs Added ensure_cargo_purse_is_empty function.
odra-vm/src/vm/odra_vm.rs Improved error handling and updated to use is_payable attribute in tests.

Sequence Diagram(s) (Beta)

sequenceDiagram
    participant User
    participant ContractContainer
    participant EntryPoint
    participant VM

    User->>ContractContainer: call(CallDef)
    ContractContainer->>EntryPoint: check is_payable and amount
    alt is_payable and amount > 0
        ContractContainer->>User: ExecutionError::NonPayable
    else
        ContractContainer->>VM: execute call
        VM->>ContractContainer: return result
        ContractContainer->>User: return result
    end
Loading

Poem

In code's vast fields, a change does bloom,
Payable paths, now clear as noon.
Tokens and checks, in harmony dance,
Ensuring errors have no chance.
With tests and tweaks, our work is done,
In Casper's realm, we've just begun. 🌟


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

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

CodeRabbit Commands (invoked as PR comments)

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

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

CodeRabbit Configration 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: 0

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 8fa9770 and d59a4ac.
Files selected for processing (7)
  • core/src/contract_container.rs (2 hunks)
  • core/src/entry_point_callback.rs (1 hunks)
  • examples/src/features/native_token.rs (1 hunks)
  • odra-macros/src/ast/deployer_item.rs (2 hunks)
  • odra-macros/src/ast/deployer_utils.rs (1 hunks)
  • odra-macros/src/ast/test_parts.rs (2 hunks)
  • odra-macros/src/utils/expr.rs (1 hunks)
Additional comments not posted (8)
examples/src/features/native_token.rs (1)

51-63: The new test function test_call_non_payable_function_with_tokens correctly simulates the scenario of calling a non-payable function with tokens. Consider adding more assertions to cover different edge cases or error messages for comprehensive testing.

core/src/entry_point_callback.rs (1)

68-89: The addition of the is_payable field and the new constructor methods new and new_payable in the EntryPoint struct are well-implemented. Consider adding detailed documentation for the is_payable field and the behavior of these methods to enhance code readability and maintainability.

core/src/contract_container.rs (1)

26-36: The modifications in the call method to handle non-payable entry points when tokens are sent are correctly implemented. Consider adding unit tests to cover scenarios where tokens are mistakenly sent to non-payable functions to ensure robust error handling.

odra-macros/src/utils/expr.rs (1)

167-179: The update to the new_entry_point function to support both payable and non-payable entry points is well-implemented. Consider adding comprehensive tests for this function to ensure that it correctly handles both types of entry points under various scenarios.

odra-macros/src/ast/deployer_utils.rs (1)

24-27: The changes to include the is_payable attribute in the EntrypointsInitExpr struct are correctly implemented. Consider adding comments or documentation explaining the use and impact of the is_payable attribute to enhance code clarity.

odra-macros/src/ast/deployer_item.rs (1)

Line range hint 217-277: The changes to the DeployerItem struct to support the creation of payable entry points are well-implemented. Consider adding tests to ensure that the deployment process correctly handles payable entry points under various scenarios.

odra-macros/src/ast/test_parts.rs (2)

295-295: Update to EntryPoint::new_payable reflects the new "payable" functionality correctly.

This change correctly updates the entry point for "pay_to_mint" to be payable, aligning with the new system requirements for handling token transactions. Good job ensuring that the system's behavior matches the intended functionality.


457-457: Correct implementation of the payable entry point for "pay_to_mint".

This change is consistent with the updates made elsewhere in the codebase to support the new "payable" functionality. It ensures that the "pay_to_mint" function can correctly handle token transactions, which is crucial for the correct operation of the contract.

* Update proxy_caller and OdraVm
* proxy caller ensures if the cargo purse is empty
* update OdraVm's call_contract to revert on error
Copy link

Benchmark report

Action Details Gas diff
Contract Call Entry point: get_variable 🔴 +0.00037951 CSPR (0.07%)
Contract Call Entry point: get_struct_variable 🔴 +0.00037951 CSPR (0.09%)
Contract Call Entry point: get_mapping 🔴 +0.00037951 CSPR (0.10%)
Contract Call Entry point: get_list 🔴 +0.00037951 CSPR (0.10%)
Contract Call Entry point: call_submodule 🔴 +0.00037951 CSPR (0.10%)
Contract Call Entry point: call_payable 🔴 +0.00975279 CSPR (0.16%)
Contract Call Entry point: get_named_key 🔴 +0.00037951 CSPR (0.09%)
Contract Call Entry point: get_dictionary 🔴 +0.00037951 CSPR (0.09%)

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

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between d59a4ac and d2c61f9.
Files ignored due to path filters (2)
  • odra-casper/test-vm/resources/proxy_caller.wasm is excluded by !**/*.wasm
  • odra-casper/test-vm/resources/proxy_caller_with_return.wasm is excluded by !**/*.wasm
Files selected for processing (5)
  • examples/src/features/native_token.rs (1 hunks)
  • odra-casper/proxy-caller/bin/proxy_caller.rs (1 hunks)
  • odra-casper/proxy-caller/bin/proxy_caller_with_return.rs (2 hunks)
  • odra-casper/proxy-caller/src/lib.rs (1 hunks)
  • odra-vm/src/vm/odra_vm.rs (5 hunks)
Files skipped from review as they are similar to previous changes (1)
  • examples/src/features/native_token.rs
Additional comments not posted (8)
odra-casper/proxy-caller/bin/proxy_caller.rs (2)

10-12: Ensure correct usage of new imports and function call.

The addition of ensure_cargo_purse_is_empty aligns with the PR's goal to prevent token transfer when calling non-payable functions. Ensure that the function is tested thoroughly.


23-23: Verify the placement and logic of ensure_cargo_purse_is_empty.

Verification successful

The function ensure_cargo_purse_is_empty is designed to ensure that the cargo purse is empty and reverts if it is not. It is used in two places: proxy_caller_with_return.rs and proxy_caller.rs. In both files, it is called after the proxy call is made, which seems appropriate as it ensures the cargo purse is empty after the operation.

  • In proxy_caller_with_return.rs, it is called after call_versioned_contract_ret_bytes.
  • In proxy_caller.rs, it is called after runtime::call_versioned_contract.

Both usages appear to be correctly placed to ensure the cargo purse is empty after the respective operations.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that `ensure_cargo_purse_is_empty` is called correctly and only when necessary.

# Test: Search for the function usage. Expect: Only occurances where it's necessary.
rg --type rust $'ensure_cargo_purse_is_empty'

Length of output: 613



Script:

#!/bin/bash
# Extract the definition of `ensure_cargo_purse_is_empty`
rg --type rust --context 10 'pub fn ensure_cargo_purse_is_empty' odra-casper/proxy-caller/src/lib.rs

# Extract the surrounding code where `ensure_cargo_purse_is_empty` is used in `proxy_caller_with_return.rs`
rg --type rust --context 10 'ensure_cargo_purse_is_empty' odra-casper/proxy-caller/bin/proxy_caller_with_return.rs

# Extract the surrounding code where `ensure_cargo_purse_is_empty` is used in `proxy_caller.rs`
rg --type rust --context 10 'ensure_cargo_purse_is_empty' odra-casper/proxy-caller/bin/proxy_caller.rs

Length of output: 2460

odra-casper/proxy-caller/bin/proxy_caller_with_return.rs (2)

10-12: Ensure correct usage of new imports and function call.

The addition of ensure_cargo_purse_is_empty aligns with the PR's goal to prevent token transfer when calling non-payable functions. Ensure that the function is tested thoroughly.


25-25: Verify the placement and logic of ensure_cargo_purse_is_empty.

Verification successful

The function ensure_cargo_purse_is_empty is designed to ensure that the cargo purse is empty and reverts if it is not. This function is used in two files: proxy_caller_with_return.rs and proxy_caller.rs. In both files, it is called after a proxy call is made.

Observations:

  • Definition: The function checks if the provided value is zero. If not, it retrieves the cargo purse balance and reverts if the balance is not zero.
  • Usage in proxy_caller_with_return.rs: The function is called after making a call to a versioned contract and before setting the result key.
  • Usage in proxy_caller.rs: The function is called after making a call to a versioned contract.

Conclusion:

The placement of ensure_cargo_purse_is_empty appears to be correct in both files. It is called after the proxy call, which is a logical point to ensure that the cargo purse is empty.

Actionable Directive:

  • The placement and logic of ensure_cargo_purse_is_empty are verified and correct.
Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that `ensure_cargo_purse_is_empty` is called correctly and only when necessary.

# Test: Search for the function usage. Expect: Only occurances where it's necessary.
rg --type rust $'ensure_cargo_purse_is_empty'

Length of output: 613



Script:

#!/bin/bash
# Description: Gather the definition of `ensure_cargo_purse_is_empty` and its usage context in the relevant files.

# Get the definition of `ensure_cargo_purse_is_empty`
rg --type rust --context 10 'pub fn ensure_cargo_purse_is_empty' odra-casper/proxy-caller/src/lib.rs

# Get the usage context in `proxy_caller_with_return.rs`
rg --type rust --context 10 'ensure_cargo_purse_is_empty' odra-casper/proxy-caller/bin/proxy_caller_with_return.rs

# Get the usage context in `proxy_caller.rs`
rg --type rust --context 10 'ensure_cargo_purse_is_empty' odra-casper/proxy-caller/bin/proxy_caller.rs

Length of output: 2460

odra-casper/proxy-caller/src/lib.rs (1)

119-128: Ensure correct implementation and usage of ensure_cargo_purse_is_empty.

The implementation of ensure_cargo_purse_is_empty correctly checks if the attached value is non-zero and then checks the balance of the cargo purse. This aligns with the PR's goal to prevent unintended token transfers.

odra-vm/src/vm/odra_vm.rs (3)

79-82: Refactor error handling in call_contract.

The refactoring of error handling in call_contract simplifies the flow and makes it more robust by directly handling errors and successful calls.


361-371: Simplify snapshot management in handle_call_result.

The changes to handle_call_result simplify snapshot management, making the VM's state management more efficient and less error-prone.


488-490: Ensure proper error handling in test blocks.

The addition of catch_unwind in test blocks is a good practice to ensure that the VM handles errors gracefully and does not crash unexpectedly during contract calls.

Also applies to: 508-510

@kpob kpob merged commit 9708458 into release/1.1.0 May 29, 2024
4 checks passed
@kpob kpob deleted the fix/incorrect-contract-balance-when-calling-a-non-payable-function branch May 29, 2024 09:51
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.

Incorrect contract balance when calling a non payable function
3 participants