-
Notifications
You must be signed in to change notification settings - Fork 834
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
fix(str): Apply changes from internal audit #2476
fix(str): Apply changes from internal audit #2476
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @ramacarlucho!!
Please, address linter issues
Also, tests are failing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Left some nits, pending passing tests.
x/erc20/keeper/msg_server.go
Outdated
) | ||
|
||
return &types.MsgConvertERC20Response{}, nil | ||
return nil, types.ErrUndefinedOwner | ||
} | ||
|
||
// convertERC20NativeToken handles the erc20 conversion for a native erc20 token |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment needs to be updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Great work @ramacarlucho!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @ramacarlucho! 🙏 left some comments
x/erc20/keeper/msg_server.go
Outdated
if pair.IsNativeERC20() { | ||
return k.convertERC20IntoCoinsForNativeToken(ctx, pair, msg, receiver, sender) // case 2.1 | ||
} | ||
|
||
// Check expected receiver balance after transfer | ||
balanceCoinAfter := k.bankKeeper.GetBalance(ctx, receiver, pair.Denom) | ||
expCoin := balanceCoin.Add(coins[0]) | ||
if ok := balanceCoinAfter.IsEqual(expCoin); !ok { | ||
return nil, errorsmod.Wrapf( | ||
types.ErrBalanceInvariance, | ||
"invalid coin balance - expected: %v, actual: %v", | ||
expCoin, balanceCoinAfter, | ||
) | ||
} | ||
|
||
// Check expected Sender balance after transfer | ||
tokens := coins[0].Amount.BigInt() | ||
balanceTokenAfter := k.BalanceOf(ctx, erc20, contract, sender) | ||
if balanceTokenAfter == nil { | ||
return nil, errorsmod.Wrap(types.ErrEVMCall, "failed to retrieve balance") | ||
} | ||
|
||
expToken := big.NewInt(0).Sub(balanceToken, tokens) | ||
if r := balanceTokenAfter.Cmp(expToken); r != 0 { | ||
return nil, errorsmod.Wrapf( | ||
types.ErrBalanceInvariance, | ||
"invalid token balance - expected: %v, actual: %v", | ||
expToken, balanceTokenAfter, | ||
) | ||
} | ||
|
||
defer func() { | ||
telemetry.IncrCounterWithLabels( | ||
[]string{"tx", "msg", "convert", "erc20", "total"}, | ||
1, | ||
[]metrics.Label{ | ||
telemetry.NewLabel("denom", pair.Denom), | ||
}, | ||
) | ||
|
||
if msg.Amount.IsInt64() { | ||
telemetry.IncrCounterWithLabels( | ||
[]string{"tx", "msg", "convert", "erc20", "amount", "total"}, | ||
float32(msg.Amount.Int64()), | ||
[]metrics.Label{ | ||
telemetry.NewLabel("denom", pair.Denom), | ||
}, | ||
) | ||
} | ||
}() | ||
|
||
ctx.EventManager().EmitEvents( | ||
sdk.Events{ | ||
sdk.NewEvent( | ||
types.EventTypeConvertERC20, | ||
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), | ||
sdk.NewAttribute(types.AttributeKeyReceiver, msg.Receiver), | ||
sdk.NewAttribute(sdk.AttributeKeyAmount, msg.Amount.String()), | ||
sdk.NewAttribute(types.AttributeKeyCosmosCoin, pair.Denom), | ||
sdk.NewAttribute(types.AttributeKeyERC20Token, msg.ContractAddress), | ||
), | ||
}, | ||
) | ||
|
||
return &types.MsgConvertERC20Response{}, nil | ||
return nil, types.ErrUndefinedOwner |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the error raised in case it's not a native ERC-20 is incorrect for the native coins, because it claims that the owner is undefined.
We should rather check if it's not an ERC-20 and then return a corresponding error:
if pair.IsNativeERC20() { | |
return k.convertERC20IntoCoinsForNativeToken(ctx, pair, msg, receiver, sender) // case 2.1 | |
} | |
// Check expected receiver balance after transfer | |
balanceCoinAfter := k.bankKeeper.GetBalance(ctx, receiver, pair.Denom) | |
expCoin := balanceCoin.Add(coins[0]) | |
if ok := balanceCoinAfter.IsEqual(expCoin); !ok { | |
return nil, errorsmod.Wrapf( | |
types.ErrBalanceInvariance, | |
"invalid coin balance - expected: %v, actual: %v", | |
expCoin, balanceCoinAfter, | |
) | |
} | |
// Check expected Sender balance after transfer | |
tokens := coins[0].Amount.BigInt() | |
balanceTokenAfter := k.BalanceOf(ctx, erc20, contract, sender) | |
if balanceTokenAfter == nil { | |
return nil, errorsmod.Wrap(types.ErrEVMCall, "failed to retrieve balance") | |
} | |
expToken := big.NewInt(0).Sub(balanceToken, tokens) | |
if r := balanceTokenAfter.Cmp(expToken); r != 0 { | |
return nil, errorsmod.Wrapf( | |
types.ErrBalanceInvariance, | |
"invalid token balance - expected: %v, actual: %v", | |
expToken, balanceTokenAfter, | |
) | |
} | |
defer func() { | |
telemetry.IncrCounterWithLabels( | |
[]string{"tx", "msg", "convert", "erc20", "total"}, | |
1, | |
[]metrics.Label{ | |
telemetry.NewLabel("denom", pair.Denom), | |
}, | |
) | |
if msg.Amount.IsInt64() { | |
telemetry.IncrCounterWithLabels( | |
[]string{"tx", "msg", "convert", "erc20", "amount", "total"}, | |
float32(msg.Amount.Int64()), | |
[]metrics.Label{ | |
telemetry.NewLabel("denom", pair.Denom), | |
}, | |
) | |
} | |
}() | |
ctx.EventManager().EmitEvents( | |
sdk.Events{ | |
sdk.NewEvent( | |
types.EventTypeConvertERC20, | |
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender), | |
sdk.NewAttribute(types.AttributeKeyReceiver, msg.Receiver), | |
sdk.NewAttribute(sdk.AttributeKeyAmount, msg.Amount.String()), | |
sdk.NewAttribute(types.AttributeKeyCosmosCoin, pair.Denom), | |
sdk.NewAttribute(types.AttributeKeyERC20Token, msg.ContractAddress), | |
), | |
}, | |
) | |
return &types.MsgConvertERC20Response{}, nil | |
return nil, types.ErrUndefinedOwner | |
if !pair.IsNativeERC20() { | |
return nil, errors.New("converting erc-20s to coins is only supported for native erc-20 tokens") | |
} | |
return k.convertERC20IntoCoinsForNativeToken(ctx, pair, msg, receiver, sender) |
We also need to delete or adjust the ErrUndefinedOwner
in the types if it's not used somewhere else
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ErrUndefinedOwner is used when its an empty token pair.
x/erc20/keeper/msg_server.go
Outdated
// Remove token pair if contract is suicided | ||
acc := k.evmKeeper.GetAccountWithoutBalance(ctx, pair.GetERC20Contract()) | ||
if acc == nil || !acc.IsContract() { | ||
k.DeleteTokenPair(ctx, pair) | ||
k.Logger(ctx).Debug( | ||
"deleting selfdestructed token pair from state", | ||
"contract", pair.Erc20Address, | ||
) | ||
// NOTE: return nil error to persist the changes from the deletion | ||
return nil, nil | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm IMO this should remain on the higher level of abstraction in ConvertERC20
- was there a specific reason to move it into this method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved it outside the function, but inside the pair.IsNativeERC20
check to garantee safety
x/erc20/keeper/msg_server.go
Outdated
@@ -210,6 +105,8 @@ func (k Keeper) convertERC20NativeToken( | |||
} | |||
|
|||
// Check expected escrow balance after transfer execution | |||
// NOTE: coin fields already validated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: would be good to mention where it was validated
// NOTE: coin fields already validated | |
// NOTE: coin fields already validated in the ValidateBasic() of the message |
@@ -34,23 +35,24 @@ func TestPrecompileTestSuite(t *testing.T) { | |||
|
|||
func (s *PrecompileTestSuite) SetupTest() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not possible for me to comment in that line but in line 20 of this file there is: var _ *PrecompileTestSuite
which we should remove I think
|
||
err = evmosutils.FundAccountWithBaseDenom(s.unitNetwork.GetContext(), s.unitNetwork.App.BankKeeper, sender, 1000000000000000000) | ||
s.Require().NoError(err, "failed to fund account") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this necessary? We should rather set up the test suite with enough funds or adjust the test case to make use of the existing balance I think - also not sure where this amount comes from, why exactly 1000000000000000000?
precompiles/bank/setup_test.go
Outdated
@@ -32,7 +32,7 @@ type PrecompileTestSuite struct { | |||
network *network.UnitTestNetwork | |||
factory factory.TxFactory | |||
grpcHandler grpc.Handler | |||
keyring testkeyring.Keyring |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would leave this as it was, when renaming the import we are shadowing the import name with the keyring
variable below
keyring testkeyring.Keyring | |
keyring testkeyring.Keyring |
6d5d101
into
Vvaradinov/feat-strv2-feature-branch
Description
Closes: EVM-63
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...
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...
Unreleased
section inCHANGELOG.md