Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(evm): tx for creating fun token from coin #1946

Closed
wants to merge 5 commits into from

Conversation

onikonychev
Copy link
Contributor

@onikonychev onikonychev commented Jun 28, 2024

Summary by CodeRabbit

  • New Features

    • Introduced functionality to create a fun token from an existing Cosmos coin in the EVM module.
    • New feature to register an existing Cosmos coin as an EVM ERC-20 fungible token contract.
  • Tests

    • Added tests for the creation of a fun token from a coin to ensure validity under various scenarios.

Copy link
Contributor

coderabbitai bot commented Jun 28, 2024

Walkthrough

The submitted changes introduce a new feature to the NibiruChain/nibiru project: the ability to register an existing Cosmos coin as an EVM ERC-20 fungible token, known as a "fun token." This feature includes modifications to .proto files, new methods in the Keeper struct, and associated test cases to ensure functionality and robustness.

Changes

File(s) Summary
CHANGELOG.md Added a feature for creating a fun token from a coin in the EVM module.
proto/eth/evm/v1/events.proto Added EventCreateFunTokenFromCoin message with fields denom, contract_address, and creator.
proto/eth/evm/v1/tx.proto Added CreateFunTokenFromCoin RPC, messages MsgCreateFunTokenFromCoin and MsgCreateFunTokenFromCoinResponse.
x/evm/keeper/funtoken_state.go Renamed variable funtoken to funToken in SafeInsert method.
x/evm/keeper/msg_fun_token.go Introduced method CreateFunTokenFromCoin in Keeper struct to register Cosmos coin as fun token.
x/evm/keeper/msg_fun_token_test.go Added TestMsgCreateFunTokenFromCoin in the keeper_test package.
x/evm/msg.go Integrated MsgCreateFunTokenFromCoin, its ValidateBasic, and GetSigners methods.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Client
    participant CosmosApp
    participant EVMModule
    participant Keeper

    User->>Client: Initiate CreateFunTokenFromCoin Request
    Client->>CosmosApp: Send MsgCreateFunTokenFromCoin
    CosmosApp->>EVMModule: Forward MsgCreateFunTokenFromCoin
    EVMModule->>Keeper: Call CreateFunTokenFromCoin Method
    Keeper-->>EVMModule: Return MsgCreateFunTokenFromCoinResponse
    EVMModule-->>CosmosApp: Response with new_contract_address
    CosmosApp-->>Client: Return new_contract_address
    Client-->>User: Display new_contract_address
Loading

Possibly related issues

Poem

Amidst the chains that intertwine,
A coin transforms by design.
With magic code and tokens spun,
Cosmos meets EVM, the fun's begun.
In bytes and blocks, they come alive,
A rabbit's joy, the chains now thrive.
🌟🚀


Tip

Early access features: enabled

We are currently testing the following features in early access:

  • OpenAI gpt-4o model for code reviews and chat: OpenAI claims that this model is better at understanding and generating code than the previous models. We seek your feedback over the next few weeks before making it generally available.

Note:

  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.
  • Please join our Discord Community to provide feedback and report issues.
  • OSS projects are currently opted into early access features by default.

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

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (invoked as PR comments)

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

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

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@onikonychev onikonychev marked this pull request as ready for review June 28, 2024 16:32
@onikonychev onikonychev requested a review from a team as a code owner June 28, 2024 16:32
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

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 422c676 and 1931969.

Files ignored due to path filters (2)
  • x/evm/events.pb.go is excluded by !**/*.pb.go
  • x/evm/tx.pb.go is excluded by !**/*.pb.go
Files selected for processing (7)
  • CHANGELOG.md (1 hunks)
  • proto/eth/evm/v1/events.proto (1 hunks)
  • proto/eth/evm/v1/tx.proto (2 hunks)
  • x/evm/keeper/funtoken_state.go (1 hunks)
  • x/evm/keeper/msg_fun_token.go (1 hunks)
  • x/evm/keeper/msg_fun_token_test.go (1 hunks)
  • x/evm/msg.go (2 hunks)
Additional comments not posted (7)
x/evm/keeper/msg_fun_token.go (1)

13-38: Ensure proper error handling and event emission in CreateFunTokenFromCoin.

  1. Error Handling: The function correctly handles errors from ValidateBasic, key generation, and token insertion. Each potential error point correctly returns an error, ensuring robust error handling.
  2. Event Emission: The event emission at lines 31-35 correctly logs the creation of the token, including all relevant details such as the creator, denom, and contract address.
  3. Response Creation: The function returns a response with the new contract address, which aligns with the intended functionality.

Overall, the function is well-structured and follows good practices in error handling and response generation.

proto/eth/evm/v1/events.proto (1)

47-51: Review the structure of EventCreateFunTokenFromCoin.

The new protobuf message EventCreateFunTokenFromCoin correctly defines fields for denom, contract_address, and creator. These fields are essential for tracking the creation of new tokens and are appropriately indexed starting from 1. This structure aligns well with the intended functionality of logging token creation events.

x/evm/keeper/msg_fun_token_test.go (1)

9-62: Ensure comprehensive test coverage in TestMsgCreateFunTokenFromCoin.

The test cases cover various scenarios including valid and invalid inputs for denom and sender. The use of table-driven tests enhances maintainability and scalability of the test suite. However, consider adding more edge cases, such as testing with boundary values for denom and sender.

Also, ensure that the error messages and assertions are specific and informative, helping in quick identification of issues during test failures.

x/evm/keeper/funtoken_state.go (1)

83-87: Review the implementation of SafeInsert.

The SafeInsert method correctly creates a FunToken object and validates it before insertion. The use of defensive programming by validating the FunToken before insertion enhances the robustness of the method. Ensure that the Validate method of FunToken is thoroughly tested to prevent any corrupt data from being inserted into the state.

Verification successful

The Validate method of FunToken is thoroughly tested.

The test cases in x/evm/evm_test.go cover various scenarios, including invalid bank denominations, different formats of ERC20 addresses, and mixed case compatibility. This ensures that the Validate method is robust and handles different edge cases effectively.

  • x/evm/evm_test.go: Comprehensive test cases for FunToken.Validate.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that the Validate method of FunToken is thoroughly tested.

# Test: Search for the Validate method usage in tests. Expect: Comprehensive test coverage.
rg --type go $'FunToken.Validate'

Length of output: 32



Script:

#!/bin/bash
# Search for the definition of the Validate method in FunToken
ast-grep --lang go --pattern 'func ($_ FunToken) Validate() $_' --json

# Search for calls to the Validate method in the codebase
ast-grep --lang go --pattern '$_ .Validate()' --json

# Search for test files that might indirectly test the Validate method by testing SafeInsert
rg --type go -l 'SafeInsert' | xargs rg -l 'func Test'

Length of output: 39150



Script:

#!/bin/bash
# Display the contents of the test file where FunToken.Validate is called to verify thorough testing.
cat ./x/evm/evm_test.go

Length of output: 2794

proto/eth/evm/v1/tx.proto (1)

24-25: Review the structure of MsgCreateFunTokenFromCoin and its response.

The new service CreateFunTokenFromCoin and its associated request and response messages are well-defined. The fields in MsgCreateFunTokenFromCoin and MsgCreateFunTokenFromCoinResponse are appropriately tagged and structured to align with the functionality of registering a Cosmos denom as an EVM ERC-20 contract. Ensure that these protobuf definitions are aligned with the actual implementation in the Go code to maintain consistency across the codebase.

Also applies to: 184-196

x/evm/msg.go (1)

36-36: Approval of interface implementation for MsgCreateFunTokenFromCoin.

The declaration correctly implements the sdk.Msg interface for MsgCreateFunTokenFromCoin, ensuring it can be utilized within the Cosmos SDK messaging framework.

CHANGELOG.md (1)

80-80: Changelog entry for PR #1946 is correctly documented.

The entry is concise, links directly to the PR, and accurately describes the feature introduced. This aligns well with the project's standards for changelog entries.

x/evm/msg.go Outdated
Comment on lines 477 to 484
func (msg *MsgCreateFunTokenFromCoin) ValidateBasic() error {
_, err := sdk.AccAddressFromBech32(msg.Sender)
if err != nil {
return fmt.Errorf("invalid sender: %s", msg.Sender)
}
if err := sdk.ValidateDenom(msg.Denom); err != nil {
return errValidateFunToken(err.Error())
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Enhance error reporting in ValidateBasic method.

Consider including the specific error message when validation fails for better debugging and user feedback.

- return errValidateFunToken(err.Error())
+ return fmt.Errorf("validation error for denom '%s': %s", msg.Denom, err)
Committable suggestion

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

Suggested change
func (msg *MsgCreateFunTokenFromCoin) ValidateBasic() error {
_, err := sdk.AccAddressFromBech32(msg.Sender)
if err != nil {
return fmt.Errorf("invalid sender: %s", msg.Sender)
}
if err := sdk.ValidateDenom(msg.Denom); err != nil {
return errValidateFunToken(err.Error())
}
func (msg *MsgCreateFunTokenFromCoin) ValidateBasic() error {
_, err := sdk.AccAddressFromBech32(msg.Sender)
if err != nil {
return fmt.Errorf("invalid sender: %s", msg.Sender)
}
if err := sdk.ValidateDenom(msg.Denom); err != nil {
return fmt.Errorf("validation error for denom '%s': %s", msg.Denom, err)
}

Comment on lines +488 to +490
func (msg *MsgCreateFunTokenFromCoin) GetSigners() []sdk.AccAddress {
sender, _ := sdk.AccAddressFromBech32(msg.Sender)
return []sdk.AccAddress{sender}
Copy link
Contributor

Choose a reason for hiding this comment

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

Handle potential error when retrieving sender address in GetSigners.

Ignoring the error from sdk.AccAddressFromBechiz could lead to runtime panics if the address is invalid. It's important to handle this error appropriately.

- sender, _ := sdk.AccAddressFromBech32(msg.Sender)
+ sender, err := sdk.AccAddressFromBech32(msg.Sender)
+ if err != nil {
+     return nil, err
+ }

Committable suggestion was skipped due to low confidence.

Copy link

codecov bot commented Jun 29, 2024

Codecov Report

Attention: Patch coverage is 50.00000% with 15 lines in your changes missing coverage. Please review.

Project coverage is 64.80%. Comparing base (822d838) to head (202a3bd).

Current head 202a3bd differs from pull request most recent head cd1ec0a

Please upload reports for the commit cd1ec0a to get more accurate results.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1946      +/-   ##
==========================================
- Coverage   64.83%   64.80%   -0.03%     
==========================================
  Files         253      254       +1     
  Lines       16065    16092      +27     
==========================================
+ Hits        10416    10429      +13     
- Misses       4892     4904      +12     
- Partials      757      759       +2     
Files Coverage Δ
x/evm/keeper/funtoken_state.go 92.00% <66.66%> (ø)
x/evm/keeper/msg_fun_token.go 76.47% <76.47%> (ø)
x/evm/msg.go 71.42% <0.00%> (-3.14%) ⬇️

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 1931969 and 202a3bd.

Files selected for processing (3)
  • CHANGELOG.md (1 hunks)
  • x/evm/keeper/funtoken_state.go (1 hunks)
  • x/evm/msg.go (2 hunks)
Files skipped from review as they are similar to previous changes (2)
  • CHANGELOG.md
  • x/evm/keeper/funtoken_state.go
Additional context used
Learnings (1)
x/evm/msg.go (2)
Learnt from: Unique-Divine
PR: NibiruChain/nibiru#1680
File: x/perp/v2/keeper/msg_server.go:210-210
Timestamp: 2023-11-28T17:20:18.983Z
Learning: The user indicated that error handling for `sdk.AccAddressFromBech32(msg.Sender)` is covered by prior `ValidateBasic` checks in the code flow.
Learnt from: Unique-Divine
PR: NibiruChain/nibiru#1680
File: x/perp/v2/keeper/msg_server.go:198-198
Timestamp: 2023-11-28T17:20:08.561Z
Learning: The user Unique-Divine has indicated that the error check for `sdk.AccAddressFromBech32(msg.Sender)` is not necessary in the context of their code because it is covered by the `ValidateBasic` method.
GitHub Check: codecov/patch
x/evm/msg.go

[warning] 477-480: x/evm/msg.go#L477-L480
Added lines #L477 - L480 were not covered by tests


[warning] 482-483: x/evm/msg.go#L482-L483
Added lines #L482 - L483 were not covered by tests


[warning] 485-485: x/evm/msg.go#L485
Added line #L485 was not covered by tests


[warning] 488-490: x/evm/msg.go#L488-L490
Added lines #L488 - L490 were not covered by tests

Additional comments not posted (2)
x/evm/msg.go (2)

477-486: LGTM!

Tools
GitHub Check: codecov/patch

[warning] 477-480: x/evm/msg.go#L477-L480
Added lines #L477 - L480 were not covered by tests


[warning] 482-483: x/evm/msg.go#L482-L483
Added lines #L482 - L483 were not covered by tests


[warning] 485-485: x/evm/msg.go#L485
Added line #L485 was not covered by tests


488-490: Acknowledged: Error handling for address retrieval.

Based on previous learnings, error handling for sdk.AccAddressFromBech32(msg.Sender) is covered by ValidateBasic.

Tools
GitHub Check: codecov/patch

[warning] 488-490: x/evm/msg.go#L488-L490
Added lines #L488 - L490 were not covered by tests

Comment on lines +477 to +486
func (msg *MsgCreateFunTokenFromCoin) ValidateBasic() error {
_, err := sdk.AccAddressFromBech32(msg.Sender)
if err != nil {
return fmt.Errorf("invalid sender: %s", msg.Sender)
}
if err := sdk.ValidateDenom(msg.Denom); err != nil {
return fmt.Errorf("invalid denom: %s", msg.Denom)
}
return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Reminder: Add tests for ValidateBasic.

The static analysis tool indicates that the ValidateBasic function is not covered by tests.

Do you want me to generate the unit testing code or open a GitHub issue to track this task?

Tools
GitHub Check: codecov/patch

[warning] 477-480: x/evm/msg.go#L477-L480
Added lines #L477 - L480 were not covered by tests


[warning] 482-483: x/evm/msg.go#L482-L483
Added lines #L482 - L483 were not covered by tests


[warning] 485-485: x/evm/msg.go#L485
Added line #L485 was not covered by tests

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 202a3bd and cd1ec0a.

Files selected for processing (1)
  • CHANGELOG.md (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

Comment on lines +14 to +37
func (k *Keeper) CreateFunTokenFromCoin(
goCtx context.Context, msg *evm.MsgCreateFunTokenFromCoin,
) (*evm.MsgCreateFunTokenFromCoinResponse, error) {
if err := msg.ValidateBasic(); err != nil {
return nil, err
}
priv, err := ethsecp256k1.GenerateKey()
if err != nil {
return nil, err
}
newContractAddress := common.BytesToAddress(priv.PubKey().Address().Bytes())
ctx := sdk.UnwrapSDKContext(goCtx)
err = k.FunTokens.SafeInsert(ctx, newContractAddress, msg.Denom, true)
if err != nil {
return nil, err
}

_ = ctx.EventManager().EmitTypedEvent(&evm.EventCreateFunTokenFromCoin{
Creator: msg.Sender,
Denom: msg.Denom,
ContractAddress: newContractAddress.String(),
})

return &evm.MsgCreateFunTokenFromCoinResponse{NewContractAddress: newContractAddress.String()}, nil
Copy link
Member

Choose a reason for hiding this comment

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

This tx should not use a random address and should instead deploy an ERC20 based on the coin metadata and use its address

@onikonychev onikonychev closed this Jul 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants