diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 08c4e6d335..f997dd9e02 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -59,7 +59,14 @@ jobs: command: | echo "Running Build Tests" make clean - make test + make test-coverage + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4.0.1 + with: + file: coverage.out + token: ${{ secrets.CODECOV_TOKEN }} + slug: zeta-chain/node - name: Build zetacored and zetaclientd env: diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 04988adeb0..277bc9e654 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -216,7 +216,14 @@ jobs: command: | echo "Running Build Tests" make clean - make test + make test-coverage + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4.0.1 + with: + file: coverage.out + token: ${{ secrets.CODECOV_TOKEN }} + slug: zeta-chain/node - name: Build zetacored and zetaclientd if: ${{ github.event.inputs.skip_checks != 'true' }} diff --git a/app/ante/handler_options.go b/app/ante/handler_options.go index e46f7b728e..4d116a581e 100644 --- a/app/ante/handler_options.go +++ b/app/ante/handler_options.go @@ -21,6 +21,7 @@ import ( observerkeeper "github.com/zeta-chain/zetacore/x/observer/keeper" + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/tx/signing" @@ -165,7 +166,7 @@ func (sud SetUpContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate // Set a gas meter with limit 0 as to prevent an infinite gas meter attack // during runTx. newCtx = SetGasMeter(simulate, ctx, 0) - return newCtx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be GasTx") + return newCtx, cosmoserrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be GasTx") } newCtx = SetGasMeter(simulate, ctx, gasTx.GetGas()) @@ -183,7 +184,7 @@ func (sud SetUpContextDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate "out of gas in location: %v; gasWanted: %d, gasUsed: %d", rType.Descriptor, gasTx.GetGas(), newCtx.GasMeter().GasConsumed()) - err = sdkerrors.Wrap(sdkerrors.ErrOutOfGas, log) + err = cosmoserrors.Wrap(sdkerrors.ErrOutOfGas, log) default: panic(r) } diff --git a/app/app.go b/app/app.go index c7c749cda3..63b889fa9c 100644 --- a/app/app.go +++ b/app/app.go @@ -6,6 +6,7 @@ import ( "os" "time" + cosmoserrors "cosmossdk.io/errors" "github.com/gorilla/mux" "github.com/rakyll/statik/fs" "github.com/spf13/cast" @@ -776,10 +777,10 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino // VerifyAddressFormat verifies the address is compatible with ethereum func VerifyAddressFormat(bz []byte) error { if len(bz) == 0 { - return sdkerrors.Wrap(sdkerrors.ErrUnknownAddress, "invalid address; cannot be empty") + return cosmoserrors.Wrap(sdkerrors.ErrUnknownAddress, "invalid address; cannot be empty") } if len(bz) != AddrLen { - return sdkerrors.Wrapf( + return cosmoserrors.Wrapf( sdkerrors.ErrUnknownAddress, "invalid address length; got: %d, expect: %d", len(bz), AddrLen, ) diff --git a/changelog.md b/changelog.md index 783834761a..8535e19839 100644 --- a/changelog.md +++ b/changelog.md @@ -43,6 +43,7 @@ * [1746](https://github.com/zeta-chain/node/pull/1746) - rename smoke tests to e2e tests * [1753](https://github.com/zeta-chain/node/pull/1753) - fix gosec errors on usage of rand package * [1762](https://github.com/zeta-chain/node/pull/1762) - improve coverage for fungibile module +* [1782](https://github.com/zeta-chain/node/pull/1782) - improve coverage for fungibile module system contract ### CI @@ -52,6 +53,7 @@ * Added docker-compose and make commands for launching full nodes. `make mainnet-zetarpc-node` `make mainnet-bitcoind-node` * Made adjustments to the docker-compose for launching mainnet full nodes to include examples of using the docker images build from the docker image build pipeline. * [1736](https://github.com/zeta-chain/node/pull/1736) - chore: add Ethermint endpoints to OpenAPI +* [1781](https://github.com/zeta-chain/node/pull/1781) - add codecov coverage report in CI ### Features diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000000..647094cf84 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,74 @@ +coverage: + round: down + precision: 2 + status: + project: + default: + threshold: 1% # allow this much decrease on project + zetacore: + if_ci_failed: error + target: 60% + flags: + - zetacore + zetaclient: + if_ci_failed: error + target: 60% + flags: + - zetaclient + common: + if_ci_failed: error + target: 60% + flags: + - common + +comment: + layout: "reach, diff, files" + behavior: default + require_changes: true + +flags: + zetacore: + carryforward: true + paths: + - "x/" + zetaclient: + carryforward: true + paths: + - "zetaclient/" + common: + carryforward: true + paths: + - "common/" + +ignore: + - "x/**/client/" + - "x/**/keeper/keeper.go" + - "x/**/keeper/msg_server.go" + - "x/**/keeper/grpc_query_params.go" + - "x/**/types/codec.go" + - "x/**/types/errors.go" + - "x/**/types/keys.go" + - "x/**/types/key_*.go" + - "x/**/types/types.go" + - "x/**/types/expected_keepers.go" + - "x/**/module.go" + - "x/**/module_simulation.go" + - "x/**/simulation/" + - "*.proto" + - "*.md" + - "*.yml" + - "*.yaml" + - "*.pb.go" + - "*.pb.gw.go" + - "*.json" + - ".github/" + - "app/" + - "cmd/" + - "contrib/" + - "docs/" + - "rpc/" + - "proto/" + - "scripts/" + - "server/" + - "testutil/" + - "typescript/" \ No newline at end of file diff --git a/x/crosschain/keeper/msg_server_gas_price_voter.go b/x/crosschain/keeper/msg_server_gas_price_voter.go index 2c56b3f266..db38b4c8f4 100644 --- a/x/crosschain/keeper/msg_server_gas_price_voter.go +++ b/x/crosschain/keeper/msg_server_gas_price_voter.go @@ -7,10 +7,10 @@ import ( "sort" "strconv" + cosmoserrors "cosmossdk.io/errors" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/zeta-chain/zetacore/x/crosschain/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -31,7 +31,7 @@ func (k msgServer) GasPriceVoter(goCtx context.Context, msg *types.MsgGasPriceVo return nil, observertypes.ErrNotAuthorizedPolicy } if chain == nil { - return nil, sdkerrors.Wrap(types.ErrUnsupportedChain, fmt.Sprintf("ChainID : %d ", msg.ChainId)) + return nil, cosmoserrors.Wrap(types.ErrUnsupportedChain, fmt.Sprintf("ChainID : %d ", msg.ChainId)) } gasPrice, isFound := k.GetGasPrice(ctx, chain.ChainId) diff --git a/x/crosschain/keeper/msg_server_vote_inbound_tx.go b/x/crosschain/keeper/msg_server_vote_inbound_tx.go index ef98c85bf8..930bbd8421 100644 --- a/x/crosschain/keeper/msg_server_vote_inbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_inbound_tx.go @@ -4,9 +4,8 @@ import ( "context" "fmt" - errorsmod "cosmossdk.io/errors" + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/zeta-chain/zetacore/common" "github.com/zeta-chain/zetacore/x/crosschain/types" observerKeeper "github.com/zeta-chain/zetacore/x/observer/keeper" @@ -67,11 +66,11 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg // GetChainFromChainID makes sure we are getting only supported chains , if a chain support has been turned on using gov proposal, this function returns nil observationChain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.SenderChainId) if observationChain == nil { - return nil, sdkerrors.Wrap(types.ErrUnsupportedChain, fmt.Sprintf("ChainID %d, Observation %s", msg.SenderChainId, observationType.String())) + return nil, cosmoserrors.Wrap(types.ErrUnsupportedChain, fmt.Sprintf("ChainID %d, Observation %s", msg.SenderChainId, observationType.String())) } receiverChain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.ReceiverChain) if receiverChain == nil { - return nil, sdkerrors.Wrap(types.ErrUnsupportedChain, fmt.Sprintf("ChainID %d, Observation %s", msg.ReceiverChain, observationType.String())) + return nil, cosmoserrors.Wrap(types.ErrUnsupportedChain, fmt.Sprintf("ChainID %d, Observation %s", msg.ReceiverChain, observationType.String())) } tssPub := "" tss, tssFound := k.zetaObserverKeeper.GetTSS(ctx) @@ -93,7 +92,7 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg if isNew { // Check if the inbound has already been processed. if k.IsFinalizedInbound(ctx, msg.InTxHash, msg.SenderChainId, msg.EventIndex) { - return nil, errorsmod.Wrap(types.ErrObservedTxAlreadyFinalized, fmt.Sprintf("InTxHash:%s, SenderChainID:%d, EventIndex:%d", msg.InTxHash, msg.SenderChainId, msg.EventIndex)) + return nil, cosmoserrors.Wrap(types.ErrObservedTxAlreadyFinalized, fmt.Sprintf("InTxHash:%s, SenderChainID:%d, EventIndex:%d", msg.InTxHash, msg.SenderChainId, msg.EventIndex)) } observerKeeper.EmitEventBallotCreated(ctx, ballot, msg.InTxHash, observationChain.String()) } diff --git a/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go b/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go index 1a8c742c5b..1605a37e33 100644 --- a/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go +++ b/x/crosschain/keeper/msg_server_vote_inbound_tx_test.go @@ -60,7 +60,7 @@ func TestKeeper_VoteOnObservedInboundTx(t *testing.T) { require.NoError(t, err) } ballot, _, _ := zk.ObserverKeeper.FindBallot(ctx, msg.Digest(), zk.ObserverKeeper.GetSupportedChainFromChainID(ctx, msg.SenderChainId), observerTypes.ObservationType_InBoundTx) - require.Equal(t, ballot.BallotStatus, observerTypes.BallotStatus_BallotFinalized_SuccessObservation) + require.Equal(t, ballot.BallotStatus, observertypes.BallotStatus_BallotFinalized_SuccessObservation) cctx, found := k.GetCrossChainTx(ctx, msg.Digest()) require.True(t, found) require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_OutboundMined) @@ -122,7 +122,7 @@ func TestNoDoubleEventProtections(t *testing.T) { // Check that the vote passed ballot, found := zk.ObserverKeeper.GetBallot(ctx, msg.Digest()) require.True(t, found) - require.Equal(t, ballot.BallotStatus, observerTypes.BallotStatus_BallotFinalized_SuccessObservation) + require.Equal(t, ballot.BallotStatus, observertypes.BallotStatus_BallotFinalized_SuccessObservation) //Perform the SAME event. Except, this time, we resubmit the event. msg2 := &types.MsgVoteOnObservedInboundTx{ Creator: validatorAddr, diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx.go b/x/crosschain/keeper/msg_server_vote_outbound_tx.go index 17319d1f8a..72555df8cd 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" + cosmoserrors "cosmossdk.io/errors" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" @@ -81,11 +82,11 @@ func (k msgServer) VoteOnObservedOutboundTx(goCtx context.Context, msg *types.Ms // Check if CCTX exists cctx, found := k.GetCrossChainTx(ctx, msg.CctxHash) if !found { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, fmt.Sprintf("CCTX %s does not exist", msg.CctxHash)) + return nil, cosmoserrors.Wrap(sdkerrors.ErrInvalidRequest, fmt.Sprintf("CCTX %s does not exist", msg.CctxHash)) } if cctx.GetCurrentOutTxParam().OutboundTxTssNonce != msg.OutTxTssNonce { - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, fmt.Sprintf("OutTxTssNonce %d does not match CCTX OutTxTssNonce %d", msg.OutTxTssNonce, cctx.GetCurrentOutTxParam().OutboundTxTssNonce)) + return nil, cosmoserrors.Wrap(sdkerrors.ErrInvalidRequest, fmt.Sprintf("OutTxTssNonce %d does not match CCTX OutTxTssNonce %d", msg.OutTxTssNonce, cctx.GetCurrentOutTxParam().OutboundTxTssNonce)) } ballotIndex := msg.Digest() @@ -117,7 +118,7 @@ func (k msgServer) VoteOnObservedOutboundTx(goCtx context.Context, msg *types.Ms log.Error().Msgf("VoteOnObservedOutboundTx: Mint mismatch: %s value received vs %s cctx amount", msg.ValueReceived, cctx.GetCurrentOutTxParam().Amount) - return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, fmt.Sprintf("ValueReceived %s does not match sent value %s", msg.ValueReceived, cctx.GetCurrentOutTxParam().Amount)) + return nil, cosmoserrors.Wrap(sdkerrors.ErrInvalidRequest, fmt.Sprintf("ValueReceived %s does not match sent value %s", msg.ValueReceived, cctx.GetCurrentOutTxParam().Amount)) } } diff --git a/x/crosschain/keeper/utils_test.go b/x/crosschain/keeper/utils_test.go index 253e20dbb6..aed660b70b 100644 --- a/x/crosschain/keeper/utils_test.go +++ b/x/crosschain/keeper/utils_test.go @@ -175,7 +175,7 @@ func setupZRC20Pool( ) require.NoError(t, err) - // approve the router to spend the zeta + // approve the router to spend the zrc20 err = k.CallZRC20Approve( ctx, types.ModuleAddressEVM, diff --git a/x/crosschain/types/message_add_to_out_tx_tracker.go b/x/crosschain/types/message_add_to_out_tx_tracker.go index 06716762a1..44d7b7f3e0 100644 --- a/x/crosschain/types/message_add_to_out_tx_tracker.go +++ b/x/crosschain/types/message_add_to_out_tx_tracker.go @@ -1,6 +1,7 @@ package types import ( + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/zeta-chain/zetacore/common" @@ -54,10 +55,10 @@ func (msg *MsgAddToOutTxTracker) GetSignBytes() []byte { func (msg *MsgAddToOutTxTracker) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } if msg.ChainId < 0 { - return sdkerrors.Wrapf(ErrInvalidChainID, "chain id (%d)", msg.ChainId) + return cosmoserrors.Wrapf(ErrInvalidChainID, "chain id (%d)", msg.ChainId) } return nil } diff --git a/x/crosschain/types/message_gas_price_voter.go b/x/crosschain/types/message_gas_price_voter.go index 70e4738f91..a42d9b692e 100644 --- a/x/crosschain/types/message_gas_price_voter.go +++ b/x/crosschain/types/message_gas_price_voter.go @@ -1,6 +1,7 @@ package types import ( + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/zeta-chain/zetacore/common" @@ -42,10 +43,10 @@ func (msg *MsgGasPriceVoter) GetSignBytes() []byte { func (msg *MsgGasPriceVoter) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } if msg.ChainId < 0 { - return sdkerrors.Wrapf(ErrInvalidChainID, "chain id (%d)", msg.ChainId) + return cosmoserrors.Wrapf(ErrInvalidChainID, "chain id (%d)", msg.ChainId) } return nil } diff --git a/x/crosschain/types/message_remove_from_out_tx_tracker.go b/x/crosschain/types/message_remove_from_out_tx_tracker.go index d1f3bca387..145d20a76c 100644 --- a/x/crosschain/types/message_remove_from_out_tx_tracker.go +++ b/x/crosschain/types/message_remove_from_out_tx_tracker.go @@ -1,6 +1,7 @@ package types import ( + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -41,10 +42,10 @@ func (msg *MsgRemoveFromOutTxTracker) GetSignBytes() []byte { func (msg *MsgRemoveFromOutTxTracker) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } if msg.ChainId < 0 { - return sdkerrors.Wrapf(ErrInvalidChainID, "chain id (%d)", msg.ChainId) + return cosmoserrors.Wrapf(ErrInvalidChainID, "chain id (%d)", msg.ChainId) } return nil } diff --git a/x/crosschain/types/message_tss_voter.go b/x/crosschain/types/message_tss_voter.go index 683f792064..d88147ce5a 100644 --- a/x/crosschain/types/message_tss_voter.go +++ b/x/crosschain/types/message_tss_voter.go @@ -3,6 +3,7 @@ package types import ( "fmt" + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/zeta-chain/zetacore/common" @@ -43,7 +44,7 @@ func (msg *MsgCreateTSSVoter) GetSignBytes() []byte { func (msg *MsgCreateTSSVoter) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } return nil } diff --git a/x/crosschain/types/message_vote_on_observed_inbound_tx.go b/x/crosschain/types/message_vote_on_observed_inbound_tx.go index b94b0567a4..251a8a8077 100644 --- a/x/crosschain/types/message_vote_on_observed_inbound_tx.go +++ b/x/crosschain/types/message_vote_on_observed_inbound_tx.go @@ -1,6 +1,7 @@ package types import ( + cosmoserrors "cosmossdk.io/errors" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -74,19 +75,19 @@ func (msg *MsgVoteOnObservedInboundTx) GetSignBytes() []byte { func (msg *MsgVoteOnObservedInboundTx) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s): %s", err, msg.Creator) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s): %s", err, msg.Creator) } if msg.SenderChainId < 0 { - return sdkerrors.Wrapf(ErrInvalidChainID, "chain id (%d)", msg.SenderChainId) + return cosmoserrors.Wrapf(ErrInvalidChainID, "chain id (%d)", msg.SenderChainId) } if msg.ReceiverChain < 0 { - return sdkerrors.Wrapf(ErrInvalidChainID, "chain id (%d)", msg.ReceiverChain) + return cosmoserrors.Wrapf(ErrInvalidChainID, "chain id (%d)", msg.ReceiverChain) } if len(msg.Message) > MaxMessageLength { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "message is too long: %d", len(msg.Message)) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "message is too long: %d", len(msg.Message)) } return nil diff --git a/x/crosschain/types/message_vote_on_observed_outbound_tx.go b/x/crosschain/types/message_vote_on_observed_outbound_tx.go index bf940f6984..12d0276847 100644 --- a/x/crosschain/types/message_vote_on_observed_outbound_tx.go +++ b/x/crosschain/types/message_vote_on_observed_outbound_tx.go @@ -1,6 +1,7 @@ package types import ( + cosmoserrors "cosmossdk.io/errors" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -64,10 +65,10 @@ func (msg *MsgVoteOnObservedOutboundTx) GetSignBytes() []byte { func (msg *MsgVoteOnObservedOutboundTx) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } if msg.OutTxChain < 0 { - return sdkerrors.Wrapf(ErrInvalidChainID, "chain id (%d)", msg.OutTxChain) + return cosmoserrors.Wrapf(ErrInvalidChainID, "chain id (%d)", msg.OutTxChain) } return nil diff --git a/x/crosschain/types/message_whitelist_erc20.go b/x/crosschain/types/message_whitelist_erc20.go index a2cfd069e0..e2811287b7 100644 --- a/x/crosschain/types/message_whitelist_erc20.go +++ b/x/crosschain/types/message_whitelist_erc20.go @@ -1,6 +1,7 @@ package types import ( + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ethcommon "github.com/ethereum/go-ethereum/common" @@ -49,17 +50,17 @@ func (msg *MsgWhitelistERC20) GetSignBytes() []byte { func (msg *MsgWhitelistERC20) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } // check if the system contract address is valid if ethcommon.HexToAddress(msg.Erc20Address) == (ethcommon.Address{}) { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid ERC20 contract address (%s)", msg.Erc20Address) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid ERC20 contract address (%s)", msg.Erc20Address) } if msg.Decimals > 128 { - return sdkerrors.Wrapf(types.ErrInvalidDecimals, "invalid decimals (%d)", msg.Decimals) + return cosmoserrors.Wrapf(types.ErrInvalidDecimals, "invalid decimals (%d)", msg.Decimals) } if msg.GasLimit <= 0 { - return sdkerrors.Wrapf(types.ErrInvalidGasLimit, "invalid gas limit (%d)", msg.GasLimit) + return cosmoserrors.Wrapf(types.ErrInvalidGasLimit, "invalid gas limit (%d)", msg.GasLimit) } return nil } diff --git a/x/fungible/keeper/evm.go b/x/fungible/keeper/evm.go index 53fe3c9859..04251028f0 100644 --- a/x/fungible/keeper/evm.go +++ b/x/fungible/keeper/evm.go @@ -432,7 +432,7 @@ func (k Keeper) QueryZRC20Data( zrc4ABI, err := zrc20.ZRC20MetaData.GetAbi() if err != nil { - return types.ZRC20Data{}, sdkerrors.Wrapf( + return types.ZRC20Data{}, cosmoserrors.Wrapf( types.ErrABIUnpack, "failed to get ABI: %s", err.Error(), ) } diff --git a/x/fungible/keeper/evm_test.go b/x/fungible/keeper/evm_test.go index df8037aa06..e1af5c041c 100644 --- a/x/fungible/keeper/evm_test.go +++ b/x/fungible/keeper/evm_test.go @@ -86,6 +86,57 @@ func deploySystemContracts( return } +type SystemContractDeployConfig struct { + DeployWZeta bool + DeployUniswapV2Factory bool + DeployUniswapV2Router bool +} + +// deploySystemContractsConfigurable deploys the system contracts and returns their addresses +// while having a possibility to skip some deployments to test different scenarios +func deploySystemContractsConfigurable( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + evmk types.EVMKeeper, + config *SystemContractDeployConfig, +) (wzeta, uniswapV2Factory, uniswapV2Router, connector, systemContract common.Address) { + var err error + + if config.DeployWZeta { + wzeta, err = k.DeployWZETA(ctx) + require.NoError(t, err) + require.NotEmpty(t, wzeta) + assertContractDeployment(t, evmk, ctx, wzeta) + } + + if config.DeployUniswapV2Factory { + uniswapV2Factory, err = k.DeployUniswapV2Factory(ctx) + require.NoError(t, err) + require.NotEmpty(t, uniswapV2Factory) + assertContractDeployment(t, evmk, ctx, uniswapV2Factory) + } + + if config.DeployUniswapV2Router { + uniswapV2Router, err = k.DeployUniswapV2Router02(ctx, uniswapV2Factory, wzeta) + require.NoError(t, err) + require.NotEmpty(t, uniswapV2Router) + assertContractDeployment(t, evmk, ctx, uniswapV2Router) + } + + connector, err = k.DeployConnectorZEVM(ctx, wzeta) + require.NoError(t, err) + require.NotEmpty(t, connector) + assertContractDeployment(t, evmk, ctx, connector) + + systemContract, err = k.DeploySystemContract(ctx, wzeta, uniswapV2Factory, uniswapV2Router) + require.NoError(t, err) + require.NotEmpty(t, systemContract) + assertContractDeployment(t, evmk, ctx, systemContract) + + return +} + // assertExampleBarValue asserts value Bar of the contract Example, used to test onCrossChainCall func assertExampleBarValue( t *testing.T, diff --git a/x/fungible/keeper/gas_coin_and_pool.go b/x/fungible/keeper/gas_coin_and_pool.go index 7540b90f69..7a847f3906 100644 --- a/x/fungible/keeper/gas_coin_and_pool.go +++ b/x/fungible/keeper/gas_coin_and_pool.go @@ -4,8 +4,8 @@ import ( "fmt" "math/big" + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ethcommon "github.com/ethereum/go-ethereum/common" systemcontract "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/systemcontract.sol" zrc20 "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" @@ -50,7 +50,7 @@ func (k Keeper) SetupChainGasCoinAndPool( zrc20Addr, err := k.DeployZRC20Contract(ctx, name, symbol, decimals, chain.ChainId, common.CoinType_Gas, "", transferGasLimit) if err != nil { - return ethcommon.Address{}, sdkerrors.Wrapf(err, "failed to DeployZRC20Contract") + return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to DeployZRC20Contract") } ctx.EventManager().EmitEvent( sdk.NewEvent(sdk.EventTypeMessage, @@ -76,33 +76,33 @@ func (k Keeper) SetupChainGasCoinAndPool( } systemContractAddress, err := k.GetSystemContractAddress(ctx) if err != nil || systemContractAddress == (ethcommon.Address{}) { - return ethcommon.Address{}, sdkerrors.Wrapf(types.ErrContractNotFound, "system contract address invalid: %s", systemContractAddress) + return ethcommon.Address{}, cosmoserrors.Wrapf(types.ErrContractNotFound, "system contract address invalid: %s", systemContractAddress) } systemABI, err := systemcontract.SystemContractMetaData.GetAbi() if err != nil { - return ethcommon.Address{}, sdkerrors.Wrapf(err, "failed to get system contract abi") + return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to get system contract abi") } _, err = k.CallEVM(ctx, *systemABI, types.ModuleAddressEVM, systemContractAddress, BigIntZero, nil, true, false, "setGasZetaPool", big.NewInt(chain.ChainId), zrc20Addr) if err != nil { - return ethcommon.Address{}, sdkerrors.Wrapf(err, "failed to CallEVM method setGasZetaPool(%d, %s)", chain.ChainId, zrc20Addr.String()) + return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to CallEVM method setGasZetaPool(%d, %s)", chain.ChainId, zrc20Addr.String()) } // setup uniswap v2 pools gas/zeta routerAddress, err := k.GetUniswapV2Router02Address(ctx) if err != nil { - return ethcommon.Address{}, sdkerrors.Wrapf(err, "failed to GetUniswapV2Router02Address") + return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to GetUniswapV2Router02Address") } routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() if err != nil { - return ethcommon.Address{}, sdkerrors.Wrapf(err, "failed to get uniswap router abi") + return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to get uniswap router abi") } ZRC20ABI, err := zrc20.ZRC20MetaData.GetAbi() if err != nil { - return ethcommon.Address{}, sdkerrors.Wrapf(err, "failed to GetAbi zrc20") + return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to GetAbi zrc20") } _, err = k.CallEVM(ctx, *ZRC20ABI, types.ModuleAddressEVM, zrc20Addr, BigIntZero, nil, true, false, "approve", routerAddress, amount) if err != nil { - return ethcommon.Address{}, sdkerrors.Wrapf(err, "failed to CallEVM method approve(%s, %d)", routerAddress.String(), amount) + return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to CallEVM method approve(%s, %d)", routerAddress.String(), amount) } //function addLiquidityETH( @@ -116,14 +116,14 @@ func (k Keeper) SetupChainGasCoinAndPool( res, err := k.CallEVM(ctx, *routerABI, types.ModuleAddressEVM, routerAddress, amountAZeta, big.NewInt(5_000_000), true, false, "addLiquidityETH", zrc20Addr, amount, BigIntZero, BigIntZero, types.ModuleAddressEVM, amountAZeta) if err != nil { - return ethcommon.Address{}, sdkerrors.Wrapf(err, "failed to CallEVM method addLiquidityETH(%s, %s)", zrc20Addr.String(), amountAZeta.String()) + return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to CallEVM method addLiquidityETH(%s, %s)", zrc20Addr.String(), amountAZeta.String()) } AmountToken := new(*big.Int) AmountETH := new(*big.Int) Liquidity := new(*big.Int) err = routerABI.UnpackIntoInterface(&[]interface{}{AmountToken, AmountETH, Liquidity}, "addLiquidityETH", res.Ret) if err != nil { - return ethcommon.Address{}, sdkerrors.Wrapf(err, "failed to UnpackIntoInterface addLiquidityETH") + return ethcommon.Address{}, cosmoserrors.Wrapf(err, "failed to UnpackIntoInterface addLiquidityETH") } ctx.EventManager().EmitEvent( diff --git a/x/fungible/keeper/gas_coin_and_pool_test.go b/x/fungible/keeper/gas_coin_and_pool_test.go index b6f05431ac..9935f11ee6 100644 --- a/x/fungible/keeper/gas_coin_and_pool_test.go +++ b/x/fungible/keeper/gas_coin_and_pool_test.go @@ -9,6 +9,9 @@ import ( evmkeeper "github.com/evmos/ethermint/x/evm/keeper" "github.com/stretchr/testify/require" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + uniswapv2router02 "github.com/zeta-chain/protocol-contracts/pkg/uniswap/v2-periphery/contracts/uniswapv2router02.sol" + "github.com/zeta-chain/zetacore/cmd/zetacored/config" testkeeper "github.com/zeta-chain/zetacore/testutil/keeper" fungiblekeeper "github.com/zeta-chain/zetacore/x/fungible/keeper" "github.com/zeta-chain/zetacore/x/fungible/types" @@ -62,6 +65,73 @@ func deployZRC20( return addr } +// setupZRC20Pool setup a Uniswap pool with liquidity for the pair zeta/asset +func setupZRC20Pool( + t *testing.T, + ctx sdk.Context, + k *fungiblekeeper.Keeper, + bankKeeper bankkeeper.Keeper, + zrc20Addr common.Address, +) { + routerAddress, err := k.GetUniswapV2Router02Address(ctx) + require.NoError(t, err) + routerABI, err := uniswapv2router02.UniswapV2Router02MetaData.GetAbi() + require.NoError(t, err) + + // enough for the small numbers used in test + liquidityAmount := big.NewInt(1e17) + + // mint some zrc20 and zeta + _, err = k.DepositZRC20(ctx, zrc20Addr, types.ModuleAddressEVM, liquidityAmount) + require.NoError(t, err) + err = bankKeeper.MintCoins( + ctx, + types.ModuleName, + sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewIntFromBigInt(liquidityAmount))), + ) + require.NoError(t, err) + + // approve the router to spend the zrc20 + err = k.CallZRC20Approve( + ctx, + types.ModuleAddressEVM, + zrc20Addr, + routerAddress, + liquidityAmount, + false, + ) + require.NoError(t, err) + + // k2 := liquidityAmount.Sub(liquidityAmount, big.NewInt(1000)) + // add the liquidity + //function addLiquidityETH( + // address token, + // uint amountTokenDesired, + // uint amountTokenMin, + // uint amountETHMin, + // address to, + // uint deadline + //) + _, err = k.CallEVM( + ctx, + *routerABI, + types.ModuleAddressEVM, + routerAddress, + liquidityAmount, + big.NewInt(5_000_000), + true, + false, + "addLiquidityETH", + zrc20Addr, + liquidityAmount, + fungiblekeeper.BigIntZero, + fungiblekeeper.BigIntZero, + types.ModuleAddressEVM, + liquidityAmount, + ) + require.NoError(t, err) +} + func TestKeeper_SetupChainGasCoinAndPool(t *testing.T) { t.Run("can setup a new chain gas coin", func(t *testing.T) { k, ctx, sdkk, _ := testkeeper.FungibleKeeper(t) diff --git a/x/fungible/keeper/gas_price.go b/x/fungible/keeper/gas_price.go index 58ca702b69..636cffeec9 100644 --- a/x/fungible/keeper/gas_price.go +++ b/x/fungible/keeper/gas_price.go @@ -3,9 +3,9 @@ package keeper import ( "math/big" + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/ethereum/go-ethereum/common" + ethcommon "github.com/ethereum/go-ethereum/common" systemcontract "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/systemcontract.sol" "github.com/zeta-chain/zetacore/x/fungible/types" ) @@ -13,74 +13,74 @@ import ( // SetGasPrice sets gas price on the system contract in zEVM; return the gasUsed and error code func (k Keeper) SetGasPrice(ctx sdk.Context, chainid *big.Int, gasPrice *big.Int) (uint64, error) { if gasPrice == nil { - return 0, sdkerrors.Wrapf(types.ErrNilGasPrice, "gas price param should be set") + return 0, cosmoserrors.Wrapf(types.ErrNilGasPrice, "gas price param should be set") } system, found := k.GetSystemContract(ctx) if !found { - return 0, sdkerrors.Wrapf(types.ErrContractNotFound, "system contract state variable not found") + return 0, cosmoserrors.Wrapf(types.ErrContractNotFound, "system contract state variable not found") } - oracle := common.HexToAddress(system.SystemContract) - if oracle == common.HexToAddress("0x0") { - return 0, sdkerrors.Wrapf(types.ErrContractNotFound, "system contract invalid address") + oracle := ethcommon.HexToAddress(system.SystemContract) + if oracle == (ethcommon.Address{}) { + return 0, cosmoserrors.Wrapf(types.ErrContractNotFound, "system contract invalid address") } abi, err := systemcontract.SystemContractMetaData.GetAbi() if err != nil { - return 0, sdkerrors.Wrapf(types.ErrABIGet, "SystemContractMetaData") + return 0, cosmoserrors.Wrapf(types.ErrABIGet, "SystemContractMetaData") } res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, oracle, BigIntZero, big.NewInt(50_000), true, false, "setGasPrice", chainid, gasPrice) if err != nil { - return 0, sdkerrors.Wrapf(types.ErrContractCall, err.Error()) + return 0, cosmoserrors.Wrapf(types.ErrContractCall, err.Error()) } if res.Failed() { - return res.GasUsed, sdkerrors.Wrapf(types.ErrContractCall, "setGasPrice tx failed") + return res.GasUsed, cosmoserrors.Wrapf(types.ErrContractCall, "setGasPrice tx failed") } return res.GasUsed, nil } -func (k Keeper) SetGasCoin(ctx sdk.Context, chainid *big.Int, address common.Address) error { +func (k Keeper) SetGasCoin(ctx sdk.Context, chainid *big.Int, address ethcommon.Address) error { system, found := k.GetSystemContract(ctx) if !found { - return sdkerrors.Wrapf(types.ErrContractNotFound, "system contract state variable not found") + return cosmoserrors.Wrapf(types.ErrContractNotFound, "system contract state variable not found") } - oracle := common.HexToAddress(system.SystemContract) - if oracle == common.HexToAddress("0x0") { - return sdkerrors.Wrapf(types.ErrContractNotFound, "system contract invalid address") + oracle := ethcommon.HexToAddress(system.SystemContract) + if oracle == (ethcommon.Address{}) { + return cosmoserrors.Wrapf(types.ErrContractNotFound, "system contract invalid address") } abi, err := systemcontract.SystemContractMetaData.GetAbi() if err != nil { - return sdkerrors.Wrapf(types.ErrABIGet, "SystemContractMetaData") + return cosmoserrors.Wrapf(types.ErrABIGet, "SystemContractMetaData") } res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, oracle, BigIntZero, nil, true, false, "setGasCoinZRC20", chainid, address) if err != nil { - return sdkerrors.Wrapf(types.ErrContractCall, err.Error()) + return cosmoserrors.Wrapf(types.ErrContractCall, err.Error()) } if res.Failed() { - return sdkerrors.Wrapf(types.ErrContractCall, "setGasCoinZRC20 tx failed") + return cosmoserrors.Wrapf(types.ErrContractCall, "setGasCoinZRC20 tx failed") } return nil } -func (k Keeper) SetGasZetaPool(ctx sdk.Context, chainid *big.Int, pool common.Address) error { +func (k Keeper) SetGasZetaPool(ctx sdk.Context, chainid *big.Int, pool ethcommon.Address) error { system, found := k.GetSystemContract(ctx) if !found { - return sdkerrors.Wrapf(types.ErrContractNotFound, "system contract state variable not found") + return cosmoserrors.Wrapf(types.ErrContractNotFound, "system contract state variable not found") } - oracle := common.HexToAddress(system.SystemContract) - if oracle == common.HexToAddress("0x0") { - return sdkerrors.Wrapf(types.ErrContractNotFound, "system contract invalid address") + oracle := ethcommon.HexToAddress(system.SystemContract) + if oracle == (ethcommon.Address{}) { + return cosmoserrors.Wrapf(types.ErrContractNotFound, "system contract invalid address") } abi, err := systemcontract.SystemContractMetaData.GetAbi() if err != nil { - return sdkerrors.Wrapf(types.ErrABIGet, "SystemContractMetaData") + return cosmoserrors.Wrapf(types.ErrABIGet, "SystemContractMetaData") } res, err := k.CallEVM(ctx, *abi, types.ModuleAddressEVM, oracle, BigIntZero, nil, true, false, "setGasZetaPool", chainid, pool) if err != nil { - return sdkerrors.Wrapf(types.ErrContractCall, err.Error()) + return cosmoserrors.Wrapf(types.ErrContractCall, err.Error()) } if res.Failed() { - return sdkerrors.Wrapf(types.ErrContractCall, "setGasZetaPool tx failed") + return cosmoserrors.Wrapf(types.ErrContractCall, "setGasZetaPool tx failed") } return nil diff --git a/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go index 1bd16ce1a4..a490f060c6 100644 --- a/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go +++ b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go @@ -4,6 +4,7 @@ import ( "context" "math/big" + cosmoserrors "cosmossdk.io/errors" "github.com/ethereum/go-ethereum/common" sdk "github.com/cosmos/cosmos-sdk/types" @@ -42,14 +43,14 @@ func (k msgServer) DeployFungibleCoinZRC20(goCtx context.Context, msg *types.Msg } if msg.Creator != k.observerKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_group2) { - return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Deploy can only be executed by the correct policy account") + return nil, cosmoserrors.Wrap(sdkerrors.ErrUnauthorized, "Deploy can only be executed by the correct policy account") } if msg.CoinType == zetacommon.CoinType_Gas { // #nosec G701 always in range address, err = k.SetupChainGasCoinAndPool(ctx, msg.ForeignChainId, msg.Name, msg.Symbol, uint8(msg.Decimals), big.NewInt(msg.GasLimit)) if err != nil { - return nil, sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") + return nil, cosmoserrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } } else { // #nosec G701 always in range @@ -74,7 +75,7 @@ func (k msgServer) DeployFungibleCoinZRC20(goCtx context.Context, msg *types.Msg }, ) if err != nil { - return nil, sdkerrors.Wrapf(err, "failed to emit event") + return nil, cosmoserrors.Wrapf(err, "failed to emit event") } return &types.MsgDeployFungibleCoinZRC20Response{ diff --git a/x/fungible/keeper/msg_server_remove_foreign_coin.go b/x/fungible/keeper/msg_server_remove_foreign_coin.go index ccab6eb9e2..a66f02a9c1 100644 --- a/x/fungible/keeper/msg_server_remove_foreign_coin.go +++ b/x/fungible/keeper/msg_server_remove_foreign_coin.go @@ -3,6 +3,7 @@ package keeper import ( "context" + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/zeta-chain/zetacore/x/fungible/types" @@ -16,12 +17,12 @@ import ( func (k msgServer) RemoveForeignCoin(goCtx context.Context, msg *types.MsgRemoveForeignCoin) (*types.MsgRemoveForeignCoinResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) if msg.Creator != k.observerKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_group2) { - return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Removal can only be executed by the correct policy account") + return nil, cosmoserrors.Wrap(sdkerrors.ErrUnauthorized, "Removal can only be executed by the correct policy account") } index := msg.Name _, found := k.GetForeignCoins(ctx, index) if !found { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "foreign coin not found") + return nil, cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "foreign coin not found") } k.RemoveForeignCoins(ctx, index) return &types.MsgRemoveForeignCoinResponse{}, nil diff --git a/x/fungible/keeper/msg_server_update_system_contract.go b/x/fungible/keeper/msg_server_update_system_contract.go index a61ff78e97..1a5ce6dbc9 100644 --- a/x/fungible/keeper/msg_server_update_system_contract.go +++ b/x/fungible/keeper/msg_server_update_system_contract.go @@ -4,6 +4,7 @@ import ( "context" "math/big" + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ethcommon "github.com/ethereum/go-ethereum/common" @@ -18,21 +19,21 @@ import ( func (k msgServer) UpdateSystemContract(goCtx context.Context, msg *types.MsgUpdateSystemContract) (*types.MsgUpdateSystemContractResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) if msg.Creator != k.observerKeeper.GetParams(ctx).GetAdminPolicyAccount(zetaObserverTypes.Policy_Type_group2) { - return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Deploy can only be executed by the correct policy account") + return nil, cosmoserrors.Wrap(sdkerrors.ErrUnauthorized, "Deploy can only be executed by the correct policy account") } newSystemContractAddr := ethcommon.HexToAddress(msg.NewSystemContractAddress) if newSystemContractAddr == (ethcommon.Address{}) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid system contract address (%s)", msg.NewSystemContractAddress) + return nil, cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid system contract address (%s)", msg.NewSystemContractAddress) } // update contracts zrc20ABI, err := zrc20.ZRC20MetaData.GetAbi() if err != nil { - return nil, sdkerrors.Wrapf(types.ErrABIGet, "failed to get zrc20 abi") + return nil, cosmoserrors.Wrapf(types.ErrABIGet, "failed to get zrc20 abi") } sysABI, err := systemcontract.SystemContractMetaData.GetAbi() if err != nil { - return nil, sdkerrors.Wrapf(types.ErrABIGet, "failed to get system contract abi") + return nil, cosmoserrors.Wrapf(types.ErrABIGet, "failed to get system contract abi") } foreignCoins := k.GetAllForeignCoins(ctx) tmpCtx, commit := ctx.CacheContext() @@ -44,16 +45,16 @@ func (k msgServer) UpdateSystemContract(goCtx context.Context, msg *types.MsgUpd } _, err = k.CallEVM(tmpCtx, *zrc20ABI, types.ModuleAddressEVM, zrc20Addr, BigIntZero, nil, true, false, "updateSystemContractAddress", newSystemContractAddr) if err != nil { - return nil, sdkerrors.Wrapf(types.ErrContractCall, "failed to call zrc20 contract method updateSystemContractAddress (%s)", err.Error()) + return nil, cosmoserrors.Wrapf(types.ErrContractCall, "failed to call zrc20 contract method updateSystemContractAddress (%s)", err.Error()) } if fcoin.CoinType == common.CoinType_Gas { _, err = k.CallEVM(tmpCtx, *sysABI, types.ModuleAddressEVM, newSystemContractAddr, BigIntZero, nil, true, false, "setGasCoinZRC20", big.NewInt(fcoin.ForeignChainId), zrc20Addr) if err != nil { - return nil, sdkerrors.Wrapf(types.ErrContractCall, "failed to call system contract method setGasCoinZRC20 (%s)", err.Error()) + return nil, cosmoserrors.Wrapf(types.ErrContractCall, "failed to call system contract method setGasCoinZRC20 (%s)", err.Error()) } _, err = k.CallEVM(tmpCtx, *sysABI, types.ModuleAddressEVM, newSystemContractAddr, BigIntZero, nil, true, false, "setGasZetaPool", big.NewInt(fcoin.ForeignChainId), zrc20Addr) if err != nil { - return nil, sdkerrors.Wrapf(types.ErrContractCall, "failed to call system contract method setGasZetaPool (%s)", err.Error()) + return nil, cosmoserrors.Wrapf(types.ErrContractCall, "failed to call system contract method setGasZetaPool (%s)", err.Error()) } } } @@ -75,7 +76,7 @@ func (k msgServer) UpdateSystemContract(goCtx context.Context, msg *types.MsgUpd ) 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()) + return nil, cosmoserrors.Wrapf(types.ErrEmitEvent, "failed to emit event (%s)", err.Error()) } commit() return &types.MsgUpdateSystemContractResponse{}, nil diff --git a/x/fungible/keeper/system_contract.go b/x/fungible/keeper/system_contract.go index be531f1597..af36727f54 100644 --- a/x/fungible/keeper/system_contract.go +++ b/x/fungible/keeper/system_contract.go @@ -78,7 +78,6 @@ func (k *Keeper) GetWZetaContractAddress(ctx sdk.Context) (ethcommon.Address, er ) if err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(types.ErrContractCall, "failed to call wZetaContractAddress (%s)", err.Error()) - } type AddressResponse struct { Value ethcommon.Address @@ -87,6 +86,10 @@ func (k *Keeper) GetWZetaContractAddress(ctx sdk.Context) (ethcommon.Address, er if err := sysABI.UnpackIntoInterface(&wzetaResponse, "wZetaContractAddress", res.Ret); err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack wZetaContractAddress: %s", err.Error()) } + + if wzetaResponse.Value == (ethcommon.Address{}) { + return ethcommon.Address{}, cosmoserrors.Wrapf(types.ErrContractNotFound, "wzeta contract invalid address") + } return wzetaResponse.Value, nil } @@ -119,11 +122,15 @@ func (k *Keeper) GetUniswapV2FactoryAddress(ctx sdk.Context) (ethcommon.Address, type AddressResponse struct { Value ethcommon.Address } - var wzetaResponse AddressResponse - if err := sysABI.UnpackIntoInterface(&wzetaResponse, "uniswapv2FactoryAddress", res.Ret); err != nil { + var uniswapFactoryResponse AddressResponse + if err := sysABI.UnpackIntoInterface(&uniswapFactoryResponse, "uniswapv2FactoryAddress", res.Ret); err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack uniswapv2FactoryAddress: %s", err.Error()) } - return wzetaResponse.Value, nil + + if uniswapFactoryResponse.Value == (ethcommon.Address{}) { + return ethcommon.Address{}, cosmoserrors.Wrapf(types.ErrContractNotFound, "uniswap factory contract invalid address") + } + return uniswapFactoryResponse.Value, nil } // GetUniswapV2Router02Address returns the uniswapv2 router02 address on ZetaChain @@ -159,6 +166,10 @@ func (k *Keeper) GetUniswapV2Router02Address(ctx sdk.Context) (ethcommon.Address if err := sysABI.UnpackIntoInterface(&routerResponse, "uniswapv2Router02Address", res.Ret); err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack uniswapv2Router02Address: %s", err.Error()) } + + if routerResponse.Value == (ethcommon.Address{}) { + return ethcommon.Address{}, cosmoserrors.Wrapf(types.ErrContractNotFound, "uniswap router contract invalid address") + } return routerResponse.Value, nil } @@ -265,6 +276,9 @@ func (k *Keeper) QuerySystemContractGasCoinZRC20(ctx sdk.Context, chainid *big.I if err := sysABI.UnpackIntoInterface(&zrc20Res, "gasCoinZRC20ByChainId", res.Ret); err != nil { return ethcommon.Address{}, cosmoserrors.Wrapf(types.ErrABIUnpack, "failed to unpack gasCoinZRC20ByChainId: %s", err.Error()) } + if zrc20Res.Value == (ethcommon.Address{}) { + return ethcommon.Address{}, cosmoserrors.Wrapf(types.ErrContractNotFound, "gas coin contract invalid address") + } return zrc20Res.Value, nil } @@ -316,7 +330,7 @@ func (k *Keeper) CallUniswapV2RouterSwapExactTokensForTokens( big.NewInt(1e17), ) if err != nil { - return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method swapExactTokensForTokens") + return nil, cosmoserrors.Wrapf(types.ErrContractCall, "failed to CallEVM method swapExactTokensForTokens (%s)", err.Error()) } amounts := new([3]*big.Int) @@ -374,7 +388,7 @@ func (k *Keeper) CallUniswapV2RouterSwapExactTokensForETH( big.NewInt(1e17), ) if err != nil { - return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method swapExactTokensForETH") + return nil, cosmoserrors.Wrapf(types.ErrContractCall, "failed to CallEVM method swapExactTokensForETH (%s)", err.Error()) } amounts := new([2]*big.Int) @@ -426,7 +440,7 @@ func (k *Keeper) CallUniswapV2RouterSwapExactETHForToken( big.NewInt(1e17), ) if err != nil { - return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method swapExactETHForTokens") + return nil, cosmoserrors.Wrapf(types.ErrContractCall, "failed to CallEVM method swapExactETHForTokens (%s)", err.Error()) } amounts := new([2]*big.Int) @@ -477,7 +491,7 @@ func (k *Keeper) CallUniswapV2RouterSwapEthForExactToken( big.NewInt(1e17), ) if err != nil { - return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method swapETHForExactTokens") + return nil, cosmoserrors.Wrapf(types.ErrContractCall, "failed to CallEVM method swapETHForExactTokens (%s)", err.Error()) } amounts := new([2]*big.Int) @@ -519,7 +533,7 @@ func (k *Keeper) QueryUniswapV2RouterGetZetaAmountsIn(ctx sdk.Context, amountOut []ethcommon.Address{wzetaAddr, outZRC4}, ) if err != nil { - return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method getAmountsIn") + return nil, cosmoserrors.Wrapf(types.ErrContractCall, "failed to CallEVM method getAmountsIn (%s)", err.Error()) } amounts := new([2]*big.Int) @@ -560,7 +574,7 @@ func (k *Keeper) QueryUniswapV2RouterGetZRC4AmountsIn(ctx sdk.Context, amountOut []ethcommon.Address{inZRC4, wzetaAddr}, ) if err != nil { - return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method getAmountsIn") + return nil, cosmoserrors.Wrapf(types.ErrContractCall, "failed to CallEVM method getAmountsIn (%s)", err.Error()) } amounts := new([2]*big.Int) @@ -601,7 +615,7 @@ func (k *Keeper) QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx sdk.Context, amo []ethcommon.Address{inZRC4, wzetaAddr, outZRC4}, ) if err != nil { - return nil, cosmoserrors.Wrapf(err, "failed to CallEVM method getAmountsIn") + return nil, cosmoserrors.Wrapf(types.ErrContractCall, "failed to CallEVM method getAmountsIn (%s)", err.Error()) } amounts := new([3]*big.Int) @@ -638,7 +652,7 @@ func (k *Keeper) CallZRC20Burn( amount, ) if err != nil { - return cosmoserrors.Wrapf(err, "failed to CallEVM method burn") + return cosmoserrors.Wrapf(types.ErrContractCall, "failed to CallEVM method burn (%s)", err.Error()) } return nil @@ -671,7 +685,7 @@ func (k *Keeper) CallZRC20Deposit( amount, ) if err != nil { - return cosmoserrors.Wrapf(err, "failed to CallEVM method burn") + return cosmoserrors.Wrapf(types.ErrContractCall, "failed to CallEVM method burn (%s)", err.Error()) } return nil } @@ -704,7 +718,7 @@ func (k *Keeper) CallZRC20Approve( amount, ) if err != nil { - return cosmoserrors.Wrapf(err, "failed to CallEVM method approve") + return cosmoserrors.Wrapf(types.ErrContractCall, "failed to CallEVM method approve (%s)", err.Error()) } return nil diff --git a/x/fungible/keeper/system_contract_test.go b/x/fungible/keeper/system_contract_test.go index e2340cb4c1..10f7908807 100644 --- a/x/fungible/keeper/system_contract_test.go +++ b/x/fungible/keeper/system_contract_test.go @@ -4,6 +4,7 @@ import ( "math/big" "testing" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" @@ -12,347 +13,1036 @@ import ( ) func TestKeeper_GetSystemContract(t *testing.T) { - k, ctx, _, _ := keepertest.FungibleKeeper(t) - k.SetSystemContract(ctx, types.SystemContract{SystemContract: "test"}) - val, found := k.GetSystemContract(ctx) - require.True(t, found) - require.Equal(t, types.SystemContract{SystemContract: "test"}, val) - - // can remove contract - k.RemoveSystemContract(ctx) - _, found = k.GetSystemContract(ctx) - require.False(t, found) + t.Run("should get and remove system contract", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.SetSystemContract(ctx, types.SystemContract{SystemContract: "test"}) + val, found := k.GetSystemContract(ctx) + require.True(t, found) + require.Equal(t, types.SystemContract{SystemContract: "test"}, val) + + // can remove contract + k.RemoveSystemContract(ctx) + _, found = k.GetSystemContract(ctx) + require.False(t, found) + }) } func TestKeeper_GetSystemContractAddress(t *testing.T) { - k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + t.Run("should fail to get system contract address if system contracts are not deployed", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, err := k.GetSystemContractAddress(ctx) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + }) - _, err := k.GetSystemContractAddress(ctx) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + t.Run("should get system contract address if system contracts are deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - _, _, _, _, systemContract := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) - found, err := k.GetSystemContractAddress(ctx) - require.NoError(t, err) - require.Equal(t, systemContract, found) + _, _, _, _, systemContract := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + found, err := k.GetSystemContractAddress(ctx) + require.NoError(t, err) + require.Equal(t, systemContract, found) + }) } func TestKeeper_GetWZetaContractAddress(t *testing.T) { - k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + t.Run("should fail to get wzeta contract address if system contracts are not deployed", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - _, err := k.GetWZetaContractAddress(ctx) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + _, err := k.GetWZetaContractAddress(ctx) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + }) - wzeta, _, _, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) - found, err := k.GetWZetaContractAddress(ctx) - require.NoError(t, err) - require.Equal(t, wzeta, found) -} + t.Run("should get wzeta contract address if system contracts are deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) -func TestKeeper_GetWZetaContractAddressFails(t *testing.T) { - k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ - UseEVMMock: true, + wzeta, _, _, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + found, err := k.GetWZetaContractAddress(ctx) + require.NoError(t, err) + require.Equal(t, wzeta, found) }) - mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - _, err := k.GetWZetaContractAddress(ctx) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + t.Run("should fail if wzeta not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: false, + DeployUniswapV2Router: true, + DeployUniswapV2Factory: true, + }) - mockEVMKeeper.MockEVMFailCallOnce() - _, err = k.GetWZetaContractAddress(ctx) - require.ErrorIs(t, err, types.ErrContractCall) -} + _, err := k.GetWZetaContractAddress(ctx) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) -func TestKeeper_GetWZetaContractAddressFailsToUnpack(t *testing.T) { - k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ - UseEVMMock: true, + t.Run("should fail if evm call fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + + mockEVMKeeper.MockEVMFailCallOnce() + + _, err := k.GetWZetaContractAddress(ctx) + require.ErrorIs(t, err, types.ErrContractCall) }) - mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - _, err := k.GetWZetaContractAddress(ctx) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + t.Run("should fail if abi unpack fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) - deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + mockEVMKeeper.MockEVMSuccessCallOnce() - mockEVMKeeper.MockEVMSuccessCallOnce() - _, err = k.GetWZetaContractAddress(ctx) - require.ErrorIs(t, err, types.ErrABIUnpack) + _, err := k.GetWZetaContractAddress(ctx) + require.ErrorIs(t, err, types.ErrABIUnpack) + }) } func TestKeeper_GetUniswapV2FactoryAddress(t *testing.T) { - k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + t.Run("should fail to get uniswapfactory contract address if system contracts are not deployed", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - _, err := k.GetUniswapV2FactoryAddress(ctx) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + _, err := k.GetUniswapV2FactoryAddress(ctx) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + }) - _, factory, _, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) - found, err := k.GetUniswapV2FactoryAddress(ctx) - require.NoError(t, err) - require.Equal(t, factory, found) -} + t.Run("should get uniswapfactory contract address if system contracts are deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) -func TestKeeper_GetUniswapV2FactoryAddressFails(t *testing.T) { - k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ - UseEVMMock: true, + _, factory, _, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + found, err := k.GetUniswapV2FactoryAddress(ctx) + require.NoError(t, err) + require.Equal(t, factory, found) }) - mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - _, err := k.GetUniswapV2FactoryAddress(ctx) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + t.Run("should fail in factory not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: true, + DeployUniswapV2Router: true, + DeployUniswapV2Factory: false, + }) - mockEVMKeeper.MockEVMFailCallOnce() - _, err = k.GetUniswapV2FactoryAddress(ctx) - require.ErrorIs(t, err, types.ErrContractCall) -} + _, err := k.GetUniswapV2FactoryAddress(ctx) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) + + t.Run("should fail if evm call fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + + mockEVMKeeper.MockEVMFailCallOnce() -func TestKeeper_GetUniswapV2FactoryAddressFailsToUnpack(t *testing.T) { - k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ - UseEVMMock: true, + _, err := k.GetUniswapV2FactoryAddress(ctx) + require.ErrorIs(t, err, types.ErrContractCall) }) - mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - _, err := k.GetUniswapV2FactoryAddress(ctx) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + t.Run("should fail if abi unpack fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) - mockEVMKeeper.MockEVMSuccessCallOnce() - _, err = k.GetUniswapV2FactoryAddress(ctx) - require.ErrorIs(t, err, types.ErrABIUnpack) + mockEVMKeeper.MockEVMSuccessCallOnce() + + _, err := k.GetUniswapV2FactoryAddress(ctx) + require.ErrorIs(t, err, types.ErrABIUnpack) + }) } func TestKeeper_GetUniswapV2Router02Address(t *testing.T) { - k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + t.Run("should fail to get uniswaprouter contract address if system contracts are not deployed", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, err := k.GetUniswapV2Router02Address(ctx) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + }) + + t.Run("should get uniswaprouter contract address if system contracts are deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + _, _, router, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + found, err := k.GetUniswapV2Router02Address(ctx) + require.NoError(t, err) + require.Equal(t, router, found) + }) + + t.Run("should fail in router not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: true, + DeployUniswapV2Router: false, + DeployUniswapV2Factory: true, + }) + + _, err := k.GetUniswapV2Router02Address(ctx) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) + + t.Run("should fail if evm call fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - _, err := k.GetUniswapV2Router02Address(ctx) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) - _, _, router, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) - found, err := k.GetUniswapV2Router02Address(ctx) - require.NoError(t, err) - require.Equal(t, router, found) + mockEVMKeeper.MockEVMFailCallOnce() + + _, err := k.GetUniswapV2Router02Address(ctx) + require.ErrorIs(t, err, types.ErrContractCall) + }) + + t.Run("should fail if abi unpack fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + + mockEVMKeeper.MockEVMSuccessCallOnce() + + _, err := k.GetUniswapV2Router02Address(ctx) + require.ErrorIs(t, err, types.ErrABIUnpack) + }) } -func TestKeeper_GetUniswapV2Router02AddressFails(t *testing.T) { - k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ - UseEVMMock: true, +func TestKeeper_CallWZetaDeposit(t *testing.T) { + t.Run("should fail to deposit if system contracts are not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // mint tokens + addr := sample.Bech32AccAddress() + ethAddr := common.BytesToAddress(addr.Bytes()) + coins := sample.Coins() + err := sdkk.BankKeeper.MintCoins(ctx, types.ModuleName, sample.Coins()) + require.NoError(t, err) + err = sdkk.BankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, coins) + require.NoError(t, err) + + // fail if no system contract + err = k.CallWZetaDeposit(ctx, ethAddr, big.NewInt(42)) + require.Error(t, err) }) - mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - _, err := k.GetUniswapV2Router02Address(ctx) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + t.Run("should deposit if system contracts are deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + // mint tokens + addr := sample.Bech32AccAddress() + ethAddr := common.BytesToAddress(addr.Bytes()) + coins := sample.Coins() + err := sdkk.BankKeeper.MintCoins(ctx, types.ModuleName, sample.Coins()) + require.NoError(t, err) + err = sdkk.BankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, coins) + require.NoError(t, err) - mockEVMKeeper.MockEVMFailCallOnce() - _, err = k.GetUniswapV2Router02Address(ctx) - require.ErrorIs(t, err, types.ErrContractCall) + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + // deposit + err = k.CallWZetaDeposit(ctx, ethAddr, big.NewInt(42)) + require.NoError(t, err) + + balance, err := k.QueryWZetaBalanceOf(ctx, ethAddr) + require.NoError(t, err) + require.Equal(t, big.NewInt(42), balance) + }) +} + +func TestKeeper_QueryWZetaBalanceOf(t *testing.T) { + t.Run("should fail if system contracts are not deployed", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // fail if no system contract + _, err := k.QueryWZetaBalanceOf(ctx, sample.EthAddress()) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + }) } -func TestKeeper_GetUniswapV2Router02AddressFailsToUnpack(t *testing.T) { - k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ - UseEVMMock: true, +func TestKeeper_QuerySystemContractGasCoinZRC20(t *testing.T) { + t.Run("should fail if system contracts are not deployed", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + _, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + }) + + t.Run("should query if system contracts are deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + _, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + found, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.NoError(t, err) + require.Equal(t, zrc20, found) + }) + + t.Run("should fail if gas coin not setup", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + _, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.Error(t, err) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + _, err = k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) + + t.Run("should fail if evm call fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + + mockEVMKeeper.MockEVMFailCallOnce() + + _, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(1)) + require.ErrorIs(t, err, types.ErrContractCall) }) - mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - _, err := k.GetUniswapV2Router02Address(ctx) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + t.Run("should fail if abi unpack fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) - mockEVMKeeper.MockEVMSuccessCallOnce() - _, err = k.GetUniswapV2Router02Address(ctx) - require.ErrorIs(t, err, types.ErrABIUnpack) + mockEVMKeeper.MockEVMSuccessCallOnce() + + _, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(1)) + require.ErrorIs(t, err, types.ErrABIUnpack) + }) } -func TestKeeper_CallWZetaDeposit(t *testing.T) { - k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - - // mint tokens - addr := sample.Bech32AccAddress() - ethAddr := common.BytesToAddress(addr.Bytes()) - coins := sample.Coins() - err := sdkk.BankKeeper.MintCoins(ctx, types.ModuleName, sample.Coins()) - require.NoError(t, err) - err = sdkk.BankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, coins) - require.NoError(t, err) - - // fail if no system contract - err = k.CallWZetaDeposit(ctx, ethAddr, big.NewInt(42)) - require.Error(t, err) - - deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) - - // deposit - err = k.CallWZetaDeposit(ctx, ethAddr, big.NewInt(42)) - require.NoError(t, err) - - balance, err := k.QueryWZetaBalanceOf(ctx, ethAddr) - require.NoError(t, err) - require.Equal(t, big.NewInt(42), balance) +func TestKeeper_CallUniswapV2RouterSwapExactETHForToken(t *testing.T) { + t.Run("should fail if system contracts are not deployed", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // fail if no system contract + _, err := k.CallUniswapV2RouterSwapExactETHForToken( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + sample.EthAddress(), + true, + ) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) + }) + + t.Run("should swap if system contracts are deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + // deploy system contracts and swap exact eth for 1 token + tokenAmount := big.NewInt(1) + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + amountToSwap, err := k.QueryUniswapV2RouterGetZetaAmountsIn(ctx, tokenAmount, zrc20) + require.NoError(t, err) + err = sdkk.BankKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(sdk.NewCoin("azeta", sdk.NewIntFromBigInt(amountToSwap)))) + require.NoError(t, err) + + amounts, err := k.CallUniswapV2RouterSwapExactETHForToken( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + amountToSwap, + zrc20, + true, + ) + require.NoError(t, err) + + require.Equal(t, 2, len(amounts)) + require.Equal(t, tokenAmount, amounts[1]) + }) + + t.Run("should fail if missing zeta balance", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + // deploy system contracts and swap 1 token fails because of missing wrapped balance + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + amountToSwap, err := k.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(1), zrc20) + require.NoError(t, err) + + _, err = k.CallUniswapV2RouterSwapExactETHForToken( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + amountToSwap, + zrc20, + true, + ) + require.ErrorIs(t, err, types.ErrContractCall) + }) + + t.Run("should fail if wzeta not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: false, + DeployUniswapV2Factory: true, + DeployUniswapV2Router: true, + }) + + _, err := k.CallUniswapV2RouterSwapExactETHForToken( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + sample.EthAddress(), + true, + ) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) + + t.Run("should fail if router not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: true, + DeployUniswapV2Factory: true, + DeployUniswapV2Router: false, + }) + + _, err := k.CallUniswapV2RouterSwapExactETHForToken( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + sample.EthAddress(), + true, + ) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) } -func TestKeeper_CallWZetaDepositFails(t *testing.T) { - k, ctx, sdkk, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ - UseEVMMock: true, +func TestKeeper_CallUniswapV2RouterSwapEthForExactToken(t *testing.T) { + t.Run("should fail if system contracts are not deployed", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // fail if no system contract + _, err := k.CallUniswapV2RouterSwapExactETHForToken( + ctx, types.ModuleAddressEVM, types.ModuleAddressEVM, big.NewInt(1), sample.EthAddress(), true) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) }) - mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - // mint tokens - addr := sample.Bech32AccAddress() - ethAddr := common.BytesToAddress(addr.Bytes()) - coins := sample.Coins() - err := sdkk.BankKeeper.MintCoins(ctx, types.ModuleName, sample.Coins()) - require.NoError(t, err) - err = sdkk.BankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, coins) - require.NoError(t, err) + t.Run("should swap if system contracts are deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + // deploy system contracts and swap exact 1 token + tokenAmount := big.NewInt(1) + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + amountToSwap, err := k.QueryUniswapV2RouterGetZetaAmountsIn(ctx, tokenAmount, zrc20) + require.NoError(t, err) + err = sdkk.BankKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(sdk.NewCoin("azeta", sdk.NewIntFromBigInt(amountToSwap)))) + require.NoError(t, err) + + amounts, err := k.CallUniswapV2RouterSwapEthForExactToken( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + amountToSwap, + tokenAmount, + zrc20, + ) + require.NoError(t, err) + + require.Equal(t, 2, len(amounts)) + require.Equal(t, big.NewInt(1), amounts[1]) + }) - // fail if no system contract - err = k.CallWZetaDeposit(ctx, ethAddr, big.NewInt(42)) - require.Error(t, err) + t.Run("should fail if missing zeta balance", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + // deploy system contracts and swap 1 token fails because of missing wrapped balance + tokenAmount := big.NewInt(1) + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + amountToSwap, err := k.QueryUniswapV2RouterGetZetaAmountsIn(ctx, tokenAmount, zrc20) + require.NoError(t, err) + + _, err = k.CallUniswapV2RouterSwapEthForExactToken( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + amountToSwap, + tokenAmount, + zrc20, + ) + require.ErrorIs(t, err, types.ErrContractCall) + }) - deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + t.Run("should fail if wzeta not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: false, + DeployUniswapV2Factory: true, + DeployUniswapV2Router: true, + }) + + _, err := k.CallUniswapV2RouterSwapEthForExactToken( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + big.NewInt(1), + sample.EthAddress(), + ) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) - // deposit - mockEVMKeeper.MockEVMFailCallOnce() - err = k.CallWZetaDeposit(ctx, ethAddr, big.NewInt(42)) - require.ErrorIs(t, err, types.ErrContractCall) + t.Run("should fail if router not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: true, + DeployUniswapV2Factory: true, + DeployUniswapV2Router: false, + }) + + _, err := k.CallUniswapV2RouterSwapEthForExactToken( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + big.NewInt(1), + sample.EthAddress(), + ) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) } -func TestKeeper_QueryWZetaBalanceOfFails(t *testing.T) { - k, ctx, sdkk, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ - UseEVMMock: true, +func TestKeeper_CallUniswapV2RouterSwapExactTokensForETH(t *testing.T) { + t.Run("should fail if system contracts are not deployed", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // fail if no system contract + _, err := k.CallUniswapV2RouterSwapExactTokensForETH( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + sample.EthAddress(), + true, + ) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) }) - mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - // mint tokens - addr := sample.Bech32AccAddress() - ethAddr := common.BytesToAddress(addr.Bytes()) - coins := sample.Coins() - err := sdkk.BankKeeper.MintCoins(ctx, types.ModuleName, sample.Coins()) - require.NoError(t, err) - err = sdkk.BankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, coins) - require.NoError(t, err) + t.Run("should swap if system contracts are deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + // fail if no system contract + _, err := k.CallUniswapV2RouterSwapExactTokensForETH( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + sample.EthAddress(), + true, + ) + require.Error(t, err) + + // deploy system contracts and swap exact eth for 1 token + ethAmount := big.NewInt(1) + _, _, router, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + amountToSwap, err := k.QueryUniswapV2RouterGetZRC4AmountsIn(ctx, ethAmount, zrc20) + require.NoError(t, err) + + _, err = k.DepositZRC20(ctx, zrc20, types.ModuleAddressEVM, amountToSwap) + require.NoError(t, err) + k.CallZRC20Approve( + ctx, + types.ModuleAddressEVM, + zrc20, + router, + amountToSwap, + false, + ) + + amounts, err := k.CallUniswapV2RouterSwapExactTokensForETH( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + amountToSwap, + zrc20, + true, + ) + require.NoError(t, err) + + require.Equal(t, 2, len(amounts)) + require.Equal(t, ethAmount, amounts[0]) + }) - // fail if no system contract - err = k.CallWZetaDeposit(ctx, ethAddr, big.NewInt(42)) - require.Error(t, err) + t.Run("should fail if missing tokens balance", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + // fail if no system contract + _, err := k.CallUniswapV2RouterSwapExactTokensForETH( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + sample.EthAddress(), + true, + ) + require.Error(t, err) + + // deploy system contracts and swap fails because of missing balance + ethAmount := big.NewInt(1) + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + + amountToSwap, err := k.QueryUniswapV2RouterGetZRC4AmountsIn(ctx, ethAmount, zrc20) + require.NoError(t, err) + + _, err = k.CallUniswapV2RouterSwapExactTokensForETH( + ctx, types.ModuleAddressEVM, types.ModuleAddressEVM, amountToSwap, zrc20, true) + require.ErrorIs(t, err, types.ErrContractCall) + }) - deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + t.Run("should fail if wzeta not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: false, + DeployUniswapV2Factory: true, + DeployUniswapV2Router: true, + }) + _, err := k.CallUniswapV2RouterSwapExactTokensForETH( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + sample.EthAddress(), + true, + ) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) - // query - mockEVMKeeper.MockEVMFailCallOnce() - _, err = k.QueryWZetaBalanceOf(ctx, ethAddr) - require.ErrorIs(t, err, types.ErrContractCall) + t.Run("should fail if router not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: true, + DeployUniswapV2Factory: true, + DeployUniswapV2Router: false, + }) + _, err := k.CallUniswapV2RouterSwapExactTokensForETH( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + sample.EthAddress(), + true, + ) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) } -func TestKeeper_QueryWZetaBalanceOfFailsToUnpack(t *testing.T) { - k, ctx, sdkk, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ - UseEVMMock: true, +func TestKeeper_CallUniswapV2RouterSwapExactTokensForTokens(t *testing.T) { + t.Run("should fail if system contracts are not deployed", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // fail if no system contract + _, err := k.CallUniswapV2RouterSwapExactTokensForTokens( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + sample.EthAddress(), + sample.EthAddress(), + true, + ) + require.ErrorIs(t, err, types.ErrStateVariableNotFound) }) - mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - // mint tokens - addr := sample.Bech32AccAddress() - ethAddr := common.BytesToAddress(addr.Bytes()) - coins := sample.Coins() - err := sdkk.BankKeeper.MintCoins(ctx, types.ModuleName, sample.Coins()) - require.NoError(t, err) - err = sdkk.BankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, addr, coins) - require.NoError(t, err) + t.Run("should swap if system contracts are deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + // fail if no system contract + _, err := k.CallUniswapV2RouterSwapExactTokensForTokens( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + sample.EthAddress(), + sample.EthAddress(), + true, + ) + require.Error(t, err) + + // deploy system contracts and swap exact token for 1 token + tokenAmount := big.NewInt(1) + _, _, router, _, _ := deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + inzrc20 := deployZRC20(t, ctx, k, sdkk.EvmKeeper, chainID, "foo", sample.EthAddress().String(), "foo") + outzrc20 := deployZRC20(t, ctx, k, sdkk.EvmKeeper, chainID, "bar", sample.EthAddress().String(), "bar") + setupZRC20Pool(t, ctx, k, sdkk.BankKeeper, inzrc20) + setupZRC20Pool(t, ctx, k, sdkk.BankKeeper, outzrc20) + + amountToSwap, err := k.QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx, tokenAmount, inzrc20, outzrc20) + require.NoError(t, err) + + _, err = k.DepositZRC20(ctx, inzrc20, types.ModuleAddressEVM, amountToSwap) + require.NoError(t, err) + k.CallZRC20Approve( + ctx, + types.ModuleAddressEVM, + inzrc20, + router, + amountToSwap, + false, + ) + + amounts, err := k.CallUniswapV2RouterSwapExactTokensForTokens( + ctx, types.ModuleAddressEVM, types.ModuleAddressEVM, amountToSwap, inzrc20, outzrc20, true) + require.NoError(t, err) + require.Equal(t, 3, len(amounts)) + require.Equal(t, amounts[2], tokenAmount) + }) - // fail if no system contract - err = k.CallWZetaDeposit(ctx, ethAddr, big.NewInt(42)) - require.Error(t, err) + t.Run("should fail if missing tokens balance", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + chainID := getValidChainID(t) + + // deploy system contracts and swap fails because of missing balance + tokenAmount := big.NewInt(1) + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + inzrc20 := deployZRC20(t, ctx, k, sdkk.EvmKeeper, chainID, "foo", sample.EthAddress().String(), "foo") + outzrc20 := deployZRC20(t, ctx, k, sdkk.EvmKeeper, chainID, "bar", sample.EthAddress().String(), "bar") + setupZRC20Pool(t, ctx, k, sdkk.BankKeeper, inzrc20) + setupZRC20Pool(t, ctx, k, sdkk.BankKeeper, outzrc20) + + amountToSwap, err := k.QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx, tokenAmount, inzrc20, outzrc20) + require.NoError(t, err) + + _, err = k.CallUniswapV2RouterSwapExactTokensForTokens( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + amountToSwap, + inzrc20, + outzrc20, + true, + ) + require.ErrorIs(t, err, types.ErrContractCall) + }) - deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + t.Run("should fail if wzeta not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // fail if no system contract + _, err := k.CallUniswapV2RouterSwapExactTokensForTokens( + ctx, types.ModuleAddressEVM, types.ModuleAddressEVM, big.NewInt(1), sample.EthAddress(), sample.EthAddress(), true) + require.Error(t, err) + + // deploy system contracts except router + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployUniswapV2Router: true, + DeployWZeta: false, + DeployUniswapV2Factory: true, + }) + + _, err = k.CallUniswapV2RouterSwapExactTokensForTokens( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + sample.EthAddress(), + sample.EthAddress(), + true, + ) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) + + t.Run("should fail if router not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + // fail if no system contract + _, err := k.CallUniswapV2RouterSwapExactTokensForTokens( + ctx, types.ModuleAddressEVM, types.ModuleAddressEVM, big.NewInt(1), sample.EthAddress(), sample.EthAddress(), true) + require.Error(t, err) + + // deploy system contracts except router + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployUniswapV2Router: false, + DeployWZeta: true, + DeployUniswapV2Factory: true, + }) + + _, err = k.CallUniswapV2RouterSwapExactTokensForTokens( + ctx, + types.ModuleAddressEVM, + types.ModuleAddressEVM, + big.NewInt(1), + sample.EthAddress(), + sample.EthAddress(), + true, + ) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) - // query - mockEVMKeeper.MockEVMSuccessCallOnce() - _, err = k.QueryWZetaBalanceOf(ctx, ethAddr) - require.ErrorIs(t, err, types.ErrABIUnpack) } -func TestKeeper_QuerySystemContractGasCoinZRC20(t *testing.T) { - k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - chainID := getValidChainID(t) +func TestKeeper_QueryUniswapV2RouterGetZRC4AmountsIn(t *testing.T) { + t.Run("should fail if no amounts out", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + _, err := k.QueryUniswapV2RouterGetZRC4AmountsIn(ctx, big.NewInt(1), sample.EthAddress()) + require.ErrorIs(t, err, types.ErrContractCall) + }) + + t.Run("should fail if wzeta not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - _, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: false, + DeployUniswapV2Factory: true, + DeployUniswapV2Router: true, + }) - deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) - zrc20 := setupGasCoin(t, ctx, k, sdkk.EvmKeeper, chainID, "foobar", "foobar") + _, err := k.QueryUniswapV2RouterGetZRC4AmountsIn(ctx, big.NewInt(1), sample.EthAddress()) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) + + t.Run("should fail if router not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - found, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) - require.NoError(t, err) - require.Equal(t, zrc20, found) + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: true, + DeployUniswapV2Factory: true, + DeployUniswapV2Router: false, + }) + + _, err := k.QueryUniswapV2RouterGetZRC4AmountsIn(ctx, big.NewInt(1), sample.EthAddress()) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) } -func TestKeeper_QuerySystemContractGasCoinZRC20Fails(t *testing.T) { - k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ - UseEVMMock: true, +func TestKeeper_QueryUniswapV2RouterGetZetaAmountsIn(t *testing.T) { + t.Run("should fail if no amounts out", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + _, err := k.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(1), sample.EthAddress()) + require.ErrorIs(t, err, types.ErrContractCall) }) - mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - chainID := getValidChainID(t) + t.Run("should fail if wzeta not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: false, + DeployUniswapV2Factory: true, + DeployUniswapV2Router: true, + }) + + _, err := k.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(1), sample.EthAddress()) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) - _, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + t.Run("should fail if router not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: true, + DeployUniswapV2Factory: true, + DeployUniswapV2Router: false, + }) - mockEVMKeeper.MockEVMFailCallOnce() - _, err = k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) - require.ErrorIs(t, err, types.ErrContractCall) + _, err := k.QueryUniswapV2RouterGetZetaAmountsIn(ctx, big.NewInt(1), sample.EthAddress()) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) } -func TestKeeper_QuerySystemContractGasCoinZRC20FailsToUnpack(t *testing.T) { - k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ - UseEVMMock: true, +func TestKeeper_QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(t *testing.T) { + t.Run("should fail if no amounts out", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContracts(t, ctx, k, sdkk.EvmKeeper) + + _, err := k.QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx, big.NewInt(1), sample.EthAddress(), sample.EthAddress()) + require.ErrorIs(t, err, types.ErrContractCall) }) - mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) - k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - chainID := getValidChainID(t) + t.Run("should fail if wzeta not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - _, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) - require.Error(t, err) - require.ErrorIs(t, err, types.ErrStateVariableNotFound) + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: false, + DeployUniswapV2Factory: true, + DeployUniswapV2Router: true, + }) - deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + _, err := k.QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx, big.NewInt(1), sample.EthAddress(), sample.EthAddress()) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) + + t.Run("should fail if router not deployed", func(t *testing.T) { + k, ctx, sdkk, _ := keepertest.FungibleKeeper(t) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) - mockEVMKeeper.MockEVMSuccessCallOnce() - _, err = k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) - require.ErrorIs(t, err, types.ErrABIUnpack) + deploySystemContractsConfigurable(t, ctx, k, sdkk.EvmKeeper, &SystemContractDeployConfig{ + DeployWZeta: true, + DeployUniswapV2Factory: true, + DeployUniswapV2Router: false, + }) + + _, err := k.QueryUniswapV2RouterGetZRC4ToZRC4AmountsIn(ctx, big.NewInt(1), sample.EthAddress(), sample.EthAddress()) + require.ErrorIs(t, err, types.ErrContractNotFound) + }) +} + +func TestKeeper_CallZRC20Burn(t *testing.T) { + t.Run("should fail if evm call fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + + mockEVMKeeper.MockEVMFailCallOnce() + err := k.CallZRC20Burn(ctx, types.ModuleAddressEVM, sample.EthAddress(), big.NewInt(1), false) + require.ErrorIs(t, err, types.ErrContractCall) + }) +} + +func TestKeeper_CallZRC20Approve(t *testing.T) { + t.Run("should fail if evm call fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + + mockEVMKeeper.MockEVMFailCallOnce() + err := k.CallZRC20Approve(ctx, types.ModuleAddressEVM, sample.EthAddress(), types.ModuleAddressEVM, big.NewInt(1), false) + require.ErrorIs(t, err, types.ErrContractCall) + }) +} + +func TestKeeper_CallZRC20Deposit(t *testing.T) { + t.Run("should fail if evm call fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{ + UseEVMMock: true, + }) + mockEVMKeeper := keepertest.GetFungibleEVMMock(t, k) + k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName) + + deploySystemContractsWithMockEvmKeeper(t, ctx, k, mockEVMKeeper) + + mockEVMKeeper.MockEVMFailCallOnce() + err := k.CallZRC20Deposit(ctx, types.ModuleAddressEVM, sample.EthAddress(), types.ModuleAddressEVM, big.NewInt(1)) + require.ErrorIs(t, err, types.ErrContractCall) + }) } diff --git a/x/fungible/types/message_deploy_fungible_coin_zrc20.go b/x/fungible/types/message_deploy_fungible_coin_zrc20.go index 6b23365001..1f695e63cb 100644 --- a/x/fungible/types/message_deploy_fungible_coin_zrc20.go +++ b/x/fungible/types/message_deploy_fungible_coin_zrc20.go @@ -1,6 +1,7 @@ package types import ( + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/zeta-chain/zetacore/common" @@ -47,14 +48,14 @@ func (msg *MsgDeployFungibleCoinZRC20) GetSignBytes() []byte { func (msg *MsgDeployFungibleCoinZRC20) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } if msg.GasLimit < 0 { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidGasLimit, "invalid gas limit") + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidGasLimit, "invalid gas limit") } if msg.Decimals > 77 { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "decimals must be less than 78") + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "decimals must be less than 78") } return nil } diff --git a/x/fungible/types/message_deploy_fungible_coin_zrc20_test.go b/x/fungible/types/message_deploy_fungible_coin_zrc20_test.go index e107af7781..12e6e0750e 100644 --- a/x/fungible/types/message_deploy_fungible_coin_zrc20_test.go +++ b/x/fungible/types/message_deploy_fungible_coin_zrc20_test.go @@ -3,6 +3,7 @@ package types_test import ( "testing" + cosmoserrors "cosmossdk.io/errors" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/testutil/sample" @@ -36,7 +37,7 @@ func TestMsgDeployFungibleCoinZRC4_ValidateBasic(t *testing.T) { Creator: sample.AccAddress(), Decimals: 78, }, - err: sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "decimals must be less than 78"), + err: cosmoserrors.Wrapf(sdkerrors.ErrInvalidRequest, "decimals must be less than 78"), }, { name: "valid message", diff --git a/x/fungible/types/message_deploy_system_contracts.go b/x/fungible/types/message_deploy_system_contracts.go index 579df47a25..4c4515e856 100644 --- a/x/fungible/types/message_deploy_system_contracts.go +++ b/x/fungible/types/message_deploy_system_contracts.go @@ -1,6 +1,7 @@ package types import ( + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -39,7 +40,7 @@ func (msg *MsgDeploySystemContracts) GetSignBytes() []byte { func (msg *MsgDeploySystemContracts) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } return nil } diff --git a/x/fungible/types/message_remove_foreign_coin.go b/x/fungible/types/message_remove_foreign_coin.go index 999b3364b1..0c7282dc4a 100644 --- a/x/fungible/types/message_remove_foreign_coin.go +++ b/x/fungible/types/message_remove_foreign_coin.go @@ -1,6 +1,7 @@ package types import ( + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -40,7 +41,7 @@ func (msg *MsgRemoveForeignCoin) GetSignBytes() []byte { func (msg *MsgRemoveForeignCoin) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } return nil } diff --git a/x/fungible/types/message_update_system_contract.go b/x/fungible/types/message_update_system_contract.go index b6879f2ff6..2a347baada 100644 --- a/x/fungible/types/message_update_system_contract.go +++ b/x/fungible/types/message_update_system_contract.go @@ -1,6 +1,7 @@ package types import ( + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ethcommon "github.com/ethereum/go-ethereum/common" @@ -41,11 +42,11 @@ func (msg *MsgUpdateSystemContract) GetSignBytes() []byte { func (msg *MsgUpdateSystemContract) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } // check if the system contract address is valid if ethcommon.HexToAddress(msg.NewSystemContractAddress) == (ethcommon.Address{}) { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid system contract address (%s)", msg.NewSystemContractAddress) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid system contract address (%s)", msg.NewSystemContractAddress) } return nil diff --git a/x/observer/keeper/msg_server_add_blame_vote.go b/x/observer/keeper/msg_server_add_blame_vote.go index 40f2fe54b0..6ff74146b6 100644 --- a/x/observer/keeper/msg_server_add_blame_vote.go +++ b/x/observer/keeper/msg_server_add_blame_vote.go @@ -4,8 +4,8 @@ import ( "context" "fmt" + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" crosschainTypes "github.com/zeta-chain/zetacore/x/crosschain/types" "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -16,7 +16,7 @@ func (k msgServer) AddBlameVote(goCtx context.Context, vote *types.MsgAddBlameVo // GetChainFromChainID makes sure we are getting only supported chains , if a chain support has been turned on using gov proposal, this function returns nil observationChain := k.GetSupportedChainFromChainID(ctx, vote.ChainId) if observationChain == nil { - return nil, sdkerrors.Wrap(crosschainTypes.ErrUnsupportedChain, fmt.Sprintf("ChainID %d, Blame vote", vote.ChainId)) + return nil, cosmoserrors.Wrap(crosschainTypes.ErrUnsupportedChain, fmt.Sprintf("ChainID %d, Blame vote", vote.ChainId)) } // IsAuthorized does various checks against the list of observer mappers if ok := k.IsAuthorized(ctx, vote.Creator); !ok { diff --git a/x/observer/types/message_add_blame_vote.go b/x/observer/types/message_add_blame_vote.go index 1d9422f757..d10411f026 100644 --- a/x/observer/types/message_add_blame_vote.go +++ b/x/observer/types/message_add_blame_vote.go @@ -1,6 +1,7 @@ package types import ( + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/ethereum/go-ethereum/crypto" @@ -30,10 +31,10 @@ func (m *MsgAddBlameVote) Type() string { func (m *MsgAddBlameVote) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(m.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } if common.GetChainFromChainID(m.ChainId) == nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidChainID, "chain id (%d)", m.ChainId) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidChainID, "chain id (%d)", m.ChainId) } return nil } diff --git a/x/observer/types/message_add_observer.go b/x/observer/types/message_add_observer.go index 3c27255590..991bb0afa1 100644 --- a/x/observer/types/message_add_observer.go +++ b/x/observer/types/message_add_observer.go @@ -1,7 +1,7 @@ package types import ( - errorsmod "cosmossdk.io/errors" + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/zeta-chain/zetacore/common" @@ -44,19 +44,19 @@ func (msg *MsgAddObserver) GetSignBytes() []byte { func (msg *MsgAddObserver) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } _, err = sdk.AccAddressFromBech32(msg.ObserverAddress) if err != nil { - return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid observer address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid observer address (%s)", err) } _, err = common.NewPubKey(msg.ZetaclientGranteePubkey) if err != nil { - return errorsmod.Wrapf(sdkerrors.ErrInvalidPubKey, "invalid zetaclient grantee pubkey (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidPubKey, "invalid zetaclient grantee pubkey (%s)", err) } _, err = common.GetAddressFromPubkeyString(msg.ZetaclientGranteePubkey) if err != nil { - return errorsmod.Wrapf(sdkerrors.ErrInvalidPubKey, "invalid zetaclient grantee pubkey (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidPubKey, "invalid zetaclient grantee pubkey (%s)", err) } return nil } diff --git a/x/observer/types/message_update_keygen.go b/x/observer/types/message_update_keygen.go index 561a9319ff..e13c83dd7a 100644 --- a/x/observer/types/message_update_keygen.go +++ b/x/observer/types/message_update_keygen.go @@ -1,6 +1,7 @@ package types import ( + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -40,7 +41,7 @@ func (msg *MsgUpdateKeygen) GetSignBytes() []byte { func (msg *MsgUpdateKeygen) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } return nil } diff --git a/x/observer/types/message_update_observer.go b/x/observer/types/message_update_observer.go index e5b541859b..c6db5a1206 100644 --- a/x/observer/types/message_update_observer.go +++ b/x/observer/types/message_update_observer.go @@ -1,7 +1,7 @@ package types import ( - errorsmod "cosmossdk.io/errors" + cosmoserrors "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -43,21 +43,21 @@ func (msg *MsgUpdateObserver) GetSignBytes() []byte { func (msg *MsgUpdateObserver) ValidateBasic() error { _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) } _, err = sdk.AccAddressFromBech32(msg.OldObserverAddress) if err != nil { - return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid old observer address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid old observer address (%s)", err) } _, err = sdk.AccAddressFromBech32(msg.NewObserverAddress) if err != nil { - return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid new observer address (%s)", err) + return cosmoserrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid new observer address (%s)", err) } if msg.UpdateReason != ObserverUpdateReason_Tombstoned && msg.UpdateReason != ObserverUpdateReason_AdminUpdate { - return errorsmod.Wrapf(ErrUpdateObserver, "invalid update reason (%s)", msg.UpdateReason) + return cosmoserrors.Wrapf(ErrUpdateObserver, "invalid update reason (%s)", msg.UpdateReason) } if msg.UpdateReason == ObserverUpdateReason_Tombstoned && msg.OldObserverAddress != msg.Creator { - return errorsmod.Wrapf(ErrUpdateObserver, "invalid old observer address (%s)", msg.OldObserverAddress) + return cosmoserrors.Wrapf(ErrUpdateObserver, "invalid old observer address (%s)", msg.OldObserverAddress) } return nil }