Skip to content

Conversation

Vvaradinov
Copy link
Contributor

@Vvaradinov Vvaradinov commented Nov 25, 2024

Description

Adds Deposit and CancelProposal transactions with tests.

Closes: #XXXX


Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • tackled an existing issue or discussed with a team member
  • left instructions on how to review the changes
  • targeted the correct branch (see PR Targeting)

Reviewers Checklist

All items are required.
Please add a note if the item is not applicable
and please add your handle next to the items reviewed
if you only reviewed selected items.

I have...

  • added a relevant changelog entry to the Unreleased section in CHANGELOG.md
  • confirmed all author checklist items have been addressed
  • confirmed that this PR does not change production code
  • reviewed content
  • tested instructions (if applicable)
  • confirmed all CI checks have passed

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced Deposit and CancelProposal functionalities in governance, allowing users to deposit to proposals and cancel proposals.
    • Enhanced governance precompile with new queries for proposals and proposal details.
    • Added new events for Deposit and CancelProposal to improve tracking of governance actions.
  • Improvements

    • Improved handling of EVM coin precision and transaction fee management.
    • Updated governance contract to emit events for deposits and cancellations.
  • Bug Fixes

    • Fixed issues with the command evmosd testnet init-files to ensure correct default denomination usage.

These changes enhance user interaction with governance features and improve overall system reliability.

@Vvaradinov Vvaradinov requested a review from a team as a code owner November 25, 2024 19:35
@Vvaradinov Vvaradinov requested review from MalteHerrmann and ramacarlucho and removed request for a team November 25, 2024 19:35
Copy link
Contributor

coderabbitai bot commented Nov 25, 2024

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The pull request introduces substantial updates to the governance precompile in the blockchain application. Key changes include the addition of Deposit and CancelProposal transactions, new events for tracking these actions, and enhanced error handling. The CHANGELOG.md has been updated to reflect these modifications, which also involve the removal of the EthAccount type and updates to the BaseFee to utilize Decimal. New test cases have been added to ensure the proper functionality of these features, thereby enhancing the overall governance capabilities.

Changes

File Change Summary
CHANGELOG.md Updated with new entries under "Unreleased" for "State Machine Breaking," "Improvements," and "Bug Fixes."
src/types.go Removed EthAccount type.
src/feemarket.go Updated BaseFee to use Decimal type.
src/gov/precompile.go Added Deposit, CancelProposal, getDeposit, getDeposits, and getTallyResults methods.
precompiles/gov/IGov.sol Added Deposit and CancelProposal events and methods.
precompiles/gov/abi.json Updated ABI with new events and functions for Deposit and CancelProposal.
precompiles/gov/errors.go Added new error constants for transaction origin validation.
precompiles/gov/events.go Introduced new event types and emission functions for deposits and proposal cancellations.
precompiles/gov/events_test.go Added tests for Deposit and CancelProposal events.
precompiles/gov/gov.go Integrated Deposit and CancelProposal methods into the Run function and updated transaction recognition.
precompiles/gov/integration_test.go Added integration tests for executing Deposit and CancelProposal transactions.
precompiles/gov/tx.go Added logic for handling Deposit and CancelProposal methods, including validation and event emission.
precompiles/gov/tx_test.go Introduced tests for Deposit and CancelProposal functionalities, enhancing error handling and control flow.
precompiles/gov/types.go Added NewMsgDeposit and NewMsgCancelProposal functions and updated existing functions to use new governance types.
precompiles/common/errors.go Added ErrInvalidMethodInputs constant for method input validation errors.
precompiles/ics20/types.go Enhanced input validation in NewMsgTransfer and checkTransferAuthzArgs functions.
precompiles/vesting/types.go Added validation in NewMsgFundVestingAccount function to check input length.

Possibly related PRs

Suggested reviewers

  • GAtom22
  • ramacarlucho
  • hanchon

Poem

🐇 In the land of code where bunnies play,
New features hop in, brightening the day.
With deposits and cancels, governance thrives,
In our digital burrow, innovation survives!
So let’s cheer for the changes, both big and small,
Together we build, together we stand tall! 🌟


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

🧹 Outside diff range and nitpick comments (14)
precompiles/gov/errors.go (1)

32-35: Consider aligning error constant name with its message

The error constant ErrInvalidCoin uses singular form while its message refers to "coins" (plural). Consider either:

  • Renaming to ErrInvalidCoins to match the message, or
  • Updating the message to "invalid coin %s" for consistency
-	// ErrInvalidCoin invalid coin.
-	ErrInvalidCoin = "invalid coins %s "
+	// ErrInvalidCoins invalid coins.
+	ErrInvalidCoins = "invalid coins %s "
precompiles/gov/events.go (1)

27-38: Consider standardizing the field naming convention.

The ProposalId field in both structs uses non-standard Go naming convention. Consider renaming to ProposalID to follow Go's convention for abbreviations.

Apply this diff:

-	ProposalId uint64         `json:"proposalId"` //nolint:revive,stylecheck
+	ProposalID uint64         `json:"proposalId"` //nolint:revive,stylecheck
precompiles/gov/IGov.sol (2)

128-150: Consider enhancing method documentation with validation requirements.

While the methods are well-structured, the documentation could be enhanced by specifying:

  • Parameter validation requirements (e.g., valid proposal ID ranges, non-zero deposit amounts)
  • Conditions under which the operations might fail
  • Access control requirements (if any)

Example enhancement for the deposit method:

 /// @dev deposit defines a method to add a deposit to a proposal
 /// @param depositor The address of the depositor
 /// @param proposalId The proposal id
 /// @param amount The deposit amount
 /// @return success Whether the transaction was successful or not
+/// @notice The proposal must be in the deposit period
+/// @notice The amount must be non-zero and in accepted denomination

Line range hint 1-150: Consider architectural improvements for better maintainability and standardization.

The interface could benefit from the following architectural improvements:

  1. Consider splitting into sub-interfaces (e.g., IGovTransactions, IGovQueries) for better separation of concerns
  2. Consider implementing or aligning with governance standards like ERC-3000 for better interoperability
  3. Consider adding events for error cases to improve observability
precompiles/gov/events_test.go (2)

172-244: Consider adding error test cases for Deposit events

While the happy path test case is well implemented, consider adding test cases for common error scenarios such as:

  • Invalid deposit amount
  • Non-existent proposal ID
  • Insufficient funds

246-313: Consider adding error test cases for CancelProposal events

The success path is well tested, but consider adding test cases for:

  • Non-existent proposal
  • Unauthorized cancellation (non-proposer attempt)
  • Already canceled proposal
precompiles/gov/tx_test.go (1)

399-486: Enhance proposal cancellation verification

While the test cases cover the basic scenarios, the success case could be more comprehensive:

Consider enhancing the success test case to verify:

  1. Events emitted during cancellation
  2. State changes before and after cancellation
  3. Any refunds or side effects
 func() {
+    // Verify proposal exists before cancellation
+    found, err := s.network.App.GovKeeper.Proposals.Has(s.network.GetContext(), proposalID)
+    s.Require().NoError(err)
+    s.Require().True(found)
+
+    // Get initial state if needed (e.g., deposits, votes)
+    initialDeposits, err := s.network.App.GovKeeper.GetDeposits(ctx, proposalID)
+    s.Require().NoError(err)
+
     found, err := s.network.App.GovKeeper.Proposals.Has(s.network.GetContext(), proposalID)
     s.Require().NoError(err)
     s.Require().False(found)
+
+    // Verify any expected side effects (e.g., deposit refunds)
+    // TODO: Add specific assertions based on the expected behavior
 }
precompiles/gov/integration_test.go (2)

213-235: Consider adding error test cases for CancelProposal.

While the happy path is well tested, consider adding test cases for important error scenarios:

  • Attempting to cancel a proposal by a non-proposer
  • Attempting to cancel a non-existent proposal
  • Attempting to cancel a proposal that's already in a final state (e.g., passed, rejected)

237-271: Enhance deposit test coverage and improve maintainability.

  1. Consider adding test cases for important error scenarios:

    • Attempting to deposit with insufficient balance
    • Attempting to deposit to a non-existent proposal
    • Attempting to deposit with invalid coin denominations
    • Attempting to deposit when proposal is in final state
  2. The initial deposit amount (100 wei) should be defined as a constant at the package level for better maintainability and clarity.

 // Add at the package level
+const (
+    // InitialProposalDeposit represents the initial deposit amount for test proposals
+    InitialProposalDeposit = 100
+)

 // Update the test to use the constant
-expectedAmount := big.NewInt(0).Add(big.NewInt(100), depositAmount)
+expectedAmount := big.NewInt(0).Add(big.NewInt(InitialProposalDeposit), depositAmount)
precompiles/gov/tx.go (2)

115-117: Refactor redundant origin checks into a helper function

The logic for checking whether the origin matches the depositor address is repeated across methods. Refactoring this into a helper function enhances code maintainability and reduces duplication.

For example, implement a helper function:

func (p Precompile) validateOrigin(origin, caller, address common.Address, errMsg string) error {
    isContractCaller := caller == address && caller != origin
    if !isContractCaller && origin != address {
        return fmt.Errorf(errMsg, origin.String(), address.String())
    }
    return nil
}

And then use it in your methods.


156-159: Refactor repeated origin check logic into a helper function

The origin check logic is repeated in multiple methods (Vote, VoteWeighted, Deposit, CancelProposal). Refactoring this logic into a reusable helper function will improve code readability and maintainability.

You can create a helper function as suggested earlier and replace the origin checks in your methods.

precompiles/gov/types.go (3)

Line range hint 273-299: Improve error handling in VotesOutput.FromResponse method

In the FromResponse method for VotesOutput, when an error occurs during address conversion, the function returns nil without providing error context. This may make debugging difficult.

Consider returning an error to provide more context:

 func (vo *VotesOutput) FromResponse(res *v1.QueryVotesResponse) (*VotesOutput, error) {
     vo.Votes = make([]WeightedVote, len(res.Votes))
     for i, v := range res.Votes {
         hexAddr, err := utils.Bech32ToHexAddr(v.Voter)
         if err != nil {
-            return nil
+            return nil, fmt.Errorf("failed to convert voter address: %w", err)
         }
         // Existing code...
     }
     // Existing code...
-    return vo
+    return vo, nil
 }

Adjust the function signature and handle the error accordingly.


Line range hint 402-421: Enhance error handling in DepositOutput.FromResponse method

Similar to the previous comment, if there's an error converting the depositor address, returning nil without context can hinder debugging.

Modify the method to return an error with more information:

 func (do *DepositOutput) FromResponse(res *v1.QueryDepositResponse) (*DepositOutput, error) {
     hexDepositor, err := utils.Bech32ToHexAddr(res.Deposit.Depositor)
     if err != nil {
-        return nil
+        return nil, fmt.Errorf("failed to convert depositor address: %w", err)
     }
     // Existing code...
-    return do
+    return do, nil
 }

Update the function signature and handle the error accordingly.


Line range hint 584-620: Consistent error handling in ProposalsOutput.FromResponse method

In the loop, if an error occurs during address conversion, the method returns nil. It's better to return an error to provide context.

Apply this diff to improve error handling:

 func (po *ProposalsOutput) FromResponse(res *v1.QueryProposalsResponse) (*ProposalsOutput, error) {
     po.Proposals = make([]ProposalData, len(res.Proposals))
     for i, p := range res.Proposals {
         // Existing code...
 
         proposer, err := utils.Bech32ToHexAddr(p.Proposer)
         if err != nil {
-            return nil
+            return nil, fmt.Errorf("failed to convert proposer address: %w", err)
         }
 
         po.Proposals[i] = ProposalData{
             // Existing code...
         }
     }
 
     // Existing code...
-    return po
+    return po, nil
 }

Ensure the function signature reflects the error return value.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b72a32d and 41eddc1.

📒 Files selected for processing (11)
  • CHANGELOG.md (1 hunks)
  • precompiles/gov/IGov.sol (2 hunks)
  • precompiles/gov/abi.json (2 hunks)
  • precompiles/gov/errors.go (2 hunks)
  • precompiles/gov/events.go (2 hunks)
  • precompiles/gov/events_test.go (3 hunks)
  • precompiles/gov/gov.go (2 hunks)
  • precompiles/gov/integration_test.go (2 hunks)
  • precompiles/gov/tx.go (3 hunks)
  • precompiles/gov/tx_test.go (2 hunks)
  • precompiles/gov/types.go (19 hunks)
🔇 Additional comments (21)
precompiles/gov/errors.go (2)

8-11: LGTM! Well-structured error messages for origin validation.

The new error constants follow consistent naming patterns and provide clear, specific messages for origin address validation in proposal and deposit operations.


Line range hint 8-35: Verify error handling implementation

Let's ensure these new error constants are properly utilized in the transaction implementations.

✅ Verification successful

Error constants are properly implemented and used consistently

The verification shows that the error constants are properly utilized in the codebase:

  • ErrDifferentOriginProposer and ErrDifferentOriginDepositor are used in tx.go for origin address validation
  • ErrInvalidProposer is used in types.go for proposal-related validations
  • Error handling follows consistent patterns across the governance package:
    • Origin address validation using ErrDifferentOrigin* family
    • Input validation using ErrInvalid* family
    • Proper error formatting with relevant context
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage of new error constants in the codebase

# Search for usage of new error constants
echo "Checking usage of new error constants:"
rg "ErrDifferentOriginProposer|ErrDifferentOriginDepositor|ErrInvalidProposer|ErrInvalidCoin" \
  --type go \
  -B 2 -A 2

# Look for potential error handling patterns we should match
echo -e "\nChecking existing error handling patterns in gov package:"
rg "return.*Err.*Origin|return.*Err.*Invalid" \
  --type go \
  -g 'precompiles/gov/*.go' \
  -B 2 -A 2

Length of output: 14491

precompiles/gov/gov.go (2)

148-148: LGTM! Verify method constants.

The new methods are correctly identified as transactions, ensuring proper gas calculation and execution flow.

Let's verify the method constants are properly defined:

✅ Verification successful

Method constants are properly defined and used

All method constants (VoteMethod, VoteWeightedMethod, DepositMethod, and CancelProposalMethod) are correctly defined in precompiles/gov/tx.go and consistently used in the switch cases throughout the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for the method constant definitions
# Expected: Should find constant definitions for DepositMethod and CancelProposalMethod

# Search for method constant definitions
echo "Searching for method constant definitions..."
rg -A 1 'const \(\s*DepositMethod|CancelProposalMethod\s*=\s*"'

Length of output: 251


Script:

#!/bin/bash
# Let's also check for DepositMethod constant and verify all method constants used in the switch case
echo "Searching for all method constants..."
rg "const.*(?:Vote|Deposit|CancelProposal).*Method.*=" -A 1

echo -e "\nVerifying usage in switch case..."
rg "case.*(?:Vote|Deposit|CancelProposal).*Method.*:" -A 1

Length of output: 1603


Script:

#!/bin/bash
# Let's check the tx.go file for all method constant definitions to ensure completeness
echo "Checking tx.go for all method constants..."
rg "^const \(" -A 15 precompiles/gov/tx.go

Length of output: 765


105-108: LGTM! Verify method implementations.

The new methods are properly integrated into the Run function following the established pattern. The implementation is consistent with other transaction methods in terms of error handling and gas management.

Let's verify the method implementations are present:

✅ Verification successful

Let me try a different search pattern since the previous one might have been too specific.


Implementation verified successfully

The search results confirm that both methods are properly implemented in precompiles/gov/tx.go. Additionally, the implementations are well-supported with:

  • Unit tests in precompiles/gov/tx_test.go
  • Event handling in precompiles/gov/events.go
  • Event tests in precompiles/gov/events_test.go
  • Type handling in precompiles/gov/types.go
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for the implementation of Deposit and CancelProposal methods
# Expected: Should find method implementations in the same package

# Search for Deposit method implementation
echo "Searching for Deposit method implementation..."
ast-grep --pattern 'func (p Precompile) Deposit(ctx sdk.Context, origin common.Address, contract *vm.Contract, stateDB *storetypes.KVStore, method *abi.Method, args []interface{}) '

# Search for CancelProposal method implementation
echo "Searching for CancelProposal method implementation..."
ast-grep --pattern 'func (p Precompile) CancelProposal(ctx sdk.Context, origin common.Address, contract *vm.Contract, stateDB *storetypes.KVStore, method *abi.Method, args []interface{}) '

Length of output: 594


Script:

#!/bin/bash
# Search for Deposit and CancelProposal method implementations with a more flexible pattern
echo "Searching for Deposit method..."
ast-grep --pattern 'func $_ Deposit($_) {
  $$$
}'

echo -e "\nSearching for CancelProposal method..."
ast-grep --pattern 'func $_ CancelProposal($_) {
  $$$
}'

# Fallback to ripgrep for additional context
echo -e "\nSearching with ripgrep..."
rg "func.*(?:Deposit|CancelProposal).*\(" -A 2

Length of output: 6879

precompiles/gov/events.go (3)

21-24: LGTM! Event type constants are well-defined.

The new event type constants follow the existing pattern and are properly documented.


147-180: Verify the design choice of empty event data.

The implementation sets Data: nil which differs from other events that pack some data. While this is valid, let's verify this is intentional and matches the Solidity event definition.

✅ Verification successful

Empty data field is correct per event definition

The CancelProposal event definition in IGov.sol shows:

event CancelProposal(uint64 indexed proposalId, address indexed proposer);

Both parameters are marked as indexed, which means they are included in the topics rather than the data field. Therefore, the current implementation with Data: nil is correct as there are no non-indexed parameters to pack.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify CancelProposal event definition
# Search for the CancelProposal event definition in Solidity files
rg -A 2 'event\s+CancelProposal\s*\(' --type solidity

# Check if there are any non-indexed parameters that should be packed as data
ast-grep --pattern 'event CancelProposal($_) { $$$ }'

Length of output: 144


Script:

#!/bin/bash
# Let's try searching for the event definition in all files since the .sol extension might not be recognized
rg -A 2 'event\s+CancelProposal\s*\('

# Also search for the ABI definition which would show the event structure
rg -A 5 'EventTypeCancelProposal\s*=' 

# Let's also check the interface or contract definition that might contain this event
rg -A 10 'interface.*Gov'

Length of output: 1501


104-145: LGTM! Verify event signature matches Solidity contract.

The implementation correctly handles event emission with proper indexing and data packing. Let's verify the event signature matches the Solidity contract definition.

✅ Verification successful

Event signature matches the Solidity interface definition

The implementation in EmitDepositEvent correctly matches the event signature from IGov.sol:

  • Event name: Deposit
  • Indexed parameters: proposalId (uint64), depositor (address)
  • Data parameter: amount (Coin[])

The topics array and data packing in the implementation align perfectly with this definition:

  • Topic[0]: Event signature hash
  • Topic[1]: Indexed proposalId
  • Topic[2]: Indexed depositor address
  • Data: Packed amount as Coin array
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify event signature matches Solidity definition
# Search for the Deposit event definition in Solidity files
rg -A 2 'event\s+Deposit\s*\(' --type solidity

Length of output: 81


Script:

#!/bin/bash
# Search for Deposit event definition in all files, focusing on contract interfaces and definitions
rg -A 2 'event\s+Deposit\s*\(' 

# Also search specifically in contract-related directories that might contain the interface
fd -e sol . contracts precompiles interfaces 2>/dev/null

# Backup search for ABI definitions that might contain event definitions
fd -g "*abi*.go" . | xargs rg "EventTypeDeposit"

Length of output: 2249


Script:

#!/bin/bash
# Let's find the ABI definition for the Deposit event to compare with implementation
rg -B 2 -A 2 'EventTypeDeposit.*=|const.*EventTypeDeposit' precompiles/gov/

# Also get the ABI construction to see event definition
ast-grep --pattern 'abi.NewEvent($$$)'

Length of output: 530


Script:

#!/bin/bash
# Let's find the ABI method that constructs the events
rg -A 10 'Methods.*Events.*=.*map\[string\]abi.Event' precompiles/gov/

Length of output: 72


Script:

#!/bin/bash
# Search for the ABI definition in the gov precompile
rg -A 20 'var.*ABI.*=.*abi\.JSON' precompiles/gov/

# Also check the contract interface definition again but with more context
rg -B 2 -A 5 'event\s+Deposit' precompiles/gov/IGov.sol

Length of output: 548

precompiles/gov/IGov.sol (1)

90-100: LGTM! Well-structured events with appropriate parameter indexing.

The new events are well-documented and follow best practices:

  • Correct use of indexing for filtering capabilities
  • Clear documentation
  • Consistent naming convention
precompiles/gov/events_test.go (3)

6-8: LGTM: Import changes are appropriate

The addition of the math package from cosmos-sdk is necessary for the new deposit functionality.


155-156: LGTM: Improved struct initialization clarity

The explicit use of gov.WeightedVoteOption type in the initialization improves code readability. The weights are properly balanced, summing to 1.0.


171-313: Verify test coverage for new governance transactions

The implementation aligns with the PR objectives by adding tests for both Deposit and CancelProposal events. Let's verify the test coverage:

✅ Verification successful

Test coverage for governance transactions is comprehensive

The verification shows complete test coverage for both Deposit and CancelProposal functionality:

  • Both transactions have dedicated test files covering the core functionality (tx_test.go)
  • Event emission is separately tested (events_test.go)
  • All corresponding implementation methods are properly tested:
    • Transaction handlers: Deposit and CancelProposal
    • Event emitters: EmitDepositEvent and EmitCancelProposalEvent
    • Message constructors: NewMsgDeposit and NewMsgCancelProposal
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check test coverage for the new governance transactions

# Look for all governance-related test files
fd -e go test$ precompiles/gov/ -x

# Check for any TODOs or missing test coverage
rg -i "todo|fixme|xxx" precompiles/gov/

Length of output: 192


Script:

#!/bin/bash
# Let's try a different approach to check test coverage

# Find all test files in the gov precompile directory
fd ".*_test.go$" precompiles/gov/

# Check for test functions related to Deposit and CancelProposal
rg "func.*Test(Deposit|CancelProposal)" precompiles/gov/

# Look for the implementation of these methods to ensure all cases are covered
rg "func.*(Deposit|CancelProposal)" precompiles/gov/ --type go -g '!*_test.go'

Length of output: 1737

precompiles/gov/tx_test.go (2)

5-7: LGTM: Required imports added

The new imports are necessary for handling big numbers in deposits and EVM-specific types.


283-486: Verify test coverage with additional scenarios

While the test suite covers basic functionality and error cases, consider adding tests for:

  1. Multiple deposits to the same proposal
  2. Deposits with multiple coin types
  3. Cancellation of proposals in different states (voting period, deposit period)
  4. Edge cases around minimum deposit requirements
precompiles/gov/integration_test.go (1)

13-13: LGTM!

The new import for the common precompile package is appropriately aliased and necessary for the new deposit functionality.

precompiles/gov/abi.json (2)

6-61: LGTM! Well-structured event definitions.

The new events CancelProposal and Deposit are properly defined with:

  • Appropriate indexing of fields for efficient event filtering
  • Clear and consistent parameter naming
  • Proper type definitions matching the governance domain model

124-198: LGTM! Well-designed function interfaces.

The new functions cancelProposal and deposit are well-implemented with:

  • Clear parameter naming and appropriate types
  • Proper return values including success flags
  • Correct nonpayable state mutability
  • Consistent use of types (e.g., Coin[]) with existing functions

Let's verify the consistency of these new functions with the rest of the codebase:

✅ Verification successful

The ABI functions are well-aligned with the interface contract

The cancelProposal and deposit function signatures in the ABI match their interface definitions in IGov.sol with:

  • Correct parameter types and names
  • Proper return values including success flags
  • Consistent use of Coin[] struct type for deposits
  • Appropriate event definitions for both operations
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify consistent usage of Coin[] type and function naming patterns

# Check for consistent usage of Coin[] type in other governance functions
ast-grep --pattern 'struct Coin[] {
  $$$
}'

# Check for consistent function naming patterns
ast-grep --pattern 'function $FNAME($$$) {
  $$$
}'

Length of output: 129226


Script:

#!/bin/bash
# Let's verify the ABI functions with more targeted commands

# Check for consistent usage of Coin[] type in governance functions
rg -U "struct Coin\[\].*?\{.*?\}" --multiline

# Check for consistent function patterns in governance ABI
rg -U "\"name\": \"(cancelProposal|deposit)\".*?\"type\": \"function\"" --multiline -A 20 precompiles/gov/abi.json

# Look for any related governance function implementations
rg -U "function (cancelProposal|deposit)" --multiline

Length of output: 778


Script:

#!/bin/bash
# Let's examine the governance interface and implementation more closely

# Check the full interface definitions in IGov.sol
cat precompiles/gov/IGov.sol

# Look for any test files that might show usage patterns
rg -g "*.sol" -g "*.js" -l "cancelProposal|deposit.*proposalId"

Length of output: 8143

CHANGELOG.md (1)

53-53: LGTM! The changelog entry accurately documents the new feature.

The entry properly captures the addition of Deposit and CancelProposal transactions to the governance precompile under the "Improvements" section, with correct PR reference.

precompiles/gov/tx.go (1)

173-173: Review the suppression of linter warning G115

The //nolint:gosec // G115 comment suppresses a security linter warning. Ensure that suppressing this warning is justified and does not introduce security vulnerabilities, such as using weak cryptography or insecure time sources.

Run the following script to verify the linter warning:

Review the linter output and ensure that the use of Unix() is safe in this context.

✅ Verification successful

Suppression of G115 warning is justified in this context

The G115 warning suppression is appropriate here as this code is handling blockchain governance timestamps in a safe manner. The Unix() call is used consistently throughout the codebase for handling blockchain-specific timestamps, particularly in governance and staking operations. The timestamp is obtained from resp.CanceledTime, which is a controlled, blockchain-provided time value, not a potentially insecure local system time. This pattern is used similarly in other precompiles for handling protocol-level timestamps.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Analyze the code for the G115 linter warning and determine if suppression is appropriate.

# Run gosec linter on the file
gosec -no-fail -include=G115 precompiles/gov/tx.go

Length of output: 148


Script:

#!/bin/bash
# Let's analyze the context around the Unix() call to understand its usage

# First, let's see the full context of the file
rg -A 5 -B 5 "Unix\(\)" precompiles/gov/tx.go

# Also check for any related test files or documentation
fd "tx_test.go|README" precompiles/gov/

# Look for other similar Unix() usages in the codebase
rg "Unix\(\)" precompiles/

Length of output: 4395

precompiles/gov/types.go (3)

9-16: Imports updated to accommodate new dependencies

The addition of "cosmossdk.io/math" and aliasing v1 for the governance types is appropriate and ensures compatibility with the updated modules.


112-148: Implementation of NewMsgDeposit aligns with expected functionality

The NewMsgDeposit function correctly constructs a MsgDeposit message with proper argument validation and error handling. The conversion from cmn.Coin to sdk.Coin is handled efficiently.


150-172: Implementation of NewMsgCancelProposal is correct

The NewMsgCancelProposal function appropriately creates a MsgCancelProposal message. Argument validation and error handling are implemented effectively.

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

🧹 Outside diff range and nitpick comments (20)
precompiles/gov/errors.go (1)

34-35: Fix inconsistency in error message

There's a mismatch between the constant name and its error message:

  • Constant name uses singular form: ErrInvalidCoin
  • Error message uses plural form: "invalid coins %s"

Consider maintaining consistency by either:

  1. Changing the constant to ErrInvalidCoins to match the message, or
  2. Changing the message to "invalid coin %s" to match the constant
precompiles/gov/gov.go (1)

105-108: Consider comprehensive testing scenarios.

Given that these governance operations can have significant impact on the chain state:

  1. Ensure thorough testing of gas consumption patterns for these new operations
  2. Consider adding integration tests that verify the interaction between these methods and the underlying governance module
  3. Add test cases for error conditions, especially around proposal state transitions

Would you like assistance in designing these test scenarios?

Also applies to: 148-148

precompiles/gov/events.go (1)

27-38: LGTM: Event structs are well-defined

The structs are properly defined with appropriate types and JSON tags. Consider adding a period at the end of struct documentation comments for consistency with Go documentation standards.

-// EventDeposit is the event type emitted when a deposit is made to a proposal
+// EventDeposit is the event type emitted when a deposit is made to a proposal.
-// EventCancelProposal is the event type emitted when a proposal is canceled
+// EventCancelProposal is the event type emitted when a proposal is canceled.
precompiles/gov/tx.go (2)

128-136: Enhance documentation for EVM state handling.

The EVM state consistency handling is crucial but could use more detailed documentation. Consider expanding the comment to explain:

  1. Why scaling to 18 decimals is necessary
  2. What problems could occur without this handling
  3. The relationship between bank keeper and EVM stateDB
-    // NOTE: This ensures that the changes in the bank keeper are correctly mirrored to the EVM stateDB
-    // when calling the precompile from a smart contract
-    // This prevents the stateDB from overwriting the changed balance in the bank keeper when committing the EVM state.
-    // Need to scale the amount to 18 decimals for the EVM balance change entry
+    // IMPORTANT: EVM State Consistency Handling
+    // When this precompile is called from a smart contract:
+    // 1. The bank keeper modifies the actual balance
+    // 2. These changes must be mirrored in the EVM stateDB to prevent overwrites
+    // 3. All EVM amounts must be scaled to 18 decimals (EVM standard)
+    // 4. Without this handling, the stateDB would overwrite the bank keeper changes
+    //    during the EVM state commitment phase

171-175: Document return value structure.

The method returns multiple values packed into the ABI output:

  1. A boolean success flag
  2. Cancellation timestamp
  3. Cancellation height

Consider adding a comment documenting these return values and their significance.

+    // Pack multiple return values into ABI output:
+    // - bool: success flag indicating the proposal was successfully canceled
+    // - uint64: Unix timestamp when the proposal was canceled
+    // - uint64: block height when the proposal was canceled
     return method.Outputs.Pack(
         true,
         uint64(resp.CanceledTime.Unix()),
         resp.CanceledHeight,
     )
precompiles/gov/IGov.sol (2)

129-138: Consider adding validation requirements to deposit documentation.

While the method signature is well-structured, it would be helpful to document any validation requirements for the deposit amount (e.g., minimum/maximum values, token types accepted) to guide implementers and users.


140-150: Enhance cancelProposal documentation with cancellation conditions.

The method is well-structured, but consider adding documentation about:

  • Under what conditions a proposal can be canceled
  • Any timing restrictions on cancellation
  • Whether the proposer is the only one who can cancel
precompiles/gov/events_test.go (3)

155-156: LGTM - Explicit struct initialization improves readability

The explicit use of gov.WeightedVoteOption in struct initialization improves code clarity.

Consider using the field names for even better readability:

-gov.WeightedVoteOption{Option: 1, Weight: "0.70"},
+gov.WeightedVoteOption{
+    Option: 1,
+    Weight: "0.70",
+},

172-244: Consider adding more test cases for deposit events

The test structure is solid, but consider adding these test cases for better coverage:

  1. Negative test cases:
    • Invalid deposit amount (zero or negative)
    • Non-existent proposal ID
    • Unauthorized depositor
  2. Edge cases:
    • Maximum deposit amount
    • Multiple deposit denominations

246-313: Consider adding more test cases for cancel proposal events

The test follows good practices but could be enhanced with additional test cases:

  1. Negative test cases:
    • Non-existent proposal
    • Unauthorized cancellation attempt (non-proposer)
    • Already canceled proposal
  2. Edge cases:
    • Proposal in different states (voting period, passed, rejected)
precompiles/gov/tx_test.go (2)

293-294: Consider varying gas limits for different test cases

All test cases use the same gas limit of 200000. Consider adjusting gas limits based on the complexity of each operation to ensure proper gas estimation.


283-486: Consider enhancing test infrastructure

The test suite could benefit from:

  1. Helper functions for common setup operations (e.g., proposal creation)
  2. Shared constants for common values
  3. Table-driven test utilities for better maintainability

This would reduce code duplication and make tests more maintainable.

precompiles/gov/types.go (8)

Line range hint 211-246: Potential index out of range panic when accessing method.Inputs[2]

In the function NewMsgVoteWeighted, accessing method.Inputs[2] without verifying that method.Inputs has at least three elements could cause an index out of range panic. Ensure that method.Inputs has sufficient length before accessing its elements.

Apply this diff to add the necessary check:

 func NewMsgVoteWeighted(method *abi.Method, args []interface{}) (*v1.MsgVoteWeighted, common.Address, WeightedVoteOptions, error) {
 	if len(args) != 4 {
 		return nil, common.Address{}, WeightedVoteOptions{}, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 4, len(args))
 	}

+	if len(method.Inputs) <= 2 {
+		return nil, common.Address{}, WeightedVoteOptions{}, fmt.Errorf("method.Inputs has insufficient length")
+	}

 	voterAddress, ok := args[0].(common.Address)
 	if !ok || voterAddress == (common.Address{}) {
 		return nil, common.Address{}, WeightedVoteOptions{}, fmt.Errorf(ErrInvalidVoter, args[0])

Line range hint 273-302: Inconsistent error handling in FromResponse method

In the VotesOutput.FromResponse method, if there's an error converting the Bech32 address to hex (utils.Bech32ToHexAddr), the function returns nil without signaling the error. This can lead to silent failures downstream. Consider modifying the method to return an error alongside the VotesOutput to properly handle error cases.

Apply this diff to modify the function signature and error handling:

-func (vo *VotesOutput) FromResponse(res *v1.QueryVotesResponse) *VotesOutput {
+func (vo *VotesOutput) FromResponse(res *v1.QueryVotesResponse) (*VotesOutput, error) {
 	vo.Votes = make([]WeightedVote, len(res.Votes))
 	for i, v := range res.Votes {
 		hexAddr, err := utils.Bech32ToHexAddr(v.Voter)
 		if err != nil {
-			return nil
+			return nil, err
 		}
 		// ... rest of the code ...
 	}
 	// ... rest of the code ...
-	return vo
+	return vo, nil
 }

Line range hint 326-345: Consistent error handling in VoteOutput.FromResponse method

Similar to the previous comment, in VoteOutput.FromResponse, the method returns nil in case of an error without propagating it. Consider updating the method to return an error for proper error handling.

Apply this diff to modify the function signature and error handling:

-func (vo *VoteOutput) FromResponse(res *v1.QueryVoteResponse) *VoteOutput {
+func (vo *VoteOutput) FromResponse(res *v1.QueryVoteResponse) (*VoteOutput, error) {
 	hexVoter, err := utils.Bech32ToHexAddr(res.Vote.Voter)
 	if err != nil {
-		return nil
+		return nil, err
 	}
 	// ... rest of the code ...
-	return vo
+	return vo, nil
 }

Line range hint 402-420: Ensure proper error propagation in DepositOutput.FromResponse

In the DepositOutput.FromResponse method, errors are not propagated. Modify the method to return an error along with the output to handle failures explicitly.

Apply this diff:

-func (do *DepositOutput) FromResponse(res *v1.QueryDepositResponse) *DepositOutput {
+func (do *DepositOutput) FromResponse(res *v1.QueryDepositResponse) (*DepositOutput, error) {
 	hexDepositor, err := utils.Bech32ToHexAddr(res.Deposit.Depositor)
 	if err != nil {
-		return nil
+		return nil, err
 	}
 	// ... rest of the code ...
-	return do
+	return do, nil
 }

Line range hint 422-450: Consistent error handling in DepositsOutput.FromResponse

The DepositsOutput.FromResponse method should also return errors when address conversion fails to avoid silent failures.

Apply this diff:

-func (do *DepositsOutput) FromResponse(res *v1.QueryDepositsResponse) *DepositsOutput {
+func (do *DepositsOutput) FromResponse(res *v1.QueryDepositsResponse) (*DepositsOutput, error) {
 	do.Deposits = make([]DepositData, len(res.Deposits))
 	for i, d := range res.Deposits {
 		hexDepositor, err := utils.Bech32ToHexAddr(d.Depositor)
 		if err != nil {
-			return nil
+			return nil, err
 		}
 		// ... rest of the code ...
 	}
 	// ... rest of the code ...
-	return do
+	return do, nil
 }

Line range hint 514-536: Potential issue with casting ProposalStatus

In ParseProposalsArgs, casting input.ProposalStatus directly to v1.ProposalStatus without validation could result in invalid status values. Consider adding validation to ensure input.ProposalStatus corresponds to a valid v1.ProposalStatus enum value.

Apply this diff to include validation:

 	var input ProposalsInput
 	if err := method.Inputs.Copy(&input, args); err != nil {
 		return nil, fmt.Errorf("error while unpacking args to ProposalsInput: %s", err)
 	}

+	if _, ok := v1.ProposalStatus_name[int32(input.ProposalStatus)]; !ok {
+		return nil, fmt.Errorf("invalid ProposalStatus value: %d", input.ProposalStatus)
+	}

 	voter := ""

Line range hint 542-583: Ensure error propagation in ProposalOutput.FromResponse

In the ProposalOutput.FromResponse method, errors are not propagated when address conversion fails. Modify the method to return an error for proper error handling.

Apply this diff:

-func (po *ProposalOutput) FromResponse(res *v1.QueryProposalResponse) *ProposalOutput {
+func (po *ProposalOutput) FromResponse(res *v1.QueryProposalResponse) (*ProposalOutput, error) {
 	// ... existing code ...
 	proposer, err := utils.Bech32ToHexAddr(res.Proposal.Proposer)
 	if err != nil {
-		return nil
+		return nil, err
 	}
 	// ... rest of the code ...
-	return po
+	return po, nil
 }

Line range hint 584-627: Consistent error handling in ProposalsOutput.FromResponse

The ProposalsOutput.FromResponse method should propagate errors instead of returning nil to avoid silent failures.

Apply this diff:

-func (po *ProposalsOutput) FromResponse(res *v1.QueryProposalsResponse) *ProposalsOutput {
+func (po *ProposalsOutput) FromResponse(res *v1.QueryProposalsResponse) (*ProposalsOutput, error) {
 	// ... existing code ...
 		proposer, err := utils.Bech32ToHexAddr(p.Proposer)
 		if err != nil {
-			return nil
+			return nil, err
 		}
 	// ... rest of the code ...
-	return po
+	return po, nil
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b72a32d and 41eddc1.

📒 Files selected for processing (11)
  • CHANGELOG.md (1 hunks)
  • precompiles/gov/IGov.sol (2 hunks)
  • precompiles/gov/abi.json (2 hunks)
  • precompiles/gov/errors.go (2 hunks)
  • precompiles/gov/events.go (2 hunks)
  • precompiles/gov/events_test.go (3 hunks)
  • precompiles/gov/gov.go (2 hunks)
  • precompiles/gov/integration_test.go (2 hunks)
  • precompiles/gov/tx.go (3 hunks)
  • precompiles/gov/tx_test.go (2 hunks)
  • precompiles/gov/types.go (19 hunks)
🔇 Additional comments (25)
precompiles/gov/errors.go (2)

8-11: LGTM! Well-structured error messages for origin validation

The new error constants follow the established pattern and provide clear, descriptive messages for address validation failures.


Line range hint 8-35: Verify comprehensive error handling in transaction handlers

Let's ensure these new error constants are properly utilized in the transaction handlers for comprehensive error handling.

✅ Verification successful

Let me analyze the error handling usage further with additional scripts to check for comprehensive coverage.


Based on the results from both script executions, I can now provide a final response:

Error handling implementation is comprehensive and properly utilized

The verification shows that:

  • All error constants are actively used in the codebase, primarily in precompiles/gov/types.go for input validation
  • Error handling covers different scenarios:
    • Origin address validation for proposers and depositors
    • Input validation for proposal IDs, voters, options, and metadata
    • Parameter validation for weighted votes
  • No instances of hardcoded error messages that should be using these constants instead
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if all new error constants are used in the codebase
# and verify no direct string error messages are used instead

# Search for usage of new error constants
echo "Checking usage of new error constants..."
rg "ErrDifferentOriginProposer|ErrDifferentOriginDepositor|ErrInvalidProposer|ErrInvalidCoin" --type go

# Search for potential hardcoded error messages that should use these constants
echo "Checking for potential hardcoded error messages..."
rg -i "(?:invalid (?:proposer|coins?)|(?:origin|tx).*(?:proposer|depositor))" --type go

Length of output: 9702


Script:

#!/bin/bash
# Check for the usage of other error constants defined in the file
# and their corresponding error handling in transaction handlers

# Search for usage of remaining error constants
echo "Checking usage of other error constants..."
rg "ErrInvalidVoter|ErrInvalidProposalID|ErrInvalidPageRequest|ErrInvalidOption|ErrInvalidMetadata|ErrInvalidWeightedVoteOptions|ErrInvalidWeightedVoteOption|ErrInvalidWeightedVoteOptionType|ErrInvalidWeightedVoteOptionWeight|ErrInvalidDepositor" --type go

# Check the transaction handlers implementation
echo "Checking transaction handlers implementation..."
ast-grep --pattern 'func ($x *Precompile) $method($$$) ($$$) {
  $$$
}'  precompiles/gov/tx.go

Length of output: 3730

precompiles/gov/gov.go (1)

148-148: LGTM! Verify method constants are defined.

The new transaction methods are correctly classified alongside other state-modifying operations.

Let's verify that the method constants are properly defined:

✅ Verification successful

Method constants are properly defined and used consistently

The verification shows that both DepositMethod and CancelProposalMethod are correctly defined in precompiles/gov/tx.go:

  • DepositMethod = "deposit"
  • CancelProposalMethod = "cancelProposal"

These constants are consistently used across the codebase in tests, integration tests, and the main implementation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the method constants for Deposit and CancelProposal are defined

# Search for the constant definitions
rg -A 1 'const \(.*DepositMethod.*=.*\)' 
rg -A 1 'const \(.*CancelProposalMethod.*=.*\)'

Length of output: 92


Script:

#!/bin/bash
# Let's try a broader search for these method constants
# First, search for any mentions of these methods
rg "DepositMethod|CancelProposalMethod" -B 2 -A 2

# Also search for const blocks in the same file
rg "const \(" -B 1 -A 10 precompiles/gov/gov.go

Length of output: 7899

precompiles/gov/events.go (3)

21-24: LGTM: Event type constants follow existing patterns

The new event type constants are well-documented and maintain consistency with the existing naming conventions.


147-180: LGTM: EmitCancelProposalEvent implementation is correct

The function correctly handles event emission with no additional data required beyond the indexed parameters.

Let's verify the event definition in the ABI matches the implementation:


104-145: LGTM: EmitDepositEvent implementation is correct

The function follows the established pattern for event emission, with proper error handling and data packing.

Let's verify the event definition in the ABI matches the implementation:

precompiles/gov/tx.go (3)

9-10: LGTM! Imports and constants are well-defined.

The new imports and method constants are appropriately added and follow the existing pattern in the codebase.

Also applies to: 25-28


173-173: Review Unix timestamp conversion security.

The line is marked with a nolint:gosec comment for G115 (potential time-based logic issues). While this might be acceptable for event timestamps, please verify that this doesn't introduce any security vulnerabilities in the governance process.

✅ Verification successful

Unix timestamp usage in governance module is consistent with other modules and properly documented

The Unix timestamp conversion in the governance module follows the same pattern used across other modules (vesting, staking, slashing) where timestamps are used for event logging and state transitions. All instances are properly marked with //nolint:gosec // G115 comments, acknowledging the known time-based logic considerations. The usage here is for recording the proposal cancellation time as part of the event data, which doesn't introduce security concerns in the governance process since:

  1. The timestamp is derived from the blockchain's block time, not from user input
  2. It's used for informational purposes in event logs
  3. The actual governance logic relies on block height for critical operations
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other Unix timestamp conversions in governance code
rg -A 2 "Unix\(\)" --type go

Length of output: 12702


113-117: Please clarify the origin validation logic.

The origin validation logic is complex and could benefit from additional clarification:

isOriginDepositor := contract.CallerAddress == origin
isContractDepositor := contract.CallerAddress == depositorAddr && !isOriginDepositor
if !isContractDepositor && origin != depositorAddr {
    return nil, fmt.Errorf(ErrDifferentOriginDepositor, origin.String(), depositorAddr.String())
}

Consider adding a comment explaining the different scenarios this handles:

  1. When is isOriginDepositor true?
  2. When is isContractDepositor true?
  3. What security concerns does this address?
precompiles/gov/IGov.sol (1)

90-100: LGTM! Well-structured event definitions.

The new events are well-documented and follow best practices:

  • Appropriate indexing on key parameters for efficient event filtering
  • Clear documentation following the existing pattern
  • Essential information captured in event parameters
precompiles/gov/events_test.go (1)

6-7: LGTM - Required imports for new test functions

The new imports are necessary for handling math operations and EVM types in the deposit tests.

precompiles/gov/tx_test.go (1)

5-7: LGTM: Import additions are appropriate

The new imports are correctly used in the test functions - math/big for amount comparisons and evmtypes for EVM coin denomination.

precompiles/gov/integration_test.go (1)

13-13: LGTM!

The import of the common package is correctly aliased and necessary for the new test cases.

precompiles/gov/abi.json (4)

6-24: LGTM: Well-structured event definition

The CancelProposal event is properly defined with appropriate parameter types and indexing for efficient event filtering.


25-61: LGTM: Event parameters are well-structured

The Deposit event is properly defined with:

  • Correct indexing strategy for efficient filtering
  • Appropriate use of complex types for the amount parameter

124-157: Verify proposer parameter authorization

The function includes a proposer parameter, which suggests authorization checks. Please ensure that the implementation properly validates that:

  1. Only the original proposer can cancel their proposal
  2. The proposal exists and is in a cancellable state
✅ Verification successful

Authorization checks are properly implemented

The implementation includes appropriate authorization checks:

  • Verifies that the origin (transaction sender) matches the proposer address
  • Has a special case to handle when the contract itself is the proposer
  • Only allows the original proposer to cancel their proposal through the check: if !isContractProposer && origin != proposerAddr

The proposal state validation is handled by the underlying Cosmos SDK governance module through msgSrv.CancelProposal(), which ensures the proposal exists and is in a cancellable state.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for authorization checks in the implementation
ast-grep --pattern 'if ($proposer == $_) { $$$
}'

# Search for proposal state validation
ast-grep --pattern 'if ($proposal.status == $_) { $$$
}'

Length of output: 110


Script:

#!/bin/bash
# Let's search for the implementation file first
fd "gov" --type f --extension go --extension sol

# Then search for cancelProposal implementation
rg -l "cancelProposal"

# Search for any mentions of proposal cancellation logic
rg -i "cancel.*proposal"

Length of output: 5967


Script:

#!/bin/bash
# Let's examine the implementation in tx.go
rg -A 20 "func \(p Precompile\) CancelProposal" precompiles/gov/tx.go

# Also check the message construction
rg -A 10 "func NewMsgCancelProposal" precompiles/gov/types.go

Length of output: 1212


158-198: Verify deposit validation

Please ensure that the implementation includes proper validation:

  1. The proposal exists and is in a deposit-accepting state
  2. The deposit amount meets minimum requirements
  3. The deposit denomination is valid
CHANGELOG.md (1)

53-53: LGTM! The changelog entry matches the PR objectives.

The changelog entry correctly documents the addition of Deposit and CancelProposal transactions to the governance precompile, which aligns with the PR objectives.

Let's verify the implementation of these transactions:

✅ Verification successful

Implementation of Deposit and CancelProposal transactions verified successfully

The codebase shows complete implementation of both transactions:

  • Both methods are properly defined in the governance precompile with appropriate parameters and error handling
  • Event emission is implemented for both transactions
  • Comprehensive test coverage exists including both transaction tests and event tests
  • The implementation aligns with the changelog entry
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the implementation of Deposit and CancelProposal transactions
# in the governance precompile

# Check for the transaction definitions
rg -A 5 "Deposit.*CancelProposal" precompiles/gov

# Check for any test files
fd -g "*_test.go" | xargs rg "TestDeposit|TestCancelProposal"

Length of output: 696


Script:

#!/bin/bash
# Let's verify the implementation details of these methods

# Check the method definitions and implementations
ast-grep --pattern 'func (p *Precompile) Deposit($$$) error {
  $$$
}'

ast-grep --pattern 'func (p *Precompile) CancelProposal($$$) error {
  $$$
}'

# Check the method declarations in the interface
rg -A 2 "DepositMethod.*=|CancelProposalMethod.*=" precompiles/gov

# Check for event definitions
rg "Deposit.*Event|CancelProposal.*Event" precompiles/gov

Length of output: 1756


Script:

#!/bin/bash
# Let's check the actual implementation of these transactions

# Check the transaction implementations
rg -B 2 -A 10 "^func.*Deposit\(" precompiles/gov/tx.go
rg -B 2 -A 10 "^func.*CancelProposal\(" precompiles/gov/tx.go

# Check the test implementations to understand the expected behavior
rg -B 2 -A 10 "^func.*TestDeposit\(" precompiles/gov/tx_test.go
rg -B 2 -A 10 "^func.*TestCancelProposal\(" precompiles/gov/tx_test.go

Length of output: 1572

precompiles/gov/types.go (7)

9-9: Import statement is appropriate

The addition of "cosmossdk.io/math" is necessary and correctly included for handling mathematical operations.


16-16: Updated import to use the new governance module types

The change to import v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" reflects the migration to the new governance module version and is correctly implemented.


150-172: Function NewMsgCancelProposal is correctly implemented

The NewMsgCancelProposal function is correctly implemented with proper argument checks and message construction.


Line range hint 175-200: Function NewMsgVote is correctly implemented

The NewMsgVote function correctly handles argument validation and message creation without issues.


Line range hint 257-267: Function ParseVotesArgs is correctly handling input parameters

The ParseVotesArgs function correctly unpacks the arguments and constructs the query request.


Line range hint 451-460: Function TallyResultOutput.FromResponse is correctly implemented

The TallyResultOutput.FromResponse method accurately maps the response data to the output structure.


Line range hint 498-508: Function ParseProposalArgs properly parses arguments

The ParseProposalArgs function correctly handles input validation and constructs the query request.

@ramacarlucho
Copy link
Contributor

I think we can apply most of the coderabbit suggestions

Co-authored-by: stepit <[email protected]>
Signed-off-by: Vladislav Varadinov <[email protected]>
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

🧹 Outside diff range and nitpick comments (3)
precompiles/gov/events_test.go (3)

155-156: Consider using idiomatic struct initialization

The struct initialization can be more concise using field names without repeating the type.

-				gov.WeightedVoteOption{Option: 1, Weight: "0.70"},
-				gov.WeightedVoteOption{Option: 2, Weight: "0.30"},
+				{Option: 1, Weight: "0.70"},
+				{Option: 2, Weight: "0.30"},

172-244: Consider adding error test cases

The test only covers the success path. Consider adding test cases for:

  • Invalid proposal ID
  • Insufficient deposit amount
  • Invalid deposit denomination

246-313: Consider adding error test cases

The test only covers the success path. Consider adding test cases for:

  • Invalid proposal ID
  • Non-proposer attempting to cancel
  • Already canceled proposal
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 084c539 and c009fa8.

📒 Files selected for processing (3)
  • CHANGELOG.md (1 hunks)
  • precompiles/gov/errors.go (2 hunks)
  • precompiles/gov/events_test.go (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • CHANGELOG.md
  • precompiles/gov/errors.go
🔇 Additional comments (4)
precompiles/gov/events_test.go (4)

179-219: Simplify test structure

Since we're only testing one case, we can simplify the test structure by removing the test cases array and directly implementing the test logic.


203-203: Maintain consistent assertion order

For consistency with the codebase, expected value should be the first argument in assertions.

-				s.Require().Equal(uint64(ctx.BlockHeight()), log.BlockNumber) //nolint:gosec // G115
+				s.Require().Equal(log.BlockNumber, uint64(ctx.BlockHeight())) //nolint:gosec // G115

253-289: Simplify test structure

Since we're only testing one case, we can simplify the test structure by removing the test cases array and directly implementing the test logic.


276-276: Maintain consistent assertion order

For consistency with the codebase, expected value should be the first argument in assertions.

-				s.Require().Equal(log.BlockNumber, uint64(ctx.BlockHeight())) //nolint:gosec // G115
+				s.Require().Equal(uint64(ctx.BlockHeight()), log.BlockNumber) //nolint:gosec // G115

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 and nitpick comments (5)
precompiles/common/errors.go (1)

31-32: Consider enhancing the error message with more context.

The error message is quite generic and doesn't follow the pattern of other validation errors in this file that provide more detailed context. Consider making it more specific and adding format specifiers to include validation failure details.

-	// ErrInvalidMethodInputs is raised when the method does not have the expected inputs defined.
-	ErrInvalidMethodInputs = "invalid method inputs"
+	// ErrInvalidMethodInputs is raised when the method inputs fail validation.
+	ErrInvalidMethodInputs = "invalid method inputs: %v"
precompiles/vesting/types.go (2)

105-107: Good addition of input validation, but consider making the check more precise

The validation check prevents potential panic when accessing method.Inputs[3] and [4] later in the function. However, since we know exactly how many inputs we need, we could make the check more precise.

Consider updating the check to explicitly validate for exactly 5 inputs:

-if len(method.Inputs) <= 4 {
+if len(method.Inputs) != 5 {
   return nil, common.Address{}, common.Address{}, nil, nil, fmt.Errorf(cmn.ErrInvalidMethodInputs)
}

This would better align with the function's requirements, as it uses indices 3 and 4 specifically for lockup and vesting periods.


105-107: Consider enhancing the error message

The generic ErrInvalidMethodInputs could be more helpful if it specified the expected number of inputs.

Consider using a more descriptive error message:

-return nil, common.Address{}, common.Address{}, nil, nil, fmt.Errorf(cmn.ErrInvalidMethodInputs)
+return nil, common.Address{}, common.Address{}, nil, nil, fmt.Errorf("invalid number of method inputs: expected 5, got %d", len(method.Inputs))
precompiles/gov/types.go (2)

Line range hint 408-426: Consider adding error context in FromResponse methods

The FromResponse methods for DepositOutput and DepositsOutput silently return nil on Bech32 address conversion errors. Consider adding error context to help with debugging.

 func (do *DepositOutput) FromResponse(res *v1.QueryDepositResponse) *DepositOutput {
     hexDepositor, err := utils.Bech32ToHexAddr(res.Deposit.Depositor)
     if err != nil {
-        return nil
+        return fmt.Errorf("failed to convert depositor address: %w", err)
     }

Also applies to: 428-456


Line range hint 548-589: Consider implementing pagination limit

The FromResponse methods for ProposalOutput and ProposalsOutput handle large datasets. Consider implementing pagination limits to prevent potential memory issues with large result sets.

Also applies to: 590-642

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c009fa8 and a48e608.

📒 Files selected for processing (4)
  • precompiles/common/errors.go (1 hunks)
  • precompiles/gov/types.go (19 hunks)
  • precompiles/ics20/types.go (2 hunks)
  • precompiles/vesting/types.go (1 hunks)
🔇 Additional comments (6)
precompiles/common/errors.go (1)

31-32: Verify the error constant usage across the codebase.

Let's ensure this error is being used consistently and follows similar patterns to other validation errors in the governance precompile.

✅ Verification successful

Let me gather more information about similar error patterns in the codebase to ensure consistency.


Based on the analysis of the codebase, I can now provide a final response about the usage of ErrInvalidMethodInputs:

Error constant is used consistently and follows established patterns

The ErrInvalidMethodInputs error is used appropriately across the codebase:

  • It's used consistently in input validation checks across multiple precompiles (gov, ics20, vesting) when method inputs don't meet the expected length
  • The error follows the same pattern as other validation errors in the codebase:
    • Simple, descriptive message format
    • Used in length validation checks before unpacking method inputs
    • Returns with fmt.Errorf for consistent error handling
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check how the new error constant is used and compare with similar validation patterns

# Check where the new error is used
echo "Checking usage of ErrInvalidMethodInputs:"
rg "ErrInvalidMethodInputs" -B 2 -A 2

# Check similar validation patterns in governance precompile
echo -e "\nChecking similar validation patterns in governance code:"
rg "invalid.*method|method.*invalid" --type go -g "precompiles/gov/**"

Length of output: 2300


Script:

#!/bin/bash
# Check error patterns in precompiles
echo "Checking error patterns in precompiles:"
rg "ErrInvalid|invalid" --type go -g "precompiles/**/*.go" -B 1 -A 1

# Check error string formats
echo -e "\nChecking error string formats:"
rg '= ".*invalid.*"' --type go -g "precompiles/**/*.go"

# Check error handling patterns in input validation
echo -e "\nChecking input validation patterns:"
ast-grep --pattern 'if len($_.Inputs) $_ {
  return $$$, fmt.Errorf($_)
}'

Length of output: 104793

precompiles/ics20/types.go (2)

311-313: ⚠️ Potential issue

Review the validation check for authorization method inputs

Similar to the previous issue, this validation check for method.Inputs length is problematic:

  1. It's redundant with the args length check at line 310.
  2. If method.Inputs represents ABI method inputs, it should match the expected number of arguments (2).
  3. The error message is too generic and doesn't indicate the actual requirement.

Let's verify the ABI method definition:

Consider one of these alternatives:

-	if len(method.Inputs) <= 1 {
-		return common.Address{}, nil, fmt.Errorf(cmn.ErrInvalidMethodInputs)
-	}
+	// Option 1: Match expected args length
+	if len(method.Inputs) != 2 {
+		return common.Address{}, nil, fmt.Errorf("invalid number of method inputs: expected 2, got %d", len(method.Inputs))
+	}
+
+	// Option 2: Remove redundant check if it's not necessary
✅ Verification successful

The previous search was too specific. Let's broaden our search to understand the context better and verify the validation requirements for the transfer authorization method.


Based on the provided context, I can now generate the final response. The code shows that method.Inputs represents the ABI method inputs, and the validation is part of the argument unpacking process for the allocations parameter.

The validation check for method inputs is necessary and correct

The check if len(method.Inputs) <= 1 is required because:

  1. The function needs to access method.Inputs[1] to unpack the allocations argument using ABI encoding.
  2. The error occurs before attempting to access this index, preventing a potential panic.
  3. The error message correctly indicates an issue with the method's ABI definition.

The validation is different from the args length check because:

  • len(args) validates the number of arguments passed to the function
  • len(method.Inputs) validates the ABI method definition itself has the correct parameter types
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the ABI definition or interface that defines this authorization method
rg -A 5 'transfer.*authorization.*\(.*common\.Address.*ICS20Allocation'

Length of output: 73


Script:

#!/bin/bash
# Let's try to find the method definition and its usage in a broader search
rg -A 5 'checkTransferAuthzArgs'

# Also search for any transfer authorization related code
rg -A 5 'TransferAuthorization'

# Look for the actual method definition in the file
cat precompiles/ics20/types.go

Length of output: 29050


139-141: ⚠️ Potential issue

Review the validation check for method inputs

The validation check for method.Inputs length seems problematic:

  1. It's redundant with the args length check at line 138.
  2. If method.Inputs represents ABI method inputs, it should match the expected number of arguments (9).
  3. The error message is too generic and doesn't indicate the actual requirement.

Let's verify the ABI method definition:

Consider one of these alternatives:

-	if len(method.Inputs) <= 6 {
-		return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidMethodInputs)
-	}
+	// Option 1: Match expected args length
+	if len(method.Inputs) != 9 {
+		return nil, common.Address{}, fmt.Errorf("invalid number of method inputs: expected 9, got %d", len(method.Inputs))
+	}
+
+	// Option 2: Remove redundant check if it's not necessary
precompiles/gov/types.go (3)

9-9: LGTM! Import changes look good.

The transition from govv1 to v1 and addition of math package are appropriate for the new implementation.

Also applies to: 16-16


239-242: ⚠️ Potential issue

Validate WeightedVoteOption values

This is a duplicate of a previous review comment. The VoteOption values should be validated before casting.


540-541: ⚠️ Potential issue

Validate ProposalStatus values

This is a duplicate of a previous review comment. The ProposalStatus should be validated before casting.

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 and nitpick comments (6)
precompiles/gov/tx.go (2)

133-142: Consider documenting the state consistency logic

The state consistency handling for non-origin depositors is crucial but complex. Consider adding a more detailed comment explaining why this scaling is necessary and what could happen if it's not done correctly.

 if !isOriginDepositor {
-    // NOTE: This ensures that the changes in the bank keeper are correctly mirrored to the EVM stateDB
-    // when calling the precompile from a smart contract
-    // This prevents the stateDB from overwriting the changed balance in the bank keeper when committing the EVM state.
-    // Need to scale the amount to 18 decimals for the EVM balance change entry
+    // IMPORTANT: State Consistency Handling
+    // 1. When called from a smart contract, we need to mirror bank keeper changes in the EVM stateDB
+    // 2. This prevents the stateDB from overwriting the bank keeper's balance changes during EVM state commit
+    // 3. The amount must be scaled to 18 decimals to match EVM's decimal precision
+    // 4. Without this scaling, there would be precision loss in the EVM state

97-182: Consider extracting common authorization patterns

The authorization logic for checking contract vs origin addresses is repeated across all methods (Vote, VoteWeighted, Deposit, CancelProposal). Consider extracting this into a helper function to improve maintainability and reduce duplication.

Example helper function:

func (p Precompile) validateOrigin(
    contract *vm.Contract,
    origin, expectedAddr common.Address,
    errMsg string,
) error {
    isContractCaller := contract.CallerAddress == expectedAddr && contract.CallerAddress != origin
    if !isContractCaller && origin != expectedAddr {
        return fmt.Errorf(errMsg, origin.String(), expectedAddr.String())
    }
    return nil
}
🧰 Tools
🪛 GitHub Check: Run golangci-lint

[failure] 113-113:
SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)

precompiles/gov/tx_test.go (1)

370-371: Improve clarity of initial deposit value

The magic number 100 should be defined as a constant with a descriptive name to improve readability and maintainability.

+const initialDeposit = 100
 // 100 is the initial deposit
-s.Require().Equal(math.NewInt(1e18).AddRaw(100), deposits[0].Amount[0].Amount.BigInt())
+s.Require().Equal(math.NewInt(1e18).AddRaw(initialDeposit), deposits[0].Amount[0].Amount.BigInt())
precompiles/gov/types.go (2)

112-158: LGTM: Well-structured deposit message creation with comprehensive validation

The implementation includes thorough validation of all input parameters and proper conversion of coin amounts.

Consider improving error messages for better debugging:

-		return nil, common.Address{}, fmt.Errorf(ErrInvalidDeposit)
+		return nil, common.Address{}, fmt.Errorf("%s: empty deposit amount", ErrInvalidDeposit)
-			return nil, common.Address{}, fmt.Errorf(ErrInvalidDeposit)
+			return nil, common.Address{}, fmt.Errorf("%s: non-positive amount %v", ErrInvalidDeposit, c.Amount)
🧰 Tools
🪛 GitHub Check: Run golangci-lint

[failure] 138-138:
SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)


[failure] 144-144:
SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)


160-182: Add validation for proposal ID

The implementation looks good but could benefit from additional validation.

Consider adding validation for non-zero proposal ID:

 	proposalID, ok := args[1].(uint64)
 	if !ok {
 		return nil, common.Address{}, fmt.Errorf(ErrInvalidProposalID, args[1])
 	}
+	if proposalID == 0 {
+		return nil, common.Address{}, fmt.Errorf("%s: proposal ID cannot be zero", ErrInvalidProposalID)
+	}
precompiles/gov/integration_test.go (1)

259-325: Well-structured test cases for Deposit!

The test cases effectively cover both success and error scenarios, with proper verification of deposit amounts. Good use of the initialDeposit constant for maintainability.

Consider adding a test case for depositing after the deposit end time:

It("should fail when depositing after deposit end time", func() {
    // Advance past the deposit end time
    proposal, _ := s.network.App.GovKeeper.Proposals.Get(s.network.GetContext(), proposalID)
    ctx := s.network.GetContext()
    ctx = ctx.WithBlockTime(proposal.DepositEndTime.Add(time.Hour))
    s.network.App.GovKeeper.Proposals.Set(ctx, proposalID, proposal)

    depositAmount := big.NewInt(1e18)
    coins := []cmn.Coin{{Denom: evmtypes.GetEVMCoinDenom(), Amount: depositAmount}}
    callArgs.Args = []interface{}{
        s.keyring.GetAddr(0),
        proposalID,
        coins,
    }

    depositCheck := defaultLogCheck.WithErrContains("deposit period ended")

    _, _, err := s.factory.CallContractAndCheckLogs(s.keyring.GetPrivKey(0), txArgs, callArgs, depositCheck)
    Expect(err).To(BeNil())
})
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a48e608 and b7716fe.

📒 Files selected for processing (5)
  • precompiles/gov/errors.go (2 hunks)
  • precompiles/gov/integration_test.go (2 hunks)
  • precompiles/gov/tx.go (3 hunks)
  • precompiles/gov/tx_test.go (2 hunks)
  • precompiles/gov/types.go (19 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • precompiles/gov/errors.go
🧰 Additional context used
🪛 GitHub Check: Run golangci-lint
precompiles/gov/tx.go

[failure] 113-113:
SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)

precompiles/gov/types.go

[failure] 138-138:
SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)


[failure] 144-144:
SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)

🔇 Additional comments (9)
precompiles/gov/tx.go (3)

25-28: LGTM: Constants follow naming convention

The new constants for Deposit and CancelProposal methods follow the existing naming pattern and correctly define the ABI method names.


146-182: LGTM: Well-structured authorization and event handling

The CancelProposal implementation follows good practices:

  • Proper authorization checks for contract vs origin proposer
  • Clear event emission
  • Complete return values including cancellation details

177-181: Consider handling time conversion edge cases

The Unix timestamp conversion could potentially overflow for dates beyond 2038 on 32-bit systems. Consider adding validation or documentation about this limitation.

precompiles/gov/tx_test.go (2)

6-7: LGTM!

The added import for evmtypes is necessary and correctly placed following Go's standard import grouping.


470-474: 🛠️ Refactor suggestion

Enhance proposal cancellation verification

The success test case should verify the proposal's existence before cancellation and ensure proper status changes.

 func() {
+    // Verify proposal exists before cancellation
+    proposal, err := s.network.App.GovKeeper.Proposals.Get(ctx, proposalID)
+    s.Require().NoError(err)
+    s.Require().NotNil(proposal)
+
+    // Verify proposal is cancelled
     found, err := s.network.App.GovKeeper.Proposals.Has(s.network.GetContext(), proposalID)
     s.Require().NoError(err)
     s.Require().False(found)
 }
precompiles/gov/types.go (2)

9-9: LGTM: Import changes align with v1 governance types

The changes correctly update the imports to use the new v1 governance types from the Cosmos SDK.

Also applies to: 16-16


246-249: ⚠️ Potential issue

Add validation for VoteOption values

The VoteOption is cast without validation, which could lead to invalid votes being processed.

As noted in the previous review, please add validation for VoteOption values:

 	weightedOptions := make([]*v1.WeightedVoteOption, len(options))
 	for i, option := range options {
+		if _, ok := v1.VoteOption_name[int32(option.Option)]; !ok {
+			return nil, common.Address{}, WeightedVoteOptions{}, fmt.Errorf("invalid VoteOption: %d", option.Option)
+		}
 		weightedOptions[i] = &v1.WeightedVoteOption{
 			Option: v1.VoteOption(option.Option),
 			Weight: option.Weight,
 		}
 	}
precompiles/gov/integration_test.go (2)

13-13: LGTM!

The added import for the common package is necessary for the new test cases and follows the project's naming conventions.


213-257: Well-structured test cases for CancelProposal!

The test cases effectively cover both success and error scenarios, with clear assertions and error messages.

As suggested in the previous review, consider adding test cases for:

  1. Attempting to cancel an already executed proposal
  2. Attempting to cancel an expired proposal

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 and nitpick comments (5)
precompiles/gov/tx.go (1)

155-171: Consider additional validation for proposal cancellation

While the basic validation is in place, consider adding checks for:

  1. Proposal existence
  2. Proposal status (ensure it can be cancelled)
  3. Cancellation timeframe validation (if there are time-based restrictions)
 msg, proposerAddr, err := NewMsgCancelProposal(args)
 if err != nil {
     return nil, err
 }
+
+// Add proposal existence check
+proposal, err := p.govKeeper.GetProposal(ctx, msg.ProposalId)
+if err != nil {
+    return nil, fmt.Errorf("proposal %d not found", msg.ProposalId)
+}
+
+// Add status check
+if !proposal.Status.IsCancellable() {
+    return nil, fmt.Errorf("proposal %d cannot be cancelled in status %s", msg.ProposalId, proposal.Status)
+}
precompiles/gov/tx_test.go (1)

288-377: Consider adding more test cases

The test suite could benefit from additional edge cases:

  1. Multiple deposits from the same depositor
  2. Deposit with multiple coins
  3. Deposit with zero amount

Would you like me to provide implementations for these additional test cases?

precompiles/gov/types.go (2)

137-139: Improve error message specificity

The error message should provide more context about why the deposit is invalid.

 if len(amount) == 0 {
-    return nil, common.Address{}, fmt.Errorf(ErrInvalidDeposit)
+    return nil, common.Address{}, fmt.Errorf("%s: empty amount", ErrInvalidDeposit)
 }
🧰 Tools
🪛 GitHub Check: Run golangci-lint

[failure] 138-138:
SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)


143-145: Improve error message for invalid deposit amount

The error message should specify which coin has an invalid amount.

 if c.Amount.Sign() <= 0 {
-    return nil, common.Address{}, fmt.Errorf(ErrInvalidDeposit)
+    return nil, common.Address{}, fmt.Errorf("%s: non-positive amount for coin %s", ErrInvalidDeposit, c.Denom)
 }
🧰 Tools
🪛 GitHub Check: Run golangci-lint

[failure] 144-144:
SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)

precompiles/gov/integration_test.go (1)

276-276: Consider using a more specific error message.

The error message "failed ETH tx" is too generic. Consider checking for a more specific error message that indicates the proposal doesn't exist.

-			depositCheck := defaultLogCheck.WithErrContains("failed ETH tx")
+			depositCheck := defaultLogCheck.WithErrContains("not found: key '999'")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a48e608 and b7716fe.

📒 Files selected for processing (5)
  • precompiles/gov/errors.go (2 hunks)
  • precompiles/gov/integration_test.go (2 hunks)
  • precompiles/gov/tx.go (3 hunks)
  • precompiles/gov/tx_test.go (2 hunks)
  • precompiles/gov/types.go (19 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • precompiles/gov/errors.go
🧰 Additional context used
🪛 GitHub Check: Run golangci-lint
precompiles/gov/tx.go

[failure] 113-113:
SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)

precompiles/gov/types.go

[failure] 138-138:
SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)


[failure] 144-144:
SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)

🔇 Additional comments (12)
precompiles/gov/tx.go (3)

25-28: LGTM: Constants follow consistent naming pattern

The new method constants for DepositMethod and CancelProposalMethod are well-defined and follow the existing naming convention.


177-181: Verify timestamp handling in response

The Unix timestamp conversion should be checked for potential timezone issues or edge cases.

✅ Verification successful

Let me analyze the timestamp handling in the codebase based on the search results. The code in question is:

return method.Outputs.Pack(
    true,
    uint64(resp.CanceledTime.Unix()), //nolint:gosec // G115
    resp.CanceledHeight,
)

From the search results, I can see that:

  1. The timestamp handling is consistent across the codebase, using Unix() for timestamp conversions
  2. The CanceledTime is already in UTC as it comes from the blockchain's context
  3. The code is properly handling the conversion by:
    • Using the standard Unix() method which returns seconds since epoch
    • Converting to uint64 which is the expected type for the ABI encoding
  4. The G115 linter suppression is consistently used across the codebase for similar conversions
  5. The conversion doesn't involve any timezone-specific operations that could cause issues

No timezone or edge case concerns with timestamp handling

The timestamp handling is safe and consistent with the rest of the codebase. The CanceledTime is already in UTC, and the conversion to Unix timestamp is straightforward without any timezone manipulation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for timestamp handling in tests
rg -A 5 "CanceledTime|Unix" 

Length of output: 38339


133-142: Review the balance scaling implementation

The balance scaling logic is critical for EVM state consistency. Ensure that:

  1. The conversion to 18 decimals is properly tested with various token denominations
  2. The balance change entries are correctly applied in all edge cases
✅ Verification successful

Let me gather more information about the testing coverage of this functionality.


Let me check the actual decimal conversion implementation and test coverage.


Let me check the actual test implementations to verify the coverage of edge cases.


Based on the comprehensive test coverage shown in the scaling tests, I can now provide the final response:

Balance scaling implementation is properly tested and verified

The balance scaling implementation is thoroughly tested with:

  • Conversion between 6 and 18 decimals
  • Edge cases including:
    • Zero amounts
    • Amounts less than conversion factor
    • Maximum amounts ("one ether")
    • Smallest possible amounts (1 wei)
  • Rounding behavior for decimal places
  • Different token denominations
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for tests covering the balance scaling logic
rg -A 5 "ConvertAmountTo18DecimalsBigInt|SetBalanceChangeEntries" 

Length of output: 7356


Script:

#!/bin/bash
# Search for test files that might cover the balance scaling logic
rg -t go -g "*_test.go" "ConvertAmountTo18DecimalsBigInt|SetBalanceChangeEntries" -A 5

# Also check the implementation of GetEVMCoinDecimals which is crucial for the conversion
ast-grep --pattern 'func GetEVMCoinDecimals() $_'

Length of output: 493


Script:

#!/bin/bash
# Check the Decimals type and conversion factor implementation
rg -A 10 "type Decimals struct" x/evm/types/

# Look for test files covering decimal conversions
rg -g "*_test.go" "TestConvert.*Decimals|TestGetEVMCoin" -A 10

Length of output: 1930


Script:

#!/bin/bash
# Get the full content of the scaling tests
cat x/evm/types/scaling_test.go

# Check for any integration tests that might cover this functionality
rg -g "*_test.go" "TestIntegration.*Balance|TestPrecompile.*Balance" -A 10

Length of output: 10272

precompiles/gov/tx_test.go (3)

6-7: LGTM!

The added import for evmtypes is necessary and properly organized.


470-474: Enhance proposal cancellation verification

The success case should verify the proposal's existence and status before cancellation.

This is a duplicate of a previous review comment. The suggestion to enhance the verification by checking the proposal's existence and status before cancellation remains valid.


413-425: LGTM! Good error case coverage

The test case for non-existent proposal is well implemented and covers an important edge case.

precompiles/gov/types.go (3)

160-182: LGTM! Well-implemented proposal cancellation

The function includes all necessary validations and proper error handling.


547-548: Validate ProposalStatus to prevent invalid enum values

The ProposalStatus is cast without validation, which could lead to unexpected behavior.


246-251: ⚠️ Potential issue

Add validation for vote options

The conversion of vote options lacks validation, which could allow invalid vote options to pass through.

 weightedOptions := make([]*v1.WeightedVoteOption, len(options))
 for i, option := range options {
+    if _, ok := v1.VoteOption_name[int32(option.Option)]; !ok {
+        return nil, common.Address{}, WeightedVoteOptions{}, fmt.Errorf("invalid vote option: %d", option.Option)
+    }
     weightedOptions[i] = &v1.WeightedVoteOption{
         Option: v1.VoteOption(option.Option),
         Weight: option.Weight,
     }
 }

Likely invalid or redundant comment.

precompiles/gov/integration_test.go (3)

13-13: LGTM!

The import of the common package is necessary for the Coin type used in Deposit tests and follows the project's naming conventions.


213-257: LGTM! Comprehensive test coverage for CancelProposal.

The test suite effectively covers:

  • Error case: non-existent proposal
  • Error case: unauthorized cancellation
  • Success case: proper proposal cancellation with state verification

259-325: LGTM! Well-structured test suite for Deposit functionality.

The test suite provides good coverage of success and failure scenarios, with proper state verification.

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

🧹 Outside diff range and nitpick comments (1)
precompiles/gov/tx_test.go (1)

372-373: Improve clarity of deposit amount verification

The comment about initial deposit (100) needs better documentation and the verification could be more explicit.

-				// 100 is the initial deposit
-				s.Require().Equal(math.NewInt(1e18).AddRaw(100).BigInt(), deposits[0].Amount[0].Amount.BigInt())
+				// Verify total deposit amount (initial proposal deposit + new deposit)
+				initialDeposit := int64(100) // Initial deposit required for proposal creation
+				newDeposit := math.NewInt(1e18)
+				expectedAmount := newDeposit.AddRaw(initialDeposit)
+				s.Require().Equal(expectedAmount.BigInt(), deposits[0].Amount[0].Amount.BigInt())
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b7716fe and a83b569.

📒 Files selected for processing (1)
  • precompiles/gov/tx_test.go (2 hunks)
🔇 Additional comments (3)
precompiles/gov/tx_test.go (3)

6-7: LGTM!

The added import for evmtypes is necessary and properly used throughout the test cases.


282-503: Overall implementation looks good!

The implementation of both TestDeposit and TestCancelProposal functions follows good testing practices:

  • Comprehensive test cases covering various scenarios
  • Proper error handling and validation
  • Consistent structure with existing test functions

474-478: 🛠️ Refactor suggestion

Enhance proposal cancellation verification

The success test case should verify the proposal's existence before cancellation for a more comprehensive test.

 			func() {
+				// Verify proposal exists before cancellation
+				found, err := s.network.App.GovKeeper.Proposals.Has(ctx, proposalID)
+				s.Require().NoError(err)
+				s.Require().True(found)
+
+				// Verify proposal is cancelled
 				found, err := s.network.App.GovKeeper.Proposals.Has(s.network.GetContext(), proposalID)
 				s.Require().NoError(err)
 				s.Require().False(found)
 			},

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 and nitpick comments (8)
precompiles/gov/tx.go (3)

107-115: Enhance deposit validation

While basic validation exists, consider adding more comprehensive checks:

  1. Validate that the amount is positive
  2. Verify the denomination is correct for your chain
  3. Add maximum deposit amount validation if applicable
 if len(msg.Amount) != 1 {
   return nil, errors.New(ErrInvalidDeposit)
 }
+if msg.Amount[0].IsZero() {
+    return nil, errors.New("deposit amount must be positive")
+}
+if msg.Amount[0].Denom != ExpectedDenom {
+    return nil, fmt.Errorf("invalid denomination: expected %s, got %s", ExpectedDenom, msg.Amount[0].Denom)
+}

134-143: Improve documentation of EVM state synchronization

The current comment could be more explicit about the technical details of the state synchronization process.

Consider expanding the comment to:

-// NOTE: This ensures that the changes in the bank keeper are correctly mirrored to the EVM stateDB
-// when calling the precompile from a smart contract
-// This prevents the stateDB from overwriting the changed balance in the bank keeper when committing the EVM state.
-// Need to scale the amount to 18 decimals for the EVM balance change entry
+// NOTE: When a precompile is called from a smart contract, we need to ensure that
+// balance changes made by the bank keeper are correctly reflected in the EVM state:
+// 1. The bank keeper modifies the actual balance
+// 2. We record a corresponding change in the EVM stateDB
+// 3. This prevents the final EVM state commit from overwriting the bank keeper's changes
+// 4. The amount must be scaled to 18 decimals to match EVM precision

178-182: Document timestamp handling

The Unix timestamp conversion needs clearer documentation about timezone handling and potential limitations.

 return method.Outputs.Pack(
     true,
-    uint64(resp.CanceledTime.Unix()), //nolint:gosec // G115
+    uint64(resp.CanceledTime.Unix()), // Convert to Unix timestamp (UTC) for EVM compatibility
     resp.CanceledHeight,
 )
precompiles/gov/types.go (1)

138-146: Enhance deposit amount validation

While the function validates that the amount is not empty and positive, consider adding these additional checks:

  • Validate maximum deposit amount
  • Ensure denomination is allowed
 if len(amount) == 0 {
   return nil, common.Address{}, errors.New(ErrInvalidDeposit)
 }

+// Define allowed denominations
+var allowedDenoms = map[string]bool{"stake": true, "evmos": true}
+
 coins := make([]sdk.Coin, len(amount))
 for i, c := range amount {
   if c.Amount.Sign() <= 0 {
     return nil, common.Address{}, errors.New(ErrInvalidDeposit)
   }
+  if !allowedDenoms[c.Denom] {
+    return nil, common.Address{}, fmt.Errorf("invalid denomination: %s", c.Denom)
+  }
+  // Add maximum deposit check if applicable
+  if c.Amount.BitLen() > 256 {
+    return nil, common.Address{}, fmt.Errorf("deposit amount too large")
+  }
   coins[i] = sdk.Coin{
precompiles/gov/integration_test.go (4)

225-225: Consider using a more specific error message check.

The error message "not found: key '999'" is implementation-specific. Consider using a more domain-specific error message that better describes the business logic failure.


213-257: Add more test cases for comprehensive coverage.

While the current test cases cover the basic scenarios, consider adding tests for:

  1. Attempting to cancel an already executed proposal
  2. Attempting to cancel a proposal after voting period ends
  3. Attempting to cancel a proposal with insufficient gas

276-276: Consider using a more specific error message check.

Similar to the cancel proposal tests, the error message "not found: key '999'" is implementation-specific. Consider using a more domain-specific error message.


259-325: Add test cases for additional edge cases.

Consider adding tests for:

  1. Depositing after the deposit period ends
  2. Depositing with invalid denomination
  3. Depositing with zero amount
  4. Multiple deposits from the same depositor
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a83b569 and 9a7ce35.

📒 Files selected for processing (3)
  • precompiles/gov/integration_test.go (2 hunks)
  • precompiles/gov/tx.go (3 hunks)
  • precompiles/gov/types.go (19 hunks)
🧰 Additional context used
🪛 GitHub Check: Run golangci-lint
precompiles/gov/types.go

[failure] 169-169:
SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)

🔇 Additional comments (3)
precompiles/gov/tx.go (1)

26-29: LGTM: Constants follow consistent naming pattern

The new constants DepositMethod and CancelProposalMethod are well-named and follow the existing pattern.

precompiles/gov/types.go (1)

214-214: Add validation for VoteOption values

The VoteOption is still being cast without validation in multiple places, which could lead to invalid vote options being processed.

This issue was previously identified in the past review comments. Please implement the suggested validation for VoteOption values.

Also applies to: 250-250

precompiles/gov/integration_test.go (1)

298-324: LGTM! Well-structured successful deposit test.

The successful deposit test is well implemented with:

  • Clear setup of test data
  • Proper event verification
  • Thorough state validation

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

🧹 Outside diff range and nitpick comments (2)
precompiles/gov/types.go (2)

129-131: Improve error message for method inputs validation

The error message should be more specific about the expected number of inputs.

-		return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidMethodInputs)
+		return nil, common.Address{}, fmt.Errorf("%s: expected > 2 inputs, got %d", cmn.ErrInvalidMethodInputs, len(method.Inputs))

138-146: Enhance deposit amount validation

The current validation could be more specific about the requirements for valid deposits.

 	if len(amount) == 0 {
-		return nil, common.Address{}, errors.New(ErrInvalidDeposit)
+		return nil, common.Address{}, fmt.Errorf("%s: deposit amount cannot be empty", ErrInvalidDeposit)
 	}
 
 	coins := make([]sdk.Coin, len(amount))
 	for i, c := range amount {
 		if c.Amount.Sign() <= 0 {
-			return nil, common.Address{}, errors.New(ErrInvalidDeposit)
+			return nil, common.Address{}, fmt.Errorf("%s: deposit amount must be positive for coin %s", ErrInvalidDeposit, c.Denom)
 		}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 9a7ce35 and 36b5dd3.

📒 Files selected for processing (1)
  • precompiles/gov/types.go (19 hunks)
🔇 Additional comments (5)
precompiles/gov/types.go (5)

17-17: LGTM: Import changes align with governance types update

The change from govv1 to v1 correctly reflects the transition to updated governance types in the Cosmos SDK.


247-252: Add validation for vote options

The code casts option.Option to v1.VoteOption without validating if it's a valid option value.

This issue was previously identified in past reviews. Please refer to the existing comment for the suggested fix.


167-170: ⚠️ Potential issue

Fix error message formatting

The error message uses fmt.Errorf without any formatting arguments.

 	proposer, ok := args[0].(common.Address)
 	if !ok || proposer == (common.Address{}) {
-		return nil, common.Address{}, errors.New(ErrInvalidProposer)
+		return nil, common.Address{}, fmt.Errorf(ErrInvalidProposer, proposer)
 	}

Likely invalid or redundant comment.


172-175: 🛠️ Refactor suggestion

Add validation for proposal ID value

The function should validate that the proposal ID is not zero.

 	proposalID, ok := args[1].(uint64)
 	if !ok {
 		return nil, common.Address{}, fmt.Errorf(ErrInvalidProposalID, args[1])
 	}
+	if proposalID == 0 {
+		return nil, common.Address{}, fmt.Errorf("%s: proposal ID cannot be zero", ErrInvalidProposalID)
+	}

Likely invalid or redundant comment.


113-183: Verify transaction authorization checks

Please ensure that proper authorization checks are implemented in the precompile contract for these new transaction types.

✅ Verification successful

Based on the comprehensive review of the implementation, I can now provide the final response:

Authorization checks are properly implemented through the precompile framework

The governance precompile inherits from the common precompile framework which provides several security measures:

  • Transaction vs. query validation through RunSetup
  • Write protection for read-only calls
  • Proper gas accounting and error handling
  • State management through journal entries
  • Origin address validation in transaction methods

The Deposit and CancelProposal methods are properly secured as they:

  • Run through the common precompile framework's security checks
  • Validate the origin address of transactions
  • Include proper error handling for invalid inputs
  • Maintain state consistency through journal entries
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for authorization checks in the precompile contract

# Search for authorization checks in the precompile implementation
rg -A 5 "RequireNotPayable|RequireOnlyFromEOA|RequireAuth" precompiles/gov/

Length of output: 77


Script:

#!/bin/bash
# Let's check the precompile contract implementation for these methods
ast-grep --pattern 'func (p $_) Deposit($$$) error {
  $$$
}'

# Also check for CancelProposal
ast-grep --pattern 'func (p $_) CancelProposal($$$) error {
  $$$
}'

# Check for any authorization-related functions or methods
rg -B 2 -A 5 "authorize|auth|require" precompiles/gov/

Length of output: 4241


Script:

#!/bin/bash
# Let's check the actual implementation of these methods in the contract
rg -B 2 -A 10 "func \(p \*Precompile\) (Deposit|CancelProposal)" precompiles/gov/

# Also check for any transaction validation or authorization in the base precompile
rg -B 2 -A 10 "func \(p \*Precompile\) (CheckTransaction|ValidateBasic)" precompiles/gov/

# Check the common precompile package for authorization mechanisms
rg -B 2 -A 10 "func.*Require(Auth|NotPayable|OnlyFromEOA)" precompiles/common/

Length of output: 256


Script:

#!/bin/bash
# Let's check the transaction methods in the contract file
rg -B 2 -A 10 "func.*Deposit|func.*CancelProposal" precompiles/gov/tx.go

# Check the base contract implementation
cat precompiles/gov/gov.go

# Check if there are any other transaction methods that might show the pattern
rg -l "MsgServer" precompiles/gov/

Length of output: 5504


Script:

#!/bin/bash
# Let's check the common precompile implementation for authorization checks
cat precompiles/common/precompile.go

# Check if there are any authorization checks in the base setup
rg -B 2 -A 10 "RunSetup" precompiles/common/

# Check for any authorization checks in the transaction execution
rg -B 2 -A 10 "HandleGasError|AddJournalEntries" precompiles/common/

Length of output: 14392

@hanchon hanchon enabled auto-merge (squash) November 27, 2024 23:10
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

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

53-54: Consider breaking long line into multiple lines for better readability.

The changelog entry exceeds the recommended line length. Consider reformatting it as:

-- (precompiles) [#3004](https://github.com/evmos/evmos/pull/3004) Add `Deposit` and `CancelProposal` tx to gov precompile.
++ (precompiles) [#3004](https://github.com/evmos/evmos/pull/3004) Add `Deposit` and 
++   `CancelProposal` tx to gov precompile.
🧰 Tools
🪛 Markdownlint (0.35.0)

54-54: Expected: 120; Actual: 137
Line length

(MD013, line-length)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 36b5dd3 and 42be691.

📒 Files selected for processing (1)
  • CHANGELOG.md (1 hunks)
🧰 Additional context used
🪛 Markdownlint (0.35.0)
CHANGELOG.md

54-54: Expected: 120; Actual: 137
Line length

(MD013, line-length)

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

🧹 Outside diff range and nitpick comments (3)
precompiles/gov/tx.go (3)

112-115: Enhance deposit amount validation

While the length check is good, consider adding more comprehensive validation:

  • Verify amount is positive
  • Validate denomination if specific tokens are required
 if len(msg.Amount) != 1 {
     return nil, errors.New(ErrInvalidDeposit)
 }
+if msg.Amount[0].IsZero() {
+    return nil, errors.New("deposit amount must be positive")
+}

134-143: Consider documenting the scaling factor

The balance scaling logic is correct, but it would be helpful to document:

  1. Why 18 decimals is used as the target
  2. What happens if the original token has more than 18 decimals

178-182: Add comment explaining the return values

The method returns multiple values (success, canceledTime, canceledHeight) but their purpose isn't immediately clear. Consider adding a comment explaining what these values represent and how they should be used.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 42be691 and e3ad771.

📒 Files selected for processing (1)
  • precompiles/gov/tx.go (3 hunks)
🔇 Additional comments (2)
precompiles/gov/tx.go (2)

26-29: LGTM: Constants follow established naming patterns

The new constants for DepositMethod and CancelProposalMethod are well-defined and consistent with existing method naming conventions.


180-180: Consider time zone handling for canceledTime

The Unix timestamp conversion assumes UTC. Consider documenting this assumption or handling time zones explicitly if needed.

✅ Verification successful

Based on the search results, I can see a consistent pattern across the codebase where Unix timestamps are handled uniformly. Here's what I found:

  1. In the EVM/RPC layer (rpc/types/utils.go), timestamps are explicitly converted to UTC before Unix conversion: time := uint64(header.Time.UTC().Unix())

  2. In other precompiles (staking, slashing, gov), Unix timestamps are used with //nolint:gosec // G115 comment, indicating a deliberate choice to use Unix timestamps consistently.

  3. The codebase consistently treats time values as UTC timestamps when converting to Unix format, as seen in multiple precompiles like staking and evidence modules.

The time zone handling is consistent with blockchain conventions

The use of Unix timestamps in resp.CanceledTime.Unix() follows the established pattern in the codebase where blockchain time is consistently handled in UTC. This is the standard approach in blockchain systems and doesn't require additional documentation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if there are any time zone conversions or assumptions in the codebase
rg -A 2 "Unix\(\)" 

Length of output: 13488

@ramacarlucho ramacarlucho marked this pull request as draft November 28, 2024 12:34
auto-merge was automatically disabled November 28, 2024 12:34

Pull request was converted to draft

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants