Skip to content

Commit db7fef8

Browse files
vladjdkreecepbcups
andauthored
feat!: permissionless erc20 registration (#84)
* feat: permissionless erc20 registration * lints * use non-gov signer * fix proto --------- Co-authored-by: Reece Williams <reecepbcups@gmail.com>
1 parent 07f2a66 commit db7fef8

File tree

11 files changed

+258
-222
lines changed

11 files changed

+258
-222
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
### FEATURES
2020

2121
- [\#69](https://github.com/cosmos/evm/pull/69) Add new `x/precisebank` module with bank decimal extension for EVM usage.
22+
- [\#84](https://github.com/cosmos/evm/pull/84) permissionless erc20 registration to cosmos coin conversion
2223

2324
### STATE BREAKING
2425

api/cosmos/evm/erc20/v1/tx.pulsar.go

Lines changed: 148 additions & 145 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proto/cosmos/evm/erc20/v1/tx.proto

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ message MsgConvertERC20 {
5555
(amino.dont_omitempty) = true
5656
];
5757
// receiver is the bech32 address to receive native Cosmos coins
58-
string receiver = 3;
58+
string receiver = 3 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
5959
// sender is the hex address from the owner of the given ERC20 tokens
6060
string sender = 4;
6161
}
@@ -74,7 +74,7 @@ message MsgConvertCoin {
7474
string receiver = 2;
7575
// sender is the cosmos bech32 address from the owner of the given Cosmos
7676
// coins
77-
string sender = 3;
77+
string sender = 3 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
7878
}
7979

8080
// MsgConvertCoinResponse returns no fields
@@ -104,10 +104,10 @@ message MsgUpdateParamsResponse {}
104104
// an Erc20 contract token pair.
105105
message MsgRegisterERC20 {
106106
option (amino.name) = "cosmos/evm/x/erc20/MsgRegisterERC20";
107-
option (cosmos.msg.v1.signer) = "authority";
107+
option (cosmos.msg.v1.signer) = "signer";
108108

109-
// authority is the address of the governance account.
110-
string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
109+
// signer is the address registering the erc20 pairs
110+
string signer = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
111111

112112
// erc20addresses is a slice of ERC20 token contract hex addresses
113113
repeated string erc20addresses = 2;

tests/ibc/helper.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func SetupNativeErc20(t *testing.T, chain *evmibctesting.TestChain) *NativeErc20
4949

5050
// Register the contract
5151
_, err = evmApp.Erc20Keeper.RegisterERC20(evmCtx, &erc20types.MsgRegisterERC20{
52-
Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(),
52+
Signer: authtypes.NewModuleAddress(govtypes.ModuleName).String(), // does not have to be gov
5353
Erc20Addresses: []string{contractAddr.Hex()},
5454
})
5555
if err != nil {

testutil/integration/os/utils/erc20.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func RegisterERC20(tf factory.TxFactory, network network.Network, data ERC20Regi
5858
}
5959

6060
proposal := erc20types.MsgRegisterERC20{
61-
Authority: authtypes.NewModuleAddress("gov").String(),
61+
Signer: authtypes.NewModuleAddress("gov").String(),
6262
Erc20Addresses: data.Addresses,
6363
}
6464

x/erc20/client/cli/tx.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ func NewTxCmd() *cobra.Command {
3030
txCmd.AddCommand(
3131
NewConvertCoinCmd(),
3232
NewConvertERC20Cmd(),
33+
NewMsgRegisterERC20Cmd(),
3334
)
3435
return txCmd
3536
}
@@ -127,3 +128,33 @@ func NewConvertCoinCmd() *cobra.Command {
127128
flags.AddTxFlagsToCmd(cmd)
128129
return cmd
129130
}
131+
132+
func NewMsgRegisterERC20Cmd() *cobra.Command {
133+
cmd := &cobra.Command{
134+
Use: "register-erc20 [CONTRACT_ADDRESS...]",
135+
Short: "Register a native ERC20 token",
136+
Args: cobra.MinimumNArgs(1),
137+
RunE: func(cmd *cobra.Command, args []string) error {
138+
cliCtx, err := client.GetClientTxContext(cmd)
139+
if err != nil {
140+
return err
141+
}
142+
143+
for _, contract := range args {
144+
if err := cosmosevmtypes.ValidateAddress(contract); err != nil {
145+
return fmt.Errorf("invalid ERC20 contract address %w", err)
146+
}
147+
}
148+
149+
msg := &types.MsgRegisterERC20{
150+
Signer: cliCtx.GetFromAddress().String(),
151+
Erc20Addresses: args,
152+
}
153+
154+
return tx.GenerateOrBroadcastTxCLI(cliCtx, cmd.Flags(), msg)
155+
},
156+
}
157+
158+
flags.AddTxFlagsToCmd(cmd)
159+
return cmd
160+
}

x/erc20/keeper/msg_server.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -315,20 +315,15 @@ func (k *Keeper) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams)
315315
return &types.MsgUpdateParamsResponse{}, nil
316316
}
317317

318-
// RegisterERC20 implements the gRPC MsgServer interface. After a successful governance vote
319-
// it updates creates the token pair for an ERC20 contract if the requested authority
320-
// is the Cosmos SDK governance module account
318+
// RegisterERC20 implements the gRPC MsgServer interface. Any account can permissionlessly
319+
// register a native ERC20 contract to map to a Cosmos Coin.
321320
func (k *Keeper) RegisterERC20(goCtx context.Context, req *types.MsgRegisterERC20) (*types.MsgRegisterERC20Response, error) {
322321
ctx := sdk.UnwrapSDKContext(goCtx)
323322
// Check if the conversion is globally enabled
324323
if !k.IsERC20Enabled(ctx) {
325324
return nil, types.ErrERC20Disabled.Wrap("registration is currently disabled by governance")
326325
}
327326

328-
if err := k.validateAuthority(req.Authority); err != nil {
329-
return nil, err
330-
}
331-
332327
for _, addr := range req.Erc20Addresses {
333328
if !common.IsHexAddress(addr) {
334329
return nil, errortypes.ErrInvalidAddress.Wrapf("invalid ERC20 contract address: %s", addr)

x/erc20/keeper/proposals_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ func (suite *KeeperTestSuite) TestRegisterERC20() {
166166
tc.malleate()
167167

168168
_, err = suite.network.App.Erc20Keeper.RegisterERC20(ctx, &types.MsgRegisterERC20{
169-
Authority: authtypes.NewModuleAddress("gov").String(),
169+
Signer: suite.keyring.GetAccAddr(0).String(),
170170
Erc20Addresses: []string{contractAddr.Hex()},
171171
})
172172
metadata, found := suite.network.App.BankKeeper.GetDenomMetaData(ctx, coinName)

x/erc20/types/msg.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ func (m MsgUpdateParams) GetSignBytes() []byte {
100100

101101
// ValidateBasic does a sanity check of the provided data
102102
func (m *MsgRegisterERC20) ValidateBasic() error {
103+
_, err := sdk.AccAddressFromBech32(m.Signer)
104+
if err != nil {
105+
return errorsmod.Wrap(err, "invalid signer address")
106+
}
107+
103108
for _, addr := range m.Erc20Addresses {
104109
if !common.IsHexAddress(addr) {
105110
return errortypes.ErrInvalidAddress.Wrapf("invalid ERC20 contract address: %s", addr)

x/erc20/types/tx.pb.go

Lines changed: 62 additions & 61 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)