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: implement MsgUpdateERC20CustodyPauseStatus to pause or unpause ERC20 Custody #2681

Merged
merged 35 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2a026cd
refactor cmd cctx creation
lumtis Aug 4, 2024
45f5a1d
initialize migrate funds message
lumtis Aug 4, 2024
fb389f8
implement migrate message
lumtis Aug 4, 2024
c4462a1
zetaclient implementation
lumtis Aug 4, 2024
d00a1db
fix event
lumtis Aug 5, 2024
497ff84
fix params
lumtis Aug 5, 2024
e30a31c
add e2e test
lumtis Aug 5, 2024
fc28be0
generate
lumtis Aug 5, 2024
3db77d2
changelog
lumtis Aug 5, 2024
a7253be
zetaclient test
lumtis Aug 5, 2024
3d6e11e
fix message test
lumtis Aug 5, 2024
9128af7
initialize cctx test
lumtis Aug 5, 2024
7c2a29e
cmd cctx type tests
lumtis Aug 5, 2024
eba8c00
message test
lumtis Aug 6, 2024
e93d861
conflicts
lumtis Aug 6, 2024
719d44e
Update zetaclient/chains/evm/signer/admin_cmd.go
lumtis Aug 12, 2024
8d08528
tanmay comments
lumtis Aug 12, 2024
4a1d9ed
stefan comments
lumtis Aug 12, 2024
c6898fd
admin commands
lumtis Aug 12, 2024
bad8fb6
changelogs
lumtis Aug 12, 2024
5f2bb5f
make generate
lumtis Aug 12, 2024
9153d1f
initialize message
lumtis Aug 12, 2024
e315994
some message fixes
lumtis Aug 12, 2024
01f6ce3
implement logic on ZetaClient
lumtis Aug 12, 2024
d71fdda
update pause status
lumtis Aug 12, 2024
b2d8d4a
add in authorization list
lumtis Aug 12, 2024
d081561
E2E test
lumtis Aug 12, 2024
eab6e3a
add test in admin workflow
lumtis Aug 12, 2024
63b7baa
add event for pausing
lumtis Aug 12, 2024
7a381d2
changelogs
lumtis Aug 12, 2024
2dcb35e
Update x/crosschain/types/cmd_cctxs.go
lumtis Aug 12, 2024
11142ed
Update x/crosschain/types/cmd_cctxs.go
lumtis Aug 12, 2024
b83adb8
conflicts
lumtis Aug 15, 2024
769f048
fix
lumtis Aug 15, 2024
12e02dc
remove rate limiter test
lumtis Aug 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* [2634](https://github.com/zeta-chain/node/pull/2634) - add support for EIP-1559 gas fees
* [2597](https://github.com/zeta-chain/node/pull/2597) - Add generic rpc metrics to zetaclient
* [2538](https://github.com/zeta-chain/node/pull/2538) - add background worker routines to shutdown zetaclientd when needed for tss migration
* [2681](https://github.com/zeta-chain/node/pull/2681) - implement `MsgUpdateERC20CustodyPauseStatus` to pause or unpause ERC20 Custody contract (to be used for the migration process for smart contract V2)
* [2644](https://github.com/zeta-chain/node/pull/2644) - add created_timestamp to cctx status

### Refactor
Expand Down
8 changes: 7 additions & 1 deletion cmd/zetae2e/local/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,14 +296,20 @@ func localE2ETest(cmd *cobra.Command, _ []string) {
if testAdmin {
eg.Go(adminTestRoutine(conf, deployerRunner, verbose,
e2etests.TestWhitelistERC20Name,
e2etests.TestRateLimiterName,
e2etests.TestPauseZRC20Name,
e2etests.TestUpdateBytecodeZRC20Name,
e2etests.TestUpdateBytecodeConnectorName,
e2etests.TestDepositEtherLiquidityCapName,
e2etests.TestCriticalAdminTransactionsName,
e2etests.TestPauseERC20CustodyName,
e2etests.TestMigrateERC20CustodyFundsName,

// Test the rate limiter functionalities
// this test is currently incomplete and takes 10m to run
// TODO: define assertion, and make more optimized
// https://github.com/zeta-chain/node/issues/2090
//e2etests.TestRateLimiterName,

// TestMigrateChainSupportName tests EVM chain migration. Currently this test doesn't work with Anvil because pre-EIP1559 txs are not supported
// See issue below for details
// TODO: renenable this test as per the issue below
Expand Down
5 changes: 5 additions & 0 deletions docs/openapi/openapi.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57242,6 +57242,11 @@ definitions:
type: object
crosschainMsgRemoveOutboundTrackerResponse:
type: object
crosschainMsgUpdateERC20CustodyPauseStatusResponse:
type: object
properties:
cctx_index:
type: string
crosschainMsgUpdateRateLimiterFlagsResponse:
type: object
crosschainMsgUpdateTssAddressResponse:
Expand Down
12 changes: 12 additions & 0 deletions docs/spec/crosschain/messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,3 +286,15 @@ message MsgMigrateERC20CustodyFunds {
}
```

## MsgUpdateERC20CustodyPauseStatus

UpdateERC20CustodyPauseStatus creates a admin cmd cctx to update the pause status of the ERC20 custody contract

```proto
message MsgUpdateERC20CustodyPauseStatus {
string creator = 1;
int64 chain_id = 2;
bool pause = 3;
}
```

10 changes: 8 additions & 2 deletions e2e/e2etests/e2etests.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ const (
TestUpdateBytecodeConnectorName = "update_bytecode_connector"
TestRateLimiterName = "rate_limiter"
TestCriticalAdminTransactionsName = "critical_admin_transactions"
TestPauseERC20CustodyName = "pause_erc20_custody"
TestMigrateERC20CustodyFundsName = "migrate_erc20_custody_funds"

TestMigrateTSSName = "migrate_TSS"
TestMigrateTSSName = "migrate_TSS"

/*
Special tests
Expand Down Expand Up @@ -573,6 +573,12 @@ var AllE2ETests = []runner.E2ETest{
[]runner.ArgDefinition{},
TestCriticalAdminTransactions,
),
runner.NewE2ETest(
TestPauseERC20CustodyName,
"pausing ERC20 custody on ZetaChain",
[]runner.ArgDefinition{},
TestPauseERC20Custody,
),
runner.NewE2ETest(
TestMigrateERC20CustodyFundsName,
"migrate ERC20 custody funds",
Expand Down
81 changes: 81 additions & 0 deletions e2e/e2etests/test_pause_erc20_custody.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package e2etests

import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/stretchr/testify/require"

"github.com/zeta-chain/zetacore/e2e/runner"
"github.com/zeta-chain/zetacore/e2e/txserver"
"github.com/zeta-chain/zetacore/e2e/utils"
crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types"
)

// TestPauseERC20Custody tests the pausing and unpausing of ERC20 custody contracts on the EVM chain
func TestPauseERC20Custody(r *runner.E2ERunner, _ []string) {
// get EVM chain ID
chainID, err := r.EVMClient.ChainID(r.Ctx)
require.NoError(r, err)

// check ERC20 custody contract is not paused
paused, err := r.ERC20Custody.Paused(&bind.CallOpts{})
require.NoError(r, err)
require.False(r, paused)

// Part 1: Pause ERC20 custody contract

// send command for pausing ERC20 custody contract
msg := crosschaintypes.NewMsgUpdateERC20CustodyPauseStatus(
r.ZetaTxServer.MustGetAccountAddressFromName(utils.AdminPolicyName),
chainID.Int64(),
true,
)
res, err := r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, msg)
require.NoError(r, err)

// fetch cctx index from tx response
cctxIndex, err := txserver.FetchAttributeFromTxResponse(res, "cctx_index")
require.NoError(r, err)

cctxRes, err := r.CctxClient.Cctx(r.Ctx, &crosschaintypes.QueryGetCctxRequest{Index: cctxIndex})
require.NoError(r, err)

cctx := cctxRes.CrossChainTx
r.Logger.CCTX(*cctx, "pausing")

// wait for the cctx to be mined
r.WaitForMinedCCTXFromIndex(cctxIndex)

// check ERC20 custody contract is paused
paused, err = r.ERC20Custody.Paused(&bind.CallOpts{})
require.NoError(r, err)
require.True(r, paused)

// Part 2: Unpause ERC20 custody contract

// send command for unpausing ERC20 custody contract
msg = crosschaintypes.NewMsgUpdateERC20CustodyPauseStatus(
r.ZetaTxServer.MustGetAccountAddressFromName(utils.AdminPolicyName),
chainID.Int64(),
false,
)
res, err = r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, msg)
require.NoError(r, err)

// fetch cctx index from tx response
cctxIndex, err = txserver.FetchAttributeFromTxResponse(res, "cctx_index")
require.NoError(r, err)

cctxRes, err = r.CctxClient.Cctx(r.Ctx, &crosschaintypes.QueryGetCctxRequest{Index: cctxIndex})
require.NoError(r, err)

cctx = cctxRes.CrossChainTx
r.Logger.CCTX(*cctx, "unpausing")

// wait for the cctx to be mined
r.WaitForMinedCCTXFromIndex(cctxIndex)

// check ERC20 custody contract is unpaused
paused, err = r.ERC20Custody.Paused(&bind.CallOpts{})
require.NoError(r, err)
require.False(r, paused)
}
9 changes: 9 additions & 0 deletions pkg/constant/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ const (
// CmdMigrateERC20CustodyFunds is used for CCTX of type cmd to give the instruction to the TSS to transfer its funds on a new address
CmdMigrateERC20CustodyFunds = "cmd_migrate_erc20_custody_funds"

// CmdUpdateERC20CustodyPauseStatus is used for CCTX of type cmd to give the instruction to the TSS to update the pause status of the ERC20 custody contract
CmdUpdateERC20CustodyPauseStatus = "cmd_update_erc20_custody_pause_status"

// CmdMigrateTssFunds is used for CCTX of type cmd to give the instruction to the TSS to transfer its funds on a new address
CmdMigrateTssFunds = "cmd_migrate_tss_funds"

Expand All @@ -28,4 +31,10 @@ const (
// The Solana protocol sets minimum rent exempt to 890880 lamports but we set it to 1_000_000 lamports (0.001 SOL)
// The number 890880 comes from CLI command `solana rent 0` and has been verified on devnet gateway program
SolanaWalletRentExempt = 1_000_000

// OptionPause is the argument used in CmdUpdateERC20CustodyPauseStatus to pause the ERC20 custody contract
OptionPause = "pause"

// OptionUnpause is the argument used in CmdUpdateERC20CustodyPauseStatus to unpause the ERC20 custody contract
OptionUnpause = "unpause"
)
6 changes: 6 additions & 0 deletions proto/zetachain/zetacore/crosschain/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,9 @@ message EventERC20CustodyFundsMigration {
string amount = 3;
string cctx_index = 4;
}

message EventERC20CustodyPausing {
int64 chain_id = 1;
bool pause = 2;
string cctx_index = 3;
}
14 changes: 14 additions & 0 deletions proto/zetachain/zetacore/crosschain/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ service Msg {

rpc MigrateERC20CustodyFunds(MsgMigrateERC20CustodyFunds)
returns (MsgMigrateERC20CustodyFundsResponse);

rpc UpdateERC20CustodyPauseStatus(MsgUpdateERC20CustodyPauseStatus)
returns (MsgUpdateERC20CustodyPauseStatusResponse);
}

message MsgMigrateTssFunds {
Expand Down Expand Up @@ -204,3 +207,14 @@ message MsgMigrateERC20CustodyFunds {
}

message MsgMigrateERC20CustodyFundsResponse { string cctx_index = 1; }

message MsgUpdateERC20CustodyPauseStatus {
string creator = 1;
int64 chain_id = 2;

// pause or unpause
// true = pause, false = unpause
bool pause = 3;
}

message MsgUpdateERC20CustodyPauseStatusResponse { string cctx_index = 1; }
34 changes: 34 additions & 0 deletions typescript/zetachain/zetacore/crosschain/events_pb.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,37 @@ export declare class EventERC20CustodyFundsMigration extends Message<EventERC20C
static equals(a: EventERC20CustodyFundsMigration | PlainMessage<EventERC20CustodyFundsMigration> | undefined, b: EventERC20CustodyFundsMigration | PlainMessage<EventERC20CustodyFundsMigration> | undefined): boolean;
}

/**
* @generated from message zetachain.zetacore.crosschain.EventERC20CustodyPausing
*/
export declare class EventERC20CustodyPausing extends Message<EventERC20CustodyPausing> {
/**
* @generated from field: int64 chain_id = 1;
*/
chainId: bigint;

/**
* @generated from field: bool pause = 2;
*/
pause: boolean;

/**
* @generated from field: string cctx_index = 3;
*/
cctxIndex: string;

constructor(data?: PartialMessage<EventERC20CustodyPausing>);

static readonly runtime: typeof proto3;
static readonly typeName = "zetachain.zetacore.crosschain.EventERC20CustodyPausing";
static readonly fields: FieldList;

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): EventERC20CustodyPausing;

static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): EventERC20CustodyPausing;

static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): EventERC20CustodyPausing;

static equals(a: EventERC20CustodyPausing | PlainMessage<EventERC20CustodyPausing> | undefined, b: EventERC20CustodyPausing | PlainMessage<EventERC20CustodyPausing> | undefined): boolean;
}

61 changes: 61 additions & 0 deletions typescript/zetachain/zetacore/crosschain/tx_pb.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -894,3 +894,64 @@ export declare class MsgMigrateERC20CustodyFundsResponse extends Message<MsgMigr
static equals(a: MsgMigrateERC20CustodyFundsResponse | PlainMessage<MsgMigrateERC20CustodyFundsResponse> | undefined, b: MsgMigrateERC20CustodyFundsResponse | PlainMessage<MsgMigrateERC20CustodyFundsResponse> | undefined): boolean;
}

/**
* @generated from message zetachain.zetacore.crosschain.MsgUpdateERC20CustodyPauseStatus
*/
export declare class MsgUpdateERC20CustodyPauseStatus extends Message<MsgUpdateERC20CustodyPauseStatus> {
/**
* @generated from field: string creator = 1;
*/
creator: string;

/**
* @generated from field: int64 chain_id = 2;
*/
chainId: bigint;

/**
* pause or unpause
* true = pause, false = unpause
*
* @generated from field: bool pause = 3;
*/
pause: boolean;

constructor(data?: PartialMessage<MsgUpdateERC20CustodyPauseStatus>);

static readonly runtime: typeof proto3;
static readonly typeName = "zetachain.zetacore.crosschain.MsgUpdateERC20CustodyPauseStatus";
static readonly fields: FieldList;

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): MsgUpdateERC20CustodyPauseStatus;

static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): MsgUpdateERC20CustodyPauseStatus;

static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): MsgUpdateERC20CustodyPauseStatus;

static equals(a: MsgUpdateERC20CustodyPauseStatus | PlainMessage<MsgUpdateERC20CustodyPauseStatus> | undefined, b: MsgUpdateERC20CustodyPauseStatus | PlainMessage<MsgUpdateERC20CustodyPauseStatus> | undefined): boolean;
}

/**
* @generated from message zetachain.zetacore.crosschain.MsgUpdateERC20CustodyPauseStatusResponse
*/
export declare class MsgUpdateERC20CustodyPauseStatusResponse extends Message<MsgUpdateERC20CustodyPauseStatusResponse> {
/**
* @generated from field: string cctx_index = 1;
*/
cctxIndex: string;

constructor(data?: PartialMessage<MsgUpdateERC20CustodyPauseStatusResponse>);

static readonly runtime: typeof proto3;
static readonly typeName = "zetachain.zetacore.crosschain.MsgUpdateERC20CustodyPauseStatusResponse";
static readonly fields: FieldList;

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): MsgUpdateERC20CustodyPauseStatusResponse;

static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): MsgUpdateERC20CustodyPauseStatusResponse;

static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): MsgUpdateERC20CustodyPauseStatusResponse;

static equals(a: MsgUpdateERC20CustodyPauseStatusResponse | PlainMessage<MsgUpdateERC20CustodyPauseStatusResponse> | undefined, b: MsgUpdateERC20CustodyPauseStatusResponse | PlainMessage<MsgUpdateERC20CustodyPauseStatusResponse> | undefined): boolean;
}

1 change: 1 addition & 0 deletions x/authority/types/authorization_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var (
}
// AdminPolicyMessages keeps track of the message URLs that can, by default, only be executed by admin policy address
AdminPolicyMessages = []string{
"/zetachain.zetacore.crosschain.MsgUpdateERC20CustodyPauseStatus",
"/zetachain.zetacore.crosschain.MsgMigrateERC20CustodyFunds",
"/zetachain.zetacore.crosschain.MsgMigrateTssFunds",
"/zetachain.zetacore.crosschain.MsgUpdateTssAddress",
Expand Down
1 change: 1 addition & 0 deletions x/authority/types/authorization_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ func TestDefaultAuthorizationsList(t *testing.T) {

// AdminPolicyMessageList is a list of messages that can be authorized by the admin policy
var AdminPolicyMessageList = []string{
sdk.MsgTypeURL(&crosschaintypes.MsgUpdateERC20CustodyPauseStatus{}),
sdk.MsgTypeURL(&crosschaintypes.MsgMigrateERC20CustodyFunds{}),
sdk.MsgTypeURL(&crosschaintypes.MsgMigrateTssFunds{}),
sdk.MsgTypeURL(&crosschaintypes.MsgUpdateTssAddress{}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"github.com/zeta-chain/zetacore/pkg/coin"
"github.com/zeta-chain/zetacore/pkg/constant"
testkeeper "github.com/zeta-chain/zetacore/testutil/keeper"
"github.com/zeta-chain/zetacore/testutil/sample"
authoritytypes "github.com/zeta-chain/zetacore/x/authority/types"
Expand Down Expand Up @@ -58,6 +59,7 @@ func TestKeeper_MigrateERC20CustodyFunds(t *testing.T) {
cctx, found := k.GetCrossChainTx(ctx, res.CctxIndex)
require.True(t, found)
require.Equal(t, coin.CoinType_Cmd, cctx.InboundParams.CoinType)
require.Contains(t, cctx.RelayedMessage, constant.CmdMigrateERC20CustodyFunds)
require.Len(t, cctx.OutboundParams, 1)
require.EqualValues(
t,
Expand Down
Loading
Loading