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

ENG 450 feesplit state machine audit #715

Merged
merged 45 commits into from
Jul 6, 2022
Merged

Conversation

danburck
Copy link
Contributor

@danburck danburck commented Jun 23, 2022

Description

This PR adds improvements from performing a state machine audit on the x/feesplit module. Here are some changes to point out:

Module rename

x/fees -> x/feesplit

KV store Changes

fee_split_prefix | contract_address -> fees
deployer_prefix | deployer_address | contract_address -> byte{1}
withdraw_prefix | withdraw_address | contract_address -> byte{1}

UpdateFee msg

Sets withdraw address to "" if the withdraw address is empty or the same as deployer address

Closes ENG-450: https://linear.app/evmos/issue/ENG-450/state-machine-audit

x/fees/keeper/msg_server.go Outdated Show resolved Hide resolved
x/fees/keeper/msg_server.go Outdated Show resolved Hide resolved
x/fees/keeper/grpc_query.go Outdated Show resolved Hide resolved
x/fees/keeper/grpc_query.go Outdated Show resolved Hide resolved
x/fees/keeper/evm_hooks.go Outdated Show resolved Hide resolved
x/fees/keeper/evm_hooks.go Outdated Show resolved Hide resolved
x/fees/keeper/fees.go Outdated Show resolved Hide resolved
x/fees/keeper/fees.go Outdated Show resolved Hide resolved
x/fees/genesis.go Outdated Show resolved Hide resolved
@danburck danburck marked this pull request as ready for review June 24, 2022 17:56
x/fees/genesis.go Outdated Show resolved Hide resolved
x/fees/keeper/evm_hooks.go Outdated Show resolved Hide resolved
x/fees/keeper/msg_server_test.go Show resolved Hide resolved
@codecov
Copy link

codecov bot commented Jun 25, 2022

Codecov Report

Merging #715 (f356dfe) into main (877683c) will decrease coverage by 0.21%.
The diff coverage is 90.13%.

❗ Current head f356dfe differs from pull request most recent head be9932d. Consider uploading reports for the commit be9932d to get more accurate results

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #715      +/-   ##
==========================================
- Coverage   81.50%   81.29%   -0.22%     
==========================================
  Files         123      123              
  Lines        7013     7120     +107     
==========================================
+ Hits         5716     5788      +72     
- Misses       1159     1190      +31     
- Partials      138      142       +4     
Impacted Files Coverage Δ
x/feesplit/keeper/keeper.go 100.00% <ø> (ø)
x/feesplit/keeper/params.go 100.00% <ø> (ø)
x/feesplit/types/keys.go 0.00% <0.00%> (ø)
x/feesplit/types/fee_split.go 70.96% <70.96%> (ø)
x/feesplit/types/params.go 94.64% <75.00%> (ø)
x/erc20/keeper/evm_hooks.go 88.88% <84.61%> (+0.28%) ⬆️
x/feesplit/keeper/msg_server.go 86.84% <86.84%> (ø)
x/feesplit/keeper/grpc_query.go 88.18% <88.18%> (ø)
x/feesplit/keeper/fee_splits.go 97.14% <97.14%> (ø)
app/app.go 85.21% <100.00%> (ø)
... and 6 more

Copy link
Contributor

@MalteHerrmann MalteHerrmann left a comment

Choose a reason for hiding this comment

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

Changes look good to me! Minor comments on the docs table and what I believe to be a dev line.

Thank you for incorporating several of my suggestions that fast!

app/ante/ante.go Outdated Show resolved Hide resolved
x/fees/spec/02_state.md Outdated Show resolved Hide resolved
@danburck danburck changed the title ENG 450 fees state machine audit ENG 450 feesplit state machine audit Jul 5, 2022
proto/evmos/feesplit/v1/genesis.proto Outdated Show resolved Hide resolved
data/application.db/CURRENT Outdated Show resolved Hide resolved
third_party/proto/cosmos/distribution/v1beta1/query.proto Outdated Show resolved Hide resolved
third_party/proto/cosmos/distribution/v1beta1/tx.proto Outdated Show resolved Hide resolved
x/feesplit/spec/05_hooks.md Outdated Show resolved Hide resolved
x/feesplit/spec/05_hooks.md Outdated Show resolved Hide resolved
Copy link
Contributor

@fedekunze fedekunze left a comment

Choose a reason for hiding this comment

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

LGTM, minor suggestions

third_party/proto/cosmos/distribution/v1beta1/query.proto Outdated Show resolved Hide resolved
x/feesplit/client/cli/query.go Outdated Show resolved Hide resolved
x/feesplit/client/cli/query.go Outdated Show resolved Hide resolved
x/feesplit/client/cli/tx.go Outdated Show resolved Hide resolved
x/feesplit/keeper/evm_hooks.go Outdated Show resolved Hide resolved
x/feesplit/keeper/msg_server.go Outdated Show resolved Hide resolved
x/feesplit/keeper/msg_server.go Show resolved Hide resolved
x/feesplit/keeper/msg_server_test.go Show resolved Hide resolved
x/feesplit/spec/08_clients.md Outdated Show resolved Hide resolved
@danburck danburck enabled auto-merge (squash) July 6, 2022 14:20
@danburck danburck merged commit 0d6c04b into main Jul 6, 2022
@danburck danburck deleted the ENG-450-fees-state-machine-audit branch July 6, 2022 14:37
// AfterEVMStateTransition implements the ethermint evm PostTxProcessing hook.
// PostTxProcessing is a wrapper for calling the EVM PostTxProcessing hook on
// the module keeper
func (h Hooks) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error {

Choose a reason for hiding this comment

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

Nit: would not it be more consistent if we use the prefix After instead of Post? just like what used for other hooks.

return sdkerrors.Wrapf(err, "invalid withdraw address address %s", msg.WithdrawAddress)
if msg.WithdrawerAddress != "" {
if _, err := sdk.AccAddressFromBech32(msg.WithdrawerAddress); err != nil {
return sdkerrors.Wrapf(err, "invalid withdraw address %s", msg.WithdrawerAddress)

Choose a reason for hiding this comment

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

Nit: A little typo in invalid withdraw address %s according to the new changes, it should be withdrawer, right?

Copy link
Contributor

@GAtom22 GAtom22 left a comment

Choose a reason for hiding this comment

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

LGTM! There are some cases where I believe the naming consistency is compromised. Please, check the comments left about this. Also, it would have been nicer to have this refactor broken down into 2 or 3 different PRs to make it easier for review.

Comment on lines 23 to 24

Users pay transaction fees to pay interact with smart contracts using the EVM. When a transaction is executed, the entire fee amount (`gasLimit * gasPrice`) is sent to the `FeeCollector` module account during the [Cosmos SDK AnteHandler](https://docs.cosmos.network/v0.44/modules/auth/03_antehandlers.html) execution. After the EVM executes the transaction, the user receives a refund of `(gasLimit - gasUsed) * gasPrice`. In result a user pays a total transaction fee of `txFee = gasUsed * gasPrice` for the execution.
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe there's an extra word in the first line. In the phrase "Users pay transaction fees to pay interact with smart contracts ...". Should we remove the pay there?

WithdrawAddress string `protobuf:"bytes,3,opt,name=withdraw_address,json=withdrawAddress,proto3" json:"withdraw_address,omitempty"`
WithdrawerAddress string `protobuf:"bytes,3,opt,name=withdraw_address,json=withdrawerAddress,proto3" json:"withdraw_address,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

According to the code in tx.pb.go, the tag fields name and json should also be updated to withdrawer_address. This line should be:

WithdrawerAddress string `protobuf:"bytes,3,opt,name=withdrawer_address,json=withdrawerAddress,proto3" json:"withdrawer_address,omitempty"`


// errors
var (
ErrInternalFeeSplit = sdkerrors.Register(ModuleName, 2, "internal feesplit error")
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: to keep the same naming convention as the other errors, we could change this to ErrFeeSplitInternal

@@ -0,0 +1,62 @@
package types
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: to keep the naming convention with the package name that contains this package, we could refactor this file name to feesplit.go

Comment on lines +24 to +37
// GetContractAddr returns the contract address
func (fs FeeSplit) GetContractAddr() common.Address {
return common.HexToAddress(fs.ContractAddress)
}

// GetDeployerAddr returns the contract deployer address
func (fs FeeSplit) GetDeployerAddr() sdk.AccAddress {
return sdk.MustAccAddressFromBech32(fs.DeployerAddress)
}

// GetWithdrawerAddr returns the account address to where the funds proceeding
// from the fees will be received. If the withdraw address is not defined, it
// defaults to the deployer address.
func (fs FeeSplit) GetWithdrawerAddr() sdk.AccAddress {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: according to some opinions about best practices in Golang, getter methods should be called by the field name with upper case. For example, the method name should be ContractAddr instead of GetContractAddr

req = &types.QueryFeeSplitsRequest{
Pagination: &query.PageRequest{Limit: 10, CountTotal: true},
}
feeSplit := types.NewFeeSplit(contract, deployer, withdraw)
Copy link
Contributor

Choose a reason for hiding this comment

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

Nil: refactor withdraw param to withdrawer

{
"fee info found",
func() {
feeSplit := types.NewFeeSplit(contract, deployer, withdraw)
Copy link
Contributor

Choose a reason for hiding this comment

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

Nil: Idem as above, refactor to withdrawer

contractAddress,
deployerAddress,
deployerAddress,
withdraw,
Copy link
Contributor

Choose a reason for hiding this comment

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

Nil: refactor var name to withdrawer

}

func (m *MsgRegisterFee) Marshal() (dAtA []byte, err error) {
func (m *MsgRegisterFeeSplit) Marshal() (dAtA []byte, 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.

Refactor parameter name dAtA to data for better naming consistency

@@ -860,7 +861,7 @@ func sovTx(x uint64) (n int) {
func sozTx(x uint64) (n int) {
return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *MsgRegisterFee) Unmarshal(dAtA []byte) error {
func (m *MsgRegisterFeeSplit) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor var name iNdEx to index for better naming consistency

Copy link

@K1-R1 K1-R1 left a comment

Choose a reason for hiding this comment

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

LGTM. This CL looks good to me; other than the instances of naming inconsistency already pointed out above, I only additionally identified some minor grammar corrections in the docs.

@@ -23,7 +23,7 @@ As described above, developers will earn a portion of the transaction fee after

Copy link

Choose a reason for hiding this comment

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

Nit: docs grammar for Fee Distribution (not in CL);
The registration of factory contracts (smart contracts that have been deployed by other contracts) requires the identification of the original contract's deployer. This is done through address derivation.

@@ -23,7 +23,7 @@ As described above, developers will earn a portion of the transaction fee after

Users pay transaction fees to pay interact with smart contracts using the EVM. When a transaction is executed, the entire fee amount (`gasLimit * gasPrice`) is sent to the `FeeCollector` module account during the [Cosmos SDK AnteHandler](https://docs.cosmos.network/v0.44/modules/auth/03_antehandlers.html) execution. After the EVM executes the transaction, the user receives a refund of `(gasLimit - gasUsed) * gasPrice`. In result a user pays a total transaction fee of `txFee = gasUsed * gasPrice` for the execution.

This transaction fee is distributed between developers and validators, in accordance with the `x/fees` module parameters: `DeveloperShares`, `ValidatorShares`. This distribution is handled through the EVM's [`PostTxProcessing` Hook](./05_hooks.md).
This transaction fee is distributed between developers and validators, in accordance with the `x/feesplit` module parameters: `DeveloperShares`, `ValidatorShares`. This distribution is handled through the EVM's [`PostTxProcessing` Hook](./05_hooks.md).

### Address Derivation

Copy link

Choose a reason for hiding this comment

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

Nit: docs grammar for Address Derivation (not in CL);
In both cases, the fee distribution requires the identification of a deployer address that is an EOA address, unless a withdrawal address is set by the contract deployer during registration to receive transaction fees for a registered smart contract.

@@ -6,19 +6,19 @@ order: 4

This section defines the `sdk.Msg` concrete types that result in the state transitions defined on the previous section.
Copy link

Choose a reason for hiding this comment

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

Nit: docs grammar for intro;
This section defines the sdk.Msg concrete types that result in the state transitions defined in the previous section.

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.

7 participants