Skip to content

Commit

Permalink
feat: msg update withdraw fee (#929)
Browse files Browse the repository at this point in the history
* make smoketest work

* smoketest: add test for context in depositAndCall

* add missing files

* add Update System Contract Address msg

and smoketest

* fix linter complaints

* fix openapi

* fix gosec complaint and CI config

* fix linter config

* fix generated file check fail

* try fix CI config

* address PR comments

* add typed events

* migrate one more event to typed event

* cleanup fixme

* update protocol-contract package to latest main branch

* Update x/fungible/keeper/evm.go

Co-authored-by: Lucas Bertrand <[email protected]>

* PR comments address: error types

* re-generate go.sum

* add msg & handler for MsgUpdateZRC20WithdrawFee

* add smoketest for this

* rename protobuf field

* add missing file

* fix linter complaints

---------

Co-authored-by: brewmaster012 <>
Co-authored-by: Lucas Bertrand <[email protected]>
  • Loading branch information
brewmaster012 and lumtis authored Aug 10, 2023
1 parent 4321846 commit 64a8d53
Show file tree
Hide file tree
Showing 13 changed files with 1,160 additions and 72 deletions.
2 changes: 2 additions & 0 deletions docs/openapi/openapi.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50409,6 +50409,8 @@ definitions:
type: object
fungibleMsgUpdateSystemContractResponse:
type: object
fungibleMsgUpdateZRC20WithdrawFeeResponse:
type: object
fungibleQueryAllForeignCoinsResponse:
type: object
properties:
Expand Down
12 changes: 11 additions & 1 deletion docs/spec/fungible/messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,17 @@ message MsgRemoveForeignCoin {
```proto
message MsgUpdateSystemContract {
string creator = 1;
string newSystemContractAddress = 2;
string new_system_contract_address = 2;
}
```

## MsgUpdateZRC20WithdrawFee

```proto
message MsgUpdateZRC20WithdrawFee {
string creator = 1;
string zrc20_address = 2;
string new_withdraw_fee = 6;
}
```

10 changes: 10 additions & 0 deletions proto/fungible/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,14 @@ message EventZRC20Deployed {
common.CoinType coin_type = 7;
string erc20 = 8;
int64 gasLimit = 9;
}

message EventZRC20WithdrawFeeUpdated {
string msg_type_url = 1;
int64 chain_id = 2;
common.CoinType coin_type = 3;
string zrc20_address = 4;
string old_withdraw_fee = 5;
string new_withdraw_fee = 6;
string signer = 7;
}
15 changes: 14 additions & 1 deletion proto/fungible/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ syntax = "proto3";
package zetachain.zetacore.fungible;

import "common/common.proto";
import "gogoproto/gogo.proto";

option go_package = "github.com/zeta-chain/zetacore/x/fungible/types";

Expand All @@ -10,11 +11,23 @@ service Msg {
rpc DeployFungibleCoinZRC20(MsgDeployFungibleCoinZRC20) returns (MsgDeployFungibleCoinZRC20Response);
rpc RemoveForeignCoin(MsgRemoveForeignCoin) returns (MsgRemoveForeignCoinResponse);
rpc UpdateSystemContract(MsgUpdateSystemContract) returns (MsgUpdateSystemContractResponse);
rpc UpdateZRC20WithdrawFee(MsgUpdateZRC20WithdrawFee) returns (MsgUpdateZRC20WithdrawFeeResponse);
}

message MsgUpdateZRC20WithdrawFee {
string creator = 1;
string zrc20_address = 2; // zrc20 address
string new_withdraw_fee = 6 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Uint",
(gogoproto.nullable) = false
];
}

message MsgUpdateZRC20WithdrawFeeResponse {}

message MsgUpdateSystemContract {
string creator = 1;
string newSystemContractAddress = 2;
string new_system_contract_address = 2;
}

message MsgUpdateSystemContractResponse {}
Expand Down
5 changes: 4 additions & 1 deletion x/fungible/keeper/begin_blocker_deploy_system_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import (
func (k Keeper) BlockOneDeploySystemContracts(goCtx context.Context) error {
return nil
}
func (k Keeper) UpdateSystemContractAddress(goCtx context.Context) error {
func (k Keeper) TestUpdateSystemContractAddress(goCtx context.Context) error {
return nil
}
func (k Keeper) TestUpdateZRC20WithdrawFee(goCtx context.Context) error {
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func (k Keeper) BlockOneDeploySystemContracts(goCtx context.Context) error {
return nil
}

func (k Keeper) UpdateSystemContractAddress(goCtx context.Context) error {
func (k Keeper) TestUpdateSystemContractAddress(goCtx context.Context) error {
ctx := sdk.UnwrapSDKContext(goCtx)

wzeta, err := k.GetWZetaContractAddress(ctx)
Expand All @@ -135,3 +135,20 @@ func (k Keeper) UpdateSystemContractAddress(goCtx context.Context) error {
_, err = k.UpdateSystemContract(ctx, msg)
return err
}

func (k Keeper) TestUpdateZRC20WithdrawFee(goCtx context.Context) error {
ctx := sdk.UnwrapSDKContext(goCtx)

foreignCoins := k.GetAllForeignCoins(ctx)
creator := k.zetaobserverKeeper.GetParams(ctx).GetAdminPolicyAccount(observertypes.Policy_Type_deploy_fungible_coin)

for _, foreignCoin := range foreignCoins {
msg := types.NewMsgUpdateZRC20WithdrawFee(creator, foreignCoin.Zrc20ContractAddress, sdk.NewUint(uint64(foreignCoin.ForeignChainId)))
_, err := k.UpdateZRC20WithdrawFee(ctx, msg)
if err != nil {
return err
}
}

return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ func (k Keeper) BlockOneDeploySystemContracts(goCtx context.Context) error {
return nil
}

func (k Keeper) UpdateSystemContractAddress(goCtx context.Context) error {
func (k Keeper) TestUpdateSystemContractAddress(goCtx context.Context) error {
return nil
}

func (k Keeper) TestUpdateZRC20WithdrawFee(goCtx context.Context) error {
return nil
}
2 changes: 1 addition & 1 deletion x/fungible/keeper/msg_server_update_system_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ func (k Keeper) UpdateSystemContract(goCtx context.Context, msg *types.MsgUpdate
oldSystemContractAddress := sys.SystemContract
sys.SystemContract = newSystemContractAddr.Hex()
k.SetSystemContract(ctx, sys)
commit()
err = ctx.EventManager().EmitTypedEvent(
&types.EventSystemContractUpdated{
MsgTypeUrl: sdk.MsgTypeURL(&types.MsgUpdateSystemContract{}),
Expand All @@ -77,5 +76,6 @@ func (k Keeper) UpdateSystemContract(goCtx context.Context, msg *types.MsgUpdate
k.Logger(ctx).Error("failed to emit event", "error", err.Error())
return nil, sdkerrors.Wrapf(types.ErrEmitEvent, "failed to emit event (%s)", err.Error())
}
commit()
return &types.MsgUpdateSystemContractResponse{}, nil
}
84 changes: 84 additions & 0 deletions x/fungible/keeper/msg_server_update_zrc20_withdraw_fee.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package keeper

import (
"context"
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol"
"github.com/zeta-chain/zetacore/x/fungible/types"
zetaObserverTypes "github.com/zeta-chain/zetacore/x/observer/types"
)

func (k Keeper) UpdateZRC20WithdrawFee(goCtx context.Context, msg *types.MsgUpdateZRC20WithdrawFee) (*types.MsgUpdateZRC20WithdrawFeeResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
if msg.Creator != k.zetaobserverKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_deploy_fungible_coin) {
return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Deploy can only be executed by the correct policy account")
}
zrc20Addr := ethcommon.HexToAddress(msg.Zrc20Address)
if zrc20Addr == (ethcommon.Address{}) {
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid zrc20 contract address (%s)", msg.Zrc20Address)
}

// update contracts
zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi()
if err != nil {
return nil, sdkerrors.Wrapf(types.ErrABIGet, "failed to get zrc20 abi")
}

foreignCoins := k.GetAllForeignCoins(ctx)
found := false
var coin types.ForeignCoins
for _, fcoin := range foreignCoins {
coinZRC20Addr := ethcommon.HexToAddress(fcoin.Zrc20ContractAddress)
if coinZRC20Addr == (ethcommon.Address{}) {
k.Logger(ctx).Error("invalid zrc20 contract address", "address", fcoin.Zrc20ContractAddress)
continue
}
if coinZRC20Addr == zrc20Addr {
coin = fcoin
found = true
break
}
}

if !found {
return nil, sdkerrors.Wrapf(types.ErrInvalidAddress, "no foreign coin match requested zrc20 address (%s)", msg.Zrc20Address)
}

res, err := k.CallEVM(ctx, *zrc20ABI, types.ModuleAddressEVM, zrc20Addr, BigIntZero, nil, false, "PROTOCOL_FLAT_FEE")
if err != nil {
return nil, sdkerrors.Wrapf(types.ErrContractCall, "failed to call zrc20 contract PROTOCOL_FLAT_FEE method (%s)", err.Error())
}
unpacked, err := zrc20ABI.Unpack("PROTOCOL_FLAT_FEE", res.Ret)
if err != nil || len(unpacked) == 0 {
return nil, sdkerrors.Wrapf(types.ErrContractCall, "failed to unpack zrc20 contract PROTOCOL_FLAT_FEE method (%s)", err.Error())
}
oldWithdrawFee, ok := unpacked[0].(*big.Int)
if !ok {
return nil, sdkerrors.Wrapf(types.ErrContractCall, "failed to interpret the returned unpacked zrc20 contract PROTOCOL_FLAT_FEE method; ret %x", res.Ret)
}

tmpCtx, commit := ctx.CacheContext()
_, err = k.CallEVM(tmpCtx, *zrc20ABI, types.ModuleAddressEVM, zrc20Addr, BigIntZero, nil, true, "updateProtocolFlatFee", msg.NewWithdrawFee.BigInt())

err = ctx.EventManager().EmitTypedEvent(
&types.EventZRC20WithdrawFeeUpdated{
MsgTypeUrl: sdk.MsgTypeURL(&types.MsgUpdateZRC20WithdrawFee{}),
ChainId: coin.ForeignChainId,
CoinType: coin.CoinType,
Zrc20Address: zrc20Addr.Hex(),
OldWithdrawFee: oldWithdrawFee.String(),
NewWithdrawFee: msg.NewWithdrawFee.BigInt().String(),
Signer: msg.Creator,
},
)
if err != nil {
k.Logger(ctx).Error("failed to emit event", "error", err.Error())
return nil, sdkerrors.Wrapf(types.ErrEmitEvent, "failed to emit event (%s)", err.Error())
}
commit()
return &types.MsgUpdateZRC20WithdrawFeeResponse{}, nil
}
11 changes: 10 additions & 1 deletion x/fungible/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,23 @@ func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {
ctx.Logger().Error("Unable To deploy contracts", "err", err.Error())
}
}

if ctx.BlockHeight() == 20 {
err := am.keeper.UpdateSystemContractAddress(sdk.WrapSDKContext(ctx))
err := am.keeper.TestUpdateSystemContractAddress(sdk.WrapSDKContext(ctx))
if err != nil {
ctx.Logger().Error("Unable To update system contracts", "err", err.Error())
} else {
ctx.Logger().Info("System contract updated")
}
}
if ctx.BlockHeight() == 25 {
err := am.keeper.TestUpdateZRC20WithdrawFee(sdk.WrapSDKContext(ctx))
if err != nil {
ctx.Logger().Error("Unable To update zrc20 withdraw fee", "err", err.Error())
} else {
ctx.Logger().Info("zrc20 withdraw fee updated")
}
}
}

// EndBlock executes all ABCI EndBlock logic respective to the fungible module. It
Expand Down
Loading

0 comments on commit 64a8d53

Please sign in to comment.