diff --git a/.VERSION b/.VERSION index 85f7059b..188bef59 100644 --- a/.VERSION +++ b/.VERSION @@ -1 +1 @@ -v0.8.1 +v0.9.3 diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index b51ec90b..131c82fc 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -6,12 +6,12 @@ jobs: name: lint runs-on: ubuntu-latest steps: - - uses: actions/setup-go@v3 + - uses: actions/setup-go@v5 with: go-version: '1.20' - uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v6 with: # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version version: latest diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml index 73aa24a4..9d17d592 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release.yml @@ -27,7 +27,7 @@ jobs: VER=$(cat .VERSION)-${{ github.head_ref || github.ref_name }} echo "VERSION=$VER" >> $GITHUB_ENV - - uses: mukunku/tag-exists-action@v1.4.0 + - uses: mukunku/tag-exists-action@v1.6.0 id: checkTag with: tag: ${{ env.VERSION }} @@ -39,7 +39,7 @@ jobs: exit 1 - name: Delete the "latest" Pre-Release - uses: dev-drprasad/delete-older-releases@v0.3.2 + uses: dev-drprasad/delete-older-releases@v0.3.4 with: keep_latest: 0 delete_tag_pattern: .*-${{ github.head_ref || github.ref_name }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 764819c2..c8f4ae67 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: '1.20' diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a2bbc68..f5627b05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,14 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## Unreleased +## [v0.9.3] - 2024-08-05 +### Improvements +- Upgrade to evmos v18.1.0 +- Use erc20 module to automatically convert ibc tokens to registered erc20 tokens +- Remove precompiles as they are not compatible with evmos v18.1.0 +- Remove ibc-hooks +- Update dependencies + ## [v0.8.1] - 2024-05-22 ### Improvements - Clean unused code in evmutil module @@ -173,4 +181,4 @@ Upgrade sdk to v0.47.4 - Bump wasmd version to version `v0.18.0` - Bump cosmos-sdk to version `v0.45.5` -- Feegrant allows to use contract address \ No newline at end of file +- Feegrant allows to use contract address diff --git a/README.md b/README.md index cf53be4d..9cc9119a 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,6 @@ Aura project source code files are made available under Apache-2.0 License, loca ## Acknowledgments Aura project is built using [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) and uses additional modules: -- ```github.com/evmos/evmos/v16``` by Tharsis Labs Ltd.(Evmos). This EVM library is distributed under [ENCL-1.0](https://github.com/evmos/evmos/blob/v16.0.3/LICENSE). +- ```github.com/evmos/evmos/v18``` by Tharsis Labs Ltd.(Evmos). This EVM library is distributed under [ENCL-1.0](https://github.com/evmos/evmos/blob/v16.0.3/LICENSE). - ```x/evmutil``` by Kava Labs, Inc. This module is distributed under [Apache v2 License](https://github.com/Kava-Labs/kava/blob/master/LICENSE.md). diff --git a/app/ante.go b/app/ante.go index 98fd6ca5..1ee5e8e8 100644 --- a/app/ante.go +++ b/app/ante.go @@ -22,12 +22,12 @@ import ( // ethermint ante sdkvesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" - evmosante "github.com/evmos/evmos/v16/app/ante" - cosmosante "github.com/evmos/evmos/v16/app/ante/cosmos" - "github.com/evmos/evmos/v16/app/ante/evm" - evmante "github.com/evmos/evmos/v16/app/ante/evm" - evmostypes "github.com/evmos/evmos/v16/types" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" + evmosante "github.com/evmos/evmos/v18/app/ante" + cosmosante "github.com/evmos/evmos/v18/app/ante/cosmos" + "github.com/evmos/evmos/v18/app/ante/evm" + evmante "github.com/evmos/evmos/v18/app/ante/evm" + evmostypes "github.com/evmos/evmos/v18/types" + evmtypes "github.com/evmos/evmos/v18/x/evm/types" smartaccount "github.com/aura-nw/aura/x/smartaccount" smartaccountkeeper "github.com/aura-nw/aura/x/smartaccount/keeper" diff --git a/app/app.go b/app/app.go index a87a863c..03119f43 100644 --- a/app/app.go +++ b/app/app.go @@ -18,9 +18,11 @@ import ( v700 "github.com/aura-nw/aura/app/upgrades/v0.7.0" v701 "github.com/aura-nw/aura/app/upgrades/v0.7.1" v702 "github.com/aura-nw/aura/app/upgrades/v0.7.2" - + + ibcupgrade "github.com/aura-nw/aura/app/upgrades/ibcupgrade" v081 "github.com/aura-nw/aura/app/upgrades/v0.8.1" - + v093 "github.com/aura-nw/aura/app/upgrades/v0.9.3" + "github.com/aura-nw/aura/app/internal" "github.com/aura-nw/aura/app/utils" @@ -144,14 +146,14 @@ import ( "github.com/prometheus/client_golang/prometheus" // evm module - srvflags "github.com/evmos/evmos/v16/server/flags" - "github.com/evmos/evmos/v16/x/erc20" - erc20client "github.com/evmos/evmos/v16/x/erc20/client" - erc20keeper "github.com/evmos/evmos/v16/x/erc20/keeper" - erc20types "github.com/evmos/evmos/v16/x/erc20/types" - "github.com/evmos/evmos/v16/x/evm" - evmkeeper "github.com/evmos/evmos/v16/x/evm/keeper" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" + srvflags "github.com/evmos/evmos/v18/server/flags" + "github.com/evmos/evmos/v18/x/erc20" + erc20client "github.com/evmos/evmos/v18/x/erc20/client" + erc20keeper "github.com/evmos/evmos/v18/x/erc20/keeper" + erc20types "github.com/evmos/evmos/v18/x/erc20/types" + "github.com/evmos/evmos/v18/x/evm" + evmkeeper "github.com/evmos/evmos/v18/x/evm/keeper" + evmtypes "github.com/evmos/evmos/v18/x/evm/types" // Force-load the tracer engines to trigger registration due to Go-Ethereum v1.10.15 changes _ "github.com/ethereum/go-ethereum/eth/tracers/js" @@ -163,12 +165,12 @@ import ( evmutiltypes "github.com/aura-nw/aura/x/evmutil/types" // overide transfer for erc20 - "github.com/evmos/evmos/v16/x/ibc/transfer" - transferkeeper "github.com/evmos/evmos/v16/x/ibc/transfer/keeper" + "github.com/evmos/evmos/v18/x/ibc/transfer" + transferkeeper "github.com/evmos/evmos/v18/x/ibc/transfer/keeper" - "github.com/evmos/evmos/v16/x/feemarket" - feemarketkeeper "github.com/evmos/evmos/v16/x/feemarket/keeper" - feemarkettypes "github.com/evmos/evmos/v16/x/feemarket/types" + "github.com/evmos/evmos/v18/x/feemarket" + feemarketkeeper "github.com/evmos/evmos/v18/x/feemarket/keeper" + feemarkettypes "github.com/evmos/evmos/v18/x/feemarket/types" v0_3_0 "github.com/aura-nw/aura/app/upgrades/v0.3.0" v0_3_1 "github.com/aura-nw/aura/app/upgrades/v0.3.1" @@ -592,13 +594,12 @@ func New( ) app.IBCHooksKeeper = &hooksKeeper - auraPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix() - wasmHooks := ibc_hooks.NewWasmHooks(app.IBCHooksKeeper, &app.WasmKeeper, auraPrefix) // The contract keeper needs to be set later - app.Ics20WasmHooks = &wasmHooks - app.HooksICS4Wrapper = ibc_hooks.NewICS4Middleware( - app.IBCKeeper.ChannelKeeper, - app.Ics20WasmHooks, - ) + // auraPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix() + // wasmHooks := ibc_hooks.NewWasmHooks(app.IBCHooksKeeper, &app.WasmKeeper, auraPrefix) // The contract keeper needs to be set later + // app.Ics20WasmHooks = &wasmHooks + // app.HooksICS4Wrapper = ibc_hooks.NewICS4Middleware( + // app.IBCKeeper.ChannelKeeper, + // ) // Create Transfer Keepers // app.TransferKeeper = transferkeeper.NewKeeper( @@ -620,15 +621,19 @@ func New( app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, app.Erc20Keeper, // Add ERC20 Keeper for ERC20 transfers ) - transferIBCModule := transfer.NewIBCModule(app.TransferKeeper) - middlewareTransferModule := ibc_hooks.NewIBCMiddleware( - transferIBCModule, - &app.HooksICS4Wrapper, - ) + + var transferIBCModule ibcporttypes.IBCModule + transferIBCModule = transfer.NewIBCModule(app.TransferKeeper) + transferIBCModule = erc20.NewIBCMiddleware(app.Erc20Keeper, transferIBCModule) + + // middlewareTransferModule := ibc_hooks.NewIBCMiddleware( + // transferIBCModule, + // &app.HooksICS4Wrapper, + // ) // Create static IBC router, add transfer route, then set and seal it ibcRouter := ibcporttypes.NewRouter() - ibcRouter.AddRoute(ibctransfertypes.ModuleName, middlewareTransferModule) + ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule) // enable evm precompile, this need to be done after initialized ibc and transfer keeper chainID := bApp.ChainID() @@ -698,7 +703,7 @@ func New( saModule := samodule.NewAppModule(appCodec, app.SaKeeper, app.ContractKeeper, app.AccountKeeper) // Pass the contract keeper to ICS4Wrappers for ibc middlewares - app.Ics20WasmHooks.ContractKeeper = &app.WasmKeeper + // app.Ics20WasmHooks.ContractKeeper = &app.WasmKeeper // The gov proposal types can be individually enabled enabledProposals := GetEnabledProposals() @@ -1300,6 +1305,16 @@ func (app *App) setupUpgradeHandlers() { v081.CreateUpgradeHandler(app.mm, app.configurator), ) + app.UpgradeKeeper.SetUpgradeHandler( + ibcupgrade.UpgradeName, + ibcupgrade.CreateUpgradeHandler(app.mm, app.configurator), + ) + + app.UpgradeKeeper.SetUpgradeHandler( + v093.UpgradeName, + v093.CreateUpgradeHandler(app.mm, app.configurator), + ) + // When a planned update height is reached, the old binary will panic // writing on disk the height and name of the update that triggered it // This will read that value, and execute the preparations for the upgrade. @@ -1315,73 +1330,76 @@ func (app *App) setupUpgradeHandlers() { var storeUpgrades *storetypes.StoreUpgrades switch upgradeInfo.Name { - case v0_3_0.UpgradeName: - // no store upgrades in v0.3.0 + case v0_3_0.UpgradeName: + // no store upgrades in v0.3.0 - case v0_3_1.UpgradeName: - // no store upgrades in v0.3.1 + case v0_3_1.UpgradeName: + // no store upgrades in v0.3.1 - case v0_3_2.UpgradeName: - // no store upgrades in v0.3.2 + case v0_3_2.UpgradeName: + // no store upgrades in v0.3.2 - case v0_3_3.UpgradeName: - // no store upgrades in v0.3.3 + case v0_3_3.UpgradeName: + // no store upgrades in v0.3.3 - case v0_4_0.UpgradeName: - // no store upgrades in v0.4.0 + case v0_4_0.UpgradeName: + // no store upgrades in v0.4.0 - case v0_4_1.UpgradeName: - // no store upgrades in v0.4.1 + case v0_4_1.UpgradeName: + // no store upgrades in v0.4.1 - case v0_4_2.UpgradeName: - // no store upgrades in v0.4.2 + case v0_4_2.UpgradeName: + // no store upgrades in v0.4.2 - case v0_4_4.UpgradeName: - // no store upgrades in v0.4.4 + case v0_4_4.UpgradeName: + // no store upgrades in v0.4.4 - case v500.UpgradeName: - // no store upgrades in v0.5.0 + case v500.UpgradeName: + // no store upgrades in v0.5.0 - case v501.UpgradeName: - storeUpgrades = &storetypes.StoreUpgrades{ - //Added: []string{ibcmiddlewaretypes.StoreKey}, - } - case v600.UpgradeName: - storeUpgrades = &storetypes.StoreUpgrades{ - Added: []string{samoduletypes.StoreKey}, - } + case v501.UpgradeName: + storeUpgrades = &storetypes.StoreUpgrades{ + //Added: []string{ibcmiddlewaretypes.StoreKey}, + } + case v600.UpgradeName: + storeUpgrades = &storetypes.StoreUpgrades{ + Added: []string{samoduletypes.StoreKey}, + } - case v601.UpgradeName: - // no store upgrades in v0.6. + case v601.UpgradeName: + // no store upgrades in v0.6. - case v700.UpgradeName: + case v700.UpgradeName: + storeUpgrades = &storetypes.StoreUpgrades{ + Added: []string{ + consensusparamtypes.StoreKey, + crisistypes.StoreKey, + }, + } + + case v701.UpgradeName: + if ChainID == "xstaxy-1" { storeUpgrades = &storetypes.StoreUpgrades{ Added: []string{ + ibchookstypes.StoreKey, + samoduletypes.StoreKey, consensusparamtypes.StoreKey, crisistypes.StoreKey, }, } + } - case v701.UpgradeName: - if ChainID == "xstaxy-1" { - storeUpgrades = &storetypes.StoreUpgrades{ - Added: []string{ - ibchookstypes.StoreKey, - samoduletypes.StoreKey, - consensusparamtypes.StoreKey, - crisistypes.StoreKey, - }, - } - } - - case v702.UpgradeName: - // no store upgrades in v0.7.2 - case v703.UpgradeName: - // no store upgrades in v0.7.3 - - case v081.UpgradeName: - // no store upgrades in v0.8.1 - + case v702.UpgradeName: + // no store upgrades in v0.7.2 + case v703.UpgradeName: + // no store upgrades in v0.7.3 + + case v081.UpgradeName: + // no store upgrades in v0.8.1 + case ibcupgrade.UpgradeName: + // no store upgrades in ibcupgrade + case v093.UpgradeName: + // no store upgrades in v0.9.3 } if storeUpgrades != nil { diff --git a/app/evm_utils.go b/app/evm_utils.go index 9cf01554..7c238fb3 100644 --- a/app/evm_utils.go +++ b/app/evm_utils.go @@ -3,25 +3,22 @@ package app import ( "fmt" - "github.com/evmos/evmos/v16/precompiles/bech32" + "github.com/evmos/evmos/v18/precompiles/bech32" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" "golang.org/x/exp/maps" // staking and distribution precompiles - distprecompile "github.com/aura-nw/aura/precompiles/distribution" - stakingprecompile "github.com/aura-nw/aura/precompiles/staking" authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" channelkeeper "github.com/cosmos/ibc-go/v7/modules/core/04-channel/keeper" - ics20precompile "github.com/evmos/evmos/v16/precompiles/ics20" - "github.com/evmos/evmos/v16/precompiles/p256" - erc20Keeper "github.com/evmos/evmos/v16/x/erc20/keeper" - transferkeeper "github.com/evmos/evmos/v16/x/ibc/transfer/keeper" + "github.com/evmos/evmos/v18/precompiles/p256" + erc20Keeper "github.com/evmos/evmos/v18/x/erc20/keeper" + transferkeeper "github.com/evmos/evmos/v18/x/ibc/transfer/keeper" ) func Precompiles( @@ -45,29 +42,29 @@ func Precompiles( panic(fmt.Errorf("failed to instantiate bech32 precompile: %w", err)) } - stakingPrecompile, err := stakingprecompile.NewPrecompile(stakingKeeper, authzKeeper) - if err != nil { - panic(fmt.Errorf("failed to instantiate staking precompile: %w", err)) - } + // stakingPrecompile, err := stakingprecompile.NewPrecompile(stakingKeeper, authzKeeper) + // if err != nil { + // panic(fmt.Errorf("failed to instantiate staking precompile: %w", err)) + // } - distributionPrecompile, err := distprecompile.NewPrecompile(distributionKeeper, stakingKeeper, authzKeeper) - if err != nil { - panic(fmt.Errorf("failed to instantiate distribution precompile: %w", err)) - } + // distributionPrecompile, err := distprecompile.NewPrecompile(distributionKeeper, stakingKeeper, authzKeeper) + // if err != nil { + // panic(fmt.Errorf("failed to instantiate distribution precompile: %w", err)) + // } - ibcTransferPrecompile, err := ics20precompile.NewPrecompile(transferKeeper, channelKeeper, authzKeeper) - if err != nil { - panic(fmt.Errorf("failed to instantiate ICS20 precompile: %w", err)) - } + // ibcTransferPrecompile, err := ics20precompile.NewPrecompile(stakingKeeper, transferKeeper, channelKeeper, authzKeeper) + // if err != nil { + // panic(fmt.Errorf("failed to instantiate ICS20 precompile: %w", err)) + // } // Stateless precompiles precompiles[bech32Precompile.Address()] = bech32Precompile precompiles[p256Precompile.Address()] = p256Precompile // Stateful precompiles - precompiles[stakingPrecompile.Address()] = stakingPrecompile - precompiles[distributionPrecompile.Address()] = distributionPrecompile - precompiles[ibcTransferPrecompile.Address()] = ibcTransferPrecompile + // precompiles[stakingPrecompile.Address()] = stakingPrecompile + // precompiles[distributionPrecompile.Address()] = distributionPrecompile + // precompiles[ibcTransferPrecompile.Address()] = ibcTransferPrecompile return precompiles } diff --git a/app/upgrades/ibcupgrade/upgrades.go b/app/upgrades/ibcupgrade/upgrades.go new file mode 100644 index 00000000..3a4f7a62 --- /dev/null +++ b/app/upgrades/ibcupgrade/upgrades.go @@ -0,0 +1,20 @@ +package ibcupgrade + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" +) + +// UpgradeName is the name of upgrade. This upgrade added new module +const UpgradeName = "ibcupgrade" + +func CreateUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { + + return mm.RunMigrations(ctx, configurator, vm) + } +} diff --git a/app/upgrades/v0.9.3/upgrades.go b/app/upgrades/v0.9.3/upgrades.go new file mode 100644 index 00000000..94222c9a --- /dev/null +++ b/app/upgrades/v0.9.3/upgrades.go @@ -0,0 +1,20 @@ +package v093 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" +) + +// UpgradeName is the name of upgrade. This upgrade added new module +const UpgradeName = "v0.9.3" + +func CreateUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { + + return mm.RunMigrations(ctx, configurator, vm) + } +} diff --git a/cmd/aurad/cmd/root.go b/cmd/aurad/cmd/root.go index beb5c97c..7b5c9e95 100644 --- a/cmd/aurad/cmd/root.go +++ b/cmd/aurad/cmd/root.go @@ -2,10 +2,10 @@ package cmd import ( "errors" + "fmt" "io" "os" "path/filepath" - "fmt" simappparams "cosmossdk.io/simapp/params" @@ -34,7 +34,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - "github.com/evmos/evmos/v16/encoding" + "github.com/evmos/evmos/v18/encoding" "github.com/spf13/cast" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -44,8 +44,8 @@ import ( "github.com/aura-nw/aura/app" // evmos - serverconfig "github.com/evmos/evmos/v16/server/config" - evmosserver "github.com/evmos/evmos/v16/server" + evmosserver "github.com/evmos/evmos/v18/server" + serverconfig "github.com/evmos/evmos/v18/server/config" ) // NewRootCmd creates a new root command for a Cosmos SDK application @@ -210,7 +210,7 @@ func txCommand() *cobra.Command { //Set DefaultGasAdjustment flags.DefaultGasAdjustment = 1.4 - + app.ModuleBasics.AddTxCommands(cmd) cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID") @@ -367,7 +367,7 @@ func initAppConfig() (string, interface{}) { srvCfg.StateSync.SnapshotInterval = 1000 srvCfg.StateSync.SnapshotKeepRecent = 2 srvCfg.IAVLDisableFastNode = false - srvCfg.Config.MinGasPrices = "0.001uaura" + srvCfg.Config.MinGasPrices = "0.001uaura" return customAppTemplate, srvCfg } diff --git a/go.mod b/go.mod index c804eb3b..928568cd 100644 --- a/go.mod +++ b/go.mod @@ -1,53 +1,51 @@ module github.com/aura-nw/aura -go 1.20 +go 1.19 require ( cosmossdk.io/api v0.3.1 cosmossdk.io/errors v1.0.1 - cosmossdk.io/math v1.2.0 + cosmossdk.io/math v1.3.0 cosmossdk.io/simapp v0.0.0-20230608160436-666c345ad23d github.com/CosmWasm/wasmd v0.42.0 github.com/armon/go-metrics v0.4.1 - github.com/cometbft/cometbft v0.37.4 + github.com/cometbft/cometbft v0.37.5 github.com/cometbft/cometbft-db v0.8.0 - github.com/cosmos/cosmos-proto v1.0.0-beta.3 - github.com/cosmos/cosmos-sdk v0.47.8 + github.com/cosmos/cosmos-proto v1.0.0-beta.5 + github.com/cosmos/cosmos-sdk v0.47.12 github.com/cosmos/gogoproto v1.4.10 github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20230803181732-7c8f814d3b79 - github.com/cosmos/ibc-go/v7 v7.3.1 + github.com/cosmos/ibc-go/v7 v7.6.0 github.com/ethereum/go-ethereum v1.11.5 - github.com/evmos/evmos/v16 v16.0.3 + github.com/evmos/evmos/v18 v18.1.0 github.com/gogo/protobuf v1.3.2 github.com/golang/mock v1.6.0 - github.com/golang/protobuf v1.5.3 + github.com/golang/protobuf v1.5.4 github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 - github.com/onsi/ginkgo/v2 v2.13.2 - github.com/onsi/gomega v1.30.0 github.com/prometheus/client_golang v1.16.0 github.com/regen-network/cosmos-proto v0.3.1 github.com/spf13/cast v1.6.0 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.8.4 - golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb - google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 - google.golang.org/grpc v1.60.1 - google.golang.org/protobuf v1.32.0 + github.com/stretchr/testify v1.9.0 + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 + google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 + google.golang.org/grpc v1.62.1 + google.golang.org/protobuf v1.33.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - cloud.google.com/go v0.111.0 // indirect + cloud.google.com/go v0.112.0 // indirect cloud.google.com/go/compute v1.23.3 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.5 // indirect - cloud.google.com/go/storage v1.30.1 // indirect + cloud.google.com/go/storage v1.36.0 // indirect cosmossdk.io/core v0.6.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.4 // indirect - cosmossdk.io/log v1.3.0 // indirect + cosmossdk.io/log v1.3.1 // indirect cosmossdk.io/tools/rosetta v0.2.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -65,7 +63,6 @@ require ( github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/btcutil v1.1.3 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect - github.com/bytedance/sonic v1.11.0 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -86,9 +83,8 @@ require ( github.com/creachadair/taskgroup v0.4.2 // indirect github.com/crypto-org-chain/cronos/memiavl v0.0.5-0.20231027074119-c05c9c61c90e // indirect github.com/crypto-org-chain/cronos/store v0.0.5-0.20231027074119-c05c9c61c90e // indirect - github.com/crypto-org-chain/cronos/versiondb v0.0.0-20231027074119-c05c9c61c90e // indirect github.com/danieljoos/wincred v1.1.2 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckarep/golang-set v1.8.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect @@ -99,10 +95,10 @@ require ( github.com/docker/distribution v2.8.2+incompatible // indirect github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/edsrzf/mmap-go v1.1.0 // indirect - github.com/felixge/httpsnoop v1.0.2 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect github.com/getsentry/sentry-go v0.23.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect @@ -114,19 +110,17 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-stack/stack v1.8.1 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/googleapis v1.4.1 // indirect - github.com/golang/glog v1.1.2 // indirect + github.com/golang/glog v1.2.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/orderedcode v0.0.1 // indirect - github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10 // indirect github.com/google/s2a-go v0.1.7 // indirect - github.com/google/uuid v1.4.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect @@ -136,7 +130,7 @@ require ( github.com/gtank/merlin v0.1.1 // indirect github.com/gtank/ristretto255 v0.1.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.1 // indirect + github.com/hashicorp/go-getter v1.7.5 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect @@ -152,7 +146,7 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/compress v1.17.0 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/ledgerwatch/erigon-lib v0.0.0-20230210071639-db0e7ed11263 // indirect @@ -173,10 +167,10 @@ require ( github.com/mtibben/percent v0.2.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/pelletier/go-toml/v2 v2.0.9 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/petermattis/goid v0.0.0-20230518223814-80aa455d8761 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.11.0 // indirect @@ -186,14 +180,16 @@ require ( github.com/rjeczalik/notify v0.9.3 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/rs/cors v1.10.1 // indirect - github.com/rs/zerolog v1.31.0 // indirect + github.com/rs/zerolog v1.32.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect - github.com/spf13/afero v1.9.5 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/viper v1.16.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/viper v1.18.2 // indirect github.com/status-im/keycard-go v0.2.0 // indirect - github.com/subosito/gotenv v1.4.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.6.0 // indirect @@ -212,43 +208,56 @@ require ( github.com/zondax/ledger-go v0.14.3 // indirect go.etcd.io/bbolt v1.3.7 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect - golang.org/x/crypto v0.16.0 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/oauth2 v0.13.0 // indirect - golang.org/x/sync v0.4.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/term v0.15.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect + go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/net v0.23.0 // indirect + golang.org/x/oauth2 v0.16.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.14.0 // indirect - google.golang.org/api v0.149.0 // indirect + golang.org/x/time v0.5.0 // indirect + google.golang.org/api v0.155.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect + google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v3 v3.0.1 // indirect nhooyr.io/websocket v1.8.7 // indirect - pgregory.net/rapid v0.5.5 // indirect + pgregory.net/rapid v1.1.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) replace ( github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 github.com/CosmWasm/wasmvm => github.com/CosmWasm/wasmvm v1.4.3 - // use Cosmos-SDK fork to enable Ledger functionality - github.com/cosmos/cosmos-sdk => github.com/evmos/cosmos-sdk v0.47.8-evmos github.com/cometbft/cometbft => github.com/aura-nw/cometbft v0.37.4-aura.2 + // use Cosmos-SDK fork to enable Ledger functionality + github.com/cosmos/cosmos-sdk => github.com/evmos/cosmos-sdk v0.47.12-evmos // Ledger Nano S+ support github.com/cosmos/ledger-go => github.com/cosmos/ledger-go v0.9.3 // use Evmos geth fork - github.com/ethereum/go-ethereum => github.com/evmos/go-ethereum v1.10.26-evmos-rc2 + github.com/ethereum/go-ethereum => github.com/evmos/go-ethereum v1.10.26-evmos-rc4 + + github.com/evmos/evmos/v18 => github.com/aura-nw/evmos/v18 v18.1.0-aura.2 - github.com/evmos/evmos/v16 => github.com/aura-nw/evmos/v16 v16.0.3-aura.3 + // Security Advisory https://github.com/advisories/GHSA-h395-qcrw-5vmq + github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.9.1 // https://github.com/cosmos/cosmos-sdk/issues/14949 // pin the version of goleveldb to v1.0.1-0.20210819022825-2ae1ddf74ef7 required by SDK v47 upgrade guide. github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + + // need this replace with cosmos-sdk v0.47.11 (more info here https://github.com/cosmos/cosmos-sdk/issues/20159) + golang.org/x/exp => golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb + + // stick with compatible version of rapid in v0.47.x line + pgregory.net/rapid => pgregory.net/rapid v0.5.5 ) diff --git a/go.sum b/go.sum index 95a8ff2a..03a84de0 100644 --- a/go.sum +++ b/go.sum @@ -3,7 +3,6 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -16,7 +15,6 @@ cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOY cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= @@ -32,8 +30,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9 cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.111.0 h1:YHLKNupSD1KqjDbQ3+LVdQ81h/UJbJyZG203cEfnQgM= -cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU= +cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= +cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= @@ -170,12 +168,11 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM= -cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= +cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8= +cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= @@ -195,22 +192,20 @@ cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98ok cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= -cosmossdk.io/log v1.3.0 h1:L0Z0XstClo2kOU4h3V1iDoE5Ji64sg5HLOogzGg67Oo= -cosmossdk.io/log v1.3.0/go.mod h1:HIDyvWLqZe2ovlWabsDN4aPMpY/nUEquAhgfTf2ZzB8= -cosmossdk.io/math v1.2.0 h1:8gudhTkkD3NxOP2YyyJIYYmt6dQ55ZfJkDOaxXpy7Ig= -cosmossdk.io/math v1.2.0/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= +cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= +cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= +cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= +cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/simapp v0.0.0-20230608160436-666c345ad23d h1:E/8y0oG3u9hBR8l4F9MtC0LdZIamPCUwUoLlrHrX86I= cosmossdk.io/simapp v0.0.0-20230608160436-666c345ad23d/go.mod h1:xbjky3L3DJEylaho6gXplkrMvJ5sFgv+qNX+Nn47bzY= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= github.com/CosmWasm/wasmd v0.42.0 h1:4xZ7GHLrJp3P8qN0wsWOpk5qYLHW9AM5fgcDFPi/p90= @@ -255,8 +250,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aura-nw/cometbft v0.37.4-aura.2 h1:J+oiEiZp8AA6WBsNcWO1SMFci4wM/cTtvEfCY1Lp0sc= github.com/aura-nw/cometbft v0.37.4-aura.2/go.mod h1:Cmg5Hp4sNpapm7j+x0xRyt2g0juQfmB752ous+pA0G8= -github.com/aura-nw/evmos/v16 v16.0.3-aura.3 h1:0+lDKyJqduHESvZ9KTW4zy/CfKWDJffi33ZWB5AS8U4= -github.com/aura-nw/evmos/v16 v16.0.3-aura.3/go.mod h1:w0vtRYI4I0/O8eihq6ZuDvlca4ZiYCKN6vpakG9zHcc= +github.com/aura-nw/evmos/v18 v18.1.0-aura.2 h1:VsRVdgisIkNPpWU7hG1onM3emB580qj22W95Z1OdGzw= +github.com/aura-nw/evmos/v18 v18.1.0-aura.2/go.mod h1:GfZd17bX4cerdRd0/LK6134akWx+Ef+MEvyaFtUrbYY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= @@ -300,9 +295,8 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= -github.com/bytedance/sonic v1.11.0 h1:FwNNv6Vu4z2Onf1++LNzxB/QhitD8wuTdpZzMTGITWo= -github.com/bytedance/sonic v1.11.0/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= +github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= +github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -318,11 +312,8 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= -github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= -github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= @@ -345,6 +336,7 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -370,8 +362,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQYKXTdEcpW6o= -github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -384,8 +376,8 @@ github.com/cosmos/iavl v0.21.0-alpha.1.0.20230904092046-df3db2d96583 h1:3Matt7/L github.com/cosmos/iavl v0.21.0-alpha.1.0.20230904092046-df3db2d96583/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20230803181732-7c8f814d3b79 h1:pCxyhIxgWTabAQC5UerkITraHG3SwajdLKKMCFDWCv4= github.com/cosmos/ibc-apps/modules/ibc-hooks/v7 v7.0.0-20230803181732-7c8f814d3b79/go.mod h1:JwHFbo1oX/ht4fPpnPvmhZr+dCkYK1Vihw+vZE9umR4= -github.com/cosmos/ibc-go/v7 v7.3.1 h1:bil1IjnHdyWDASFYKfwdRiNtFP6WK3osW7QFEAgU4I8= -github.com/cosmos/ibc-go/v7 v7.3.1/go.mod h1:wvx4pPBofe5ZdMNV3OFRxSI4auEP5Qfqf8JXLLNV04g= +github.com/cosmos/ibc-go/v7 v7.6.0 h1:S1G5hcIVe9go+jQV6F9+I9yy+hylbJeLiVHUmktQNrM= +github.com/cosmos/ibc-go/v7 v7.6.0/go.mod h1:LifBA7JHRHl95ujjHIaBEHmUqy2qCGyqDCXB7qmAsZk= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= @@ -408,13 +400,13 @@ github.com/crypto-org-chain/cronos/memiavl v0.0.5-0.20231027074119-c05c9c61c90e/ github.com/crypto-org-chain/cronos/store v0.0.5-0.20231027074119-c05c9c61c90e h1:3mq9zn5+49covVejnfwPIIx0i6pzRXxKJzz4PuVVn9g= github.com/crypto-org-chain/cronos/store v0.0.5-0.20231027074119-c05c9c61c90e/go.mod h1:N6IfJDLTTo0vxyuY4MSMMX2TOdBd/tozpjnYGJmAfmE= github.com/crypto-org-chain/cronos/versiondb v0.0.0-20231027074119-c05c9c61c90e h1:kN1HNLp2xmy8vIHpGWjsX8dCL6sXID2Tw4qZZk7XYd4= -github.com/crypto-org-chain/cronos/versiondb v0.0.0-20231027074119-c05c9c61c90e/go.mod h1:8W9LCw+FhR2sFI+nkjSi0ItZ0IeSyUjc6CSvuaYTU2s= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= @@ -448,8 +440,8 @@ github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:Htrtb github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= -github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY= +github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= @@ -467,14 +459,15 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evmos/cosmos-sdk v0.47.8-evmos h1:XOkJq3MeWDnTrNfDZk1bvCdrmjyyoxyL5gaTrguHPuA= -github.com/evmos/cosmos-sdk v0.47.8-evmos/go.mod h1:VTAtthIsmfplanhFfUTfT6ED4F+kkJxT7nmvmKXRthI= -github.com/evmos/go-ethereum v1.10.26-evmos-rc2 h1:tYghk1ZZ8X4/OQ4YI9hvtm8aSN8OSqO0g9vo/sCMdBo= -github.com/evmos/go-ethereum v1.10.26-evmos-rc2/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo= +github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/evmos/cosmos-sdk v0.47.12-evmos h1:XyKyNboK9fLTjlY798KyfeaNxFjMIICGXNuibIALrTU= +github.com/evmos/cosmos-sdk v0.47.12-evmos/go.mod h1:ADjORYzUQqQv/FxDi0H0K5gW/rAk1CiDR3ZKsExfJV0= +github.com/evmos/go-ethereum v1.10.26-evmos-rc4 h1:vwDVMScuB2KSu8ze5oWUuxm6v3bMUp6dL3PWvJNJY+I= +github.com/evmos/go-ethereum v1.10.26-evmos-rc4/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= -github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -482,8 +475,10 @@ github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2 github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE= @@ -492,12 +487,9 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= +github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -519,13 +511,13 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= +github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -533,14 +525,14 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -556,8 +548,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= -github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -592,8 +584,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -641,22 +633,20 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10 h1:CqYfpuYIjnlNxM3msdyPRKabhXZWbKjf3Q8BWROFBso= -github.com/google/pprof v0.0.0-20230228050547-1710fef4ab10/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= @@ -674,7 +664,6 @@ github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMd github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= @@ -712,8 +701,8 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY= -github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-getter v1.7.5 h1:dT58k9hQ/vbxNMwoI5+xFYAJuv6152UNvdHokfI5wE4= +github.com/hashicorp/go-getter v1.7.5/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -786,6 +775,7 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -800,14 +790,13 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= +github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -819,8 +808,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/ledgerwatch/erigon-lib v0.0.0-20230210071639-db0e7ed11263 h1:LGEzZvf33Y1NhuP5+jI/ni9l1TFS6oYPDilgy74NusM= github.com/ledgerwatch/erigon-lib v0.0.0-20230210071639-db0e7ed11263/go.mod h1:OXgMDuUo2lZ3NpH29ZvMYbk+LxFd5ffDl2Z2mGMuY/I= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -840,7 +829,6 @@ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxec github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -878,6 +866,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -906,13 +895,11 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= -github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -933,8 +920,9 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= -github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230518223814-80aa455d8761 h1:W04oB3d0J01W5jgYRGKsV8LCM6g9EkCvPkZcmFuy0OE= @@ -948,9 +936,9 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= @@ -1005,14 +993,18 @@ github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= -github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= @@ -1029,12 +1021,14 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= @@ -1043,15 +1037,13 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= -github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -1060,8 +1052,8 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1071,10 +1063,13 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= @@ -1105,11 +1100,9 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= @@ -1147,28 +1140,37 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= -go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= -go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= -go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= -go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= -go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= -go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= +golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1181,26 +1183,14 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us= golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1213,18 +1203,17 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1268,14 +1257,12 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -1288,8 +1275,11 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1315,8 +1305,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1331,8 +1321,9 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1345,7 +1336,6 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1357,7 +1347,6 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1366,7 +1355,6 @@ golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1391,14 +1379,12 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1427,22 +1413,27 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1454,12 +1445,17 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1467,7 +1463,6 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1476,9 +1471,7 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1494,7 +1487,6 @@ golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1515,7 +1507,6 @@ golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1523,8 +1514,9 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1583,8 +1575,8 @@ google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.149.0 h1:b2CqT6kG+zqJIVKRQ3ELJVLN1PwHZ6DJ3dW8yl82rgY= -google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= +google.golang.org/api v0.155.0 h1:vBmGhCYs0djJttDNynWo44zosHlPvHmA0XiN2zP2DtA= +google.golang.org/api v0.155.0/go.mod h1:GI5qK5f40kCpHfPn6+YzGAByIKWv8ujFnmoWm7Igduk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1633,10 +1625,8 @@ google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1703,12 +1693,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= -google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= -google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 h1:s1w3X6gQxwrLEpxnLd/qXTVLgQE2yXwaOaoa6IlY/+o= -google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0/go.mod h1:CAny0tYF+0/9rmDB9fahA9YLzX3+AEVl1qXbv5hhj6c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= +google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= +google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= +google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 h1:Lj5rbfG876hIAYFjqiJnPHfhXbv+nzTWfm04Fg/XSVU= +google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1750,8 +1740,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1768,8 +1758,9 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1817,7 +1808,6 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/precompiles/README.md b/precompiles/README.md deleted file mode 100644 index 047c75e5..00000000 --- a/precompiles/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Precompiles - -These precompile contracts are adapted from [Evmos precompiles](https://github.com/evmos/evmos/tree/v16.0.3/precompiles) - -Copyright Tharsis Labs Ltd.(Evmos) -SPDX-License-Identifier: [ENCL-1.0](https://github.com/evmos/evmos/blob/v16.0.3/LICENSE) - diff --git a/precompiles/distribution/DistributionI.sol b/precompiles/distribution/DistributionI.sol deleted file mode 100644 index d46c989d..00000000 --- a/precompiles/distribution/DistributionI.sol +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-only -pragma solidity >=0.8.17; - -import "../common/Types.sol"; - -/// @dev The DistributionI contract's address. -address constant DISTRIBUTION_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000801; - -/// @dev Define all the available distribution methods. -string constant MSG_SET_WITHDRAWER_ADDRESS = "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress"; -string constant MSG_WITHDRAW_DELEGATOR_REWARD = "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"; -string constant MSG_WITHDRAW_VALIDATOR_COMMISSION = "/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission"; - -/// @dev The DistributionI contract's instance. -DistributionI constant DISTRIBUTION_CONTRACT = DistributionI( - DISTRIBUTION_PRECOMPILE_ADDRESS -); - -struct ValidatorSlashEvent { - uint64 validatorPeriod; - Dec fraction; -} - -struct ValidatorDistributionInfo { - string operatorAddress; - DecCoin[] selfBondRewards; - DecCoin[] commission; -} - -struct DelegationDelegatorReward { - string validatorAddress; - DecCoin[] reward; -} - -/// @author Evmos Team -/// @title Distribution Precompile Contract -/// @dev The interface through which solidity contracts will interact with Distribution -/// @custom:address 0x0000000000000000000000000000000000000801 -interface DistributionI { - /// @dev ClaimRewards defines an Event emitted when rewards are claimed - /// @param delegatorAddress the address of the delegator - /// @param amount the amount being claimed - event ClaimRewards( - address indexed delegatorAddress, - uint256 amount - ); - - /// @dev SetWithdrawerAddress defines an Event emitted when a new withdrawer address is being set - /// @param caller the caller of the transaction - /// @param withdrawerAddress the newly set withdrawer address - event SetWithdrawerAddress( - address indexed caller, - string withdrawerAddress - ); - - /// @dev WithdrawDelegatorRewards defines an Event emitted when rewards from a delegation are withdrawn - /// @param delegatorAddress the address of the delegator - /// @param validatorAddress the address of the validator - /// @param amount the amount being withdrawn from the delegation - event WithdrawDelegatorRewards( - address indexed delegatorAddress, - address indexed validatorAddress, - uint256 amount - ); - - /// @dev WithdrawValidatorCommission defines an Event emitted when validator commissions are being withdrawn - /// @param validatorAddress is the address of the validator - /// @param commission is the total commission earned by the validator - event WithdrawValidatorCommission( - string indexed validatorAddress, - uint256 commission - ); - - /// TRANSACTIONS - - /// @dev Claims all rewards from a select set of validators or all of them for a delegator. - /// @param delegatorAddress The address of the delegator - /// @param maxRetrieve The maximum number of validators to claim rewards from - /// @return success Whether the transaction was successful or not - function claimRewards( - address delegatorAddress, - uint32 maxRetrieve - ) external returns (bool success); - - /// @dev Change the address, that can withdraw the rewards of a delegator. - /// Note that this address cannot be a module account. - /// @param delegatorAddress The address of the delegator - /// @param withdrawerAddress The address that will be capable of withdrawing rewards for - /// the given delegator address - function setWithdrawAddress( - address delegatorAddress, - string memory withdrawerAddress - ) external returns (bool success); - - /// @dev Withdraw the rewards of a delegator from a validator - /// @param delegatorAddress The address of the delegator - /// @param validatorAddress The address of the validator - /// @return amount The amount of Coin withdrawn - function withdrawDelegatorRewards( - address delegatorAddress, - string memory validatorAddress - ) external returns (Coin[] calldata amount); - - /// @dev Withdraws the rewards commission of a validator. - /// @param validatorAddress The address of the validator - /// @return amount The amount of Coin withdrawn - function withdrawValidatorCommission( - string memory validatorAddress - ) external returns (Coin[] calldata amount); - - /// QUERIES - /// @dev Queries validator commission and self-delegation rewards for validator. - /// @param validatorAddress The address of the validator - /// @return distributionInfo The validator's distribution info - function validatorDistributionInfo( - string memory validatorAddress - ) - external - view - returns ( - ValidatorDistributionInfo calldata distributionInfo - ); - - /// @dev Queries the outstanding rewards of a validator address. - /// @param validatorAddress The address of the validator - /// @return rewards The validator's outstanding rewards - function validatorOutstandingRewards( - string memory validatorAddress - ) external view returns (DecCoin[] calldata rewards); - - /// @dev Queries the accumulated commission for a validator. - /// @param validatorAddress The address of the validator - /// @return commission The validator's commission - function validatorCommission( - string memory validatorAddress - ) external view returns (DecCoin[] calldata commission); - - /// @dev Queries the slashing events for a validator in a given height interval - /// defined by the starting and ending height. - /// @param validatorAddress The address of the validator - /// @param startingHeight The starting height - /// @param endingHeight The ending height - /// @param pageRequest Defines a pagination for the request. - /// @return slashes The validator's slash events - /// @return pageResponse The pagination response for the query - function validatorSlashes( - string memory validatorAddress, - uint64 startingHeight, - uint64 endingHeight, - PageRequest calldata pageRequest - ) - external - view - returns ( - ValidatorSlashEvent[] calldata slashes, - PageResponse calldata pageResponse - ); - - /// @dev Queries the total rewards accrued by a delegation from a specific address to a given validator. - /// @param delegatorAddress The address of the delegator - /// @param validatorAddress The address of the validator - /// @return rewards The total rewards accrued by a delegation. - function delegationRewards( - address delegatorAddress, - string memory validatorAddress - ) external view returns (DecCoin[] calldata rewards); - - /// @dev Queries the total rewards accrued by each validator, that a given - /// address has delegated to. - /// @param delegatorAddress The address of the delegator - /// @return rewards The total rewards accrued by each validator for a delegator. - /// @return total The total rewards accrued by a delegator. - function delegationTotalRewards( - address delegatorAddress - ) - external - view - returns ( - DelegationDelegatorReward[] calldata rewards, - DecCoin[] calldata total - ); - - /// @dev Queries all validators, that a given address has delegated to. - /// @param delegatorAddress The address of the delegator - /// @return validators The addresses of all validators, that were delegated to by the given address. - function delegatorValidators( - address delegatorAddress - ) external view returns (string[] calldata validators); - - /// @dev Queries the address capable of withdrawing rewards for a given delegator. - /// @param delegatorAddress The address of the delegator - /// @return withdrawAddress The address capable of withdrawing rewards for the delegator. - function delegatorWithdrawAddress( - address delegatorAddress - ) external view returns (string memory withdrawAddress); - -} diff --git a/precompiles/distribution/abi.json b/precompiles/distribution/abi.json deleted file mode 100644 index cf7388d7..00000000 --- a/precompiles/distribution/abi.json +++ /dev/null @@ -1,592 +0,0 @@ -[ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "ClaimRewards", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "caller", - "type": "address" - }, - { - "indexed": false, - "internalType": "string", - "name": "withdrawerAddress", - "type": "string" - } - ], - "name": "SetWithdrawerAddress", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "validatorAddress", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithdrawDelegatorRewards", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "string", - "name": "validatorAddress", - "type": "string" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "commission", - "type": "uint256" - } - ], - "name": "WithdrawValidatorCommission", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "uint32", - "name": "maxRetrieve", - "type": "uint32" - } - ], - "name": "claimRewards", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - } - ], - "name": "delegationRewards", - "outputs": [ - { - "components": [ - { - "internalType": "string", - "name": "denom", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "precision", - "type": "uint8" - } - ], - "internalType": "struct DecCoin[]", - "name": "rewards", - "type": "tuple[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - } - ], - "name": "delegationTotalRewards", - "outputs": [ - { - "components": [ - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - }, - { - "components": [ - { - "internalType": "string", - "name": "denom", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "precision", - "type": "uint8" - } - ], - "internalType": "struct DecCoin[]", - "name": "reward", - "type": "tuple[]" - } - ], - "internalType": "struct DelegationDelegatorReward[]", - "name": "rewards", - "type": "tuple[]" - }, - { - "components": [ - { - "internalType": "string", - "name": "denom", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "precision", - "type": "uint8" - } - ], - "internalType": "struct DecCoin[]", - "name": "total", - "type": "tuple[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - } - ], - "name": "delegatorValidators", - "outputs": [ - { - "internalType": "string[]", - "name": "validators", - "type": "string[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - } - ], - "name": "delegatorWithdrawAddress", - "outputs": [ - { - "internalType": "string", - "name": "withdrawAddress", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "withdrawerAddress", - "type": "string" - } - ], - "name": "setWithdrawAddress", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - } - ], - "name": "validatorCommission", - "outputs": [ - { - "components": [ - { - "internalType": "string", - "name": "denom", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "precision", - "type": "uint8" - } - ], - "internalType": "struct DecCoin[]", - "name": "commission", - "type": "tuple[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - } - ], - "name": "validatorDistributionInfo", - "outputs": [ - { - "components": [ - { - "internalType": "string", - "name": "operatorAddress", - "type": "string" - }, - { - "components": [ - { - "internalType": "string", - "name": "denom", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "precision", - "type": "uint8" - } - ], - "internalType": "struct DecCoin[]", - "name": "selfBondRewards", - "type": "tuple[]" - }, - { - "components": [ - { - "internalType": "string", - "name": "denom", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "precision", - "type": "uint8" - } - ], - "internalType": "struct DecCoin[]", - "name": "commission", - "type": "tuple[]" - } - ], - "internalType": "struct ValidatorDistributionInfo", - "name": "distributionInfo", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - } - ], - "name": "validatorOutstandingRewards", - "outputs": [ - { - "components": [ - { - "internalType": "string", - "name": "denom", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "precision", - "type": "uint8" - } - ], - "internalType": "struct DecCoin[]", - "name": "rewards", - "type": "tuple[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - }, - { - "internalType": "uint64", - "name": "startingHeight", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "endingHeight", - "type": "uint64" - }, - { - "components": [ - { - "internalType": "bytes", - "name": "key", - "type": "bytes" - }, - { - "internalType": "uint64", - "name": "offset", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "limit", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "countTotal", - "type": "bool" - }, - { - "internalType": "bool", - "name": "reverse", - "type": "bool" - } - ], - "internalType": "struct PageRequest", - "name": "pageRequest", - "type": "tuple" - } - ], - "name": "validatorSlashes", - "outputs": [ - { - "components": [ - { - "internalType": "uint64", - "name": "validatorPeriod", - "type": "uint64" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "precision", - "type": "uint8" - } - ], - "internalType": "struct Dec", - "name": "fraction", - "type": "tuple" - } - ], - "internalType": "struct ValidatorSlashEvent[]", - "name": "slashes", - "type": "tuple[]" - }, - { - "components": [ - { - "internalType": "bytes", - "name": "nextKey", - "type": "bytes" - }, - { - "internalType": "uint64", - "name": "total", - "type": "uint64" - } - ], - "internalType": "struct PageResponse", - "name": "pageResponse", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - } - ], - "name": "withdrawDelegatorRewards", - "outputs": [ - { - "components": [ - { - "internalType": "string", - "name": "denom", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "internalType": "struct Coin[]", - "name": "amount", - "type": "tuple[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - } - ], - "name": "withdrawValidatorCommission", - "outputs": [ - { - "components": [ - { - "internalType": "string", - "name": "denom", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "internalType": "struct Coin[]", - "name": "amount", - "type": "tuple[]" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } -] \ No newline at end of file diff --git a/precompiles/distribution/distribution.go b/precompiles/distribution/distribution.go deleted file mode 100644 index 41f70f73..00000000 --- a/precompiles/distribution/distribution.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package distribution - -import ( - "bytes" - "embed" - "fmt" - - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - - storetypes "github.com/cosmos/cosmos-sdk/store/types" - authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" - distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - cmn "github.com/evmos/evmos/v16/precompiles/common" -) - -var _ vm.PrecompiledContract = &Precompile{} - -// Embed abi json file to the executable binary. Needed when importing as dependency. -// -//go:embed abi.json -var f embed.FS - -// Precompile defines the precompiled contract for distribution. -type Precompile struct { - cmn.Precompile - distributionKeeper distributionkeeper.Keeper - stakingKeeper stakingkeeper.Keeper -} - -// NewPrecompile creates a new distribution Precompile instance as a -// PrecompiledContract interface. -func NewPrecompile( - distributionKeeper distributionkeeper.Keeper, - stakingKeeper stakingkeeper.Keeper, - authzKeeper authzkeeper.Keeper, -) (*Precompile, error) { - abiBz, err := f.ReadFile("abi.json") - if err != nil { - return nil, fmt.Errorf("error loading the distribution ABI %s", err) - } - - newAbi, err := abi.JSON(bytes.NewReader(abiBz)) - if err != nil { - return nil, fmt.Errorf(cmn.ErrInvalidABI, err) - } - - return &Precompile{ - Precompile: cmn.Precompile{ - ABI: newAbi, - AuthzKeeper: authzKeeper, - KvGasConfig: storetypes.KVGasConfig(), - TransientKVGasConfig: storetypes.TransientGasConfig(), - ApprovalExpiration: cmn.DefaultExpirationDuration, // should be configurable in the future. - }, - stakingKeeper: stakingKeeper, - distributionKeeper: distributionKeeper, - }, nil -} - -// Address defines the address of the distribution compile contract. -// address: 0x0000000000000000000000000000000000000801 -func (p Precompile) Address() common.Address { - return common.HexToAddress("0x0000000000000000000000000000000000000801") -} - -// RequiredGas calculates the precompiled contract's base gas rate. -func (p Precompile) RequiredGas(input []byte) uint64 { - methodID := input[:4] - - method, err := p.MethodById(methodID) - if err != nil { - // This should never happen since this method is going to fail during Run - return 0 - } - - return p.Precompile.RequiredGas(input, p.IsTransaction(method.Name)) -} - -// Run executes the precompiled contract distribution methods defined in the ABI. -func (p Precompile) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) (bz []byte, err error) { - ctx, stateDB, method, initialGas, args, err := p.RunSetup(evm, contract, readOnly, p.IsTransaction) - if err != nil { - return nil, err - } - - // This handles any out of gas errors that may occur during the execution of a precompile tx or query. - // It avoids panics and returns the out of gas error so the EVM can continue gracefully. - defer cmn.HandleGasError(ctx, contract, initialGas, &err)() - - switch method.Name { - // Custom transactions - case ClaimRewardsMethod: - bz, err = p.ClaimRewards(ctx, evm.Origin, contract, stateDB, method, args) - // Distribution transactions - case SetWithdrawAddressMethod: - bz, err = p.SetWithdrawAddress(ctx, evm.Origin, contract, stateDB, method, args) - case WithdrawDelegatorRewardsMethod: - bz, err = p.WithdrawDelegatorRewards(ctx, evm.Origin, contract, stateDB, method, args) - case WithdrawValidatorCommissionMethod: - bz, err = p.WithdrawValidatorCommission(ctx, evm.Origin, contract, stateDB, method, args) - // Distribution queries - case ValidatorDistributionInfoMethod: - bz, err = p.ValidatorDistributionInfo(ctx, contract, method, args) - case ValidatorOutstandingRewardsMethod: - bz, err = p.ValidatorOutstandingRewards(ctx, contract, method, args) - case ValidatorCommissionMethod: - bz, err = p.ValidatorCommission(ctx, contract, method, args) - case ValidatorSlashesMethod: - bz, err = p.ValidatorSlashes(ctx, contract, method, args) - case DelegationRewardsMethod: - bz, err = p.DelegationRewards(ctx, contract, method, args) - case DelegationTotalRewardsMethod: - bz, err = p.DelegationTotalRewards(ctx, contract, method, args) - case DelegatorValidatorsMethod: - bz, err = p.DelegatorValidators(ctx, contract, method, args) - case DelegatorWithdrawAddressMethod: - bz, err = p.DelegatorWithdrawAddress(ctx, contract, method, args) - } - - if err != nil { - return nil, err - } - - cost := ctx.GasMeter().GasConsumed() - initialGas - - if !contract.UseGas(cost) { - return nil, vm.ErrOutOfGas - } - - return bz, nil -} - -// IsTransaction checks if the given method name corresponds to a transaction or query. -// -// Available distribution transactions are: -// - ClaimRewards -// - SetWithdrawAddress -// - WithdrawDelegatorRewards -// - WithdrawValidatorCommission -func (Precompile) IsTransaction(methodName string) bool { - switch methodName { - case ClaimRewardsMethod, - SetWithdrawAddressMethod, - WithdrawDelegatorRewardsMethod, - WithdrawValidatorCommissionMethod: - return true - default: - return false - } -} diff --git a/precompiles/distribution/distribution_test.go b/precompiles/distribution/distribution_test.go deleted file mode 100644 index 0f90bf1e..00000000 --- a/precompiles/distribution/distribution_test.go +++ /dev/null @@ -1,222 +0,0 @@ -package distribution_test - -import ( - "math/big" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/distribution/types" - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/evmos/evmos/v16/app" - "github.com/evmos/evmos/v16/precompiles/distribution" - "github.com/evmos/evmos/v16/utils" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" -) - -func (s *PrecompileTestSuite) TestIsTransaction() { - testCases := []struct { - name string - method string - isTx bool - }{ - { - distribution.SetWithdrawAddressMethod, - s.precompile.Methods[distribution.SetWithdrawAddressMethod].Name, - true, - }, - { - distribution.WithdrawDelegatorRewardsMethod, - s.precompile.Methods[distribution.WithdrawDelegatorRewardsMethod].Name, - true, - }, - { - distribution.WithdrawValidatorCommissionMethod, - s.precompile.Methods[distribution.WithdrawValidatorCommissionMethod].Name, - true, - }, - { - distribution.ValidatorDistributionInfoMethod, - s.precompile.Methods[distribution.ValidatorDistributionInfoMethod].Name, - false, - }, - { - "invalid", - "invalid", - false, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.Require().Equal(s.precompile.IsTransaction(tc.method), tc.isTx) - }) - } -} - -// TestRun tests the precompile's Run method. -func (s *PrecompileTestSuite) TestRun() { - testcases := []struct { - name string - malleate func() (common.Address, []byte) - readOnly bool - expPass bool - errContains string - }{ - { - name: "pass - set withdraw address transaction", - malleate: func() (common.Address, []byte) { - valAddr, err := sdk.ValAddressFromBech32(s.validators[0].OperatorAddress) - s.Require().NoError(err) - val, _ := s.app.StakingKeeper.GetValidator(s.ctx, valAddr) - coins := sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(1e18))) - s.app.DistrKeeper.AllocateTokensToValidator(s.ctx, val, sdk.NewDecCoinsFromCoins(coins...)) - - input, err := s.precompile.Pack( - distribution.SetWithdrawAddressMethod, - s.address, - s.address.String(), - ) - s.Require().NoError(err, "failed to pack input") - return s.address, input - }, - readOnly: false, - expPass: true, - }, - { - name: "pass - withdraw validator commissions transaction", - malleate: func() (common.Address, []byte) { - hexAddr := common.Bytes2Hex(s.address.Bytes()) - valAddr, err := sdk.ValAddressFromHex(hexAddr) - s.Require().NoError(err) - caller := common.BytesToAddress(valAddr) - - valCommission := sdk.DecCoins{sdk.NewDecCoinFromDec(utils.BaseDenom, math.LegacyNewDecWithPrec(1000000000000000000, 1))} - // set outstanding rewards - s.app.DistrKeeper.SetValidatorOutstandingRewards(s.ctx, valAddr, types.ValidatorOutstandingRewards{Rewards: valCommission}) - // set commission - s.app.DistrKeeper.SetValidatorAccumulatedCommission(s.ctx, valAddr, types.ValidatorAccumulatedCommission{Commission: valCommission}) - - input, err := s.precompile.Pack( - distribution.WithdrawValidatorCommissionMethod, - valAddr.String(), - ) - s.Require().NoError(err, "failed to pack input") - return caller, input - }, - readOnly: false, - expPass: true, - }, - { - name: "pass - withdraw delegator rewards transaction", - malleate: func() (common.Address, []byte) { - valAddr, err := sdk.ValAddressFromBech32(s.validators[0].OperatorAddress) - s.Require().NoError(err) - val, _ := s.app.StakingKeeper.GetValidator(s.ctx, valAddr) - coins := sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(1e18))) - s.app.DistrKeeper.AllocateTokensToValidator(s.ctx, val, sdk.NewDecCoinsFromCoins(coins...)) - - input, err := s.precompile.Pack( - distribution.WithdrawDelegatorRewardsMethod, - s.address, - valAddr.String(), - ) - s.Require().NoError(err, "failed to pack input") - - return s.address, input - }, - readOnly: false, - expPass: true, - }, - { - name: "pass - claim rewards transaction", - malleate: func() (common.Address, []byte) { - valAddr, err := sdk.ValAddressFromBech32(s.validators[0].OperatorAddress) - s.Require().NoError(err) - val, _ := s.app.StakingKeeper.GetValidator(s.ctx, valAddr) - coins := sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(1e18))) - s.app.DistrKeeper.AllocateTokensToValidator(s.ctx, val, sdk.NewDecCoinsFromCoins(coins...)) - - input, err := s.precompile.Pack( - distribution.ClaimRewardsMethod, - s.address, - uint32(2), - ) - s.Require().NoError(err, "failed to pack input") - - return s.address, input - }, - readOnly: false, - expPass: true, - }, - } - - for _, tc := range testcases { - tc := tc - s.Run(tc.name, func() { - // setup basic test suite - s.SetupTest() - - baseFee := s.app.FeeMarketKeeper.GetBaseFee(s.ctx) - - // malleate testcase - caller, input := tc.malleate() - - contract := vm.NewPrecompile(vm.AccountRef(caller), s.precompile, big.NewInt(0), uint64(1e6)) - contract.Input = input - - contractAddr := contract.Address() - // Build and sign Ethereum transaction - txArgs := evmtypes.EvmTxArgs{ - ChainID: s.app.EvmKeeper.ChainID(), - Nonce: 0, - To: &contractAddr, - Amount: nil, - GasLimit: 100000, - GasPrice: app.MainnetMinGasPrices.BigInt(), - GasFeeCap: baseFee, - GasTipCap: big.NewInt(1), - Accesses: ðtypes.AccessList{}, - } - msgEthereumTx := evmtypes.NewTx(&txArgs) - - msgEthereumTx.From = s.address.String() - err := msgEthereumTx.Sign(s.ethSigner, s.signer) - s.Require().NoError(err, "failed to sign Ethereum message") - - // Instantiate config - proposerAddress := s.ctx.BlockHeader().ProposerAddress - cfg, err := s.app.EvmKeeper.EVMConfig(s.ctx, proposerAddress, s.app.EvmKeeper.ChainID()) - s.Require().NoError(err, "failed to instantiate EVM config") - - msg, err := msgEthereumTx.AsMessage(s.ethSigner, baseFee) - s.Require().NoError(err, "failed to instantiate Ethereum message") - - // Instantiate EVM - evm := s.app.EvmKeeper.NewEVM( - s.ctx, msg, cfg, nil, s.stateDB, - ) - - params := s.app.EvmKeeper.GetParams(s.ctx) - activePrecompiles := params.GetActivePrecompilesAddrs() - precompileMap := s.app.EvmKeeper.Precompiles(activePrecompiles...) - err = vm.ValidatePrecompiles(precompileMap, activePrecompiles) - s.Require().NoError(err, "invalid precompiles", activePrecompiles) - evm.WithPrecompiles(precompileMap, activePrecompiles) - - // Run precompiled contract - bz, err := s.precompile.Run(evm, contract, tc.readOnly) - - // Check results - if tc.expPass { - s.Require().NoError(err, "expected no error when running the precompile") - s.Require().NotNil(bz, "expected returned bytes not to be nil") - } else { - s.Require().Error(err, "expected error to be returned when running the precompile") - s.Require().Nil(bz, "expected returned bytes to be nil") - s.Require().ErrorContains(err, tc.errContains) - } - }) - } -} diff --git a/precompiles/distribution/errors.go b/precompiles/distribution/errors.go deleted file mode 100644 index 9728a93d..00000000 --- a/precompiles/distribution/errors.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) -package distribution - -const ( - // ErrSetWithdrawAddrAuth is raised when no authorization to set the withdraw address exists. - ErrSetWithdrawAddrAuth = "set withdrawer address authorization for address %s does not exist" - // ErrWithdrawDelRewardsAuth is raised when no authorization to withdraw delegation rewards exists. - ErrWithdrawDelRewardsAuth = "withdraw delegation rewards authorization for address %s does not exist" - // ErrWithdrawValCommissionAuth is raised when no authorization to withdraw validator commission exists. - ErrWithdrawValCommissionAuth = "withdraw validator commission authorization for address %s does not exist" - // ErrDifferentValidator is raised when the origin address is not the same as the validator address. - ErrDifferentValidator = "origin address %s is not the same as validator address %s" -) diff --git a/precompiles/distribution/events.go b/precompiles/distribution/events.go deleted file mode 100644 index ca6872a2..00000000 --- a/precompiles/distribution/events.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package distribution - -import ( - "bytes" - "reflect" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - cmn "github.com/evmos/evmos/v16/precompiles/common" -) - -const ( - // EventTypeSetWithdrawAddress defines the event type for the distribution SetWithdrawAddressMethod transaction. - EventTypeSetWithdrawAddress = "SetWithdrawerAddress" - // EventTypeWithdrawDelegatorRewards defines the event type for the distribution WithdrawDelegatorRewardsMethod transaction. - EventTypeWithdrawDelegatorRewards = "WithdrawDelegatorRewards" - // EventTypeWithdrawValidatorCommission defines the event type for the distribution WithdrawValidatorCommissionMethod transaction. - EventTypeWithdrawValidatorCommission = "WithdrawValidatorCommission" - // EventTypeClaimRewards defines the event type for the distribution ClaimRewardsMethod transaction. - EventTypeClaimRewards = "ClaimRewards" -) - -// EmitClaimRewardsEvent creates a new event emitted on a ClaimRewards transaction. -func (p Precompile) EmitClaimRewardsEvent(ctx sdk.Context, stateDB vm.StateDB, delegatorAddress common.Address, totalCoins sdk.Coins) error { - // Prepare the event topics - event := p.ABI.Events[EventTypeClaimRewards] - topics := make([]common.Hash, 2) - - // The first topic is always the signature of the event. - topics[0] = event.ID - - var err error - topics[1], err = cmn.MakeTopic(delegatorAddress) - if err != nil { - return err - } - - totalAmount := totalCoins.AmountOf(p.stakingKeeper.BondDenom(ctx)) - // Pack the arguments to be used as the Data field - arguments := abi.Arguments{event.Inputs[1]} - packed, err := arguments.Pack(totalAmount.BigInt()) - if err != nil { - return err - } - - stateDB.AddLog(ðtypes.Log{ - Address: p.Address(), - Topics: topics, - Data: packed, - BlockNumber: uint64(ctx.BlockHeight()), - }) - - return nil -} - -// EmitSetWithdrawAddressEvent creates a new event emitted on a SetWithdrawAddressMethod transaction. -func (p Precompile) EmitSetWithdrawAddressEvent(ctx sdk.Context, stateDB vm.StateDB, caller common.Address, withdrawerAddress string) error { - // Prepare the event topics - event := p.ABI.Events[EventTypeSetWithdrawAddress] - topics := make([]common.Hash, 2) - - // The first topic is always the signature of the event. - topics[0] = event.ID - - var err error - topics[1], err = cmn.MakeTopic(caller) - if err != nil { - return err - } - - // Pack the arguments to be used as the Data field - arguments := abi.Arguments{event.Inputs[1]} - packed, err := arguments.Pack(withdrawerAddress) - if err != nil { - return err - } - - stateDB.AddLog(ðtypes.Log{ - Address: p.Address(), - Topics: topics, - Data: packed, - BlockNumber: uint64(ctx.BlockHeight()), - }) - - return nil -} - -// EmitWithdrawDelegatorRewardsEvent creates a new event emitted on a WithdrawDelegatorRewards transaction. -func (p Precompile) EmitWithdrawDelegatorRewardsEvent(ctx sdk.Context, stateDB vm.StateDB, delegatorAddress common.Address, validatorAddress string, coins sdk.Coins) error { - valAddr, err := sdk.ValAddressFromBech32(validatorAddress) - if err != nil { - return err - } - - // Prepare the event topics - event := p.ABI.Events[EventTypeWithdrawDelegatorRewards] - topics := make([]common.Hash, 3) - - // The first topic is always the signature of the event. - topics[0] = event.ID - - topics[1], err = cmn.MakeTopic(delegatorAddress) - if err != nil { - return err - } - - topics[2], err = cmn.MakeTopic(common.BytesToAddress(valAddr.Bytes())) - if err != nil { - return err - } - - // Prepare the event data - var b bytes.Buffer - b.Write(cmn.PackNum(reflect.ValueOf(coins[0].Amount.BigInt()))) - - stateDB.AddLog(ðtypes.Log{ - Address: p.Address(), - Topics: topics, - Data: b.Bytes(), - BlockNumber: uint64(ctx.BlockHeight()), - }) - - return nil -} - -// EmitWithdrawValidatorCommissionEvent creates a new event emitted on a WithdrawValidatorCommission transaction. -func (p Precompile) EmitWithdrawValidatorCommissionEvent(ctx sdk.Context, stateDB vm.StateDB, validatorAddress string, coins sdk.Coins) error { - // Prepare the event topics - event := p.ABI.Events[EventTypeWithdrawValidatorCommission] - topics := make([]common.Hash, 2) - - // The first topic is always the signature of the event. - topics[0] = event.ID - - var err error - topics[1], err = cmn.MakeTopic(validatorAddress) - if err != nil { - return err - } - - // Prepare the event data - var b bytes.Buffer - b.Write(cmn.PackNum(reflect.ValueOf(coins[0].Amount.BigInt()))) - - stateDB.AddLog(ðtypes.Log{ - Address: p.Address(), - Topics: topics, - Data: b.Bytes(), - BlockNumber: uint64(ctx.BlockHeight()), - }) - - return nil -} diff --git a/precompiles/distribution/events_test.go b/precompiles/distribution/events_test.go deleted file mode 100644 index a667c3a8..00000000 --- a/precompiles/distribution/events_test.go +++ /dev/null @@ -1,249 +0,0 @@ -package distribution_test - -import ( - "math/big" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/distribution/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - cmn "github.com/evmos/evmos/v16/precompiles/common" - "github.com/evmos/evmos/v16/precompiles/distribution" - "github.com/evmos/evmos/v16/utils" -) - -func (s *PrecompileTestSuite) TestSetWithdrawAddressEvent() { - method := s.precompile.Methods[distribution.SetWithdrawAddressMethod] - testCases := []struct { - name string - malleate func(operatorAddress string) []interface{} - postCheck func() - gas uint64 - expError bool - errContains string - }{ - { - "success - the correct event is emitted", - func(operatorAddress string) []interface{} { - return []interface{}{ - s.address, - s.address.String(), - } - }, - func() { - log := s.stateDB.Logs()[0] - s.Require().Equal(log.Address, s.precompile.Address()) - - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[distribution.EventTypeSetWithdrawAddress] - s.Require().Equal(crypto.Keccak256Hash([]byte(event.Sig)), common.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - - // Check the fully unpacked event matches the one emitted - var setWithdrawerAddrEvent distribution.EventSetWithdrawAddress - err := cmn.UnpackLog(s.precompile.ABI, &setWithdrawerAddrEvent, distribution.EventTypeSetWithdrawAddress, *log) - s.Require().NoError(err) - s.Require().Equal(s.address, setWithdrawerAddrEvent.Caller) - s.Require().Equal(sdk.MustBech32ifyAddressBytes("evmos", s.address.Bytes()), setWithdrawerAddrEvent.WithdrawerAddress) - }, - 20000, - false, - "", - }, - } - - for _, tc := range testCases { - s.SetupTest() - - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - s.ctx = s.ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - initialGas := s.ctx.GasMeter().GasConsumed() - s.Require().Zero(initialGas) - - _, err := s.precompile.SetWithdrawAddress(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate(s.validators[0].OperatorAddress)) - - if tc.expError { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck() - } - } -} - -func (s *PrecompileTestSuite) TestWithdrawDelegatorRewardsEvent() { - method := s.precompile.Methods[distribution.WithdrawDelegatorRewardsMethod] - testCases := []struct { - name string - malleate func(operatorAddress string) []interface{} - postCheck func() - gas uint64 - expError bool - errContains string - }{ - { - "success - the correct event is emitted", - func(operatorAddress string) []interface{} { - valAddr, err := sdk.ValAddressFromBech32(operatorAddress) - s.Require().NoError(err) - val, _ := s.app.StakingKeeper.GetValidator(s.ctx, valAddr) - coins := sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(1e18))) - s.app.DistrKeeper.AllocateTokensToValidator(s.ctx, val, sdk.NewDecCoinsFromCoins(coins...)) - return []interface{}{ - s.address, - operatorAddress, - } - }, - func() { - log := s.stateDB.Logs()[0] - s.Require().Equal(log.Address, s.precompile.Address()) - - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[distribution.EventTypeWithdrawDelegatorRewards] - s.Require().Equal(crypto.Keccak256Hash([]byte(event.Sig)), common.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - - optAddr, err := sdk.ValAddressFromBech32(s.validators[0].OperatorAddress) - s.Require().NoError(err) - optHexAddr := common.BytesToAddress(optAddr) - - // Check the fully unpacked event matches the one emitted - var delegatorRewards distribution.EventWithdrawDelegatorRewards - err = cmn.UnpackLog(s.precompile.ABI, &delegatorRewards, distribution.EventTypeWithdrawDelegatorRewards, *log) - s.Require().NoError(err) - s.Require().Equal(s.address, delegatorRewards.DelegatorAddress) - s.Require().Equal(optHexAddr, delegatorRewards.ValidatorAddress) - s.Require().Equal(big.NewInt(1000000000000000000), delegatorRewards.Amount) - }, - 20000, - false, - "", - }, - } - - for _, tc := range testCases { - s.SetupTest() - - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - s.ctx = s.ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - initialGas := s.ctx.GasMeter().GasConsumed() - s.Require().Zero(initialGas) - - _, err := s.precompile.WithdrawDelegatorRewards(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate(s.validators[0].OperatorAddress)) - - if tc.expError { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck() - } - } -} - -func (s *PrecompileTestSuite) TestWithdrawValidatorCommissionEvent() { - method := s.precompile.Methods[distribution.WithdrawValidatorCommissionMethod] - testCases := []struct { - name string - malleate func(operatorAddress string) []interface{} - postCheck func() - gas uint64 - expError bool - errContains string - }{ - { - "success - the correct event is emitted", - func(operatorAddress string) []interface{} { - valAddr, err := sdk.ValAddressFromBech32(operatorAddress) - s.Require().NoError(err) - valCommission := sdk.DecCoins{sdk.NewDecCoinFromDec(utils.BaseDenom, math.LegacyNewDecWithPrec(1000000000000000000, 1))} - // set outstanding rewards - s.app.DistrKeeper.SetValidatorOutstandingRewards(s.ctx, valAddr, types.ValidatorOutstandingRewards{Rewards: valCommission}) - // set commission - s.app.DistrKeeper.SetValidatorAccumulatedCommission(s.ctx, valAddr, types.ValidatorAccumulatedCommission{Commission: valCommission}) - return []interface{}{ - operatorAddress, - } - }, - func() { - log := s.stateDB.Logs()[0] - s.Require().Equal(log.Address, s.precompile.Address()) - - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[distribution.EventTypeWithdrawValidatorCommission] - s.Require().Equal(crypto.Keccak256Hash([]byte(event.Sig)), common.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - - // Check the fully unpacked event matches the one emitted - var validatorRewards distribution.EventWithdrawValidatorRewards - err := cmn.UnpackLog(s.precompile.ABI, &validatorRewards, distribution.EventTypeWithdrawValidatorCommission, *log) - s.Require().NoError(err) - s.Require().Equal(crypto.Keccak256Hash([]byte(s.validators[0].OperatorAddress)), validatorRewards.ValidatorAddress) - s.Require().Equal(big.NewInt(100000000000000000), validatorRewards.Commission) - }, - 20000, - false, - "", - }, - } - - for _, tc := range testCases { - s.SetupTest() - - validatorAddress := common.BytesToAddress(s.validators[0].GetOperator().Bytes()) - contract := vm.NewContract(vm.AccountRef(validatorAddress), s.precompile, big.NewInt(0), tc.gas) - s.ctx = s.ctx.WithGasMeter(sdk.NewInfiniteGasMeter()) - initialGas := s.ctx.GasMeter().GasConsumed() - s.Require().Zero(initialGas) - - _, err := s.precompile.WithdrawValidatorCommission(s.ctx, validatorAddress, contract, s.stateDB, &method, tc.malleate(s.validators[0].OperatorAddress)) - - if tc.expError { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck() - } - } -} - -func (s *PrecompileTestSuite) TestClaimRewardsEvent() { - testCases := []struct { - name string - coins sdk.Coins - postCheck func() - }{ - { - "success", - sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(1e18))), - func() { - log := s.stateDB.Logs()[0] - s.Require().Equal(log.Address, s.precompile.Address()) - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[distribution.EventTypeClaimRewards] - s.Require().Equal(event.ID, common.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - - var claimRewardsEvent distribution.EventClaimRewards - err := cmn.UnpackLog(s.precompile.ABI, &claimRewardsEvent, distribution.EventTypeClaimRewards, *log) - s.Require().NoError(err) - s.Require().Equal(common.BytesToAddress(s.address.Bytes()), claimRewardsEvent.DelegatorAddress) - s.Require().Equal(big.NewInt(1e18), claimRewardsEvent.Amount) - }, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - err := s.precompile.EmitClaimRewardsEvent(s.ctx, s.stateDB, s.address, tc.coins) - s.Require().NoError(err) - tc.postCheck() - }) - } -} diff --git a/precompiles/distribution/integration_test.go b/precompiles/distribution/integration_test.go deleted file mode 100644 index 3be19242..00000000 --- a/precompiles/distribution/integration_test.go +++ /dev/null @@ -1,1393 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) -package distribution_test - -import ( - "fmt" - "math/big" - - "github.com/evmos/evmos/v16/utils" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/query" - distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - cmn "github.com/evmos/evmos/v16/precompiles/common" - "github.com/evmos/evmos/v16/precompiles/distribution" - "github.com/evmos/evmos/v16/precompiles/testutil" - "github.com/evmos/evmos/v16/precompiles/testutil/contracts" - evmosutil "github.com/evmos/evmos/v16/testutil" - testutiltx "github.com/evmos/evmos/v16/testutil/tx" - - //nolint:revive // dot imports are fine for Ginkgo - . "github.com/onsi/ginkgo/v2" - //nolint:revive // dot imports are fine for Ginkgo - . "github.com/onsi/gomega" -) - -// General variables used for integration tests -var ( - // differentAddr is an address generated for testing purposes that e.g. raises the different origin error - differentAddr = testutiltx.GenerateAddress() - // expRewardAmt is the expected amount of rewards - expRewardAmt = big.NewInt(2000000000000000000) - // gasPrice is the gas price used for the transactions - gasPrice = big.NewInt(1e9) - // defaultCallArgs are the default arguments for calling the smart contract - // - // NOTE: this has to be populated in a BeforeEach block because the contractAddr would otherwise be a nil address. - defaultCallArgs contracts.CallArgs - - // defaultLogCheck instantiates a log check arguments struct with the precompile ABI events populated. - defaultLogCheck testutil.LogCheckArgs - // differentOriginCheck defines the arguments to check if the precompile returns different origin error - differentOriginCheck testutil.LogCheckArgs - // passCheck defines the arguments to check if the precompile returns no error - passCheck testutil.LogCheckArgs - // outOfGasCheck defines the arguments to check if the precompile returns out of gas error - outOfGasCheck testutil.LogCheckArgs -) - -var _ = Describe("Calling distribution precompile from EOA", func() { - BeforeEach(func() { - s.SetupTest() - - // set the default call arguments - defaultCallArgs = contracts.CallArgs{ - ContractAddr: s.precompile.Address(), - ContractABI: s.precompile.ABI, - PrivKey: s.privKey, - } - - defaultLogCheck = testutil.LogCheckArgs{ - ABIEvents: s.precompile.ABI.Events, - } - differentOriginCheck = defaultLogCheck.WithErrContains(cmn.ErrDifferentOrigin, s.address, differentAddr) - passCheck = defaultLogCheck.WithExpPass(true) - outOfGasCheck = defaultLogCheck.WithErrContains(vm.ErrOutOfGas.Error()) - }) - - // ===================================== - // TRANSACTIONS - // ===================================== - Describe("Execute SetWithdrawAddress transaction", func() { - const method = distribution.SetWithdrawAddressMethod - // defaultSetWithdrawArgs are the default arguments to set the withdraw address - // - // NOTE: this has to be populated in the BeforeEach block because the private key otherwise is not yet initialized. - var defaultSetWithdrawArgs contracts.CallArgs - - BeforeEach(func() { - // set the default call arguments - defaultSetWithdrawArgs = defaultCallArgs.WithMethodName(method) - }) - - It("should return error if the provided gasLimit is too low", func() { - setWithdrawArgs := defaultSetWithdrawArgs. - WithGasLimit(30000). - WithArgs(s.address, differentAddr.String()) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, setWithdrawArgs, outOfGasCheck) - Expect(err).To(HaveOccurred(), "error while calling the precompile") - Expect(err.Error()).To(ContainSubstring("out of gas"), "expected out of gas error") - - // withdraw address should remain unchanged - withdrawAddr := s.app.DistrKeeper.GetDelegatorWithdrawAddr(s.ctx, s.address.Bytes()) - Expect(withdrawAddr.Bytes()).To(Equal(s.address.Bytes()), "expected withdraw address to remain unchanged") - }) - - It("should return error if the origin is different than the delegator", func() { - setWithdrawArgs := defaultSetWithdrawArgs.WithArgs(differentAddr, s.address.String()) - - withdrawAddrSetCheck := defaultLogCheck.WithErrContains(cmn.ErrDifferentOrigin, s.address.String(), differentAddr.String()) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, setWithdrawArgs, withdrawAddrSetCheck) - Expect(err).To(HaveOccurred(), "error while calling the precompile") - Expect(err.Error()).To(ContainSubstring(fmt.Sprintf(cmn.ErrDifferentOrigin, s.address, differentAddr)), "expected different origin error") - }) - - It("should set withdraw address", func() { - // initially, withdraw address should be same as address - withdrawAddr := s.app.DistrKeeper.GetDelegatorWithdrawAddr(s.ctx, s.address.Bytes()) - Expect(withdrawAddr.Bytes()).To(Equal(s.address.Bytes())) - - setWithdrawArgs := defaultSetWithdrawArgs.WithArgs(s.address, differentAddr.String()) - - withdrawAddrSetCheck := passCheck. - WithExpEvents(distribution.EventTypeSetWithdrawAddress) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, setWithdrawArgs, withdrawAddrSetCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - // withdraw should be updated - withdrawAddr = s.app.DistrKeeper.GetDelegatorWithdrawAddr(s.ctx, s.address.Bytes()) - Expect(withdrawAddr.Bytes()).To(Equal(differentAddr.Bytes()), "expected different withdraw address") - }) - }) - - Describe("Execute WithdrawDelegatorRewards transaction", func() { - // defaultWithdrawRewardsArgs are the default arguments to withdraw rewards - // - // NOTE: this has to be populated in the BeforeEach block because the private key otherwise is not yet initialized. - var defaultWithdrawRewardsArgs contracts.CallArgs - - BeforeEach(func() { - // set the default call arguments - defaultWithdrawRewardsArgs = defaultCallArgs.WithMethodName(distribution.WithdrawDelegatorRewardsMethod) - s.prepareStakingRewards(stakingRewards{s.address.Bytes(), s.validators[0], rewards}) - }) - - It("should return error if the origin is different than the delegator", func() { - withdrawRewardsArgs := defaultWithdrawRewardsArgs.WithArgs(differentAddr, s.validators[0].OperatorAddress) - - withdrawalCheck := defaultLogCheck.WithErrContains(cmn.ErrDifferentOrigin, s.address.String(), differentAddr.String()) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, withdrawRewardsArgs, withdrawalCheck) - Expect(err).To(HaveOccurred(), "error while calling the precompile") - Expect(err.Error()).To(ContainSubstring(fmt.Sprintf(cmn.ErrDifferentOrigin, s.address, differentAddr)), "expected different origin error") - }) - - It("should withdraw delegation rewards", func() { - // get initial balance - initialBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - Expect(initialBalance.Amount).To(Equal(initialBalance.Amount)) - - withdrawRewardsArgs := defaultWithdrawRewardsArgs. - WithArgs(s.address, s.validators[0].OperatorAddress). - WithGasPrice(gasPrice) - - withdrawalCheck := passCheck. - WithExpEvents(distribution.EventTypeWithdrawDelegatorRewards) - - res, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, withdrawRewardsArgs, withdrawalCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - var rewards []cmn.Coin - err = s.precompile.UnpackIntoInterface(&rewards, distribution.WithdrawDelegatorRewardsMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(rewards)).To(Equal(1)) - Expect(rewards[0].Denom).To(Equal(s.bondDenom)) - Expect(rewards[0].Amount).To(Equal(expRewardAmt)) - - // check that the rewards were added to the balance - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - fees := gasPrice.Int64() * res.GasUsed - expFinal := initialBalance.Amount.Int64() + expRewardAmt.Int64() - fees - Expect(finalBalance.Amount.Equal(math.NewInt(expFinal))).To(BeTrue(), "expected final balance to be equal to initial balance + rewards - fees") - }) - }) - - Describe("Validator Commission: Execute WithdrawValidatorCommission tx", func() { - var ( - // defaultWithdrawCommissionArgs are the default arguments to withdraw commission - // - // NOTE: this has to be populated in the BeforeEach block because the private key otherwise is not yet initialized. - defaultWithdrawCommissionArgs contracts.CallArgs - - // expCommAmt is the expected commission amount - expCommAmt = big.NewInt(1) - // commDec is the commission rate - commDec = math.LegacyNewDec(1) - valAddr sdk.ValAddress - stakeAmt math.Int - ) - - BeforeEach(func() { - // set the default call arguments - defaultWithdrawCommissionArgs = defaultCallArgs.WithMethodName( - distribution.WithdrawValidatorCommissionMethod, - ) - - // create a validator with s.address and s.privKey because this account is - // used for signing txs - stakeAmt = math.NewInt(100) - testutil.CreateValidator(s.ctx, s.T(), s.privKey.PubKey(), s.app.StakingKeeper, stakeAmt) - - // set some validator commission - valAddr = s.address.Bytes() - val := s.app.StakingKeeper.Validator(s.ctx, valAddr) - valCommission := sdk.DecCoins{sdk.NewDecCoinFromDec(s.bondDenom, commDec)} - - s.app.DistrKeeper.SetValidatorAccumulatedCommission(s.ctx, valAddr, distrtypes.ValidatorAccumulatedCommission{Commission: valCommission}) - s.app.DistrKeeper.AllocateTokensToValidator(s.ctx, val, sdk.DecCoins{sdk.NewDecCoin(s.bondDenom, stakeAmt)}) - }) - - It("should return error if the provided gasLimit is too low", func() { - withdrawCommissionArgs := defaultWithdrawCommissionArgs. - WithGasLimit(50000). - WithArgs(valAddr.String()) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, withdrawCommissionArgs, outOfGasCheck) - Expect(err).To(HaveOccurred(), "error while calling the precompile") - Expect(err.Error()).To(ContainSubstring("out of gas"), "expected out of gas error") - }) - - It("should return error if the origin is different than the validator", func() { - withdrawCommissionArgs := defaultWithdrawCommissionArgs.WithArgs(s.validators[0].OperatorAddress) - validatorHexAddr := common.BytesToAddress(s.validators[0].GetOperator()) - - withdrawalCheck := defaultLogCheck.WithErrContains(cmn.ErrDifferentOrigin, s.address.String(), validatorHexAddr.String()) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, withdrawCommissionArgs, withdrawalCheck) - Expect(err).To(HaveOccurred(), "error while calling the precompile") - Expect(err.Error()).To(ContainSubstring(fmt.Sprintf(cmn.ErrDifferentOrigin, s.address, validatorHexAddr)), "expected different origin error") - }) - - It("should withdraw validator commission", func() { - // initial balance should be the initial amount minus the staked amount used to create the validator - initialBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - Expect(initialBalance.Amount).To(Equal(math.NewInt(4999999999999999900))) - - withdrawCommissionArgs := defaultWithdrawCommissionArgs. - WithArgs(valAddr.String()). - WithGasPrice(gasPrice) - - withdrawalCheck := passCheck. - WithExpEvents(distribution.EventTypeWithdrawValidatorCommission) - - res, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, withdrawCommissionArgs, withdrawalCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - var comm []cmn.Coin - err = s.precompile.UnpackIntoInterface(&comm, distribution.WithdrawValidatorCommissionMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(comm)).To(Equal(1)) - Expect(comm[0].Denom).To(Equal(s.bondDenom)) - Expect(comm[0].Amount).To(Equal(expCommAmt)) - - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - fees := gasPrice.Int64() * res.GasUsed - expFinal := initialBalance.Amount.Int64() + expCommAmt.Int64() - fees - Expect(finalBalance.Amount.Equal(math.NewInt(expFinal))).To(BeTrue(), "expected final balance to be equal to the final balance after withdrawing commission") - }) - }) - - Describe("Execute ClaimRewards transaction", func() { - // defaultWithdrawRewardsArgs are the default arguments to withdraw rewards - // - // NOTE: this has to be populated in the BeforeEach block because the private key otherwise is not yet initialized. - var defaultClaimRewardsArgs contracts.CallArgs - startingBalance := math.NewInt(5e18) - expectedBalance := math.NewInt(8999665039062500000) - - BeforeEach(func() { - // set the default call arguments - defaultClaimRewardsArgs = defaultCallArgs.WithMethodName(distribution.ClaimRewardsMethod) - s.prepareStakingRewards(stakingRewards{s.address.Bytes(), s.validators[0], rewards}) - s.prepareStakingRewards(stakingRewards{s.address.Bytes(), s.validators[1], rewards}) - }) - - It("should return err if the origin is different than the delegator", func() { - claimRewardsArgs := defaultClaimRewardsArgs.WithArgs(differentAddr, uint32(1)) - - claimRewardsCheck := defaultLogCheck.WithErrContains(cmn.ErrDifferentOrigin, s.address.String(), differentAddr.String()) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, claimRewardsArgs, claimRewardsCheck) - Expect(err).To(HaveOccurred(), "error while calling the precompile") - Expect(err.Error()).To(ContainSubstring(fmt.Sprintf(cmn.ErrDifferentOrigin, s.address, differentAddr)), "expected different origin error") - }) - - It("should claim all rewards from all validators", func() { - initialBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - Expect(initialBalance.Amount).To(Equal(startingBalance)) - - claimRewardsArgs := defaultClaimRewardsArgs.WithArgs(s.address, uint32(2)) - claimRewardsCheck := passCheck.WithExpEvents(distribution.EventTypeClaimRewards) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, claimRewardsArgs, claimRewardsCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - // check that the rewards were added to the balance - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - Expect(finalBalance.Amount.Equal(expectedBalance)).To(BeTrue(), "expected final balance to be equal to initial balance + rewards - fees") - }) - }) - - // ===================================== - // QUERIES - // ===================================== - Describe("Execute queries", func() { - It("should get validator distribution info - validatorDistributionInfo query", func() { - addr := sdk.AccAddress(s.validators[0].GetOperator()) - // fund validator account to make self-delegation - err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, addr, 10) - Expect(err).To(BeNil()) - // make a self delegation - _, err = s.app.StakingKeeper.Delegate(s.ctx, addr, math.NewInt(1), stakingtypes.Unspecified, s.validators[0], true) - Expect(err).To(BeNil()) - - valDistArgs := defaultCallArgs. - WithMethodName(distribution.ValidatorDistributionInfoMethod). - WithArgs(s.validators[0].OperatorAddress) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, valDistArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - var out distribution.ValidatorDistributionInfoOutput - err = s.precompile.UnpackIntoInterface(&out, distribution.ValidatorDistributionInfoMethod, ethRes.Ret) - Expect(err).To(BeNil()) - - expAddr := sdk.AccAddress(s.validators[0].GetOperator()) - Expect(expAddr.String()).To(Equal(out.DistributionInfo.OperatorAddress)) - Expect(0).To(Equal(len(out.DistributionInfo.Commission))) - Expect(0).To(Equal(len(out.DistributionInfo.SelfBondRewards))) - }) - - It("should get validator outstanding rewards - validatorOutstandingRewards query", func() { //nolint:dupl - valRewards := sdk.DecCoins{sdk.NewDecCoinFromDec(s.bondDenom, math.LegacyNewDec(1))} - // set outstanding rewards - s.app.DistrKeeper.SetValidatorOutstandingRewards(s.ctx, s.validators[0].GetOperator(), distrtypes.ValidatorOutstandingRewards{Rewards: valRewards}) - - valOutRewardsArgs := defaultCallArgs. - WithMethodName(distribution.ValidatorOutstandingRewardsMethod). - WithArgs(s.validators[0].OperatorAddress) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, valOutRewardsArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - var rewards []cmn.DecCoin - err = s.precompile.UnpackIntoInterface(&rewards, distribution.ValidatorOutstandingRewardsMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(rewards)).To(Equal(1)) - Expect(uint8(18)).To(Equal(rewards[0].Precision)) - Expect(s.bondDenom).To(Equal(rewards[0].Denom)) - Expect(expValAmount).To(Equal(rewards[0].Amount.Int64())) - }) - - It("should get validator commission - validatorCommission query", func() { //nolint:dupl - // set commission - valCommission := sdk.DecCoins{sdk.NewDecCoinFromDec(s.bondDenom, math.LegacyNewDec(1))} - s.app.DistrKeeper.SetValidatorAccumulatedCommission(s.ctx, s.validators[0].GetOperator(), distrtypes.ValidatorAccumulatedCommission{Commission: valCommission}) - - valCommArgs := defaultCallArgs. - WithMethodName(distribution.ValidatorCommissionMethod). - WithArgs(s.validators[0].OperatorAddress) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, valCommArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - var commission []cmn.DecCoin - err = s.precompile.UnpackIntoInterface(&commission, distribution.ValidatorCommissionMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(commission)).To(Equal(1)) - Expect(uint8(18)).To(Equal(commission[0].Precision)) - Expect(s.bondDenom).To(Equal(commission[0].Denom)) - Expect(expValAmount).To(Equal(commission[0].Amount.Int64())) - }) - - Context("validatorSlashes query query", func() { - It("should get validator slashing events (default pagination)", func() { - // set slash event - slashEvent := distrtypes.ValidatorSlashEvent{ValidatorPeriod: 1, Fraction: math.LegacyNewDec(5)} - s.app.DistrKeeper.SetValidatorSlashEvent(s.ctx, s.validators[0].GetOperator(), 2, 1, slashEvent) - - valSlashArgs := defaultCallArgs. - WithMethodName(distribution.ValidatorSlashesMethod). - WithArgs( - s.validators[0].OperatorAddress, - uint64(1), uint64(5), - query.PageRequest{}, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, valSlashArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - var out distribution.ValidatorSlashesOutput - err = s.precompile.UnpackIntoInterface(&out, distribution.ValidatorSlashesMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(out.Slashes)).To(Equal(1)) - Expect(slashEvent.Fraction.BigInt()).To(Equal(out.Slashes[0].Fraction.Value)) - Expect(slashEvent.ValidatorPeriod).To(Equal(out.Slashes[0].ValidatorPeriod)) - Expect(uint64(1)).To(Equal(out.PageResponse.Total)) - Expect(out.PageResponse.NextKey).To(BeEmpty()) - }) - - It("should get validator slashing events - query w/pagination limit = 1)", func() { - // set 2 slashing events for validator[0] - slashEvent := s.setupValidatorSlashes(s.validators[0].GetOperator(), 2) - - valSlashArgs := defaultCallArgs. - WithMethodName(distribution.ValidatorSlashesMethod). - WithArgs( - s.validators[0].OperatorAddress, - uint64(1), uint64(5), - query.PageRequest{ - Limit: 1, - CountTotal: true, - }, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, valSlashArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - var out distribution.ValidatorSlashesOutput - err = s.precompile.UnpackIntoInterface(&out, distribution.ValidatorSlashesMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(out.Slashes)).To(Equal(1)) - Expect(slashEvent.Fraction.BigInt()).To(Equal(out.Slashes[0].Fraction.Value)) - Expect(slashEvent.ValidatorPeriod).To(Equal(out.Slashes[0].ValidatorPeriod)) - // total slashes count is 2 - Expect(uint64(2)).To(Equal(out.PageResponse.Total)) - Expect(out.PageResponse.NextKey).NotTo(BeEmpty()) - }) - }) - - It("should get delegation rewards - delegationRewards query", func() { - s.prepareStakingRewards(stakingRewards{s.address.Bytes(), s.validators[0], rewards}) - - delRewardsArgs := defaultCallArgs. - WithMethodName(distribution.DelegationRewardsMethod). - WithArgs(s.address, s.validators[0].OperatorAddress) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, delRewardsArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - var rewards []cmn.DecCoin - err = s.precompile.UnpackIntoInterface(&rewards, distribution.DelegationRewardsMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(rewards)).To(Equal(1)) - Expect(rewards[0].Denom).To(Equal(s.bondDenom)) - Expect(rewards[0].Amount.Int64()).To(Equal(expDelegationRewards)) - }) - - It("should get delegators's total rewards - delegationTotalRewards query", func() { - // set rewards - s.prepareStakingRewards(stakingRewards{s.address.Bytes(), s.validators[0], rewards}) - - delTotalRewardsArgs := defaultCallArgs. - WithMethodName(distribution.DelegationTotalRewardsMethod). - WithArgs(s.address) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, delTotalRewardsArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - var ( - out distribution.DelegationTotalRewardsOutput - i int - ) - err = s.precompile.UnpackIntoInterface(&out, distribution.DelegationTotalRewardsMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(2).To(Equal(len(out.Rewards))) - - // the response order may change - if out.Rewards[0].ValidatorAddress == s.validators[0].OperatorAddress { - Expect(s.validators[0].OperatorAddress).To(Equal(out.Rewards[0].ValidatorAddress)) - Expect(s.validators[1].OperatorAddress).To(Equal(out.Rewards[1].ValidatorAddress)) - Expect(0).To(Equal(len(out.Rewards[1].Reward))) - } else { - i = 1 - Expect(s.validators[0].OperatorAddress).To(Equal(out.Rewards[1].ValidatorAddress)) - Expect(s.validators[1].OperatorAddress).To(Equal(out.Rewards[0].ValidatorAddress)) - Expect(0).To(Equal(len(out.Rewards[0].Reward))) - } - - // only validator[i] has rewards - Expect(1).To(Equal(len(out.Rewards[i].Reward))) - Expect(s.bondDenom).To(Equal(out.Rewards[i].Reward[0].Denom)) - Expect(uint8(math.LegacyPrecision)).To(Equal(out.Rewards[i].Reward[0].Precision)) - Expect(expDelegationRewards).To(Equal(out.Rewards[i].Reward[0].Amount.Int64())) - - Expect(1).To(Equal(len(out.Total))) - Expect(expDelegationRewards).To(Equal(out.Total[0].Amount.Int64())) - }) - - It("should get all validators a delegators has delegated to - delegatorValidators query", func() { - delValArgs := defaultCallArgs. - WithMethodName(distribution.DelegatorValidatorsMethod). - WithArgs(s.address) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, delValArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - var validators []string - err = s.precompile.UnpackIntoInterface(&validators, distribution.DelegatorValidatorsMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(2).To(Equal(len(validators))) - - // the response order may change - if validators[0] == s.validators[0].OperatorAddress { - Expect(s.validators[0].OperatorAddress).To(Equal(validators[0])) - Expect(s.validators[1].OperatorAddress).To(Equal(validators[1])) - } else { - Expect(s.validators[1].OperatorAddress).To(Equal(validators[0])) - Expect(s.validators[0].OperatorAddress).To(Equal(validators[1])) - } - }) - - It("should get withdraw address - delegatorWithdrawAddress query", func() { - // set the withdraw address - err := s.app.DistrKeeper.SetWithdrawAddr(s.ctx, s.address.Bytes(), differentAddr.Bytes()) - Expect(err).To(BeNil()) - - delWithdrawAddrArgs := defaultCallArgs. - WithMethodName(distribution.DelegatorWithdrawAddressMethod). - WithArgs(s.address) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, delWithdrawAddrArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the precompile") - - withdrawAddr, err := s.precompile.Unpack(distribution.DelegatorWithdrawAddressMethod, ethRes.Ret) - Expect(err).To(BeNil()) - // get the bech32 encoding - expAddr := sdk.AccAddress(differentAddr.Bytes()) - Expect(withdrawAddr[0]).To(Equal(expAddr.String())) - }) - }) -}) - -var _ = Describe("Calling distribution precompile from another contract", func() { - var ( - // initBalanceAmt is the initial balance for testing - initBalanceAmt = math.NewInt(5000000000000000000) - - // contractAddr is the address of the smart contract that will be deployed - contractAddr common.Address - // err is a basic error type - err error - - // execRevertedCheck defines the default log checking arguments which includes the - // standard revert message. - execRevertedCheck testutil.LogCheckArgs - ) - - BeforeEach(func() { - s.SetupTest() - contractAddr, err = s.DeployContract(contracts.DistributionCallerContract) - Expect(err).To(BeNil(), "error while deploying the smart contract: %v", err) - - // NextBlock the smart contract - s.NextBlock() - - // check contract was correctly deployed - cAcc := s.app.EvmKeeper.GetAccount(s.ctx, contractAddr) - Expect(cAcc).ToNot(BeNil(), "contract account should exist") - Expect(cAcc.IsContract()).To(BeTrue(), "account should be a contract") - - // populate default call args - defaultCallArgs = contracts.CallArgs{ - ContractAddr: contractAddr, - ContractABI: contracts.DistributionCallerContract.ABI, - PrivKey: s.privKey, - } - - // default log check arguments - defaultLogCheck = testutil.LogCheckArgs{ABIEvents: s.precompile.Events} - execRevertedCheck = defaultLogCheck.WithErrContains("execution reverted") - passCheck = defaultLogCheck.WithExpPass(true) - }) - - // ===================================== - // TRANSACTIONS - // ===================================== - Context("setWithdrawAddress", func() { - var ( - // defaultSetWithdrawAddrArgs are the default arguments for the set withdraw address call - // - // NOTE: this has to be populated in a BeforeEach block because the contractAddr would otherwise be a nil address. - defaultSetWithdrawAddrArgs contracts.CallArgs - // newWithdrawer is the address to set the withdraw address to - newWithdrawer = differentAddr - ) - - BeforeEach(func() { - // withdraw address should be same as address - withdrawer := s.app.DistrKeeper.GetDelegatorWithdrawAddr(s.ctx, s.address.Bytes()) - Expect(withdrawer.Bytes()).To(Equal(s.address.Bytes())) - - // populate default arguments - defaultSetWithdrawAddrArgs = defaultCallArgs.WithMethodName( - "testSetWithdrawAddress", - ) - }) - - It("should set withdraw address successfully", func() { - setWithdrawAddrArgs := defaultSetWithdrawAddrArgs.WithArgs( - s.address, newWithdrawer.String(), - ) - - setWithdrawCheck := passCheck.WithExpEvents(distribution.EventTypeSetWithdrawAddress) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, setWithdrawAddrArgs, setWithdrawCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - withdrawer := s.app.DistrKeeper.GetDelegatorWithdrawAddr(s.ctx, s.address.Bytes()) - Expect(withdrawer.Bytes()).To(Equal(newWithdrawer.Bytes())) - }) - }) - - Context("setWithdrawerAddress with contract as delegator", func() { - var ( - // defaultSetWithdrawAddrArgs are the default arguments for the set withdraw address call - // - // NOTE: this has to be populated in a BeforeEach block because the contractAddr would otherwise be a nil address. - defaultSetWithdrawAddrArgs contracts.CallArgs - // newWithdrawer is the address to set the withdraw address to - newWithdrawer = differentAddr - ) - - BeforeEach(func() { - // withdraw address should be same as address - withdrawer := s.app.DistrKeeper.GetDelegatorWithdrawAddr(s.ctx, s.address.Bytes()) - Expect(withdrawer.Bytes()).To(Equal(s.address.Bytes())) - - // populate default arguments - defaultSetWithdrawAddrArgs = defaultCallArgs.WithMethodName( - "testSetWithdrawAddressFromContract", - ) - }) - - It("should set withdraw address successfully without origin check", func() { - setWithdrawAddrArgs := defaultSetWithdrawAddrArgs.WithArgs(newWithdrawer.String()) - - setWithdrawCheck := passCheck.WithExpEvents(distribution.EventTypeSetWithdrawAddress) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, setWithdrawAddrArgs, setWithdrawCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - withdrawer := s.app.DistrKeeper.GetDelegatorWithdrawAddr(s.ctx, contractAddr.Bytes()) - Expect(withdrawer.Bytes()).To(Equal(newWithdrawer.Bytes())) - }) - }) - - Context("withdrawDelegatorRewards", func() { - var ( - // defaultWithdrawDelRewardsArgs are the default arguments for the withdraw delegator rewards call - // - // NOTE: this has to be populated in a BeforeEach block because the contractAddr would otherwise be a nil address. - defaultWithdrawDelRewardsArgs contracts.CallArgs - // initialBalance is the initial balance of the delegator - initialBalance sdk.Coin - ) - - BeforeEach(func() { - // set some rewards for s.address & another address - s.prepareStakingRewards([]stakingRewards{ - {s.address.Bytes(), s.validators[0], rewards}, - {differentAddr.Bytes(), s.validators[0], rewards}, - }...) - - initialBalance = s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - - // populate default arguments - defaultWithdrawDelRewardsArgs = defaultCallArgs.WithMethodName( - "testWithdrawDelegatorRewards", - ) - }) - - It("should not withdraw rewards when sending from a different address", func() { - withdrawDelRewardsArgs := defaultWithdrawDelRewardsArgs.WithArgs( - differentAddr, s.validators[0].OperatorAddress, - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, withdrawDelRewardsArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - // balance should be equal as initial balance or less (because of fees) - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - Expect(finalBalance.Amount.Uint64() <= initialBalance.Amount.Uint64()).To(BeTrue()) - - // differentAddr balance should remain unchanged - differentAddrFinalBalance := s.app.BankKeeper.GetBalance(s.ctx, differentAddr.Bytes(), s.bondDenom) - Expect(differentAddrFinalBalance.Amount).To(Equal(math.ZeroInt())) - }) - - It("should withdraw rewards successfully", func() { - withdrawDelRewardsArgs := defaultWithdrawDelRewardsArgs.WithArgs( - s.address, s.validators[0].OperatorAddress, - ) - - logCheckArgs := passCheck. - WithExpEvents(distribution.EventTypeWithdrawDelegatorRewards) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, withdrawDelRewardsArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - // balance should remain unchanged - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - Expect(finalBalance.Amount.GT(initialBalance.Amount)).To(BeTrue(), "expected final balance to be greater than initial balance after withdrawing rewards") - }) - - It("should withdraw rewards successfully to the new withdrawer address", func() { - initialBalance := s.app.BankKeeper.GetBalance(s.ctx, differentAddr.Bytes(), s.bondDenom) - // Set new withdrawer address - err := s.app.DistrKeeper.SetWithdrawAddr(s.ctx, s.address.Bytes(), differentAddr.Bytes()) - Expect(err).To(BeNil()) - - withdrawDelRewardsArgs := defaultWithdrawDelRewardsArgs.WithArgs( - s.address, s.validators[0].OperatorAddress, - ) - - logCheckArgs := passCheck. - WithExpEvents(distribution.EventTypeWithdrawDelegatorRewards) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, withdrawDelRewardsArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - // should increase balance by rewards - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, differentAddr.Bytes(), s.bondDenom) - Expect(finalBalance.Amount.GT(initialBalance.Amount)).To(BeTrue(), "expected final balance to be greater than initial balance after withdrawing rewards") - }) - }) - - Context("withdrawDelegatorRewards with contract as delegator", func() { - var ( - // defaultWithdrawDelRewardsArgs are the default arguments for the withdraw delegator rewards call - // - // NOTE: this has to be populated in a BeforeEach block because the contractAddr would otherwise be a nil address. - defaultWithdrawDelRewardsArgs contracts.CallArgs - // initialBalance is the initial balance of the delegator - initialBalance sdk.Coin - ) - - BeforeEach(func() { - // set some rewards for s.address & another address - s.prepareStakingRewards([]stakingRewards{ - { - Delegator: contractAddr.Bytes(), - Validator: s.validators[0], - RewardAmt: rewards, - }, - }...) - - initialBalance = s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom) - - // populate default arguments - defaultWithdrawDelRewardsArgs = defaultCallArgs.WithMethodName( - "testWithdrawDelegatorRewardsFromContract", - ) - }) - - It("should withdraw rewards successfully without origin check", func() { - withdrawDelRewardsArgs := defaultWithdrawDelRewardsArgs.WithArgs(s.validators[0].OperatorAddress) - - logCheckArgs := passCheck.WithExpEvents(distribution.EventTypeWithdrawDelegatorRewards) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, withdrawDelRewardsArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - // balance should increase - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom) - Expect(finalBalance.Amount.GT(initialBalance.Amount)).To(BeTrue(), "expected final balance to be greater than initial balance after withdrawing rewards") - }) - }) - - Context("withdrawValidatorCommission", func() { - var ( - // defaultWithdrawValCommArgs are the default arguments for the withdraw validator commission call - // - // NOTE: this has to be populated in a BeforeEach block because the contractAddr would otherwise be a nil address. - defaultWithdrawValCommArgs contracts.CallArgs - // commDec is the commission rate of the validator - commDec = math.LegacyNewDec(1) - // valAddr is the address of the validator - valAddr sdk.ValAddress - // initialBalance is the initial balance of the delegator - initialBalance sdk.Coin - ) - - BeforeEach(func() { - // create a validator with s.address because is the address - // used for signing txs - valAddr = s.address.Bytes() - stakeAmt := math.NewInt(100) - testutil.CreateValidator(s.ctx, s.T(), s.privKey.PubKey(), s.app.StakingKeeper, stakeAmt) - - // set some commissions to validators - var valAddresses []sdk.ValAddress - valAddresses = append( - valAddresses, - valAddr, - s.validators[0].GetOperator(), - s.validators[1].GetOperator(), - ) - - for _, addr := range valAddresses { - val := s.app.StakingKeeper.Validator(s.ctx, addr) - valCommission := sdk.DecCoins{sdk.NewDecCoinFromDec(s.bondDenom, commDec)} - - s.app.DistrKeeper.SetValidatorAccumulatedCommission( - s.ctx, addr, - distrtypes.ValidatorAccumulatedCommission{Commission: valCommission}, - ) - s.app.DistrKeeper.AllocateTokensToValidator(s.ctx, val, sdk.DecCoins{sdk.NewDecCoin(s.bondDenom, stakeAmt)}) - } - - initialBalance = s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - - // populate default arguments - defaultWithdrawValCommArgs = defaultCallArgs.WithMethodName( - "testWithdrawValidatorCommission", - ) - }) - - It("should not withdraw commission from validator when sending from a different address", func() { - withdrawValCommArgs := defaultWithdrawValCommArgs.WithArgs( - s.validators[0].OperatorAddress, - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, withdrawValCommArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - // balance should be equal as initial balance or less (because of fees) - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - Expect(finalBalance.Amount.Uint64() <= initialBalance.Amount.Uint64()).To(BeTrue()) - - // validator's balance should remain unchanged - valFinalBalance := s.app.BankKeeper.GetBalance(s.ctx, sdk.AccAddress(s.validators[0].GetOperator()), s.bondDenom) - Expect(valFinalBalance.Amount).To(Equal(math.ZeroInt())) - }) - - It("should withdraw commission successfully", func() { - withdrawValCommArgs := defaultWithdrawValCommArgs. - WithArgs(valAddr.String()). - WithGasPrice(gasPrice) - logCheckArgs := passCheck. - WithExpEvents(distribution.EventTypeWithdrawValidatorCommission) - - res, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, withdrawValCommArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - fees := gasPrice.Int64() * res.GasUsed - expFinal := initialBalance.Amount.Int64() + expValAmount - fees - Expect(finalBalance.Amount).To(Equal(math.NewInt(expFinal)), "expected final balance to be equal to initial balance + validator commission - fees") - }) - }) - - Context("claimRewards", func() { - var ( - // defaultClaimRewardsArgs are the default arguments for the claim rewards call - // - // NOTE: this has to be populated in a BeforeEach block because the contractAddr would otherwise be a nil address. - defaultClaimRewardsArgs contracts.CallArgs - // initialBalance is the initial balance of the delegator - initialBalance sdk.Coin - ) - - BeforeEach(func() { - // set some rewards for s.address & another address - s.prepareStakingRewards([]stakingRewards{ - {s.address.Bytes(), s.validators[0], rewards}, - {differentAddr.Bytes(), s.validators[0], rewards}, - }...) - - initialBalance = s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - - // populate default arguments - defaultClaimRewardsArgs = defaultCallArgs.WithMethodName( - "testClaimRewards", - ) - }) - - It("should not claim rewards when sending from a different address", func() { - claimRewardsArgs := defaultClaimRewardsArgs.WithArgs( - differentAddr, uint32(1), - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, claimRewardsArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - // balance should be equal as initial balance or less (because of fees) - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - Expect(finalBalance.Amount.Uint64() <= initialBalance.Amount.Uint64()).To(BeTrue()) - - // differentAddr balance should remain unchanged - differentAddrFinalBalance := s.app.BankKeeper.GetBalance(s.ctx, differentAddr.Bytes(), s.bondDenom) - Expect(differentAddrFinalBalance.Amount).To(Equal(math.ZeroInt())) - }) - - It("should claim rewards successfully", func() { - claimRewardsArgs := defaultClaimRewardsArgs.WithArgs( - s.address, uint32(2), - ) - - logCheckArgs := passCheck. - WithExpEvents(distribution.EventTypeClaimRewards) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, claimRewardsArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - // balance should remain unchanged - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - Expect(finalBalance.Amount.GT(initialBalance.Amount)).To(BeTrue(), "expected final balance to be greater than initial balance after claiming rewards") - }) - }) - - Context("claimRewards with contract as delegator", func() { - var ( - // defaultClaimRewardsArgs are the default arguments for the claim rewards call - // - // NOTE: this has to be populated in a BeforeEach block because the contractAddr would otherwise be a nil address. - defaultClaimRewardsArgs contracts.CallArgs - // expectedBalance is the total after claiming from both validators - expectedBalance sdk.Coin - ) - - BeforeEach(func() { - // set some rewards for s.address & another address - s.prepareStakingRewards([]stakingRewards{ - { - Delegator: contractAddr.Bytes(), - Validator: s.validators[0], - RewardAmt: rewards, - }, { - Delegator: contractAddr.Bytes(), - Validator: s.validators[1], - RewardAmt: rewards, - }, - }...) - - expectedBalance = sdk.Coin{Denom: utils.BaseDenom, Amount: math.NewInt(2e18)} - - // populate default arguments - defaultClaimRewardsArgs = defaultCallArgs.WithMethodName( - "testClaimRewards", - ) - }) - - It("should withdraw rewards successfully without origin check", func() { - claimRewardsArgs := defaultClaimRewardsArgs.WithArgs(contractAddr, uint32(2)) - - logCheckArgs := passCheck.WithExpEvents(distribution.EventTypeClaimRewards) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, claimRewardsArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - // balance should increase - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom) - Expect(finalBalance.Amount.Equal(expectedBalance.Amount)).To(BeTrue(), "expected final balance to be greater than initial balance after withdrawing rewards") - }) - - It("should withdraw rewards successfully to a different address without origin check", func() { - expectedBalance = sdk.Coin{Denom: utils.BaseDenom, Amount: math.NewInt(6997329929187000000)} - err := s.app.DistrKeeper.SetWithdrawAddr(s.ctx, contractAddr.Bytes(), s.address.Bytes()) - Expect(err).To(BeNil()) - - claimRewardsArgs := defaultClaimRewardsArgs.WithArgs(contractAddr, uint32(2)) - - logCheckArgs := passCheck.WithExpEvents(distribution.EventTypeClaimRewards) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, claimRewardsArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - // balance should increase - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - Expect(finalBalance.Amount.Equal(expectedBalance.Amount)).To(BeTrue(), "expected final balance to be greater than initial balance after withdrawing rewards") - }) - }) - - Context("Forbidden operations", func() { - It("should revert state: modify withdraw address & then try to withdraw rewards corresponding to another user", func() { - // set rewards to another user - s.prepareStakingRewards(stakingRewards{differentAddr.Bytes(), s.validators[0], rewards}) - - revertArgs := defaultCallArgs. - WithMethodName("testRevertState"). - WithArgs( - differentAddr.String(), differentAddr, s.validators[0].OperatorAddress, - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, revertArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - // check withdraw address didn't change - withdrawer := s.app.DistrKeeper.GetDelegatorWithdrawAddr(s.ctx, s.address.Bytes()) - Expect(withdrawer.Bytes()).To(Equal(s.address.Bytes())) - - // check signer address balance should've decreased (fees paid) - finalBalance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - Expect(finalBalance.Amount.Uint64() <= initBalanceAmt.Uint64()).To(BeTrue()) - - // check other address' balance remained unchanged - finalBalance = s.app.BankKeeper.GetBalance(s.ctx, differentAddr.Bytes(), s.bondDenom) - Expect(finalBalance.Amount).To(Equal(math.ZeroInt())) - }) - - It("should not allow to call SetWithdrawAddress using delegatecall", func() { - setWithdrawAddrArgs := defaultCallArgs. - WithMethodName("delegateCallSetWithdrawAddress"). - WithArgs(s.address, differentAddr.String()) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, setWithdrawAddrArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - // check withdraw address didn't change - withdrawer := s.app.DistrKeeper.GetDelegatorWithdrawAddr(s.ctx, s.address.Bytes()) - Expect(withdrawer.Bytes()).To(Equal(s.address.Bytes())) - }) - - It("should not allow to call txs (SetWithdrawAddress) using staticcall", func() { - setWithdrawAddrArgs := defaultCallArgs. - WithMethodName("staticCallSetWithdrawAddress"). - WithArgs(s.address, differentAddr.String()) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, setWithdrawAddrArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - // check withdraw address didn't change - withdrawer := s.app.DistrKeeper.GetDelegatorWithdrawAddr(s.ctx, s.address.Bytes()) - Expect(withdrawer.Bytes()).To(Equal(s.address.Bytes())) - }) - }) - - // =================================== - // QUERIES - // =================================== - Context("Distribution precompile queries", func() { - Context("get validator distribution info", func() { - // defaultValDistArgs are the default arguments for the getValidatorDistributionInfo query - // - // NOTE: this has to be populated in BeforeEach because the test suite setup is not available prior to that. - var defaultValDistArgs contracts.CallArgs - - BeforeEach(func() { - addr := sdk.AccAddress(s.validators[0].GetOperator()) - // fund validator account to make self-delegation - err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, addr, 10) - Expect(err).To(BeNil()) - // make a self delegation - _, err = s.app.StakingKeeper.Delegate(s.ctx, addr, math.NewInt(1), stakingtypes.Unspecified, s.validators[0], true) - Expect(err).To(BeNil()) - - defaultValDistArgs = defaultCallArgs. - WithMethodName("getValidatorDistributionInfo"). - WithArgs(s.validators[0].OperatorAddress) - }) - - It("should get validator distribution info", func() { - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultValDistArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var out distribution.ValidatorDistributionInfoOutput - err = s.precompile.UnpackIntoInterface(&out, distribution.ValidatorDistributionInfoMethod, ethRes.Ret) - Expect(err).To(BeNil()) - - expAddr := sdk.AccAddress(s.validators[0].GetOperator()) - Expect(expAddr.String()).To(Equal(out.DistributionInfo.OperatorAddress)) - Expect(0).To(Equal(len(out.DistributionInfo.Commission))) - Expect(0).To(Equal(len(out.DistributionInfo.SelfBondRewards))) - }) - }) - - Context("get validator outstanding rewards", func() { //nolint:dupl - // defaultValOutRewardsArgs are the default arguments for the getValidatorOutstandingRewards query - // - // NOTE: this has to be populated in BeforeEach because the test suite setup is not available prior to that. - var defaultValOutRewardsArgs contracts.CallArgs - - BeforeEach(func() { - defaultValOutRewardsArgs = defaultCallArgs. - WithMethodName("getValidatorOutstandingRewards"). - WithArgs(s.validators[0].OperatorAddress) - }) - - It("should not get rewards - validator without outstanding rewards", func() { - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultValOutRewardsArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var rewards []cmn.DecCoin - err = s.precompile.UnpackIntoInterface(&rewards, distribution.ValidatorOutstandingRewardsMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(rewards)).To(Equal(0)) - }) - - It("should get rewards - validator with outstanding rewards", func() { - valRewards := sdk.DecCoins{sdk.NewDecCoinFromDec(s.bondDenom, math.LegacyNewDec(1))} - // set outstanding rewards - s.app.DistrKeeper.SetValidatorOutstandingRewards(s.ctx, s.validators[0].GetOperator(), distrtypes.ValidatorOutstandingRewards{Rewards: valRewards}) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultValOutRewardsArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var rewards []cmn.DecCoin - err = s.precompile.UnpackIntoInterface(&rewards, distribution.ValidatorOutstandingRewardsMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(rewards)).To(Equal(1)) - Expect(uint8(18)).To(Equal(rewards[0].Precision)) - Expect(s.bondDenom).To(Equal(rewards[0].Denom)) - Expect(expValAmount).To(Equal(rewards[0].Amount.Int64())) - }) - }) - - Context("get validator commission", func() { //nolint:dupl - // defaultValCommArgs are the default arguments for the getValidatorCommission query - // - // NOTE: this has to be populated in BeforeEach because the test suite setup is not available prior to that. - var defaultValCommArgs contracts.CallArgs - - BeforeEach(func() { - defaultValCommArgs = defaultCallArgs. - WithMethodName("getValidatorCommission"). - WithArgs(s.validators[0].OperatorAddress) - }) - - It("should not get commission - validator without commission", func() { - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultValCommArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var commission []cmn.DecCoin - err = s.precompile.UnpackIntoInterface(&commission, distribution.ValidatorCommissionMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(commission)).To(Equal(0)) - }) - - It("should get commission - validator with commission", func() { - // set commission - valCommission := sdk.DecCoins{sdk.NewDecCoinFromDec(s.bondDenom, math.LegacyNewDec(1))} - s.app.DistrKeeper.SetValidatorAccumulatedCommission(s.ctx, s.validators[0].GetOperator(), distrtypes.ValidatorAccumulatedCommission{Commission: valCommission}) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultValCommArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var commission []cmn.DecCoin - err = s.precompile.UnpackIntoInterface(&commission, distribution.ValidatorCommissionMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(commission)).To(Equal(1)) - Expect(uint8(18)).To(Equal(commission[0].Precision)) - Expect(s.bondDenom).To(Equal(commission[0].Denom)) - Expect(expValAmount).To(Equal(commission[0].Amount.Int64())) - }) - }) - - Context("get validator slashing events", func() { - // defaultValSlashArgs are the default arguments for the getValidatorSlashes query - // - // NOTE: this has to be populated in BeforeEach because the test suite setup is not available prior to that. - var defaultValSlashArgs contracts.CallArgs - - BeforeEach(func() { - defaultValSlashArgs = defaultCallArgs. - WithMethodName("getValidatorSlashes"). - WithArgs( - s.validators[0].OperatorAddress, - uint64(1), uint64(5), - query.PageRequest{}, - ) - }) - - It("should not get slashing events - validator without slashes", func() { - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultValSlashArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var out distribution.ValidatorSlashesOutput - err = s.precompile.UnpackIntoInterface(&out, distribution.ValidatorSlashesMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(out.Slashes)).To(Equal(0)) - }) - - It("should get slashing events - validator with slashes (default pagination)", func() { - // set slash event - slashEvent := s.setupValidatorSlashes(s.validators[0].GetOperator(), 1) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultValSlashArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var out distribution.ValidatorSlashesOutput - err = s.precompile.UnpackIntoInterface(&out, distribution.ValidatorSlashesMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(out.Slashes)).To(Equal(1)) - Expect(slashEvent.Fraction.BigInt()).To(Equal(out.Slashes[0].Fraction.Value)) - Expect(slashEvent.ValidatorPeriod).To(Equal(out.Slashes[0].ValidatorPeriod)) - Expect(uint64(1)).To(Equal(out.PageResponse.Total)) - Expect(out.PageResponse.NextKey).To(BeEmpty()) - }) - - It("should get slashing events - validator with slashes w/pagination", func() { - // set 2 slashing events - slashEvent := s.setupValidatorSlashes(s.validators[0].GetOperator(), 2) - - // set pagination - defaultValSlashArgs.Args = []interface{}{ - s.validators[0].OperatorAddress, - uint64(1), uint64(5), - query.PageRequest{ - Limit: 1, - CountTotal: true, - }, - } - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultValSlashArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var out distribution.ValidatorSlashesOutput - err = s.precompile.UnpackIntoInterface(&out, distribution.ValidatorSlashesMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(out.Slashes)).To(Equal(1)) - Expect(slashEvent.Fraction.BigInt()).To(Equal(out.Slashes[0].Fraction.Value)) - Expect(slashEvent.ValidatorPeriod).To(Equal(out.Slashes[0].ValidatorPeriod)) - Expect(uint64(2)).To(Equal(out.PageResponse.Total)) - Expect(out.PageResponse.NextKey).NotTo(BeEmpty()) - }) - }) - - Context("get delegation rewards", func() { - // defaultDelRewardsArgs are the default arguments for the getDelegationRewards query - // - // NOTE: this has to be populated in BeforeEach because the test suite setup is not available prior to that. - var defaultDelRewardsArgs contracts.CallArgs - - BeforeEach(func() { - defaultDelRewardsArgs = defaultCallArgs. - WithMethodName("getDelegationRewards"). - WithArgs(s.address, s.validators[0].OperatorAddress) - }) - - It("should not get rewards - no rewards available", func() { - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultDelRewardsArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var rewards []cmn.DecCoin - err = s.precompile.UnpackIntoInterface(&rewards, distribution.DelegationRewardsMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(rewards)).To(Equal(0)) - }) - It("should get rewards", func() { - s.prepareStakingRewards(stakingRewards{s.address.Bytes(), s.validators[0], rewards}) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultDelRewardsArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var rewards []cmn.DecCoin - err = s.precompile.UnpackIntoInterface(&rewards, distribution.DelegationRewardsMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(rewards)).To(Equal(1)) - Expect(len(rewards)).To(Equal(1)) - Expect(rewards[0].Denom).To(Equal(s.bondDenom)) - Expect(rewards[0].Amount.Int64()).To(Equal(expDelegationRewards)) - }) - }) - - Context("get delegator's total rewards", func() { - // defaultDelTotalRewardsArgs are the default arguments for the getDelegationTotalRewards query - // - // NOTE: this has to be populated in BeforeEach because the test suite setup is not available prior to that. - var defaultDelTotalRewardsArgs contracts.CallArgs - - BeforeEach(func() { - defaultDelTotalRewardsArgs = defaultCallArgs. - WithMethodName("getDelegationTotalRewards"). - WithArgs(s.address) - }) - - It("should not get rewards - no rewards available", func() { - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultDelTotalRewardsArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var out distribution.DelegationTotalRewardsOutput - err = s.precompile.UnpackIntoInterface(&out, distribution.DelegationTotalRewardsMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(len(out.Rewards)).To(Equal(2)) - Expect(len(out.Rewards[0].Reward)).To(Equal(0)) - Expect(len(out.Rewards[1].Reward)).To(Equal(0)) - }) - It("should get total rewards", func() { - // set rewards - s.prepareStakingRewards(stakingRewards{s.address.Bytes(), s.validators[0], rewards}) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultDelTotalRewardsArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var ( - out distribution.DelegationTotalRewardsOutput - i int - ) - err = s.precompile.UnpackIntoInterface(&out, distribution.DelegationTotalRewardsMethod, ethRes.Ret) - Expect(err).To(BeNil()) - - // the response order may change - if out.Rewards[0].ValidatorAddress == s.validators[0].OperatorAddress { - Expect(s.validators[0].OperatorAddress).To(Equal(out.Rewards[0].ValidatorAddress)) - Expect(s.validators[1].OperatorAddress).To(Equal(out.Rewards[1].ValidatorAddress)) - Expect(0).To(Equal(len(out.Rewards[1].Reward))) - } else { - i = 1 - Expect(s.validators[0].OperatorAddress).To(Equal(out.Rewards[1].ValidatorAddress)) - Expect(s.validators[1].OperatorAddress).To(Equal(out.Rewards[0].ValidatorAddress)) - Expect(0).To(Equal(len(out.Rewards[0].Reward))) - } - - // only validator[i] has rewards - Expect(1).To(Equal(len(out.Rewards[i].Reward))) - Expect(s.bondDenom).To(Equal(out.Rewards[i].Reward[0].Denom)) - Expect(uint8(math.LegacyPrecision)).To(Equal(out.Rewards[i].Reward[0].Precision)) - Expect(expDelegationRewards).To(Equal(out.Rewards[i].Reward[0].Amount.Int64())) - - Expect(1).To(Equal(len(out.Total))) - Expect(expDelegationRewards).To(Equal(out.Total[0].Amount.Int64())) - }) - }) - - Context("get all delegator validators", func() { - // defaultDelValArgs are the default arguments for the getDelegatorValidators query - // - // NOTE: this has to be populated in BeforeEach because the test suite setup is not available prior to that. - var defaultDelValArgs contracts.CallArgs - - BeforeEach(func() { - defaultDelValArgs = defaultCallArgs. - WithMethodName("getDelegatorValidators"). - WithArgs(s.address) - }) - - It("should get all validators a delegator has delegated to", func() { - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultDelValArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var validators []string - err = s.precompile.UnpackIntoInterface(&validators, distribution.DelegatorValidatorsMethod, ethRes.Ret) - Expect(err).To(BeNil()) - Expect(2).To(Equal(len(validators))) - - // the response order may change - if validators[0] == s.validators[0].OperatorAddress { - Expect(s.validators[0].OperatorAddress).To(Equal(validators[0])) - Expect(s.validators[1].OperatorAddress).To(Equal(validators[1])) - } else { - Expect(s.validators[1].OperatorAddress).To(Equal(validators[0])) - Expect(s.validators[0].OperatorAddress).To(Equal(validators[1])) - } - }) - }) - - Context("get withdraw address", func() { - // defaultWithdrawAddrArgs are the default arguments for the getDelegatorWithdrawAddress query - // - // NOTE: this has to be populated in BeforeEach because the test suite setup is not available prior to that. - var defaultWithdrawAddrArgs contracts.CallArgs - - BeforeEach(func() { - defaultWithdrawAddrArgs = defaultCallArgs. - WithMethodName("getDelegatorWithdrawAddress"). - WithArgs(s.address) - }) - - It("should get withdraw address", func() { - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, defaultWithdrawAddrArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - withdrawAddr, err := s.precompile.Unpack(distribution.DelegatorWithdrawAddressMethod, ethRes.Ret) - Expect(err).To(BeNil()) - // get the bech32 encoding - expAddr := sdk.AccAddress(s.address.Bytes()) - Expect(withdrawAddr[0]).To(Equal(expAddr.String())) - }) - - It("should call GetWithdrawAddress using staticcall", func() { - staticCallArgs := defaultCallArgs. - WithMethodName("staticCallGetWithdrawAddress"). - WithArgs(s.address) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, staticCallArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - withdrawAddr, err := s.precompile.Unpack(distribution.DelegatorWithdrawAddressMethod, ethRes.Ret) - Expect(err).To(BeNil()) - // get the bech32 encoding - expAddr := sdk.AccAddress(s.address.Bytes()) - Expect(withdrawAddr[0]).To(ContainSubstring(expAddr.String())) - }) - }) - }) -}) diff --git a/precompiles/distribution/query.go b/precompiles/distribution/query.go deleted file mode 100644 index 032272bd..00000000 --- a/precompiles/distribution/query.go +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package distribution - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/core/vm" - cmn "github.com/evmos/evmos/v16/precompiles/common" -) - -const ( - // ValidatorDistributionInfoMethod defines the ABI method name for the - // ValidatorDistributionInfo query. - ValidatorDistributionInfoMethod = "validatorDistributionInfo" - // ValidatorOutstandingRewardsMethod defines the ABI method name for the - // ValidatorOutstandingRewards query. - ValidatorOutstandingRewardsMethod = "validatorOutstandingRewards" - // ValidatorCommissionMethod defines the ABI method name for the - // ValidatorCommission query. - ValidatorCommissionMethod = "validatorCommission" - // ValidatorSlashesMethod defines the ABI method name for the - // ValidatorSlashes query. - ValidatorSlashesMethod = "validatorSlashes" - // DelegationRewardsMethod defines the ABI method name for the - // DelegationRewards query. - DelegationRewardsMethod = "delegationRewards" - // DelegationTotalRewardsMethod defines the ABI method name for the - // DelegationTotalRewards query. - DelegationTotalRewardsMethod = "delegationTotalRewards" - // DelegatorValidatorsMethod defines the ABI method name for the - // DelegatorValidators query. - DelegatorValidatorsMethod = "delegatorValidators" - // DelegatorWithdrawAddressMethod defines the ABI method name for the - // DelegatorWithdrawAddress query. - DelegatorWithdrawAddressMethod = "delegatorWithdrawAddress" -) - -// ValidatorDistributionInfo returns the distribution info for a validator. -func (p Precompile) ValidatorDistributionInfo( - ctx sdk.Context, - _ *vm.Contract, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - req, err := NewValidatorDistributionInfoRequest(args) - if err != nil { - return nil, err - } - - querier := distributionkeeper.Querier{Keeper: p.distributionKeeper} - - res, err := querier.ValidatorDistributionInfo(ctx, req) - if err != nil { - return nil, err - } - - out := new(ValidatorDistributionInfoOutput).FromResponse(res) - - return method.Outputs.Pack(out.DistributionInfo) -} - -// ValidatorOutstandingRewards returns the outstanding rewards for a validator. -func (p Precompile) ValidatorOutstandingRewards( - ctx sdk.Context, - _ *vm.Contract, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - req, err := NewValidatorOutstandingRewardsRequest(args) - if err != nil { - return nil, err - } - - querier := distributionkeeper.Querier{Keeper: p.distributionKeeper} - - res, err := querier.ValidatorOutstandingRewards(ctx, req) - if err != nil { - return nil, err - } - - return method.Outputs.Pack(cmn.NewDecCoinsResponse(res.Rewards.Rewards)) -} - -// ValidatorCommission returns the commission for a validator. -func (p Precompile) ValidatorCommission( - ctx sdk.Context, - _ *vm.Contract, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - req, err := NewValidatorCommissionRequest(args) - if err != nil { - return nil, err - } - - querier := distributionkeeper.Querier{Keeper: p.distributionKeeper} - - res, err := querier.ValidatorCommission(ctx, req) - if err != nil { - return nil, err - } - - return method.Outputs.Pack(cmn.NewDecCoinsResponse(res.Commission.Commission)) -} - -// ValidatorSlashes returns the slashes for a validator. -func (p Precompile) ValidatorSlashes( - ctx sdk.Context, - _ *vm.Contract, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - req, err := NewValidatorSlashesRequest(method, args) - if err != nil { - return nil, err - } - - querier := distributionkeeper.Querier{Keeper: p.distributionKeeper} - - res, err := querier.ValidatorSlashes(ctx, req) - if err != nil { - return nil, err - } - - out := new(ValidatorSlashesOutput).FromResponse(res) - - return out.Pack(method.Outputs) -} - -// DelegationRewards returns the total rewards accrued by a delegation. -func (p Precompile) DelegationRewards( - ctx sdk.Context, - _ *vm.Contract, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - req, err := NewDelegationRewardsRequest(args) - if err != nil { - return nil, err - } - - querier := distributionkeeper.Querier{Keeper: p.distributionKeeper} - res, err := querier.DelegationRewards(ctx, req) - if err != nil { - return nil, err - } - - return method.Outputs.Pack(cmn.NewDecCoinsResponse(res.Rewards)) -} - -// DelegationTotalRewards returns the total rewards accrued by a delegation. -func (p Precompile) DelegationTotalRewards( - ctx sdk.Context, - _ *vm.Contract, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - req, err := NewDelegationTotalRewardsRequest(args) - if err != nil { - return nil, err - } - - querier := distributionkeeper.Querier{Keeper: p.distributionKeeper} - - res, err := querier.DelegationTotalRewards(ctx, req) - if err != nil { - return nil, err - } - - out := new(DelegationTotalRewardsOutput).FromResponse(res) - - return out.Pack(method.Outputs) -} - -// DelegatorValidators returns the validators a delegator is bonded to. -func (p Precompile) DelegatorValidators( - ctx sdk.Context, - _ *vm.Contract, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - req, err := NewDelegatorValidatorsRequest(args) - if err != nil { - return nil, err - } - - querier := distributionkeeper.Querier{Keeper: p.distributionKeeper} - - res, err := querier.DelegatorValidators(ctx, req) - if err != nil { - return nil, err - } - - return method.Outputs.Pack(res.Validators) -} - -// DelegatorWithdrawAddress returns the withdraw address for a delegator. -func (p Precompile) DelegatorWithdrawAddress( - ctx sdk.Context, - _ *vm.Contract, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - req, err := NewDelegatorWithdrawAddressRequest(args) - if err != nil { - return nil, err - } - - querier := distributionkeeper.Querier{Keeper: p.distributionKeeper} - - res, err := querier.DelegatorWithdrawAddress(ctx, req) - if err != nil { - return nil, err - } - - return method.Outputs.Pack(res.WithdrawAddress) -} diff --git a/precompiles/distribution/query_test.go b/precompiles/distribution/query_test.go deleted file mode 100644 index c5ac9a9e..00000000 --- a/precompiles/distribution/query_test.go +++ /dev/null @@ -1,845 +0,0 @@ -package distribution_test - -import ( - "fmt" - "math/big" - - "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/testutil/mock" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/query" - "github.com/cosmos/cosmos-sdk/x/distribution/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/core/vm" - - "github.com/evmos/evmos/v16/testutil" - testutiltx "github.com/evmos/evmos/v16/testutil/tx" - - cmn "github.com/evmos/evmos/v16/precompiles/common" - "github.com/evmos/evmos/v16/precompiles/distribution" -) - -var ( - expDelegationRewards int64 = 2000000000000000000 - expValAmount int64 = 1 - rewards, _ = math.NewIntFromString("1000000000000000000") -) - -type distrTestCases struct { - name string - malleate func() []interface{} - postCheck func(bz []byte) - gas uint64 - expErr bool - errContains string -} - -var baseTestCases = []distrTestCases{ - { - "fail - empty input args", - func() []interface{} { - return []interface{}{} - }, - func(bz []byte) {}, - 100000, - true, - "invalid number of arguments", - }, - { - "fail - invalid validator address", - func() []interface{} { - return []interface{}{ - "invalid", - } - }, - func(bz []byte) {}, - 100000, - true, - "invalid bech32 string", - }, -} - -func (s *PrecompileTestSuite) TestValidatorDistributionInfo() { - method := s.precompile.Methods[distribution.ValidatorDistributionInfoMethod] - - testCases := []distrTestCases{ - { - "fail - nonexistent validator address", - func() []interface{} { - pv := mock.NewPV() - pk, err := pv.GetPubKey() - s.Require().NoError(err) - return []interface{}{ - sdk.ValAddress(pk.Address().Bytes()).String(), - } - }, - func(bz []byte) {}, - 100000, - true, - "validator does not exist", - }, - { - "fail - existent validator but without self delegation", - func() []interface{} { - return []interface{}{ - s.validators[0].OperatorAddress, - } - }, - func(bz []byte) {}, - 100000, - true, - "delegation does not exist", - }, - { - "success", - func() []interface{} { - addr := sdk.AccAddress(s.validators[0].GetOperator()) - // fund del account to make self-delegation - err := testutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, addr, 10) - s.Require().NoError(err) - // make a self delegation - _, err = s.app.StakingKeeper.Delegate(s.ctx, addr, math.NewInt(1), stakingtypes.Unspecified, s.validators[0], true) - s.Require().NoError(err) - return []interface{}{ - s.validators[0].OperatorAddress, - } - }, - func(bz []byte) { - var out distribution.ValidatorDistributionInfoOutput - err := s.precompile.UnpackIntoInterface(&out, distribution.ValidatorDistributionInfoMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - expAddr := sdk.AccAddress(s.validators[0].GetOperator()) - s.Require().Equal(expAddr.String(), out.DistributionInfo.OperatorAddress) - s.Require().Equal(0, len(out.DistributionInfo.Commission)) - s.Require().Equal(0, len(out.DistributionInfo.SelfBondRewards)) - }, - 100000, - false, - "", - }, - } - testCases = append(testCases, baseTestCases...) - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - bz, err := s.precompile.ValidatorDistributionInfo(s.ctx, contract, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestValidatorOutstandingRewards() { //nolint:dupl - method := s.precompile.Methods[distribution.ValidatorOutstandingRewardsMethod] - - testCases := []distrTestCases{ - { - "success - nonexistent validator address", - func() []interface{} { - pv := mock.NewPV() - pk, err := pv.GetPubKey() - s.Require().NoError(err) - return []interface{}{ - sdk.ValAddress(pk.Address().Bytes()).String(), - } - }, - func(bz []byte) { - var out []sdk.DecCoin - err := s.precompile.UnpackIntoInterface(&out, distribution.ValidatorOutstandingRewardsMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(0, len(out)) - }, - 100000, - false, - "", - }, - { - "success - existent validator, no outstanding rewards", - func() []interface{} { - return []interface{}{ - s.validators[0].OperatorAddress, - } - }, - func(bz []byte) { - var out []sdk.DecCoin - err := s.precompile.UnpackIntoInterface(&out, distribution.ValidatorOutstandingRewardsMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(0, len(out)) - }, - 100000, - false, - "", - }, - { - "success - with outstanding rewards", - func() []interface{} { - valRewards := sdk.DecCoins{sdk.NewDecCoinFromDec(s.bondDenom, math.LegacyNewDec(1))} - // set outstanding rewards - s.app.DistrKeeper.SetValidatorOutstandingRewards(s.ctx, s.validators[0].GetOperator(), types.ValidatorOutstandingRewards{Rewards: valRewards}) - return []interface{}{ - s.validators[0].OperatorAddress, - } - }, - func(bz []byte) { - var out []cmn.DecCoin - err := s.precompile.UnpackIntoInterface(&out, distribution.ValidatorOutstandingRewardsMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(1, len(out)) - s.Require().Equal(uint8(18), out[0].Precision) - s.Require().Equal(s.bondDenom, out[0].Denom) - s.Require().Equal(expValAmount, out[0].Amount.Int64()) - }, - 100000, - false, - "", - }, - } - testCases = append(testCases, baseTestCases...) - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - bz, err := s.precompile.ValidatorOutstandingRewards(s.ctx, contract, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestValidatorCommission() { //nolint:dupl - method := s.precompile.Methods[distribution.ValidatorCommissionMethod] - - testCases := []distrTestCases{ - { - "success - nonexistent validator address", - func() []interface{} { - pv := mock.NewPV() - pk, err := pv.GetPubKey() - s.Require().NoError(err) - return []interface{}{ - sdk.ValAddress(pk.Address().Bytes()).String(), - } - }, - func(bz []byte) { - var out []sdk.DecCoin - err := s.precompile.UnpackIntoInterface(&out, distribution.ValidatorCommissionMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(0, len(out)) - }, - 100000, - false, - "", - }, - { - "success - existent validator, no accumulated commission", - func() []interface{} { - return []interface{}{ - s.validators[0].OperatorAddress, - } - }, - func(bz []byte) { - var out []sdk.DecCoin - err := s.precompile.UnpackIntoInterface(&out, distribution.ValidatorCommissionMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(0, len(out)) - }, - 100000, - false, - "", - }, - { - "success - with accumulated commission", - func() []interface{} { - valCommission := sdk.DecCoins{sdk.NewDecCoinFromDec(s.bondDenom, math.LegacyNewDec(1))} - s.app.DistrKeeper.SetValidatorAccumulatedCommission(s.ctx, s.validators[0].GetOperator(), types.ValidatorAccumulatedCommission{Commission: valCommission}) - return []interface{}{ - s.validators[0].OperatorAddress, - } - }, - func(bz []byte) { - var out []cmn.DecCoin - err := s.precompile.UnpackIntoInterface(&out, distribution.ValidatorCommissionMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(1, len(out)) - s.Require().Equal(uint8(18), out[0].Precision) - s.Require().Equal(s.bondDenom, out[0].Denom) - s.Require().Equal(expValAmount, out[0].Amount.Int64()) - }, - 100000, - false, - "", - }, - } - testCases = append(testCases, baseTestCases...) - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - bz, err := s.precompile.ValidatorCommission(s.ctx, contract, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestValidatorSlashes() { - method := s.precompile.Methods[distribution.ValidatorSlashesMethod] - - testCases := []distrTestCases{ - { - "fail - invalid validator address", - func() []interface{} { - return []interface{}{ - "invalid", uint64(1), uint64(5), query.PageRequest{}, - } - }, - func(bz []byte) { - }, - 100000, - true, - "invalid validator address", - }, - { - "fail - invalid starting height type", - func() []interface{} { - return []interface{}{ - s.validators[0].OperatorAddress, - int64(1), uint64(5), - query.PageRequest{}, - } - }, - func(bz []byte) { - }, - 100000, - true, - "invalid type for startingHeight: expected uint64, received int64", - }, - { - "fail - starting height greater than ending height", - func() []interface{} { - return []interface{}{ - s.validators[0].OperatorAddress, - uint64(6), uint64(5), - query.PageRequest{}, - } - }, - func(bz []byte) { - }, - 100000, - true, - "starting height greater than ending height", - }, - { - "success - nonexistent validator address", - func() []interface{} { - pv := mock.NewPV() - pk, err := pv.GetPubKey() - s.Require().NoError(err) - return []interface{}{ - sdk.ValAddress(pk.Address().Bytes()).String(), - uint64(1), - uint64(5), - query.PageRequest{}, - } - }, - func(bz []byte) { - var out distribution.ValidatorSlashesOutput - err := s.precompile.UnpackIntoInterface(&out, distribution.ValidatorSlashesMethod, bz) - s.Require().NoError(err, "failed to unpack output") - s.Require().Equal(0, len(out.Slashes)) - s.Require().Equal(uint64(0), out.PageResponse.Total) - }, - 100000, - false, - "", - }, - { - "success - existent validator, no slashes", - func() []interface{} { - return []interface{}{ - s.validators[0].OperatorAddress, - uint64(1), - uint64(5), - query.PageRequest{}, - } - }, - func(bz []byte) { - var out distribution.ValidatorSlashesOutput - err := s.precompile.UnpackIntoInterface(&out, distribution.ValidatorSlashesMethod, bz) - s.Require().NoError(err, "failed to unpack output") - s.Require().Equal(0, len(out.Slashes)) - s.Require().Equal(uint64(0), out.PageResponse.Total) - }, - 100000, - false, - "", - }, - { - "success - with slashes", - func() []interface{} { - s.app.DistrKeeper.SetValidatorSlashEvent(s.ctx, s.validators[0].GetOperator(), 2, 1, types.ValidatorSlashEvent{ValidatorPeriod: 1, Fraction: math.LegacyNewDec(5)}) - return []interface{}{ - s.validators[0].OperatorAddress, - uint64(1), uint64(5), - query.PageRequest{}, - } - }, - func(bz []byte) { - var out distribution.ValidatorSlashesOutput - err := s.precompile.UnpackIntoInterface(&out, distribution.ValidatorSlashesMethod, bz) - s.Require().NoError(err, "failed to unpack output") - s.Require().Equal(1, len(out.Slashes)) - s.Require().Equal(math.LegacyNewDec(5).BigInt(), out.Slashes[0].Fraction.Value) - s.Require().Equal(uint64(1), out.Slashes[0].ValidatorPeriod) - s.Require().Equal(uint64(1), out.PageResponse.Total) - }, - 100000, - false, - "", - }, - { - "success - with slashes w/pagination", - func() []interface{} { - s.app.DistrKeeper.SetValidatorSlashEvent(s.ctx, s.validators[0].GetOperator(), 2, 1, types.ValidatorSlashEvent{ValidatorPeriod: 1, Fraction: math.LegacyNewDec(5)}) - return []interface{}{ - s.validators[0].OperatorAddress, - uint64(1), - uint64(5), - query.PageRequest{Limit: 1, CountTotal: true}, - } - }, - func(bz []byte) { - var out distribution.ValidatorSlashesOutput - err := s.precompile.UnpackIntoInterface(&out, distribution.ValidatorSlashesMethod, bz) - s.Require().NoError(err, "failed to unpack output") - s.Require().Equal(1, len(out.Slashes)) - s.Require().Equal(math.LegacyNewDec(5).BigInt(), out.Slashes[0].Fraction.Value) - s.Require().Equal(uint64(1), out.Slashes[0].ValidatorPeriod) - s.Require().Equal(uint64(1), out.PageResponse.Total) - }, - 100000, - false, - "", - }, - } - testCases = append(testCases, baseTestCases[0]) - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - bz, err := s.precompile.ValidatorSlashes(s.ctx, contract, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestDelegationRewards() { - method := s.precompile.Methods[distribution.DelegationRewardsMethod] - - testCases := []distrTestCases{ - { - "fail - invalid validator address", - func() []interface{} { - return []interface{}{ - s.address, - "invalid", - } - }, - func(bz []byte) {}, - 100000, - true, - "invalid bech32 string", - }, - { - "fail - nonexistent validator address", - func() []interface{} { - pv := mock.NewPV() - pk, err := pv.GetPubKey() - s.Require().NoError(err) - return []interface{}{ - s.address, - sdk.ValAddress(pk.Address().Bytes()).String(), - } - }, - func(bz []byte) {}, - 100000, - true, - "validator does not exist", - }, - { - "fail - existent validator, no delegation", - func() []interface{} { - newAddr, _ := testutiltx.NewAddrKey() - return []interface{}{ - newAddr, - s.validators[0].OperatorAddress, - } - }, - func(bz []byte) {}, - 100000, - true, - "delegation does not exist", - }, - { - "success - existent validator & delegation, but no rewards", - func() []interface{} { - return []interface{}{ - s.address, - s.validators[0].OperatorAddress, - } - }, - func(bz []byte) { - var out []cmn.DecCoin - err := s.precompile.UnpackIntoInterface(&out, distribution.DelegationRewardsMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(0, len(out)) - }, - 100000, - false, - "", - }, - { - "success - with rewards", - func() []interface{} { - s.prepareStakingRewards(stakingRewards{s.address.Bytes(), s.validators[0], rewards}) - return []interface{}{ - s.address, - s.validators[0].OperatorAddress, - } - }, - func(bz []byte) { - var out []cmn.DecCoin - err := s.precompile.UnpackIntoInterface(&out, distribution.DelegationRewardsMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(1, len(out)) - s.Require().Equal(uint8(18), out[0].Precision) - s.Require().Equal(s.bondDenom, out[0].Denom) - s.Require().Equal(expDelegationRewards, out[0].Amount.Int64()) - }, - 100000, - false, - "", - }, - } - testCases = append(testCases, baseTestCases[0]) - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - bz, err := s.precompile.DelegationRewards(s.ctx, contract, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestDelegationTotalRewards() { - method := s.precompile.Methods[distribution.DelegationTotalRewardsMethod] - - testCases := []distrTestCases{ - { - "fail - invalid delegator address", - func() []interface{} { - return []interface{}{ - "invalid", - } - }, - func(bz []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidDelegator, "invalid"), - }, - { - "success - no delegations", - func() []interface{} { - newAddr, _ := testutiltx.NewAddrKey() - return []interface{}{ - newAddr, - } - }, - func(bz []byte) { - var out distribution.DelegationTotalRewardsOutput - err := s.precompile.UnpackIntoInterface(&out, distribution.DelegationTotalRewardsMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(0, len(out.Rewards)) - s.Require().Equal(0, len(out.Total)) - }, - 100000, - false, - "", - }, - { - "success - existent validator & delegation, but no rewards", - func() []interface{} { - return []interface{}{ - s.address, - } - }, - func(bz []byte) { - var out distribution.DelegationTotalRewardsOutput - err := s.precompile.UnpackIntoInterface(&out, distribution.DelegationTotalRewardsMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(2, len(out.Rewards)) - // the response order may change - if out.Rewards[0].ValidatorAddress == s.validators[0].OperatorAddress { - s.Require().Equal(s.validators[0].OperatorAddress, out.Rewards[0].ValidatorAddress) - s.Require().Equal(s.validators[1].OperatorAddress, out.Rewards[1].ValidatorAddress) - } else { - s.Require().Equal(s.validators[1].OperatorAddress, out.Rewards[0].ValidatorAddress) - s.Require().Equal(s.validators[0].OperatorAddress, out.Rewards[1].ValidatorAddress) - } - // no rewards - s.Require().Equal(0, len(out.Rewards[0].Reward)) - s.Require().Equal(0, len(out.Rewards[1].Reward)) - s.Require().Equal(0, len(out.Total)) - }, - 100000, - false, - "", - }, - { - "success - with rewards", - func() []interface{} { - s.prepareStakingRewards(stakingRewards{s.address.Bytes(), s.validators[0], rewards}) - return []interface{}{ - s.address, - } - }, - func(bz []byte) { - var ( - out distribution.DelegationTotalRewardsOutput - i int - ) - err := s.precompile.UnpackIntoInterface(&out, distribution.DelegationTotalRewardsMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(2, len(out.Rewards)) - - // the response order may change - if out.Rewards[0].ValidatorAddress == s.validators[0].OperatorAddress { - s.Require().Equal(s.validators[0].OperatorAddress, out.Rewards[0].ValidatorAddress) - s.Require().Equal(s.validators[1].OperatorAddress, out.Rewards[1].ValidatorAddress) - s.Require().Equal(0, len(out.Rewards[1].Reward)) - } else { - i = 1 - s.Require().Equal(s.validators[0].OperatorAddress, out.Rewards[1].ValidatorAddress) - s.Require().Equal(s.validators[1].OperatorAddress, out.Rewards[0].ValidatorAddress) - s.Require().Equal(0, len(out.Rewards[0].Reward)) - } - - // only validator[i] has rewards - s.Require().Equal(1, len(out.Rewards[i].Reward)) - s.Require().Equal(s.bondDenom, out.Rewards[i].Reward[0].Denom) - s.Require().Equal(uint8(math.LegacyPrecision), out.Rewards[i].Reward[0].Precision) - s.Require().Equal(expDelegationRewards, out.Rewards[i].Reward[0].Amount.Int64()) - - s.Require().Equal(1, len(out.Total)) - s.Require().Equal(expDelegationRewards, out.Total[0].Amount.Int64()) - }, - 100000, - false, - "", - }, - } - testCases = append(testCases, baseTestCases[0]) - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - bz, err := s.precompile.DelegationTotalRewards(s.ctx, contract, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestDelegatorValidators() { - method := s.precompile.Methods[distribution.DelegatorValidatorsMethod] - - testCases := []distrTestCases{ - { - "fail - invalid delegator address", - func() []interface{} { - return []interface{}{ - "invalid", - } - }, - func(bz []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidDelegator, "invalid"), - }, - { - "success - no delegations", - func() []interface{} { - newAddr, _ := testutiltx.NewAddrKey() - return []interface{}{ - newAddr, - } - }, - func(bz []byte) { - var out []string - err := s.precompile.UnpackIntoInterface(&out, distribution.DelegatorValidatorsMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(0, len(out)) - }, - 100000, - false, - "", - }, - { - "success - existent delegations", - func() []interface{} { - return []interface{}{ - s.address, - } - }, - func(bz []byte) { - var out []string - err := s.precompile.UnpackIntoInterface(&out, distribution.DelegatorValidatorsMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(2, len(out)) - // the order may change - if out[0] == s.validators[0].OperatorAddress { - s.Require().Equal(s.validators[0].OperatorAddress, out[0]) - s.Require().Equal(s.validators[1].OperatorAddress, out[1]) - } else { - s.Require().Equal(s.validators[1].OperatorAddress, out[0]) - s.Require().Equal(s.validators[0].OperatorAddress, out[1]) - } - }, - 100000, - false, - "", - }, - } - testCases = append(testCases, baseTestCases[0]) - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - bz, err := s.precompile.DelegatorValidators(s.ctx, contract, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestDelegatorWithdrawAddress() { - method := s.precompile.Methods[distribution.DelegatorWithdrawAddressMethod] - - testCases := []distrTestCases{ - { - "fail - invalid delegator address", - func() []interface{} { - return []interface{}{ - "invalid", - } - }, - func(bz []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidDelegator, "invalid"), - }, - { - "success - withdraw address same as delegator address", - func() []interface{} { - return []interface{}{ - s.address, - } - }, - func(bz []byte) { - var out string - err := s.precompile.UnpackIntoInterface(&out, distribution.DelegatorWithdrawAddressMethod, bz) - s.Require().NoError(err, "failed to unpack output", err) - s.Require().Equal(sdk.AccAddress(s.address.Bytes()).String(), out) - }, - 100000, - false, - "", - }, - } - testCases = append(testCases, baseTestCases[0]) - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - bz, err := s.precompile.DelegatorWithdrawAddress(s.ctx, contract, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz) - } - }) - } -} diff --git a/precompiles/distribution/setup_test.go b/precompiles/distribution/setup_test.go deleted file mode 100644 index e8dda389..00000000 --- a/precompiles/distribution/setup_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package distribution_test - -import ( - "testing" - - "github.com/evmos/evmos/v16/precompiles/distribution" - "github.com/evmos/evmos/v16/x/evm/statedb" - - //nolint:revive // dot imports are fine for Ginkgo - . "github.com/onsi/ginkgo/v2" - //nolint:revive // dot imports are fine for Ginkgo - . "github.com/onsi/gomega" - - tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - sdk "github.com/cosmos/cosmos-sdk/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - evmosapp "github.com/evmos/evmos/v16/app" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" - "github.com/stretchr/testify/suite" -) - -var s *PrecompileTestSuite - -type PrecompileTestSuite struct { - suite.Suite - - ctx sdk.Context - app *evmosapp.Evmos - address common.Address - validators []stakingtypes.Validator - valSet *tmtypes.ValidatorSet - ethSigner ethtypes.Signer - privKey cryptotypes.PrivKey - signer keyring.Signer - bondDenom string - - precompile *distribution.Precompile - stateDB *statedb.StateDB - - queryClientEVM evmtypes.QueryClient -} - -func TestPrecompileTestSuite(t *testing.T) { - s = new(PrecompileTestSuite) - suite.Run(t, s) - - // Run Ginkgo integration tests - RegisterFailHandler(Fail) - RunSpecs(t, "Distribution Precompile Suite") -} - -func (s *PrecompileTestSuite) SetupTest() { - s.DoSetupTest() -} diff --git a/precompiles/distribution/tx.go b/precompiles/distribution/tx.go deleted file mode 100644 index 09114bfa..00000000 --- a/precompiles/distribution/tx.go +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package distribution - -import ( - "fmt" - "math/big" - - "github.com/evmos/evmos/v16/x/evm/statedb" - - cmn "github.com/evmos/evmos/v16/precompiles/common" - - "github.com/ethereum/go-ethereum/common" - - sdk "github.com/cosmos/cosmos-sdk/types" - distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/core/vm" -) - -const ( - // SetWithdrawAddressMethod defines the ABI method name for the distribution - // SetWithdrawAddress transaction. - SetWithdrawAddressMethod = "setWithdrawAddress" - // WithdrawDelegatorRewardsMethod defines the ABI method name for the distribution - // WithdrawDelegatorRewards transaction. - WithdrawDelegatorRewardsMethod = "withdrawDelegatorRewards" - // WithdrawValidatorCommissionMethod defines the ABI method name for the distribution - // WithdrawValidatorCommission transaction. - WithdrawValidatorCommissionMethod = "withdrawValidatorCommission" - // ClaimRewardsMethod defines the ABI method name for the custom ClaimRewards transaction - ClaimRewardsMethod = "claimRewards" -) - -// ClaimRewards claims the rewards accumulated by a delegator from multiple or all validators. -func (p Precompile) ClaimRewards( - ctx sdk.Context, - origin common.Address, - contract *vm.Contract, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - delegatorAddr, maxRetrieve, err := parseClaimRewardsArgs(args) - if err != nil { - return nil, err - } - - // If the contract is the delegator, we don't need an origin check - // Otherwise check if the origin matches the delegator address - isContractDelegator := contract.CallerAddress == delegatorAddr - if !isContractDelegator && origin != delegatorAddr { - return nil, fmt.Errorf(cmn.ErrDifferentOrigin, origin.String(), delegatorAddr.String()) - } - - validators := p.stakingKeeper.GetDelegatorValidators(ctx, delegatorAddr.Bytes(), maxRetrieve) - totalCoins := sdk.Coins{} - for _, validator := range validators { - // Convert the validator operator address into an ValAddress - valAddr, err := sdk.ValAddressFromBech32(validator.OperatorAddress) - if err != nil { - return nil, err - } - - // Withdraw the rewards for each validator address - coins, err := p.distributionKeeper.WithdrawDelegationRewards(ctx, delegatorAddr.Bytes(), valAddr) - if err != nil { - return nil, err - } - - totalCoins = totalCoins.Add(coins...) - } - - if err := p.EmitClaimRewardsEvent(ctx, stateDB, delegatorAddr, totalCoins); err != nil { - return nil, err - } - - return method.Outputs.Pack(true) -} - -// SetWithdrawAddress sets the withdrawal address for a delegator (or validator self-delegation). -func (p Precompile) SetWithdrawAddress( - ctx sdk.Context, - origin common.Address, - contract *vm.Contract, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - msg, delegatorHexAddr, err := NewMsgSetWithdrawAddress(args) - if err != nil { - return nil, err - } - - // If the contract is the delegator, we don't need an origin check - // Otherwise check if the origin matches the delegator address - isContractDelegator := contract.CallerAddress == delegatorHexAddr - if !isContractDelegator && origin != delegatorHexAddr { - return nil, fmt.Errorf(cmn.ErrDifferentOrigin, origin.String(), delegatorHexAddr.String()) - } - - msgSrv := distributionkeeper.NewMsgServerImpl(p.distributionKeeper) - if _, err = msgSrv.SetWithdrawAddress(sdk.WrapSDKContext(ctx), msg); err != nil { - return nil, err - } - - if err = p.EmitSetWithdrawAddressEvent(ctx, stateDB, delegatorHexAddr, msg.WithdrawAddress); err != nil { - return nil, err - } - - return method.Outputs.Pack(true) -} - -// WithdrawDelegatorRewards withdraws the rewards of a delegator from a single validator. -func (p Precompile) WithdrawDelegatorRewards( - ctx sdk.Context, - origin common.Address, - contract *vm.Contract, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - msg, delegatorHexAddr, err := NewMsgWithdrawDelegatorReward(args) - if err != nil { - return nil, err - } - - // If the contract is the delegator, we don't need an origin check - // Otherwise check if the origin matches the delegator address - isContractDelegator := contract.CallerAddress == delegatorHexAddr - if !isContractDelegator && origin != delegatorHexAddr { - return nil, fmt.Errorf(cmn.ErrDifferentOrigin, origin.String(), delegatorHexAddr.String()) - } - - msgSrv := distributionkeeper.NewMsgServerImpl(p.distributionKeeper) - res, err := msgSrv.WithdrawDelegatorReward(sdk.WrapSDKContext(ctx), msg) - if err != nil { - return nil, err - } - - if err = p.EmitWithdrawDelegatorRewardsEvent(ctx, stateDB, delegatorHexAddr, msg.ValidatorAddress, res.Amount); err != nil { - return nil, err - } - - // NOTE: This ensures that the changes in the bank keeper are correctly mirrored to the EVM stateDB. - // This prevents the stateDB from overwriting the changed balance in the bank keeper when committing the EVM state. - if isContractDelegator { - // the responsed amount is from cosmos module, which has 6 decimal points - // convert it to the EVM amount which has 18 decimal points - convertedAmount := res.Amount[0].Amount.BigInt() - convertedAmount.Mul(convertedAmount, big.NewInt(1e12)) - stateDB.(*statedb.StateDB).AddBalance(contract.CallerAddress, convertedAmount) - } - - return method.Outputs.Pack(cmn.NewCoinsResponse(res.Amount)) -} - -// WithdrawValidatorCommission withdraws the rewards of a validator. -func (p Precompile) WithdrawValidatorCommission( - ctx sdk.Context, - origin common.Address, - contract *vm.Contract, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - msg, validatorHexAddr, err := NewMsgWithdrawValidatorCommission(args) - if err != nil { - return nil, err - } - - // If the contract is the validator, we don't need an origin check - // Otherwise check if the origin matches the validator address - isContractValidator := contract.CallerAddress == validatorHexAddr - if !isContractValidator && origin != validatorHexAddr { - return nil, fmt.Errorf(cmn.ErrDifferentOrigin, origin.String(), validatorHexAddr.String()) - } - - msgSrv := distributionkeeper.NewMsgServerImpl(p.distributionKeeper) - res, err := msgSrv.WithdrawValidatorCommission(sdk.WrapSDKContext(ctx), msg) - if err != nil { - return nil, err - } - - if err = p.EmitWithdrawValidatorCommissionEvent(ctx, stateDB, msg.ValidatorAddress, res.Amount); err != nil { - return nil, err - } - - return method.Outputs.Pack(cmn.NewCoinsResponse(res.Amount)) -} diff --git a/precompiles/distribution/tx_test.go b/precompiles/distribution/tx_test.go deleted file mode 100644 index f0973344..00000000 --- a/precompiles/distribution/tx_test.go +++ /dev/null @@ -1,418 +0,0 @@ -package distribution_test - -import ( - "fmt" - "math/big" - - "cosmossdk.io/math" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/evmos/evmos/v16/precompiles/testutil" - - "github.com/ethereum/go-ethereum/common" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/distribution/types" - cmn "github.com/evmos/evmos/v16/precompiles/common" - "github.com/evmos/evmos/v16/precompiles/distribution" - utiltx "github.com/evmos/evmos/v16/testutil/tx" - "github.com/evmos/evmos/v16/utils" -) - -func (s *PrecompileTestSuite) TestSetWithdrawAddress() { - method := s.precompile.Methods[distribution.SetWithdrawAddressMethod] - newWithdrawerAddr := utiltx.GenerateAddress() - - testCases := []struct { - name string - malleate func() []interface{} - postCheck func() - gas uint64 - expError bool - errContains string - }{ - { - "fail - empty input args", - func() []interface{} { - return []interface{}{} - }, - func() {}, - 200000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 2, 0), - }, - { - "fail - invalid delegator address", - func() []interface{} { - return []interface{}{ - "", - s.address.String(), - } - }, - func() {}, - 200000, - true, - fmt.Sprintf(cmn.ErrInvalidDelegator, ""), - }, - { - "fail - invalid withdrawer address", - func() []interface{} { - return []interface{}{ - s.address, - nil, - } - }, - func() {}, - 200000, - true, - "invalid withdraw address: empty address string is not allowed: invalid address", - }, - { - "success - using the same address withdrawer address", - func() []interface{} { - return []interface{}{ - s.address, - s.address.String(), - } - }, - func() { - withdrawerAddr := s.app.DistrKeeper.GetDelegatorWithdrawAddr(s.ctx, s.address.Bytes()) - s.Require().Equal(withdrawerAddr.Bytes(), s.address.Bytes()) - }, - 20000, - false, - "", - }, - { - "success - using a different withdrawer address", - func() []interface{} { - return []interface{}{ - s.address, - newWithdrawerAddr.String(), - } - }, - func() { - withdrawerAddr := s.app.DistrKeeper.GetDelegatorWithdrawAddr(s.ctx, s.address.Bytes()) - s.Require().Equal(withdrawerAddr.Bytes(), newWithdrawerAddr.Bytes()) - }, - 20000, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - var contract *vm.Contract - contract, s.ctx = testutil.NewPrecompileContract(s.T(), s.ctx, s.address, s.precompile, tc.gas) - - _, err := s.precompile.SetWithdrawAddress(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate()) - - if tc.expError { - s.Require().ErrorContains(err, tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck() - } - }) - } -} - -func (s *PrecompileTestSuite) TestWithdrawDelegatorRewards() { - method := s.precompile.Methods[distribution.WithdrawDelegatorRewardsMethod] - - testCases := []struct { - name string - malleate func(operatorAddress string) []interface{} - postCheck func(data []byte) - gas uint64 - expError bool - errContains string - }{ - { - "fail - empty input args", - func(operatorAddress string) []interface{} { - return []interface{}{} - }, - func(data []byte) {}, - 200000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 2, 0), - }, - { - "fail - invalid delegator address", - func(operatorAddress string) []interface{} { - return []interface{}{ - "", - operatorAddress, - } - }, - func(data []byte) {}, - 200000, - true, - fmt.Sprintf(cmn.ErrInvalidDelegator, ""), - }, - { - "fail - invalid validator address", - func(operatorAddress string) []interface{} { - return []interface{}{ - s.address, - nil, - } - }, - func(data []byte) {}, - 200000, - true, - "invalid validator address", - }, - { - "success - withdraw rewards from a single validator without commission", - func(operatorAddress string) []interface{} { - valAddr, err := sdk.ValAddressFromBech32(operatorAddress) - s.Require().NoError(err) - val, _ := s.app.StakingKeeper.GetValidator(s.ctx, valAddr) - coins := sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(1e18))) - s.app.DistrKeeper.AllocateTokensToValidator(s.ctx, val, sdk.NewDecCoinsFromCoins(coins...)) - return []interface{}{ - s.address, - operatorAddress, - } - }, - func(data []byte) { - var coins []cmn.Coin - err := s.precompile.UnpackIntoInterface(&coins, distribution.WithdrawDelegatorRewardsMethod, data) - s.Require().NoError(err, "failed to unpack output") - s.Require().Equal(coins[0].Denom, utils.BaseDenom) - s.Require().Equal(coins[0].Amount, big.NewInt(1000000000000000000)) - // Check bank balance after the withdrawal of rewards - balance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), utils.BaseDenom) - s.Require().Equal(balance.Amount.BigInt(), big.NewInt(6000000000000000000)) - }, - 20000, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - // sanity check to make sure the starting balance is always 5 EVMOS - balance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), utils.BaseDenom) - s.Require().Equal(balance.Amount.BigInt(), big.NewInt(5000000000000000000)) - - var contract *vm.Contract - contract, s.ctx = testutil.NewPrecompileContract(s.T(), s.ctx, s.address, s.precompile, tc.gas) - - bz, err := s.precompile.WithdrawDelegatorRewards(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate(s.validators[0].OperatorAddress)) - - if tc.expError { - s.Require().ErrorContains(err, tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestWithdrawValidatorCommission() { - method := s.precompile.Methods[distribution.WithdrawDelegatorRewardsMethod] - - testCases := []struct { - name string - malleate func(operatorAddress string) []interface{} - postCheck func(data []byte) - gas uint64 - expError bool - errContains string - }{ - { - "fail - empty input args", - func(operatorAddress string) []interface{} { - return []interface{}{} - }, - func(data []byte) {}, - 200000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 1, 0), - }, - { - "fail - invalid validator address", - func(operatorAddress string) []interface{} { - return []interface{}{ - nil, - } - }, - func(data []byte) {}, - 200000, - true, - "invalid validator address", - }, - { - "success - withdraw all commission from a single validator", - func(operatorAddress string) []interface{} { - valAddr, err := sdk.ValAddressFromBech32(operatorAddress) - s.Require().NoError(err) - valCommission := sdk.DecCoins{sdk.NewDecCoinFromDec(utils.BaseDenom, math.LegacyNewDecWithPrec(1000000000000000000, 1))} - // set outstanding rewards - s.app.DistrKeeper.SetValidatorOutstandingRewards(s.ctx, valAddr, types.ValidatorOutstandingRewards{Rewards: valCommission}) - // set commission - s.app.DistrKeeper.SetValidatorAccumulatedCommission(s.ctx, valAddr, types.ValidatorAccumulatedCommission{Commission: valCommission}) - return []interface{}{ - operatorAddress, - } - }, - func(data []byte) { - var coins []cmn.Coin - err := s.precompile.UnpackIntoInterface(&coins, distribution.WithdrawValidatorCommissionMethod, data) - s.Require().NoError(err, "failed to unpack output") - s.Require().Equal(coins[0].Denom, utils.BaseDenom) - s.Require().Equal(coins[0].Amount, big.NewInt(100000000000000000)) - // Check bank balance after the withdrawal of commission - balance := s.app.BankKeeper.GetBalance(s.ctx, s.validators[0].GetOperator().Bytes(), utils.BaseDenom) - s.Require().Equal(balance.Amount.BigInt(), big.NewInt(100000000000000000)) - s.Require().Equal(balance.Denom, utils.BaseDenom) - }, - 20000, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - // Sanity check to make sure the starting balance is always 0 - balance := s.app.BankKeeper.GetBalance(s.ctx, s.validators[0].GetOperator().Bytes(), utils.BaseDenom) - s.Require().Equal(balance.Amount.BigInt(), big.NewInt(0)) - s.Require().Equal(balance.Denom, utils.BaseDenom) - - validatorAddress := common.BytesToAddress(s.validators[0].GetOperator().Bytes()) - var contract *vm.Contract - contract, s.ctx = testutil.NewPrecompileContract(s.T(), s.ctx, validatorAddress, s.precompile, tc.gas) - - bz, err := s.precompile.WithdrawValidatorCommission(s.ctx, validatorAddress, contract, s.stateDB, &method, tc.malleate(s.validators[0].OperatorAddress)) - - if tc.expError { - s.Require().ErrorContains(err, tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestClaimRewards() { - method := s.precompile.Methods[distribution.ClaimRewardsMethod] - - testCases := []struct { - name string - malleate func() []interface{} - postCheck func(data []byte) - gas uint64 - expError bool - errContains string - }{ - { - "fail - empty input args", - func() []interface{} { - return []interface{}{} - }, - func(data []byte) {}, - 200000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 2, 0), - }, - { - "fail - invalid delegator address", - func() []interface{} { - return []interface{}{ - nil, - 10, - } - }, - func(data []byte) {}, - 200000, - true, - "invalid delegator address", - }, - { - "fail - invalid type for maxRetrieve: expected uint32", - func() []interface{} { - return []interface{}{ - s.address, - big.NewInt(100000000000000000), - } - }, - func(data []byte) {}, - 200000, - true, - "invalid type for maxRetrieve: expected uint32", - }, - { - "success - withdraw from all validators - 2", - func() []interface{} { - return []interface{}{ - s.address, - uint32(2), - } - }, - func(data []byte) { - balance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), utils.BaseDenom) - s.Require().Equal(balance.Amount.BigInt(), big.NewInt(7e18)) - }, - 20000, - false, - "", - }, - { - "success - withdraw from only 1 validator", - func() []interface{} { - return []interface{}{ - s.address, - uint32(1), - } - }, - func(data []byte) { - balance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), utils.BaseDenom) - s.Require().Equal(balance.Amount.BigInt(), big.NewInt(6e18)) - }, - 20000, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - var contract *vm.Contract - contract, s.ctx = testutil.NewPrecompileContract(s.T(), s.ctx, s.address, s.precompile, tc.gas) - - // Sanity check to make sure the starting balance is always 5 EVMOS - balance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), utils.BaseDenom) - s.Require().Equal(balance.Amount.BigInt(), big.NewInt(5e18)) - - // Distribute rewards to the 2 validators, 1 EVMOS each - for _, val := range s.validators { - coins := sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(1e18))) - s.app.DistrKeeper.AllocateTokensToValidator(s.ctx, val, sdk.NewDecCoinsFromCoins(coins...)) - } - - bz, err := s.precompile.ClaimRewards(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate()) - - if tc.expError { - s.Require().ErrorContains(err, tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck(bz) - } - }) - } -} diff --git a/precompiles/distribution/types.go b/precompiles/distribution/types.go deleted file mode 100644 index 438ef21d..00000000 --- a/precompiles/distribution/types.go +++ /dev/null @@ -1,391 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package distribution - -import ( - "fmt" - "math/big" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/query" - distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - cmn "github.com/evmos/evmos/v16/precompiles/common" - - "github.com/aura-nw/aura/precompiles/util" -) - -// EventSetWithdrawAddress defines the event data for the SetWithdrawAddress transaction. -type EventSetWithdrawAddress struct { - Caller common.Address - WithdrawerAddress string -} - -// EventWithdrawDelegatorRewards defines the event data for the WithdrawDelegatorRewards transaction. -type EventWithdrawDelegatorRewards struct { - DelegatorAddress common.Address - ValidatorAddress common.Address - Amount *big.Int -} - -// EventWithdrawValidatorRewards defines the event data for the WithdrawValidatorRewards transaction. -type EventWithdrawValidatorRewards struct { - ValidatorAddress common.Hash - Commission *big.Int -} - -// EventClaimRewards defines the event data for the ClaimRewards transaction. -type EventClaimRewards struct { - DelegatorAddress common.Address - Amount *big.Int -} - -// parseClaimRewardsArgs parses the arguments for the ClaimRewards method. -func parseClaimRewardsArgs(args []interface{}) (common.Address, uint32, error) { - if len(args) != 2 { - return common.Address{}, 0, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 2, len(args)) - } - - delegatorAddress, ok := args[0].(common.Address) - if !ok || delegatorAddress == (common.Address{}) { - return common.Address{}, 0, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - maxRetrieve, ok := args[1].(uint32) - if !ok { - return common.Address{}, 0, fmt.Errorf(cmn.ErrInvalidType, "maxRetrieve", uint32(0), args[1]) - } - - return delegatorAddress, maxRetrieve, nil -} - -// NewMsgSetWithdrawAddress creates a new MsgSetWithdrawAddress instance. -func NewMsgSetWithdrawAddress(args []interface{}) (*distributiontypes.MsgSetWithdrawAddress, common.Address, error) { - if len(args) != 2 { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 2, len(args)) - } - - delegatorAddress, ok := args[0].(common.Address) - if !ok || delegatorAddress == (common.Address{}) { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - withdrawerAddress, _ := args[1].(string) - - // If the withdrawer address is a hex address, convert it to a bech32 address. - if common.IsHexAddress(withdrawerAddress) { - var err error - withdrawerAddress, err = sdk.Bech32ifyAddressBytes("aura", common.HexToAddress(withdrawerAddress).Bytes()) - if err != nil { - return nil, common.Address{}, err - } - } - - msg := &distributiontypes.MsgSetWithdrawAddress{ - DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(), - WithdrawAddress: withdrawerAddress, - } - - if err := msg.ValidateBasic(); err != nil { - return nil, common.Address{}, err - } - - return msg, delegatorAddress, nil -} - -// NewMsgWithdrawDelegatorReward creates a new MsgWithdrawDelegatorReward instance. -func NewMsgWithdrawDelegatorReward(args []interface{}) (*distributiontypes.MsgWithdrawDelegatorReward, common.Address, error) { - if len(args) != 2 { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 2, len(args)) - } - - delegatorAddress, ok := args[0].(common.Address) - if !ok || delegatorAddress == (common.Address{}) { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - validatorAddress, _ := args[1].(string) - - msg := &distributiontypes.MsgWithdrawDelegatorReward{ - DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(), - ValidatorAddress: validatorAddress, - } - - if err := msg.ValidateBasic(); err != nil { - return nil, common.Address{}, err - } - - return msg, delegatorAddress, nil -} - -// NewMsgWithdrawValidatorCommission creates a new MsgWithdrawValidatorCommission message. -func NewMsgWithdrawValidatorCommission(args []interface{}) (*distributiontypes.MsgWithdrawValidatorCommission, common.Address, error) { - if len(args) != 1 { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 1, len(args)) - } - - validatorAddress, _ := args[0].(string) - - msg := &distributiontypes.MsgWithdrawValidatorCommission{ - ValidatorAddress: validatorAddress, - } - - if err := msg.ValidateBasic(); err != nil { - return nil, common.Address{}, err - } - - validatorHexAddr, err := cmn.HexAddressFromBech32String(msg.ValidatorAddress) - if err != nil { - return nil, common.Address{}, err - } - - return msg, validatorHexAddr, nil -} - -// NewValidatorDistributionInfoRequest creates a new QueryValidatorDistributionInfoRequest instance and does sanity -// checks on the provided arguments. -func NewValidatorDistributionInfoRequest(args []interface{}) (*distributiontypes.QueryValidatorDistributionInfoRequest, error) { - if len(args) != 1 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 1, len(args)) - } - - validatorAddress, _ := args[0].(string) - - return &distributiontypes.QueryValidatorDistributionInfoRequest{ - ValidatorAddress: validatorAddress, - }, nil -} - -// NewValidatorOutstandingRewardsRequest creates a new QueryValidatorOutstandingRewardsRequest instance and does sanity -// checks on the provided arguments. -func NewValidatorOutstandingRewardsRequest(args []interface{}) (*distributiontypes.QueryValidatorOutstandingRewardsRequest, error) { - if len(args) != 1 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 1, len(args)) - } - - validatorAddress, _ := args[0].(string) - - return &distributiontypes.QueryValidatorOutstandingRewardsRequest{ - ValidatorAddress: validatorAddress, - }, nil -} - -// NewValidatorCommissionRequest creates a new QueryValidatorCommissionRequest instance and does sanity -// checks on the provided arguments. -func NewValidatorCommissionRequest(args []interface{}) (*distributiontypes.QueryValidatorCommissionRequest, error) { - if len(args) != 1 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 1, len(args)) - } - - validatorAddress, _ := args[0].(string) - - return &distributiontypes.QueryValidatorCommissionRequest{ - ValidatorAddress: validatorAddress, - }, nil -} - -// NewValidatorSlashesRequest creates a new QueryValidatorSlashesRequest instance and does sanity -// checks on the provided arguments. -func NewValidatorSlashesRequest(method *abi.Method, args []interface{}) (*distributiontypes.QueryValidatorSlashesRequest, error) { - if len(args) != 4 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 4, len(args)) - } - - if _, ok := args[1].(uint64); !ok { - return nil, fmt.Errorf(cmn.ErrInvalidType, "startingHeight", uint64(0), args[1]) - } - if _, ok := args[2].(uint64); !ok { - return nil, fmt.Errorf(cmn.ErrInvalidType, "endingHeight", uint64(0), args[2]) - } - - var input ValidatorSlashesInput - if err := method.Inputs.Copy(&input, args); err != nil { - return nil, fmt.Errorf("error while unpacking args to ValidatorSlashesInput struct: %s", err) - } - - return &distributiontypes.QueryValidatorSlashesRequest{ - ValidatorAddress: input.ValidatorAddress, - StartingHeight: input.StartingHeight, - EndingHeight: input.EndingHeight, - Pagination: &input.PageRequest, - }, nil -} - -// NewDelegationRewardsRequest creates a new QueryDelegationRewardsRequest instance and does sanity -// checks on the provided arguments. -func NewDelegationRewardsRequest(args []interface{}) (*distributiontypes.QueryDelegationRewardsRequest, error) { - if len(args) != 2 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 2, len(args)) - } - - delegatorAddress, ok := args[0].(common.Address) - if !ok || delegatorAddress == (common.Address{}) { - return nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - validatorAddress, _ := args[1].(string) - - return &distributiontypes.QueryDelegationRewardsRequest{ - DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(), - ValidatorAddress: validatorAddress, - }, nil -} - -// NewDelegationTotalRewardsRequest creates a new QueryDelegationTotalRewardsRequest instance and does sanity -// checks on the provided arguments. -func NewDelegationTotalRewardsRequest(args []interface{}) (*distributiontypes.QueryDelegationTotalRewardsRequest, error) { - if len(args) != 1 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 1, len(args)) - } - - delegatorAddress, ok := args[0].(common.Address) - if !ok || delegatorAddress == (common.Address{}) { - return nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - return &distributiontypes.QueryDelegationTotalRewardsRequest{ - DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(), - }, nil -} - -// NewDelegatorValidatorsRequest creates a new QueryDelegatorValidatorsRequest instance and does sanity -// checks on the provided arguments. -func NewDelegatorValidatorsRequest(args []interface{}) (*distributiontypes.QueryDelegatorValidatorsRequest, error) { - if len(args) != 1 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 1, len(args)) - } - - delegatorAddress, ok := args[0].(common.Address) - if !ok || delegatorAddress == (common.Address{}) { - return nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - return &distributiontypes.QueryDelegatorValidatorsRequest{ - DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(), - }, nil -} - -// NewDelegatorWithdrawAddressRequest creates a new QueryDelegatorWithdrawAddressRequest instance and does sanity -// checks on the provided arguments. -func NewDelegatorWithdrawAddressRequest(args []interface{}) (*distributiontypes.QueryDelegatorWithdrawAddressRequest, error) { - if len(args) != 1 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 1, len(args)) - } - - delegatorAddress, ok := args[0].(common.Address) - if !ok || delegatorAddress == (common.Address{}) { - return nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - return &distributiontypes.QueryDelegatorWithdrawAddressRequest{ - DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(), - }, nil -} - -// ValidatorDistributionInfo is a struct to represent the key information from -// a ValidatorDistributionInfoResponse. -type ValidatorDistributionInfo struct { - OperatorAddress string `abi:"operatorAddress"` - SelfBondRewards []cmn.DecCoin `abi:"selfBondRewards"` - Commission []cmn.DecCoin `abi:"commission"` -} - -// ValidatorDistributionInfoOutput is a wrapper for ValidatorDistributionInfo to return in the response. -type ValidatorDistributionInfoOutput struct { - DistributionInfo ValidatorDistributionInfo `abi:"distributionInfo"` -} - -// FromResponse converts a response to a ValidatorDistributionInfo. -func (o *ValidatorDistributionInfoOutput) FromResponse(res *distributiontypes.QueryValidatorDistributionInfoResponse) ValidatorDistributionInfoOutput { - return ValidatorDistributionInfoOutput{ - DistributionInfo: ValidatorDistributionInfo{ - OperatorAddress: res.OperatorAddress, - SelfBondRewards: util.NewDecCoinsResponseEVM(res.SelfBondRewards), - Commission: util.NewDecCoinsResponseEVM(res.Commission), - }, - } -} - -// ValidatorSlashEvent is a struct to represent the key information from -// a ValidatorSlashEvent response. -type ValidatorSlashEvent struct { - ValidatorPeriod uint64 `abi:"validatorPeriod"` - Fraction cmn.Dec `abi:"fraction"` -} - -// ValidatorSlashesInput is a struct to represent the key information -// to perform a ValidatorSlashes query. -type ValidatorSlashesInput struct { - ValidatorAddress string - StartingHeight uint64 - EndingHeight uint64 - PageRequest query.PageRequest -} - -// ValidatorSlashesOutput is a struct to represent the key information from -// a ValidatorSlashes response. -type ValidatorSlashesOutput struct { - Slashes []ValidatorSlashEvent - PageResponse query.PageResponse -} - -// FromResponse populates the ValidatorSlashesOutput from a QueryValidatorSlashesResponse. -func (vs *ValidatorSlashesOutput) FromResponse(res *distributiontypes.QueryValidatorSlashesResponse) *ValidatorSlashesOutput { - vs.Slashes = make([]ValidatorSlashEvent, len(res.Slashes)) - for i, s := range res.Slashes { - vs.Slashes[i] = ValidatorSlashEvent{ - ValidatorPeriod: s.ValidatorPeriod, - Fraction: cmn.Dec{ - Value: s.Fraction.BigInt(), - Precision: math.LegacyPrecision, - }, - } - } - - if res.Pagination != nil { - vs.PageResponse.Total = res.Pagination.Total - vs.PageResponse.NextKey = res.Pagination.NextKey - } - - return vs -} - -// Pack packs a given slice of abi arguments into a byte array. -func (vs *ValidatorSlashesOutput) Pack(args abi.Arguments) ([]byte, error) { - return args.Pack(vs.Slashes, vs.PageResponse) -} - -// DelegationDelegatorReward is a struct to represent the key information from -// a query for the rewards of a delegation to a given validator. -type DelegationDelegatorReward struct { - ValidatorAddress string - Reward []cmn.DecCoin -} - -// DelegationTotalRewardsOutput is a struct to represent the key information from -// a DelegationTotalRewards response. -type DelegationTotalRewardsOutput struct { - Rewards []DelegationDelegatorReward - Total []cmn.DecCoin -} - -// FromResponse populates the DelegationTotalRewardsOutput from a QueryDelegationTotalRewardsResponse. -func (dtr *DelegationTotalRewardsOutput) FromResponse(res *distributiontypes.QueryDelegationTotalRewardsResponse) *DelegationTotalRewardsOutput { - dtr.Rewards = make([]DelegationDelegatorReward, len(res.Rewards)) - for i, r := range res.Rewards { - dtr.Rewards[i] = DelegationDelegatorReward{ - ValidatorAddress: r.ValidatorAddress, - Reward: util.NewDecCoinsResponseEVM(r.Reward), - } - } - dtr.Total = util.NewDecCoinsResponseEVM(res.Total) - return dtr -} - -// Pack packs a given slice of abi arguments into a byte array. -func (dtr *DelegationTotalRewardsOutput) Pack(args abi.Arguments) ([]byte, error) { - return args.Pack(dtr.Rewards, dtr.Total) -} diff --git a/precompiles/distribution/utils_test.go b/precompiles/distribution/utils_test.go deleted file mode 100644 index 581ba9a9..00000000 --- a/precompiles/distribution/utils_test.go +++ /dev/null @@ -1,276 +0,0 @@ -package distribution_test - -import ( - "encoding/json" - "time" - - "cosmossdk.io/math" - abci "github.com/cometbft/cometbft/abci/types" - "github.com/cometbft/cometbft/crypto/tmhash" - tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/cosmos-sdk/baseapp" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" - "github.com/cosmos/cosmos-sdk/testutil/mock" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - sdkstaking "github.com/cosmos/cosmos-sdk/x/staking" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - evmosapp "github.com/evmos/evmos/v16/app" - cmn "github.com/evmos/evmos/v16/precompiles/common" - "github.com/evmos/evmos/v16/precompiles/distribution" - evmosutil "github.com/evmos/evmos/v16/testutil" - evmosutiltx "github.com/evmos/evmos/v16/testutil/tx" - evmostypes "github.com/evmos/evmos/v16/types" - "github.com/evmos/evmos/v16/utils" - "github.com/evmos/evmos/v16/x/evm/statedb" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" - inflationtypes "github.com/evmos/evmos/v16/x/inflation/v1/types" -) - -// SetupWithGenesisValSet initializes a new EvmosApp with a validator set and genesis accounts -// that also act as delegators. For simplicity, each validator is bonded with a delegation -// of one consensus engine unit (10^6) in the default token of the simapp from first genesis -// account. A Nop logger is set in SimApp. -func (s *PrecompileTestSuite) SetupWithGenesisValSet(valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) { - appI, genesisState := evmosapp.SetupTestingApp(cmn.DefaultChainID)() - app, ok := appI.(*evmosapp.Evmos) - s.Require().True(ok) - - // set genesis accounts - authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) - genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis) - - validators := make([]stakingtypes.Validator, 0, len(valSet.Validators)) - delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators)) - - bondAmt := sdk.TokensFromConsensusPower(1, evmostypes.PowerReduction) - - for _, val := range valSet.Validators { - pk, err := cryptocodec.FromTmPubKeyInterface(val.PubKey) - s.Require().NoError(err) - pkAny, err := codectypes.NewAnyWithValue(pk) - s.Require().NoError(err) - validator := stakingtypes.Validator{ - OperatorAddress: sdk.ValAddress(val.Address).String(), - ConsensusPubkey: pkAny, - Jailed: false, - Status: stakingtypes.Bonded, - Tokens: bondAmt, - DelegatorShares: math.LegacyOneDec(), - Description: stakingtypes.Description{}, - UnbondingHeight: int64(0), - UnbondingTime: time.Unix(0, 0).UTC(), - Commission: stakingtypes.NewCommission(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()), - MinSelfDelegation: math.ZeroInt(), - } - validators = append(validators, validator) - delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress(), val.Address.Bytes(), math.LegacyOneDec())) - } - s.validators = validators - - // set validators and delegations - stakingParams := stakingtypes.DefaultParams() - // set bond demon to be aevmos - stakingParams.BondDenom = utils.BaseDenom - stakingGenesis := stakingtypes.NewGenesisState(stakingParams, validators, delegations) - genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(stakingGenesis) - - totalBondAmt := bondAmt.Add(bondAmt) - totalSupply := sdk.NewCoins() - for _, b := range balances { - // add genesis acc tokens and delegated tokens to total supply - totalSupply = totalSupply.Add(b.Coins.Add(sdk.NewCoin(utils.BaseDenom, totalBondAmt))...) - } - - // add bonded amount to bonded pool module account - balances = append(balances, banktypes.Balance{ - Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), - Coins: sdk.Coins{sdk.NewCoin(utils.BaseDenom, totalBondAmt)}, - }) - - // update total supply - bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}, []banktypes.SendEnabled{}) - genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis) - - stateBytes, err := json.MarshalIndent(genesisState, "", " ") - s.Require().NoError(err) - - // init chain will set the validator set and initialize the genesis accounts - app.InitChain( - abci.RequestInitChain{ - ChainId: cmn.DefaultChainID, - Validators: []abci.ValidatorUpdate{}, - ConsensusParams: evmosapp.DefaultConsensusParams, - AppStateBytes: stateBytes, - }, - ) - app.Commit() - - // instantiate new header - header := evmosutil.NewHeader( - 2, - time.Now().UTC(), - cmn.DefaultChainID, - sdk.ConsAddress(validators[0].GetOperator()), - tmhash.Sum([]byte("app")), - tmhash.Sum([]byte("validators")), - ) - - app.BeginBlock(abci.RequestBeginBlock{ - Header: header, - }) - - // create Context - s.ctx = app.BaseApp.NewContext(false, header) - s.app = app -} - -func (s *PrecompileTestSuite) DoSetupTest() { - // generate validator private/public key - privVal := mock.NewPV() - pubKey, err := privVal.GetPubKey() - s.Require().NoError(err) - - privVal2 := mock.NewPV() - pubKey2, err := privVal2.GetPubKey() - s.Require().NoError(err) - - // create validator set with two validators - validator := tmtypes.NewValidator(pubKey, 1) - validator2 := tmtypes.NewValidator(pubKey2, 2) - s.valSet = tmtypes.NewValidatorSet([]*tmtypes.Validator{validator, validator2}) - signers := make(map[string]tmtypes.PrivValidator) - signers[pubKey.Address().String()] = privVal - signers[pubKey2.Address().String()] = privVal2 - - // generate genesis account - addr, priv := evmosutiltx.NewAddrKey() - s.privKey = priv - s.address = addr - s.signer = evmosutiltx.NewSigner(priv) - - baseAcc := authtypes.NewBaseAccount(priv.PubKey().Address().Bytes(), priv.PubKey(), 0, 0) - - acc := &evmostypes.EthAccount{ - BaseAccount: baseAcc, - CodeHash: common.BytesToHash(evmtypes.EmptyCodeHash).Hex(), - } - - amount := sdk.TokensFromConsensusPower(5, evmostypes.PowerReduction) - - balance := banktypes.Balance{ - Address: acc.GetAddress().String(), - Coins: sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, amount)), - } - - s.SetupWithGenesisValSet(s.valSet, []authtypes.GenesisAccount{acc}, balance) - - // Create StateDB - s.stateDB = statedb.New(s.ctx, s.app.EvmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(s.ctx.HeaderHash().Bytes()))) - - // bond denom - stakingParams := s.app.StakingKeeper.GetParams(s.ctx) - stakingParams.BondDenom = utils.BaseDenom - s.bondDenom = stakingParams.BondDenom - err = s.app.StakingKeeper.SetParams(s.ctx, stakingParams) - s.Require().NoError(err) - - s.ethSigner = ethtypes.LatestSignerForChainID(s.app.EvmKeeper.ChainID()) - - precompile, err := distribution.NewPrecompile(s.app.DistrKeeper, s.app.StakingKeeper, s.app.AuthzKeeper) - s.Require().NoError(err) - s.precompile = precompile - - coins := sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(5000000000000000000))) - inflCoins := sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(2000000000000000000))) - distrCoins := sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(3000000000000000000))) - err = s.app.BankKeeper.MintCoins(s.ctx, inflationtypes.ModuleName, coins) - s.Require().NoError(err) - err = s.app.BankKeeper.SendCoinsFromModuleToModule(s.ctx, inflationtypes.ModuleName, authtypes.FeeCollectorName, inflCoins) - s.Require().NoError(err) - err = s.app.BankKeeper.SendCoinsFromModuleToModule(s.ctx, inflationtypes.ModuleName, distrtypes.ModuleName, distrCoins) - s.Require().NoError(err) - - queryHelperEvm := baseapp.NewQueryServerTestHelper(s.ctx, s.app.InterfaceRegistry()) - evmtypes.RegisterQueryServer(queryHelperEvm, s.app.EvmKeeper) - s.queryClientEVM = evmtypes.NewQueryClient(queryHelperEvm) -} - -// DeployContract deploys a contract that calls the distribution precompile's methods for testing purposes. -func (s *PrecompileTestSuite) DeployContract(contract evmtypes.CompiledContract) (addr common.Address, err error) { - addr, err = evmosutil.DeployContract( - s.ctx, - s.app, - s.privKey, - s.queryClientEVM, - contract, - ) - return -} - -type stakingRewards struct { - Delegator sdk.AccAddress - Validator stakingtypes.Validator - RewardAmt math.Int -} - -// prepareStakingRewards prepares the test suite for testing delegation rewards. -// -// Specified rewards amount are allocated to the specified validator using the distribution keeper, -// such that the given amount of tokens is outstanding as a staking reward for the account. -// -// The setup is done in the following way: -// - Fund the account with the given address with the given rewards amount. -// - Delegate the rewards amount to the validator specified -// - Allocate rewards to the validator. -func (s *PrecompileTestSuite) prepareStakingRewards(stkRs ...stakingRewards) { - for _, r := range stkRs { - // fund account to make delegation - err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, r.Delegator, r.RewardAmt.Int64()) - s.Require().NoError(err) - // set distribution module account balance which pays out the rewards - distrAcc := s.app.DistrKeeper.GetDistributionAccount(s.ctx) - err = evmosutil.FundModuleAccount(s.ctx, s.app.BankKeeper, distrAcc.GetName(), sdk.NewCoins(sdk.NewCoin(s.bondDenom, r.RewardAmt))) - s.Require().NoError(err) - - // make a delegation - _, err = s.app.StakingKeeper.Delegate(s.ctx, r.Delegator, r.RewardAmt, stakingtypes.Unspecified, r.Validator, true) - s.Require().NoError(err) - - // end block to bond validator and increase block height - sdkstaking.EndBlocker(s.ctx, &s.app.StakingKeeper) - // allocate rewards to validator (of these 50% will be paid out to the delegator) - allocatedRewards := sdk.NewDecCoins(sdk.NewDecCoin(s.bondDenom, r.RewardAmt.Mul(math.NewInt(2)))) - s.app.DistrKeeper.AllocateTokensToValidator(s.ctx, r.Validator, allocatedRewards) - } - s.NextBlock() -} - -// NextBlock commits the current block and sets up the next block. -func (s *PrecompileTestSuite) NextBlock() { - var err error - s.ctx, err = evmosutil.CommitAndCreateNewCtx(s.ctx, s.app, time.Second, s.valSet) - s.Require().NoError(err) -} - -// setupValidatorSlashes sets slashes events for the provided validator -// returns the slash event set -func (s *PrecompileTestSuite) setupValidatorSlashes(valAddr sdk.ValAddress, slashesCount uint64) distrtypes.ValidatorSlashEvent { - const ( - initialHeight uint64 = 2 - initialPeriod uint64 = 1 - ) - - slashEvent := distrtypes.ValidatorSlashEvent{ValidatorPeriod: 1, Fraction: math.LegacyNewDec(5)} - - for i := uint64(0); i < slashesCount; i++ { - s.app.DistrKeeper.SetValidatorSlashEvent(s.ctx, valAddr, initialHeight+i, initialPeriod+i, slashEvent) - } - - return slashEvent -} diff --git a/precompiles/staking/StakingI.sol b/precompiles/staking/StakingI.sol deleted file mode 100644 index a2c1bff4..00000000 --- a/precompiles/staking/StakingI.sol +++ /dev/null @@ -1,334 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-only -pragma solidity >=0.8.17; - -import "../authorization/AuthorizationI.sol" as authorization; -import "../common/Types.sol"; - -/// @dev The StakingI contract's address. -address constant STAKING_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000800; - -/// @dev The StakingI contract's instance. -StakingI constant STAKING_CONTRACT = StakingI(STAKING_PRECOMPILE_ADDRESS); - -/// @dev Define all the available staking methods. -string constant MSG_CREATE_VALIDATOR = "/cosmos.staking.v1beta1.MsgCreateValidator"; -string constant MSG_DELEGATE = "/cosmos.staking.v1beta1.MsgDelegate"; -string constant MSG_UNDELEGATE = "/cosmos.staking.v1beta1.MsgUndelegate"; -string constant MSG_REDELEGATE = "/cosmos.staking.v1beta1.MsgBeginRedelegate"; -string constant MSG_CANCEL_UNDELEGATION = "/cosmos.staking.v1beta1.MsgCancelUnbondingDelegation"; - -/// @dev Defines the initial description to be used for creating -/// a validator. -struct Description { - string moniker; - string identity; - string website; - string securityContact; - string details; -} - -/// @dev Defines the initial commission rates to be used for creating -/// a validator. -struct CommissionRates { - uint256 rate; - uint256 maxRate; - uint256 maxChangeRate; -} - -/// @dev Defines commission parameters for a given validator. -struct Commission { - CommissionRates commissionRates; - uint256 updateTime; -} - - -/// @dev Represents a validator in the staking module. -struct Validator { - string operatorAddress; - string consensusPubkey; - bool jailed; - BondStatus status; - uint256 tokens; - uint256 delegatorShares; // TODO: decimal - string description; - int64 unbondingHeight; - int64 unbondingTime; - uint256 commission; - uint256 minSelfDelegation; -} - -/// @dev Represents the output of a Redelegations query. -struct RedelegationResponse { - Redelegation redelegation; - RedelegationEntryResponse[] entries; -} - -/// @dev Represents a redelegation between a delegator and a validator. -struct Redelegation { - string delegatorAddress; - string validatorSrcAddress; - string validatorDstAddress; - RedelegationEntry[] entries; -} - -/// @dev Represents a RedelegationEntryResponse for the Redelegations query. -struct RedelegationEntryResponse { - RedelegationEntry redelegationEntry; - uint256 balance; -} - -/// @dev Represents a single Redelegation entry. -struct RedelegationEntry { - int64 creationHeight; - int64 completionTime; - uint256 initialBalance; - uint256 sharesDst; // TODO: decimal -} - -/// @dev Represents the output of the Redelegation query. -struct RedelegationOutput { - string delegatorAddress; - string validatorSrcAddress; - string validatorDstAddress; - RedelegationEntry[] entries; -} - -/// @dev Represents a single entry of an unbonding delegation. -struct UnbondingDelegationEntry { - int64 creationHeight; - int64 completionTime; - uint256 initialBalance; - uint256 balance; - uint64 unbondingId; - int64 unbondingOnHoldRefCount; -} - -/// @dev Represents the output of the UnbondingDelegation query. -struct UnbondingDelegationOutput { - string delegatorAddress; - string validatorAddress; - UnbondingDelegationEntry[] entries; -} - -/// @dev The status of the validator. -enum BondStatus { - Unspecified, - Unbonded, - Unbonding, - Bonded -} - -/// @author Evmos Team -/// @title Staking Precompiled Contract -/// @dev The interface through which solidity contracts will interact with staking. -/// We follow this same interface including four-byte function selectors, in the precompile that -/// wraps the pallet. -/// @custom:address 0x0000000000000000000000000000000000000800 -interface StakingI is authorization.AuthorizationI { - /// @dev Defines a method for creating a new validator. - /// @param description The initial description - /// @param commissionRates The initial commissionRates - /// @param minSelfDelegation The validator's self declared minimum self delegation - /// @param delegatorAddress The delegator address - /// @param validatorAddress The validator address - /// @param pubkey The consensus public key of the validator - /// @param value The amount of the coin to be self delegated to the validator - /// @return success Whether or not the create validator was successful - function createValidator( - Description calldata description, - CommissionRates calldata commissionRates, - uint256 minSelfDelegation, - address delegatorAddress, - string memory validatorAddress, - string memory pubkey, - uint256 value - ) external returns (bool success); - - /// @dev Defines a method for performing a delegation of coins from a delegator to a validator. - /// @param delegatorAddress The address of the delegator - /// @param validatorAddress The address of the validator - /// @param amount The amount of the Coin to be delegated to the validator - /// @return success Whether or not the delegate was successful - function delegate( - address delegatorAddress, - string memory validatorAddress, - uint256 amount - ) external returns (bool success); - - /// @dev Defines a method for performing an undelegation from a delegate and a validator. - /// @param delegatorAddress The address of the delegator - /// @param validatorAddress The address of the validator - /// @param amount The amount to be undelegated from the validator - /// @return completionTime The time when the undelegation is completed - function undelegate( - address delegatorAddress, - string memory validatorAddress, - uint256 amount - ) external returns (int64 completionTime); - - /// @dev Defines a method for performing a redelegation - /// of coins from a delegator and source validator to a destination validator. - /// @param delegatorAddress The address of the delegator - /// @param validatorSrcAddress The validator from which the redelegation is initiated - /// @param validatorDstAddress The validator to which the redelegation is destined - /// @param amount The amount to be redelegated to the validator - /// @return completionTime The time when the redelegation is completed - function redelegate( - address delegatorAddress, - string memory validatorSrcAddress, - string memory validatorDstAddress, - uint256 amount - ) external returns (int64 completionTime); - - /// @dev Allows delegators to cancel the unbondingDelegation entry - /// and to delegate back to a previous validator. - /// @param delegatorAddress The address of the delegator - /// @param validatorAddress The address of the validator - /// @param amount The amount of the Coin - /// @param creationHeight The height at which the unbonding took place - /// @return success Whether or not the unbonding delegation was cancelled - function cancelUnbondingDelegation( - address delegatorAddress, - string memory validatorAddress, - uint256 amount, - uint256 creationHeight - ) external returns (bool success); - - /// @dev Queries the given amount of the bond denomination to a validator. - /// @param delegatorAddress The address of the delegator. - /// @param validatorAddress The address of the validator. - /// @return shares The amount of shares, that the delegator has received. - /// @return balance The amount in Coin, that the delegator has delegated to the given validator. - function delegation( - address delegatorAddress, - string memory validatorAddress - ) external view returns (uint256 shares, Coin calldata balance); - - /// @dev Returns the delegation shares and coins, that are currently - /// unbonding for a given delegator and validator pair. - /// @param delegatorAddress The address of the delegator. - /// @param validatorAddress The address of the validator. - /// @return unbondingDelegation The delegations that are currently unbonding. - function unbondingDelegation( - address delegatorAddress, - string memory validatorAddress - ) external view returns (UnbondingDelegationOutput calldata unbondingDelegation); - - /// @dev Queries validator info for a given validator address. - /// @param validatorAddress The address of the validator. - /// @return validator The validator info for the given validator address. - function validator( - string memory validatorAddress - ) external view returns (Validator calldata validator); - - /// @dev Queries all validators that match the given status. - /// @param status Enables to query for validators matching a given status. - /// @param pageRequest Defines an optional pagination for the request. - function validators( - string memory status, - PageRequest calldata pageRequest - ) - external - view - returns ( - Validator[] calldata validators, - PageResponse calldata pageResponse - ); - - /// @dev Queries all redelegations from a source to a destination validator for a given delegator. - /// @param delegatorAddress The address of the delegator. - /// @param srcValidatorAddress Defines the validator address to redelegate from. - /// @param dstValidatorAddress Defines the validator address to redelegate to. - /// @return redelegation The active redelegations for the given delegator, source and destination validator combination. - function redelegation( - address delegatorAddress, - string memory srcValidatorAddress, - string memory dstValidatorAddress - ) external view returns (RedelegationOutput calldata redelegation); - - /// @dev Queries all redelegations based on the specified criteria: - /// for a given delegator and/or origin validator address - /// and/or destination validator address - /// in a specified pagination manner. - /// @param delegatorAddress The address of the delegator as string (can be a zero address). - /// @param srcValidatorAddress Defines the validator address to redelegate from (can be empty string). - /// @param dstValidatorAddress Defines the validator address to redelegate to (can be empty string). - /// @param pageRequest Defines an optional pagination for the request. - /// @return response Holds the redelegations for the given delegator, source and destination validator combination. - function redelegations( - address delegatorAddress, - string memory srcValidatorAddress, - string memory dstValidatorAddress, - PageRequest calldata pageRequest - ) - external - view - returns ( - RedelegationResponse[] calldata response, - PageResponse calldata pageResponse - ); - - /// @dev CreateValidator defines an Event emitted when a create a new validator. - /// @param delegatorAddress The address of the delegator - /// @param validatorAddress The address of the validator - /// @param value The amount of coin being self delegated - event CreateValidator( - address indexed delegatorAddress, - address indexed validatorAddress, - uint256 value - ); - - /// @dev Delegate defines an Event emitted when a given amount of tokens are delegated from the - /// delegator address to the validator address. - /// @param delegatorAddress The address of the delegator - /// @param validatorAddress The address of the validator - /// @param amount The amount of Coin being delegated - /// @param newShares The new delegation shares being held - event Delegate( - address indexed delegatorAddress, - address indexed validatorAddress, - uint256 amount, - uint256 newShares - ); - - /// @dev Unbond defines an Event emitted when a given amount of tokens are unbonded from the - /// validator address to the delegator address. - /// @param delegatorAddress The address of the delegator - /// @param validatorAddress The address of the validator - /// @param amount The amount of Coin being unbonded - /// @param completionTime The time at which the unbonding is completed - event Unbond( - address indexed delegatorAddress, - address indexed validatorAddress, - uint256 amount, - uint256 completionTime - ); - - /// @dev Redelegate defines an Event emitted when a given amount of tokens are redelegated from - /// the source validator address to the destination validator address. - /// @param delegatorAddress The address of the delegator - /// @param validatorSrcAddress The address of the validator from which the delegation is retracted - /// @param validatorDstAddress The address of the validator to which the delegation is directed - /// @param amount The amount of Coin being redelegated - /// @param completionTime The time at which the redelegation is completed - event Redelegate( - address indexed delegatorAddress, - address indexed validatorSrcAddress, - address indexed validatorDstAddress, - uint256 amount, - uint256 completionTime - ); - - /// @dev CancelUnbondingDelegation defines an Event emitted when a given amount of tokens - /// that are in the process of unbonding from the validator address are bonded again. - /// @param delegatorAddress The address of the delegator - /// @param validatorAddress The address of the validator - /// @param amount The amount of Coin that was in the unbonding process which is to be canceled - /// @param creationHeight The block height at which the unbonding of a delegation was initiated - event CancelUnbondingDelegation( - address indexed delegatorAddress, - address indexed validatorAddress, - uint256 amount, - uint256 creationHeight - ); -} diff --git a/precompiles/staking/abi.json b/precompiles/staking/abi.json deleted file mode 100644 index 0e67804d..00000000 --- a/precompiles/staking/abi.json +++ /dev/null @@ -1,1159 +0,0 @@ -[ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "grantee", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "granter", - "type": "address" - }, - { - "indexed": false, - "internalType": "string[]", - "name": "methods", - "type": "string[]" - }, - { - "indexed": false, - "internalType": "uint256[]", - "name": "values", - "type": "uint256[]" - } - ], - "name": "AllowanceChange", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "grantee", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "granter", - "type": "address" - }, - { - "indexed": false, - "internalType": "string[]", - "name": "methods", - "type": "string[]" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "validatorAddress", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "creationHeight", - "type": "uint256" - } - ], - "name": "CancelUnbondingDelegation", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "validatorAddress", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "CreateValidator", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "validatorAddress", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newShares", - "type": "uint256" - } - ], - "name": "Delegate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "validatorSrcAddress", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "validatorDstAddress", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "completionTime", - "type": "uint256" - } - ], - "name": "Redelegate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "grantee", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "granter", - "type": "address" - }, - { - "indexed": false, - "internalType": "string[]", - "name": "methods", - "type": "string[]" - } - ], - "name": "Revocation", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "validatorAddress", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "completionTime", - "type": "uint256" - } - ], - "name": "Unbond", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "grantee", - "type": "address" - }, - { - "internalType": "address", - "name": "granter", - "type": "address" - }, - { - "internalType": "string", - "name": "method", - "type": "string" - } - ], - "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "remaining", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "grantee", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "string[]", - "name": "methods", - "type": "string[]" - } - ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "creationHeight", - "type": "uint256" - } - ], - "name": "cancelUnbondingDelegation", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "string", - "name": "moniker", - "type": "string" - }, - { - "internalType": "string", - "name": "identity", - "type": "string" - }, - { - "internalType": "string", - "name": "website", - "type": "string" - }, - { - "internalType": "string", - "name": "securityContact", - "type": "string" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - } - ], - "internalType": "struct Description", - "name": "description", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "rate", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxRate", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxChangeRate", - "type": "uint256" - } - ], - "internalType": "struct CommissionRates", - "name": "commissionRates", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "minSelfDelegation", - "type": "uint256" - }, - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - }, - { - "internalType": "string", - "name": "pubkey", - "type": "string" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "createValidator", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "grantee", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "string[]", - "name": "methods", - "type": "string[]" - } - ], - "name": "decreaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "delegate", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - } - ], - "name": "delegation", - "outputs": [ - { - "internalType": "uint256", - "name": "shares", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "string", - "name": "denom", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "internalType": "struct Coin", - "name": "balance", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "grantee", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "string[]", - "name": "methods", - "type": "string[]" - } - ], - "name": "increaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "validatorSrcAddress", - "type": "string" - }, - { - "internalType": "string", - "name": "validatorDstAddress", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "redelegate", - "outputs": [ - { - "internalType": "int64", - "name": "completionTime", - "type": "int64" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "srcValidatorAddress", - "type": "string" - }, - { - "internalType": "string", - "name": "dstValidatorAddress", - "type": "string" - } - ], - "name": "redelegation", - "outputs": [ - { - "components": [ - { - "internalType": "string", - "name": "delegatorAddress", - "type": "string" - }, - { - "internalType": "string", - "name": "validatorSrcAddress", - "type": "string" - }, - { - "internalType": "string", - "name": "validatorDstAddress", - "type": "string" - }, - { - "components": [ - { - "internalType": "int64", - "name": "creationHeight", - "type": "int64" - }, - { - "internalType": "int64", - "name": "completionTime", - "type": "int64" - }, - { - "internalType": "uint256", - "name": "initialBalance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "sharesDst", - "type": "uint256" - } - ], - "internalType": "struct RedelegationEntry[]", - "name": "entries", - "type": "tuple[]" - } - ], - "internalType": "struct RedelegationOutput", - "name": "redelegation", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "srcValidatorAddress", - "type": "string" - }, - { - "internalType": "string", - "name": "dstValidatorAddress", - "type": "string" - }, - { - "components": [ - { - "internalType": "bytes", - "name": "key", - "type": "bytes" - }, - { - "internalType": "uint64", - "name": "offset", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "limit", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "countTotal", - "type": "bool" - }, - { - "internalType": "bool", - "name": "reverse", - "type": "bool" - } - ], - "internalType": "struct PageRequest", - "name": "pageRequest", - "type": "tuple" - } - ], - "name": "redelegations", - "outputs": [ - { - "components": [ - { - "components": [ - { - "internalType": "string", - "name": "delegatorAddress", - "type": "string" - }, - { - "internalType": "string", - "name": "validatorSrcAddress", - "type": "string" - }, - { - "internalType": "string", - "name": "validatorDstAddress", - "type": "string" - }, - { - "components": [ - { - "internalType": "int64", - "name": "creationHeight", - "type": "int64" - }, - { - "internalType": "int64", - "name": "completionTime", - "type": "int64" - }, - { - "internalType": "uint256", - "name": "initialBalance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "sharesDst", - "type": "uint256" - } - ], - "internalType": "struct RedelegationEntry[]", - "name": "entries", - "type": "tuple[]" - } - ], - "internalType": "struct Redelegation", - "name": "redelegation", - "type": "tuple" - }, - { - "components": [ - { - "components": [ - { - "internalType": "int64", - "name": "creationHeight", - "type": "int64" - }, - { - "internalType": "int64", - "name": "completionTime", - "type": "int64" - }, - { - "internalType": "uint256", - "name": "initialBalance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "sharesDst", - "type": "uint256" - } - ], - "internalType": "struct RedelegationEntry", - "name": "redelegationEntry", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "internalType": "struct RedelegationEntryResponse[]", - "name": "entries", - "type": "tuple[]" - } - ], - "internalType": "struct RedelegationResponse[]", - "name": "response", - "type": "tuple[]" - }, - { - "components": [ - { - "internalType": "bytes", - "name": "nextKey", - "type": "bytes" - }, - { - "internalType": "uint64", - "name": "total", - "type": "uint64" - } - ], - "internalType": "struct PageResponse", - "name": "pageResponse", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "grantee", - "type": "address" - }, - { - "internalType": "string[]", - "name": "methods", - "type": "string[]" - } - ], - "name": "revoke", - "outputs": [ - { - "internalType": "bool", - "name": "revoked", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - } - ], - "name": "unbondingDelegation", - "outputs": [ - { - "components": [ - { - "internalType": "string", - "name": "delegatorAddress", - "type": "string" - }, - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - }, - { - "components": [ - { - "internalType": "int64", - "name": "creationHeight", - "type": "int64" - }, - { - "internalType": "int64", - "name": "completionTime", - "type": "int64" - }, - { - "internalType": "uint256", - "name": "initialBalance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - }, - { - "internalType": "uint64", - "name": "unbondingId", - "type": "uint64" - }, - { - "internalType": "int64", - "name": "unbondingOnHoldRefCount", - "type": "int64" - } - ], - "internalType": "struct UnbondingDelegationEntry[]", - "name": "entries", - "type": "tuple[]" - } - ], - "internalType": "struct UnbondingDelegationOutput", - "name": "unbondingDelegation", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "delegatorAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "undelegate", - "outputs": [ - { - "internalType": "int64", - "name": "completionTime", - "type": "int64" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - } - ], - "name": "validator", - "outputs": [ - { - "components": [ - { - "internalType": "string", - "name": "operatorAddress", - "type": "string" - }, - { - "internalType": "string", - "name": "consensusPubkey", - "type": "string" - }, - { - "internalType": "bool", - "name": "jailed", - "type": "bool" - }, - { - "internalType": "enum BondStatus", - "name": "status", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "tokens", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "delegatorShares", - "type": "uint256" - }, - { - "internalType": "string", - "name": "description", - "type": "string" - }, - { - "internalType": "int64", - "name": "unbondingHeight", - "type": "int64" - }, - { - "internalType": "int64", - "name": "unbondingTime", - "type": "int64" - }, - { - "internalType": "uint256", - "name": "commission", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minSelfDelegation", - "type": "uint256" - } - ], - "internalType": "struct Validator", - "name": "validator", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "status", - "type": "string" - }, - { - "components": [ - { - "internalType": "bytes", - "name": "key", - "type": "bytes" - }, - { - "internalType": "uint64", - "name": "offset", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "limit", - "type": "uint64" - }, - { - "internalType": "bool", - "name": "countTotal", - "type": "bool" - }, - { - "internalType": "bool", - "name": "reverse", - "type": "bool" - } - ], - "internalType": "struct PageRequest", - "name": "pageRequest", - "type": "tuple" - } - ], - "name": "validators", - "outputs": [ - { - "components": [ - { - "internalType": "string", - "name": "operatorAddress", - "type": "string" - }, - { - "internalType": "string", - "name": "consensusPubkey", - "type": "string" - }, - { - "internalType": "bool", - "name": "jailed", - "type": "bool" - }, - { - "internalType": "enum BondStatus", - "name": "status", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "tokens", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "delegatorShares", - "type": "uint256" - }, - { - "internalType": "string", - "name": "description", - "type": "string" - }, - { - "internalType": "int64", - "name": "unbondingHeight", - "type": "int64" - }, - { - "internalType": "int64", - "name": "unbondingTime", - "type": "int64" - }, - { - "internalType": "uint256", - "name": "commission", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "minSelfDelegation", - "type": "uint256" - } - ], - "internalType": "struct Validator[]", - "name": "validators", - "type": "tuple[]" - }, - { - "components": [ - { - "internalType": "bytes", - "name": "nextKey", - "type": "bytes" - }, - { - "internalType": "uint64", - "name": "total", - "type": "uint64" - } - ], - "internalType": "struct PageResponse", - "name": "pageResponse", - "type": "tuple" - } - ], - "stateMutability": "view", - "type": "function" - } -] \ No newline at end of file diff --git a/precompiles/staking/approve.go b/precompiles/staking/approve.go deleted file mode 100644 index 42d30dd7..00000000 --- a/precompiles/staking/approve.go +++ /dev/null @@ -1,355 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package staking - -import ( - "fmt" - "time" - - errorsmod "cosmossdk.io/errors" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/authz" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/evmos/evmos/v16/precompiles/authorization" - cmn "github.com/evmos/evmos/v16/precompiles/common" -) - -var ( - // DelegateMsg defines the authorization type for MsgDelegate - DelegateMsg = sdk.MsgTypeURL(&stakingtypes.MsgDelegate{}) - // UndelegateMsg defines the authorization type for MsgUndelegate - UndelegateMsg = sdk.MsgTypeURL(&stakingtypes.MsgUndelegate{}) - // RedelegateMsg defines the authorization type for MsgRedelegate - RedelegateMsg = sdk.MsgTypeURL(&stakingtypes.MsgBeginRedelegate{}) - // CancelUnbondingDelegationMsg defines the authorization type for MsgCancelUnbondingDelegation - CancelUnbondingDelegationMsg = sdk.MsgTypeURL(&stakingtypes.MsgCancelUnbondingDelegation{}) -) - -// Approve sets amount as the allowance of a grantee over the caller’s tokens. -// Returns a boolean value indicating whether the operation succeeded. -func (p Precompile) Approve( - ctx sdk.Context, - origin common.Address, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - grantee, coin, typeURLs, err := authorization.CheckApprovalArgs(args, p.stakingKeeper.BondDenom(ctx)) - if err != nil { - return nil, err - } - - for _, typeURL := range typeURLs { - switch typeURL { - case DelegateMsg, UndelegateMsg, RedelegateMsg, CancelUnbondingDelegationMsg: - authzType, err := convertMsgToAuthz(typeURL) - if err != nil { - return nil, errorsmod.Wrap(err, fmt.Sprintf(cmn.ErrInvalidMsgType, "staking", typeURL)) - } - if err = p.grantOrDeleteStakingAuthz(ctx, grantee, origin, coin, authzType); err != nil { - return nil, err - } - default: - // TODO: do we need to return an error here or just no-op? - // Implications of returning an error could be that we approve some parts of the txs but not all - return nil, fmt.Errorf(cmn.ErrInvalidMsgType, "staking", typeURL) - } - } - - // TODO: do we want to emit one approval for all typeUrls, or one approval for each typeUrl? - // NOTE: This might have gas implications as we are emitting a slice of strings - if err := p.EmitApprovalEvent(ctx, stateDB, grantee, origin, coin, typeURLs); err != nil { - return nil, err - } - return method.Outputs.Pack(true) -} - -// Revoke removes the authorization grants given in the typeUrls for a given granter to a given grantee. -// It only works if the origin matches the spender to avoid unauthorized revocations. -// Works only for staking messages. -func (p Precompile) Revoke( - ctx sdk.Context, - origin common.Address, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - grantee, typeURLs, err := authorization.CheckRevokeArgs(args) - if err != nil { - return nil, err - } - - for _, typeURL := range typeURLs { - switch typeURL { - case DelegateMsg, UndelegateMsg, RedelegateMsg, CancelUnbondingDelegationMsg: - if err = p.AuthzKeeper.DeleteGrant(ctx, grantee.Bytes(), origin.Bytes(), typeURL); err != nil { - return nil, err - } - default: - // TODO: do we need to return an error here or just no-op? - // Implications of returning an error could be that we approve some parts of the txs but not all - return nil, fmt.Errorf(cmn.ErrInvalidMsgType, "staking", typeURL) - } - } - - // NOTE: Using the new more generic event emitter that was created - if err = authorization.EmitRevocationEvent(cmn.EmitEventArgs{ - Ctx: ctx, - StateDB: stateDB, - ContractAddr: p.Address(), - ContractEvents: p.ABI.Events, - EventData: authorization.EventRevocation{ - Granter: origin, - Grantee: grantee, - TypeUrls: typeURLs, - }, - }); err != nil { - return nil, err - } - - return method.Outputs.Pack(true) -} - -// DecreaseAllowance decreases the allowance of grantee over the caller’s tokens by the amount. -func (p Precompile) DecreaseAllowance( - ctx sdk.Context, - origin common.Address, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - grantee, coin, typeUrls, err := authorization.CheckApprovalArgs(args, p.stakingKeeper.BondDenom(ctx)) - if err != nil { - return nil, err - } - - for _, typeURL := range typeUrls { - switch typeURL { - case DelegateMsg, UndelegateMsg, RedelegateMsg, CancelUnbondingDelegationMsg: - authzGrant, expiration, err := authorization.CheckAuthzExists(ctx, p.AuthzKeeper, grantee, origin, typeURL) - if err != nil { - return nil, err - } - - stakeAuthz, ok := authzGrant.(*stakingtypes.StakeAuthorization) - if !ok { - return nil, errorsmod.Wrapf(authz.ErrUnknownAuthorizationType, "expected: *types.StakeAuthorization, received: %T", authzGrant) - } - - if err = p.decreaseAllowance(ctx, grantee, origin, coin, stakeAuthz, expiration); err != nil { - return nil, err - } - default: - // TODO: do we need to return an error here or just no-op? - // Implications of returning an error could be that we decrease allowance for some parts of the typeUrls but not all - return nil, fmt.Errorf(cmn.ErrInvalidMsgType, "staking", typeURL) - } - } - - if err := p.EmitAllowanceChangeEvent(ctx, stateDB, grantee, origin, typeUrls); err != nil { - return nil, err - } - - return method.Outputs.Pack(true) -} - -// IncreaseAllowance increases the allowance of grantee over the caller’s tokens by the amount. -func (p Precompile) IncreaseAllowance( - ctx sdk.Context, - origin common.Address, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - grantee, coin, typeUrls, err := authorization.CheckApprovalArgs(args, p.stakingKeeper.BondDenom(ctx)) - if err != nil { - return nil, err - } - - for _, typeURL := range typeUrls { - switch typeURL { - case DelegateMsg, UndelegateMsg, RedelegateMsg: - if err = p.increaseAllowance(ctx, grantee, origin, coin, typeURL); err != nil { - return nil, err - } - default: - // TODO: do we need to return an error here or just no-op? - // Implications of returning an error could be that we decrease allowance for some parts of the typeUrls but not all - return nil, fmt.Errorf(cmn.ErrInvalidMsgType, "staking", typeURL) - } - } - if err := p.EmitAllowanceChangeEvent(ctx, stateDB, grantee, origin, typeUrls); err != nil { - return nil, err - } - - return method.Outputs.Pack(true) -} - -// grantOrDeleteStakingAuthz grants staking method authorization to the precompiled contract for a spender. -// If the amount is zero, it deletes the authorization if it exists. -func (p Precompile) grantOrDeleteStakingAuthz( - ctx sdk.Context, - grantee, granter common.Address, - coin *sdk.Coin, - authzType stakingtypes.AuthorizationType, -) error { - // Case 1: coin is nil -> set authorization with no limit - if coin == nil || coin.IsNil() { - p.Logger(ctx).Debug( - "setting authorization without limit", - "grantee", grantee.String(), - "granter", granter.String(), - ) - return p.createStakingAuthz(ctx, grantee, granter, coin, authzType) - } - - // Case 2: coin amount is zero or negative -> delete the authorization - if !coin.Amount.IsPositive() { - p.Logger(ctx).Debug( - "deleting authorization", - "grantee", grantee.String(), - "granter", granter.String(), - ) - stakingAuthz := stakingtypes.StakeAuthorization{AuthorizationType: authzType} - return p.AuthzKeeper.DeleteGrant(ctx, grantee.Bytes(), granter.Bytes(), stakingAuthz.MsgTypeURL()) - } - - // Case 3: coin amount is non zero -> and not coin is not nil set with custom amount - return p.createStakingAuthz(ctx, grantee, granter, coin, authzType) -} - -// createStakingAuthz creates a staking authorization for a spender. -func (p Precompile) createStakingAuthz( - ctx sdk.Context, - grantee, granter common.Address, - coin *sdk.Coin, - authzType stakingtypes.AuthorizationType, -) error { - // Get all available validators and filter out jailed validators - validators := make([]sdk.ValAddress, 0) - p.stakingKeeper.IterateValidators( - ctx, func(_ int64, validator stakingtypes.ValidatorI) (stop bool) { - if validator.IsJailed() { - return - } - validators = append(validators, validator.GetOperator()) - return - }, - ) - stakingAuthz, err := stakingtypes.NewStakeAuthorization(validators, nil, authzType, coin) - if err != nil { - return err - } - - if err := stakingAuthz.ValidateBasic(); err != nil { - return err - } - - expiration := ctx.BlockTime().Add(p.ApprovalExpiration).UTC() - return p.AuthzKeeper.SaveGrant(ctx, grantee.Bytes(), granter.Bytes(), stakingAuthz, &expiration) -} - -// decreaseAllowance decreases the allowance of spender over the caller’s tokens by the amount. -func (p Precompile) decreaseAllowance( - ctx sdk.Context, - grantee, granter common.Address, - coin *sdk.Coin, - stakeAuthz *stakingtypes.StakeAuthorization, - expiration *time.Time, -) error { - // If the authorization has no limit, no operation is performed - if stakeAuthz.MaxTokens == nil { - p.Logger(ctx).Debug("decreaseAllowance called with no limit (stakeAuthz.MaxTokens == nil): no-op") - return nil - } - - // If the authorization limit is less than the substation amount, return error - if stakeAuthz.MaxTokens.Amount.LT(coin.Amount) { - return fmt.Errorf(ErrDecreaseAmountTooBig, coin.Amount, stakeAuthz.MaxTokens.Amount) - } - - // If amount is less than or equal to the Authorization amount, subtract the amount from the limit - if coin.Amount.LTE(stakeAuthz.MaxTokens.Amount) { - stakeAuthz.MaxTokens.Amount = stakeAuthz.MaxTokens.Amount.Sub(coin.Amount) - } - - return p.AuthzKeeper.SaveGrant(ctx, grantee.Bytes(), granter.Bytes(), stakeAuthz, expiration) -} - -// increaseAllowance increases the allowance of spender over the caller’s tokens by the amount. -func (p Precompile) increaseAllowance( - ctx sdk.Context, - grantee, granter common.Address, - coin *sdk.Coin, - msgURL string, -) error { - // Check if the authorization exists for the given spender - existingAuthz, expiration, err := authorization.CheckAuthzExists(ctx, p.AuthzKeeper, grantee, granter, msgURL) - if err != nil { - return err - } - - // Cast the authorization to a staking authorization - stakeAuthz, ok := existingAuthz.(*stakingtypes.StakeAuthorization) - if !ok { - return errorsmod.Wrapf(authz.ErrUnknownAuthorizationType, "expected: *types.StakeAuthorization, received: %T", existingAuthz) - } - - // If the authorization has no limit, no operation is performed - if stakeAuthz.MaxTokens == nil { - p.Logger(ctx).Debug("increaseAllowance called with no limit (stakeAuthz.MaxTokens == nil): no-op") - return nil - } - - // Add the amount to the limit - stakeAuthz.MaxTokens.Amount = stakeAuthz.MaxTokens.Amount.Add(coin.Amount) - - return p.AuthzKeeper.SaveGrant(ctx, grantee.Bytes(), granter.Bytes(), stakeAuthz, expiration) -} - -// UpdateStakingAuthorization updates the staking grant based on the authz AcceptResponse for the given granter and grantee. -func (p Precompile) UpdateStakingAuthorization( - ctx sdk.Context, - grantee, granter common.Address, - stakeAuthz *stakingtypes.StakeAuthorization, - expiration *time.Time, - messageType string, - msg sdk.Msg, -) error { - updatedResponse, err := stakeAuthz.Accept(ctx, msg) - if err != nil { - return err - } - - if updatedResponse.Delete { - err = p.AuthzKeeper.DeleteGrant(ctx, grantee.Bytes(), granter.Bytes(), messageType) - } else { - err = p.AuthzKeeper.SaveGrant(ctx, grantee.Bytes(), granter.Bytes(), updatedResponse.Updated, expiration) - } - - if err != nil { - return err - } - return nil -} - -// convertMsgToAuthz converts a msg to an authorization type. -func convertMsgToAuthz(msg string) (stakingtypes.AuthorizationType, error) { - switch msg { - case DelegateMsg: - return DelegateAuthz, nil - case UndelegateMsg: - return UndelegateAuthz, nil - case RedelegateMsg: - return RedelegateAuthz, nil - case CancelUnbondingDelegationMsg: - return CancelUnbondingDelegationAuthz, nil - default: - return stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNSPECIFIED, authz.ErrUnknownAuthorizationType.Wrapf("cannot convert msg to authorization type with %T", msg) - } -} diff --git a/precompiles/staking/approve_test.go b/precompiles/staking/approve_test.go deleted file mode 100644 index b4720bcd..00000000 --- a/precompiles/staking/approve_test.go +++ /dev/null @@ -1,727 +0,0 @@ -package staking_test - -import ( - "fmt" - "math/big" - "time" - - "cosmossdk.io/math" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - evmosutiltx "github.com/evmos/evmos/v16/testutil/tx" - - sdk "github.com/cosmos/cosmos-sdk/types" - sdkauthz "github.com/cosmos/cosmos-sdk/x/authz" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/evmos/evmos/v16/precompiles/authorization" - cmn "github.com/evmos/evmos/v16/precompiles/common" - "github.com/evmos/evmos/v16/precompiles/staking" - "github.com/evmos/evmos/v16/precompiles/testutil" - evmosutil "github.com/evmos/evmos/v16/testutil" -) - -func (s *PrecompileTestSuite) TestApprove() { - method := s.precompile.Methods[authorization.ApproveMethod] - - testCases := []struct { - name string - malleate func(*vm.Contract) []interface{} - postCheck func(data []byte, inputArgs []interface{}) - gas uint64 - expError bool - errContains string - }{ - { - "fail - empty input args", - func(_ *vm.Contract) []interface{} { - return []interface{}{} - }, - func(data []byte, inputArgs []interface{}) {}, - 200000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 3, 0), - }, - { - "fail - invalid message type", - func(_ *vm.Contract) []interface{} { - return []interface{}{ - s.address, - abi.MaxUint256, - []string{"invalid"}, - } - }, - func(data []byte, inputArgs []interface{}) {}, - 200000, - true, - fmt.Sprintf(cmn.ErrInvalidMsgType, "staking", "invalid"), - }, - // TODO: enable this test once we check if spender and origin are the same - // { - // "fail - origin address is the same the spender address", - // func(_ *vm.Contract) []interface{} { - // return []interface{}{ - // s.address, - // abi.MaxUint256, - // []string{"invalid"}, - // } - // }, - // func(data []byte, inputArgs []interface{}) {}, - // 200000, - // true, - // "is the same as spender", - // }, - { - "success - MsgDelegate with unlimited coins", - func(_ *vm.Contract) []interface{} { - return []interface{}{ - s.address, - abi.MaxUint256, - []string{staking.DelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - s.Require().Equal(data, cmn.TrueValue) - authz, expirationTime := s.CheckAuthorization(staking.DelegateAuthz, s.address, s.address) - - s.Require().NotNil(authz) - s.Require().NotNil(expirationTime) - s.Require().Equal(authz.AuthorizationType, staking.DelegateAuthz) - var coin *sdk.Coin - s.Require().Equal(authz.MaxTokens, coin) - }, - 20000, - false, - "", - }, - { - "success - MsgUndelegate with unlimited coins", - func(_ *vm.Contract) []interface{} { - return []interface{}{ - s.address, - abi.MaxUint256, - []string{staking.UndelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - s.Require().Equal(data, cmn.TrueValue) - - authz, expirationTime := s.CheckAuthorization(staking.UndelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().NotNil(expirationTime) - s.Require().Equal(authz.AuthorizationType, staking.UndelegateAuthz) - var coin *sdk.Coin - s.Require().Equal(authz.MaxTokens, coin) - }, - 20000, - false, - "", - }, - { - "success - MsgRedelegate with unlimited coins", - func(_ *vm.Contract) []interface{} { - return []interface{}{ - s.address, - abi.MaxUint256, - []string{staking.RedelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - s.Require().Equal(data, cmn.TrueValue) - - authz, expirationTime := s.CheckAuthorization(staking.RedelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().NotNil(expirationTime) - s.Require().Equal(authz.AuthorizationType, staking.RedelegateAuthz) - var coin *sdk.Coin - s.Require().Equal(authz.MaxTokens, coin) - }, - 20000, - false, - "", - }, - { - "success - All staking methods with certain amount of coins", - func(_ *vm.Contract) []interface{} { - return []interface{}{ - s.address, - big.NewInt(1e18), - []string{ - staking.DelegateMsg, - staking.UndelegateMsg, - staking.RedelegateMsg, - }, - } - }, - func(data []byte, inputArgs []interface{}) { - s.Require().Equal(data, cmn.TrueValue) - - allAuthz, err := s.app.AuthzKeeper.GetAuthorizations(s.ctx, s.address.Bytes(), s.address.Bytes()) - s.Require().NoError(err) - s.Require().Len(allAuthz, 3) - }, - 20000, - false, - "", - }, - { - "success - remove MsgDelegate authorization", - func(contract *vm.Contract) []interface{} { - res, err := s.precompile.Approve(s.ctx, s.address, s.stateDB, &method, []interface{}{s.address, big.NewInt(1), []string{staking.DelegateMsg}}) - s.Require().NoError(err) - s.Require().Equal(res, cmn.TrueValue) - - authz, expirationTime := s.CheckAuthorization(staking.DelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().NotNil(expirationTime) - - return []interface{}{ - s.address, - big.NewInt(0), - []string{staking.DelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - s.Require().Equal(data, cmn.TrueValue) - - authz, expirationTime := s.CheckAuthorization(staking.DelegateAuthz, s.address, s.address) - s.Require().Nil(authz) - s.Require().Nil(expirationTime) - }, - 200000, - false, - "", - }, - { - "success - MsgDelegate with 1 Evmos as limit amount", - func(_ *vm.Contract) []interface{} { - return []interface{}{ - s.address, - big.NewInt(1e18), - []string{staking.DelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - s.Require().Equal(data, cmn.TrueValue) - - authz, expirationTime := s.CheckAuthorization(staking.DelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().NotNil(expirationTime) - s.Require().Equal(authz.AuthorizationType, staking.DelegateAuthz) - s.Require().Equal(authz.MaxTokens, &sdk.Coin{Denom: s.bondDenom, Amount: math.NewInt(1e18)}) - }, - 20000, - false, - "", - }, - { - "success - Authorization should only be created for validators that are not jailed", - func(_ *vm.Contract) []interface{} { - // Commit block (otherwise test logic will not be executed correctly, i.e. somehow unbonding does not take effect) - var err error - s.ctx, err = evmosutil.Commit(s.ctx, s.app, time.Second, nil) - s.Require().NoError(err, "failed to commit block") - - // Jail a validator - s.app.StakingKeeper.Jail(s.ctx, sdk.ConsAddress(s.validators[0].GetOperator())) - - // When a delegator redelegates/undelegates from a validator, the validator - // switches to Unbonding status. - // Thus, validators with this status should be considered for the authorization - - // Unbond another validator - amount, err := s.app.StakingKeeper.Unbond(s.ctx, s.address.Bytes(), s.validators[1].GetOperator(), math.LegacyOneDec()) - s.Require().NoError(err, "expected no error unbonding validator") - s.Require().Equal(math.NewInt(1e18), amount, "expected different amount of tokens to be unbonded") - - // Commit block and update time to one year later - s.ctx, err = evmosutil.Commit(s.ctx, s.app, time.Hour*24*365, nil) - s.Require().NoError(err, "failed to commit block") - - return []interface{}{ - s.address, - big.NewInt(1e18), - []string{staking.DelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - s.Require().Equal(data, cmn.TrueValue) - - authz, expirationTime := s.CheckAuthorization(staking.DelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().NotNil(expirationTime) - s.Require().Equal(authz.AuthorizationType, staking.DelegateAuthz) - s.Require().Equal(authz.MaxTokens, &sdk.Coin{Denom: s.bondDenom, Amount: math.NewInt(1e18)}) - // Check that the bonded and unbonding validators are included on the authorization - s.Require().Len(authz.GetAllowList().Address, 2, "should only be two validators in the allow list") - }, - 1e6, - false, - "", - }, - { - "success - MsgUndelegate with 1 Evmos as limit amount", - func(_ *vm.Contract) []interface{} { - return []interface{}{ - s.address, - big.NewInt(1e18), - []string{staking.UndelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - s.Require().Equal(data, cmn.TrueValue) - - authz, expirationTime := s.CheckAuthorization(staking.UndelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().NotNil(expirationTime) - s.Require().Equal(authz.AuthorizationType, staking.UndelegateAuthz) - s.Require().Equal(authz.MaxTokens, &sdk.Coin{Denom: s.bondDenom, Amount: math.NewInt(1e18)}) - }, - 20000, - false, - "", - }, - { - "success - MsgRedelegate with 1 Evmos as limit amount", - func(_ *vm.Contract) []interface{} { - return []interface{}{ - s.address, - big.NewInt(1e18), - []string{staking.RedelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - s.Require().Equal(data, cmn.TrueValue) - - authz, expirationTime := s.CheckAuthorization(staking.RedelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().NotNil(expirationTime) - }, - 20000, - false, - "", - }, - { - "success - MsgRedelegate, MsgUndelegate and MsgDelegate with 1 Evmos as limit amount", - func(_ *vm.Contract) []interface{} { - return []interface{}{ - s.address, - big.NewInt(1e18), - []string{ - staking.RedelegateMsg, - staking.UndelegateMsg, - staking.DelegateMsg, - }, - } - }, - func(data []byte, inputArgs []interface{}) { - s.Require().Equal(data, cmn.TrueValue) - - authz, expirationTime := s.CheckAuthorization(staking.DelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().NotNil(expirationTime) - s.Require().Equal(authz.AuthorizationType, staking.DelegateAuthz) - s.Require().Equal(authz.MaxTokens, &sdk.Coin{Denom: s.bondDenom, Amount: math.NewInt(1e18)}) - - authz, expirationTime = s.CheckAuthorization(staking.UndelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().NotNil(expirationTime) - - s.Require().Equal(authz.AuthorizationType, staking.UndelegateAuthz) - s.Require().Equal(authz.MaxTokens, &sdk.Coin{Denom: s.bondDenom, Amount: math.NewInt(1e18)}) - - authz, expirationTime = s.CheckAuthorization(staking.RedelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().NotNil(expirationTime) - - s.Require().Equal(authz.AuthorizationType, staking.RedelegateAuthz) - s.Require().Equal(authz.MaxTokens, &sdk.Coin{Denom: s.bondDenom, Amount: math.NewInt(1e18)}) - - // TODO: Bug here it returns 3 REDELEGATE authorizations - allAuthz, err := s.app.AuthzKeeper.GetAuthorizations(s.ctx, s.address.Bytes(), s.address.Bytes()) - s.Require().NoError(err) - s.Require().Len(allAuthz, 3) - }, - 20000, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - var contract *vm.Contract - contract, s.ctx = testutil.NewPrecompileContract(s.T(), s.ctx, s.address, s.precompile, tc.gas) - - args := tc.malleate(contract) - bz, err := s.precompile.Approve(s.ctx, s.address, s.stateDB, &method, args) - - if tc.expError { - s.Require().ErrorContains(err, tc.errContains) - s.Require().Empty(bz) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz, args) - } - }) - } -} - -func (s *PrecompileTestSuite) TestDecreaseAllowance() { - method := s.precompile.Methods[authorization.DecreaseAllowanceMethod] - - testCases := []struct { - name string - malleate func(_ *vm.Contract) []interface{} - postCheck func(data []byte, inputArgs []interface{}) - gas uint64 - expError bool - errContains string - }{ - { - "fail - empty input args", - func(_ *vm.Contract) []interface{} { - return []interface{}{} - }, - func(data []byte, inputArgs []interface{}) {}, - 200000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 3, 0), - }, - //// TODO: enable this once we check origin is not the spender - // { - // "fail - origin address is the spender address", - // func(_ *vm.Contract) []interface{} { - // return []interface{}{ - // s.address, - // abi.MaxUint256, - // []string{staking.DelegateMsg}, - // } - // }, - // func(data []byte, inputArgs []interface{}) {}, - // 200000, - // true, - // "is the same as spender", - // }, - { - "fail - delegate authorization does not exists", - func(_ *vm.Contract) []interface{} { - return []interface{}{ - s.address, - big.NewInt(15000), - []string{staking.DelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - }, - 200000, - true, - "authorization to /cosmos.staking.v1beta1.MsgDelegate", - }, - { - "fail - delegate authorization is a generic Authorization", - func(_ *vm.Contract) []interface{} { - authz := sdkauthz.NewGenericAuthorization(staking.DelegateMsg) - exp := time.Now().Add(time.Hour) - err := s.app.AuthzKeeper.SaveGrant(s.ctx, s.address.Bytes(), s.address.Bytes(), authz, &exp) - s.Require().NoError(err) - return []interface{}{ - s.address, - big.NewInt(15000), - []string{staking.DelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - }, - 200000, - true, - sdkauthz.ErrUnknownAuthorizationType.Error(), - }, - { - "fail - decrease allowance amount is greater than the authorization limit", - func(contract *vm.Contract) []interface{} { - approveArgs := []interface{}{ - s.address, - big.NewInt(1e18), - []string{staking.DelegateMsg}, - } - resp, err := s.precompile.Approve(s.ctx, s.address, s.stateDB, &method, approveArgs) - s.Require().NoError(err) - s.Require().Equal(resp, cmn.TrueValue) - - authz, _ := s.CheckAuthorization(staking.DelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().Equal(authz.AuthorizationType, staking.DelegateAuthz) - s.Require().Equal(authz.MaxTokens, &sdk.Coin{Denom: s.bondDenom, Amount: math.NewInt(1e18)}) - - return []interface{}{ - s.address, - big.NewInt(2e18), - []string{staking.DelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) {}, - 200000, - true, - "amount by which the allowance should be decreased is greater than the authorization limit", - }, - { - "success - decrease delegate authorization allowance by 1 Evmos", - func(_ *vm.Contract) []interface{} { - s.ApproveAndCheckAuthz(method, staking.DelegateMsg, big.NewInt(2e18)) - return []interface{}{ - s.address, - big.NewInt(1e18), - []string{staking.DelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - authz, _ := s.CheckAuthorization(staking.DelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().Equal(authz.AuthorizationType, staking.DelegateAuthz) - s.Require().Equal(authz.MaxTokens, &sdk.Coin{Denom: s.bondDenom, Amount: math.NewInt(1e18)}) - }, - 200000, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - - var contract *vm.Contract - contract, s.ctx = testutil.NewPrecompileContract(s.T(), s.ctx, s.address, s.precompile, tc.gas) - - args := tc.malleate(contract) - bz, err := s.precompile.DecreaseAllowance(s.ctx, s.address, s.stateDB, &method, args) - - if tc.expError { - s.Require().ErrorContains(err, tc.errContains) - s.Require().Empty(bz) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz, args) - } - }) - } -} - -func (s *PrecompileTestSuite) TestIncreaseAllowance() { - method := s.precompile.Methods[authorization.IncreaseAllowanceMethod] - - testCases := []struct { - name string - malleate func() []interface{} - postCheck func(data []byte, inputArgs []interface{}) - gas uint64 - expError bool - errContains string - }{ - { - "fail - empty input args", - func() []interface{} { - return []interface{}{} - }, - func(data []byte, inputArgs []interface{}) {}, - 200000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 3, 0), - }, - // TODO: enable this once we check origin is not the same as spender - // { - // "fail - origin address is the spender address", - // func(_ *vm.Contract) []interface{} { - // return []interface{}{ - // s.address, - // abi.MaxUint256, - // []string{staking.DelegateMsg}, - // } - // }, - // func(data []byte, inputArgs []interface{}) {}, - // 200000, - // true, - // "is the same as spender", - // }, - { - "fail - delegate authorization does not exists", - func() []interface{} { - return []interface{}{ - s.address, - big.NewInt(15000), - []string{staking.DelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - }, - 200000, - true, - "authorization to /cosmos.staking.v1beta1.MsgDelegate", - }, - { - "success - no-op, allowance amount is already set to the maximum value", - func() []interface{} { - approveArgs := []interface{}{ - s.address, - abi.MaxUint256, - []string{staking.DelegateMsg}, - } - resp, err := s.precompile.Approve(s.ctx, s.address, s.stateDB, &method, approveArgs) - s.Require().NoError(err) - s.Require().Equal(resp, cmn.TrueValue) - - authz, _ := s.CheckAuthorization(staking.DelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().Equal(authz.AuthorizationType, staking.DelegateAuthz) - var coin *sdk.Coin - s.Require().Equal(authz.MaxTokens, coin) - - return []interface{}{ - s.address, - big.NewInt(2e18), - []string{staking.DelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) {}, - 200000, - false, - "", - }, - { - "success - increase delegate authorization allowance by 1 Evmos", - func() []interface{} { - s.ApproveAndCheckAuthz(method, staking.DelegateMsg, big.NewInt(1e18)) - return []interface{}{ - s.address, - big.NewInt(1e18), - []string{staking.DelegateMsg}, - } - }, - func(data []byte, inputArgs []interface{}) { - authz, _ := s.CheckAuthorization(staking.DelegateAuthz, s.address, s.address) - s.Require().NotNil(authz) - s.Require().Equal(authz.AuthorizationType, staking.DelegateAuthz) - s.Require().Equal(authz.MaxTokens, &sdk.Coin{Denom: s.bondDenom, Amount: math.NewInt(2e18)}) - }, - 200000, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - - args := tc.malleate() - bz, err := s.precompile.IncreaseAllowance(s.ctx, s.address, s.stateDB, &method, args) - - if tc.expError { - s.Require().ErrorContains(err, tc.errContains) - s.Require().Empty(bz) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz, args) - } - }) - } -} - -func (s *PrecompileTestSuite) TestRevoke() { - method := s.precompile.Methods[authorization.RevokeMethod] - granteeAddr := evmosutiltx.GenerateAddress() - granterAddr := s.address - createdAuthz := staking.DelegateAuthz - approvedCoin := &sdk.Coin{Denom: s.bondDenom, Amount: math.NewInt(1e18)} - - testCases := []struct { - name string - malleate func() []interface{} - postCheck func(data []byte, inputArgs []interface{}) - expError bool - errContains string - }{ - { - name: "fail - empty input args", - malleate: func() []interface{} { - return []interface{}{} - }, - expError: true, - errContains: fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 2, 0), - }, - { - name: "fail - authorization does not exist", - malleate: func() []interface{} { - return []interface{}{ - granteeAddr, - []string{staking.UndelegateMsg}, - } - }, - postCheck: func(data []byte, inputArgs []interface{}) { - // expect authorization to still be there - authz, _ := s.CheckAuthorization(createdAuthz, granteeAddr, granterAddr) - s.Require().NotNil(authz) - }, - expError: true, - errContains: "authorization not found", - }, - { - name: "pass - authorization revoked", - malleate: func() []interface{} { - return []interface{}{ - granteeAddr, - []string{staking.DelegateMsg}, - } - }, - postCheck: func(data []byte, inputArgs []interface{}) { - // expect authorization to be removed - authz, _ := s.CheckAuthorization(createdAuthz, granteeAddr, granterAddr) - s.Require().Nil(authz, "expected authorization to be removed") - }, - }, - } - - for _, tc := range testCases { - tc := tc - s.Run(tc.name, func() { - s.SetupTest() // reset - - // Create a delegate authorization - validators := s.app.StakingKeeper.GetLastValidators(s.ctx) - valAddrs := make([]sdk.ValAddress, len(validators)) - for i, val := range validators { - valAddrs[i] = val.GetOperator() - } - delegationAuthz, err := stakingtypes.NewStakeAuthorization( - valAddrs, - nil, - createdAuthz, - approvedCoin, - ) - s.Require().NoError(err) - - expiration := s.ctx.BlockTime().Add(time.Hour * 24 * 365).UTC() - err = s.app.AuthzKeeper.SaveGrant(s.ctx, granteeAddr.Bytes(), granterAddr.Bytes(), delegationAuthz, &expiration) - s.Require().NoError(err, "failed to save authorization") - authz, _ := s.CheckAuthorization(createdAuthz, granteeAddr, granterAddr) - s.Require().NotNil(authz, "expected authorization to be set") - - args := tc.malleate() - bz, err := s.precompile.Revoke(s.ctx, granterAddr, s.stateDB, &method, args) - - if tc.expError { - s.Require().ErrorContains(err, tc.errContains) - s.Require().Empty(bz) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz, args) - } - }) - } -} diff --git a/precompiles/staking/errors.go b/precompiles/staking/errors.go deleted file mode 100644 index e427b486..00000000 --- a/precompiles/staking/errors.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) -package staking - -const ( - // ErrDecreaseAmountTooBig is raised when the amount by which the allowance should be decreased is greater - // than the authorization limit. - ErrDecreaseAmountTooBig = "amount by which the allowance should be decreased is greater than the authorization limit: %s > %s" - // ErrDifferentOriginFromDelegator is raised when the origin address is not the same as the delegator address. - ErrDifferentOriginFromDelegator = "origin address %s is not the same as delegator address %s" - // ErrNoDelegationFound is raised when no delegation is found for the given delegator and validator addresses. - ErrNoDelegationFound = "delegation with delegator %s not found for validator %s" -) diff --git a/precompiles/staking/events.go b/precompiles/staking/events.go deleted file mode 100644 index ef90c39f..00000000 --- a/precompiles/staking/events.go +++ /dev/null @@ -1,313 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package staking - -import ( - "bytes" - "math/big" - "reflect" - - "github.com/evmos/evmos/v16/precompiles/authorization" - - sdk "github.com/cosmos/cosmos-sdk/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - cmn "github.com/evmos/evmos/v16/precompiles/common" -) - -const ( - // EventTypeCreateValidator defines the event type for the staking CreateValidator transaction. - EventTypeCreateValidator = "CreateValidator" - // EventTypeDelegate defines the event type for the staking Delegate transaction. - EventTypeDelegate = "Delegate" - // EventTypeUnbond defines the event type for the staking Undelegate transaction. - EventTypeUnbond = "Unbond" - // EventTypeRedelegate defines the event type for the staking Redelegate transaction. - EventTypeRedelegate = "Redelegate" - // EventTypeCancelUnbondingDelegation defines the event type for the staking CancelUnbondingDelegation transaction. - EventTypeCancelUnbondingDelegation = "CancelUnbondingDelegation" -) - -// EmitApprovalEvent creates a new approval event emitted on an Approve, IncreaseAllowance and DecreaseAllowance transactions. -func (p Precompile) EmitApprovalEvent(ctx sdk.Context, stateDB vm.StateDB, grantee, granter common.Address, coin *sdk.Coin, typeUrls []string) error { - // Prepare the event topics - event := p.ABI.Events[authorization.EventTypeApproval] - topics := make([]common.Hash, 3) - - // The first topic is always the signature of the event. - topics[0] = event.ID - - var err error - topics[1], err = cmn.MakeTopic(grantee) - if err != nil { - return err - } - - topics[2], err = cmn.MakeTopic(granter) - if err != nil { - return err - } - - // Check if the coin is set to infinite - value := abi.MaxUint256 - if coin != nil { - value = coin.Amount.BigInt() - } - - // Pack the arguments to be used as the Data field - arguments := abi.Arguments{event.Inputs[2], event.Inputs[3]} - packed, err := arguments.Pack(typeUrls, value) - if err != nil { - return err - } - - stateDB.AddLog(ðtypes.Log{ - Address: p.Address(), - Topics: topics, - Data: packed, - BlockNumber: uint64(ctx.BlockHeight()), - }) - - return nil -} - -// EmitAllowanceChangeEvent creates a new allowance change event emitted on an IncreaseAllowance and DecreaseAllowance transactions. -func (p Precompile) EmitAllowanceChangeEvent(ctx sdk.Context, stateDB vm.StateDB, grantee, granter common.Address, typeUrls []string) error { - // Prepare the event topics - event := p.ABI.Events[authorization.EventTypeAllowanceChange] - topics := make([]common.Hash, 3) - - // The first topic is always the signature of the event. - topics[0] = event.ID - - var err error - topics[1], err = cmn.MakeTopic(grantee) - if err != nil { - return err - } - - topics[2], err = cmn.MakeTopic(granter) - if err != nil { - return err - } - - newValues := make([]*big.Int, len(typeUrls)) - for i, msgURL := range typeUrls { - // Not including expiration and convert check because we have already checked it in the previous call - msgAuthz, _ := p.AuthzKeeper.GetAuthorization(ctx, grantee.Bytes(), granter.Bytes(), msgURL) - stakeAuthz, _ := msgAuthz.(*stakingtypes.StakeAuthorization) - if stakeAuthz.MaxTokens == nil { - newValues[i] = abi.MaxUint256 - } else { - newValues[i] = stakeAuthz.MaxTokens.Amount.BigInt() - } - } - - // Pack the arguments to be used as the Data field - arguments := abi.Arguments{event.Inputs[2], event.Inputs[3]} - packed, err := arguments.Pack(typeUrls, newValues) - if err != nil { - return err - } - - stateDB.AddLog(ðtypes.Log{ - Address: p.Address(), - Topics: topics, - Data: packed, - BlockNumber: uint64(ctx.BlockHeight()), - }) - - return nil -} - -// EmitCreateValidatorEvent creates a new create validator event emitted on a CreateValidator transaction. -func (p Precompile) EmitCreateValidatorEvent(ctx sdk.Context, stateDB vm.StateDB, msg *stakingtypes.MsgCreateValidator, delegatorAddr common.Address) error { - // Prepare the event topics - event := p.ABI.Events[EventTypeCreateValidator] - - valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress) - if err != nil { - return err - } - - topics, err := p.createStakingTxTopics(3, event, delegatorAddr, common.BytesToAddress(valAddr.Bytes())) - if err != nil { - return err - } - - // Prepare the event data - var b bytes.Buffer - b.Write(cmn.PackNum(reflect.ValueOf(msg.Value.Amount.BigInt()))) - - stateDB.AddLog(ðtypes.Log{ - Address: p.Address(), - Topics: topics, - Data: b.Bytes(), - BlockNumber: uint64(ctx.BlockHeight()), - }) - - return nil -} - -// EmitDelegateEvent creates a new delegate event emitted on a Delegate transaction. -func (p Precompile) EmitDelegateEvent(ctx sdk.Context, stateDB vm.StateDB, msg *stakingtypes.MsgDelegate, delegatorAddr common.Address) error { - valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress) - if err != nil { - return err - } - - // Get the validator to estimate the new shares delegated - // NOTE: At this point the validator has already been checked, so no need to check again - validator, _ := p.stakingKeeper.GetValidator(ctx, valAddr) - - // Get only the new shares based on the delegation amount - newShares, err := validator.SharesFromTokens(msg.Amount.Amount) - if err != nil { - return err - } - - // Prepare the event topics - event := p.ABI.Events[EventTypeDelegate] - topics, err := p.createStakingTxTopics(3, event, delegatorAddr, common.BytesToAddress(valAddr.Bytes())) - if err != nil { - return err - } - - // Prepare the event data - var b bytes.Buffer - b.Write(cmn.PackNum(reflect.ValueOf(msg.Amount.Amount.BigInt()))) - b.Write(cmn.PackNum(reflect.ValueOf(newShares.BigInt()))) - - stateDB.AddLog(ðtypes.Log{ - Address: p.Address(), - Topics: topics, - Data: b.Bytes(), - BlockNumber: uint64(ctx.BlockHeight()), - }) - - return nil -} - -// EmitUnbondEvent creates a new unbond event emitted on an Undelegate transaction. -func (p Precompile) EmitUnbondEvent(ctx sdk.Context, stateDB vm.StateDB, msg *stakingtypes.MsgUndelegate, delegatorAddr common.Address, completionTime int64) error { - valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress) - if err != nil { - return err - } - - // Prepare the event topics - event := p.ABI.Events[EventTypeUnbond] - topics, err := p.createStakingTxTopics(3, event, delegatorAddr, common.BytesToAddress(valAddr.Bytes())) - if err != nil { - return err - } - - // Prepare the event data - var b bytes.Buffer - b.Write(cmn.PackNum(reflect.ValueOf(msg.Amount.Amount.BigInt()))) - b.Write(cmn.PackNum(reflect.ValueOf(big.NewInt(completionTime)))) - - stateDB.AddLog(ðtypes.Log{ - Address: p.Address(), - Topics: topics, - Data: b.Bytes(), - BlockNumber: uint64(ctx.BlockHeight()), - }) - - return nil -} - -// EmitRedelegateEvent creates a new redelegate event emitted on a Redelegate transaction. -func (p Precompile) EmitRedelegateEvent(ctx sdk.Context, stateDB vm.StateDB, msg *stakingtypes.MsgBeginRedelegate, delegatorAddr common.Address, completionTime int64) error { - valSrcAddr, err := sdk.ValAddressFromBech32(msg.ValidatorSrcAddress) - if err != nil { - return err - } - - valDstAddr, err := sdk.ValAddressFromBech32(msg.ValidatorDstAddress) - if err != nil { - return err - } - - // Prepare the event topics - event := p.ABI.Events[EventTypeRedelegate] - topics, err := p.createStakingTxTopics(4, event, delegatorAddr, common.BytesToAddress(valSrcAddr.Bytes())) - if err != nil { - return err - } - - topics[3], err = cmn.MakeTopic(common.BytesToAddress(valDstAddr.Bytes())) - if err != nil { - return err - } - - // Prepare the event data - var b bytes.Buffer - b.Write(cmn.PackNum(reflect.ValueOf(msg.Amount.Amount.BigInt()))) - b.Write(cmn.PackNum(reflect.ValueOf(big.NewInt(completionTime)))) - - stateDB.AddLog(ðtypes.Log{ - Address: p.Address(), - Topics: topics, - Data: b.Bytes(), - BlockNumber: uint64(ctx.BlockHeight()), - }) - - return nil -} - -// EmitCancelUnbondingDelegationEvent creates a new cancel unbonding delegation event emitted on a CancelUnbondingDelegation transaction. -func (p Precompile) EmitCancelUnbondingDelegationEvent(ctx sdk.Context, stateDB vm.StateDB, msg *stakingtypes.MsgCancelUnbondingDelegation, delegatorAddr common.Address) error { - valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress) - if err != nil { - return err - } - - // Prepare the event topics - event := p.ABI.Events[EventTypeCancelUnbondingDelegation] - topics, err := p.createStakingTxTopics(3, event, delegatorAddr, common.BytesToAddress(valAddr.Bytes())) - if err != nil { - return err - } - - // Prepare the event data - var b bytes.Buffer - b.Write(cmn.PackNum(reflect.ValueOf(msg.Amount.Amount.BigInt()))) - b.Write(cmn.PackNum(reflect.ValueOf(big.NewInt(msg.CreationHeight)))) - - stateDB.AddLog(ðtypes.Log{ - Address: p.Address(), - Topics: topics, - Data: b.Bytes(), - BlockNumber: uint64(ctx.BlockHeight()), - }) - - return nil -} - -// createStakingTxTopics creates the topics for staking transactions CreateValidator, Delegate, Undelegate, Redelegate and CancelUnbondingDelegation. -func (p Precompile) createStakingTxTopics(topicsLen uint64, event abi.Event, delegatorAddr common.Address, validatorAddr common.Address) ([]common.Hash, error) { - topics := make([]common.Hash, topicsLen) - // NOTE: If your solidity event contains indexed event types, then they become a topic rather than part of the data property of the log. - // In solidity you may only have up to 4 topics but only 3 indexed event types. The first topic is always the signature of the event. - - // The first topic is always the signature of the event. - topics[0] = event.ID - - var err error - topics[1], err = cmn.MakeTopic(delegatorAddr) - if err != nil { - return nil, err - } - - topics[2], err = cmn.MakeTopic(validatorAddr) - if err != nil { - return nil, err - } - - return topics, nil -} diff --git a/precompiles/staking/events_test.go b/precompiles/staking/events_test.go deleted file mode 100644 index 7ab9c8f8..00000000 --- a/precompiles/staking/events_test.go +++ /dev/null @@ -1,586 +0,0 @@ -package staking_test - -import ( - "math/big" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - "github.com/evmos/evmos/v16/precompiles/authorization" - cmn "github.com/evmos/evmos/v16/precompiles/common" - "github.com/evmos/evmos/v16/precompiles/staking" -) - -func (s *PrecompileTestSuite) TestApprovalEvent() { - method := s.precompile.Methods[authorization.ApproveMethod] - testCases := []struct { - name string - malleate func() []interface{} - expErr bool - errContains string - postCheck func() - }{ - { - "success - all four methods are present in the emitted event", - func() []interface{} { - return []interface{}{ - s.address, - abi.MaxUint256, - []string{ - staking.DelegateMsg, - staking.UndelegateMsg, - staking.RedelegateMsg, - staking.CancelUnbondingDelegationMsg, - }, - } - }, - false, - "", - func() { - log := s.stateDB.Logs()[0] - s.Require().Equal(log.Address, s.precompile.Address()) - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[authorization.EventTypeApproval] - s.Require().Equal(crypto.Keccak256Hash([]byte(event.Sig)), common.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - - var approvalEvent authorization.EventApproval - err := cmn.UnpackLog(s.precompile.ABI, &approvalEvent, authorization.EventTypeApproval, *log) - s.Require().NoError(err) - s.Require().Equal(s.address, approvalEvent.Grantee) - s.Require().Equal(s.address, approvalEvent.Granter) - s.Require().Equal(abi.MaxUint256, approvalEvent.Value) - s.Require().Equal(4, len(approvalEvent.Methods)) - s.Require().Equal(staking.DelegateMsg, approvalEvent.Methods[0]) - s.Require().Equal(staking.UndelegateMsg, approvalEvent.Methods[1]) - s.Require().Equal(staking.RedelegateMsg, approvalEvent.Methods[2]) - s.Require().Equal(staking.CancelUnbondingDelegationMsg, approvalEvent.Methods[3]) - }, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - - err := s.CreateAuthorization(s.address, staking.DelegateAuthz, nil) - s.Require().NoError(err) - - _, err = s.precompile.Approve(s.ctx, s.address, s.stateDB, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck() - } - }) - } -} - -func (s *PrecompileTestSuite) TestIncreaseAllowanceEvent() { - approvalMethod := s.precompile.Methods[authorization.ApproveMethod] - method := s.precompile.Methods[authorization.IncreaseAllowanceMethod] - testCases := []struct { - name string - malleate func() []interface{} - expErr bool - errContains string - postCheck func() - }{ - { - "success - increased allowance for all 3 methods by 1 evmos", - func() []interface{} { - return []interface{}{ - s.address, - big.NewInt(1000000000000000000), - []string{ - staking.DelegateMsg, - staking.UndelegateMsg, - staking.RedelegateMsg, - }, - } - }, - false, - "", - func() { - log := s.stateDB.Logs()[1] - methods := []string{ - staking.DelegateMsg, - staking.UndelegateMsg, - staking.RedelegateMsg, - } - amounts := []*big.Int{ - big.NewInt(2000000000000000000), - big.NewInt(2000000000000000000), - big.NewInt(2000000000000000000), - } - s.CheckAllowanceChangeEvent(log, methods, amounts) - }, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - - err := s.CreateAuthorization(s.address, staking.DelegateAuthz, nil) - s.Require().NoError(err) - - // Approve first with 1 evmos - _, err = s.precompile.Approve(s.ctx, s.address, s.stateDB, &approvalMethod, tc.malleate()) - s.Require().NoError(err) - - // Increase allowance after approval - _, err = s.precompile.IncreaseAllowance(s.ctx, s.address, s.stateDB, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck() - } - }) - } -} - -func (s *PrecompileTestSuite) TestDecreaseAllowanceEvent() { - approvalMethod := s.precompile.Methods[authorization.ApproveMethod] - method := s.precompile.Methods[authorization.DecreaseAllowanceMethod] - testCases := []struct { - name string - malleate func() []interface{} - expErr bool - errContains string - postCheck func() - }{ - { - "success - decreased allowance for all 3 methods by 1 evmos", - func() []interface{} { - return []interface{}{ - s.address, - big.NewInt(1000000000000000000), - []string{ - staking.DelegateMsg, - staking.UndelegateMsg, - staking.RedelegateMsg, - }, - } - }, - false, - "", - func() { - log := s.stateDB.Logs()[1] - methods := []string{ - staking.DelegateMsg, - staking.UndelegateMsg, - staking.RedelegateMsg, - } - amounts := []*big.Int{ - big.NewInt(1000000000000000000), - big.NewInt(1000000000000000000), - big.NewInt(1000000000000000000), - } - s.CheckAllowanceChangeEvent(log, methods, amounts) - }, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - - err := s.CreateAuthorization(s.address, staking.DelegateAuthz, nil) - s.Require().NoError(err) - - // Approve first with 2 evmos - args := []interface{}{ - s.address, - big.NewInt(2000000000000000000), - []string{ - staking.DelegateMsg, - staking.UndelegateMsg, - staking.RedelegateMsg, - }, - } - _, err = s.precompile.Approve(s.ctx, s.address, s.stateDB, &approvalMethod, args) - s.Require().NoError(err) - - // Decrease allowance after approval - _, err = s.precompile.DecreaseAllowance(s.ctx, s.address, s.stateDB, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck() - } - }) - } -} - -func (s *PrecompileTestSuite) TestCreateValidatorEvent() { - var ( - delegationValue = big.NewInt(1205000000000000000) - method = s.precompile.Methods[staking.CreateValidatorMethod] - operatorAddress = sdk.ValAddress(s.address.Bytes()).String() - pubkey = "nfJ0axJC9dhta1MAE1EBFaVdxxkYzxYrBaHuJVjG//M=" - ) - - testCases := []struct { - name string - malleate func() []interface{} - expErr bool - errContains string - postCheck func() - }{ - { - name: "success - the correct event is emitted", - malleate: func() []interface{} { - return []interface{}{ - staking.Description{ - Moniker: "node0", - Identity: "", - Website: "", - SecurityContact: "", - Details: "", - }, - staking.Commission{ - Rate: math.LegacyOneDec().BigInt(), - MaxRate: math.LegacyOneDec().BigInt(), - MaxChangeRate: math.LegacyOneDec().BigInt(), - }, - big.NewInt(1), - s.address, - operatorAddress, - pubkey, - delegationValue, - } - }, - postCheck: func() { - log := s.stateDB.Logs()[0] - s.Require().Equal(log.Address, s.precompile.Address()) - - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[staking.EventTypeCreateValidator] - s.Require().Equal(crypto.Keccak256Hash([]byte(event.Sig)), common.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - - // Check the fully unpacked event matches the one emitted - var createValidatorEvent staking.EventCreateValidator - err := cmn.UnpackLog(s.precompile.ABI, &createValidatorEvent, staking.EventTypeCreateValidator, *log) - s.Require().NoError(err) - s.Require().Equal(s.address, createValidatorEvent.DelegatorAddress) - s.Require().Equal(s.address, createValidatorEvent.ValidatorAddress) - s.Require().Equal(delegationValue, createValidatorEvent.Value) - }, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - operatorAddress = sdk.ValAddress(s.address.Bytes()).String() - - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), 200000) - _, err := s.precompile.CreateValidator(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck() - } - }) - } -} - -func (s *PrecompileTestSuite) TestDelegateEvent() { - var ( - delegationAmt = big.NewInt(1500000000000000000) - newSharesExp = delegationAmt - method = s.precompile.Methods[staking.DelegateMethod] - ) - testCases := []struct { - name string - malleate func() []interface{} - expErr bool - errContains string - postCheck func() - }{ - { - "success - the correct event is emitted", - func() []interface{} { - return []interface{}{ - s.address, - s.validators[0].OperatorAddress, - delegationAmt, - } - }, - false, - "", - func() { - log := s.stateDB.Logs()[0] - s.Require().Equal(log.Address, s.precompile.Address()) - - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[staking.EventTypeDelegate] - s.Require().Equal(crypto.Keccak256Hash([]byte(event.Sig)), common.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - - optAddr, err := sdk.ValAddressFromBech32(s.validators[0].OperatorAddress) - s.Require().NoError(err) - optHexAddr := common.BytesToAddress(optAddr) - - // Check the fully unpacked event matches the one emitted - var delegationEvent staking.EventDelegate - err = cmn.UnpackLog(s.precompile.ABI, &delegationEvent, staking.EventTypeDelegate, *log) - s.Require().NoError(err) - s.Require().Equal(s.address, delegationEvent.DelegatorAddress) - s.Require().Equal(optHexAddr, delegationEvent.ValidatorAddress) - s.Require().Equal(delegationAmt, delegationEvent.Amount) - s.Require().Equal(newSharesExp, delegationEvent.NewShares) - }, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - - err := s.CreateAuthorization(s.address, staking.DelegateAuthz, nil) - s.Require().NoError(err) - - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), 20000) - _, err = s.precompile.Delegate(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck() - } - }) - } -} - -func (s *PrecompileTestSuite) TestUnbondEvent() { - method := s.precompile.Methods[staking.UndelegateMethod] - - testCases := []struct { - name string - malleate func() []interface{} - expErr bool - errContains string - postCheck func() - }{ - { - "success - the correct event is emitted", - func() []interface{} { - return []interface{}{ - s.address, - s.validators[0].OperatorAddress, - big.NewInt(1000000000000000000), - } - }, - false, - "", - func() { - log := s.stateDB.Logs()[0] - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[staking.EventTypeUnbond] - s.Require().Equal(crypto.Keccak256Hash([]byte(event.Sig)), common.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - - optAddr, err := sdk.ValAddressFromBech32(s.validators[0].OperatorAddress) - s.Require().NoError(err) - optHexAddr := common.BytesToAddress(optAddr) - - // Check the fully unpacked event matches the one emitted - var unbondEvent staking.EventUnbond - err = cmn.UnpackLog(s.precompile.ABI, &unbondEvent, staking.EventTypeUnbond, *log) - s.Require().NoError(err) - s.Require().Equal(s.address, unbondEvent.DelegatorAddress) - s.Require().Equal(optHexAddr, unbondEvent.ValidatorAddress) - s.Require().Equal(big.NewInt(1000000000000000000), unbondEvent.Amount) - }, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - - err := s.CreateAuthorization(s.address, staking.UndelegateAuthz, nil) - s.Require().NoError(err) - - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), 20000) - _, err = s.precompile.Undelegate(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - tc.postCheck() - } - }) - } -} - -func (s *PrecompileTestSuite) TestRedelegateEvent() { - method := s.precompile.Methods[staking.RedelegateMethod] - - testCases := []struct { - name string - malleate func() []interface{} - expErr bool - errContains string - postCheck func() - }{ - { - "success - the correct event is emitted", - func() []interface{} { - return []interface{}{ - s.address, - s.validators[0].OperatorAddress, - s.validators[1].OperatorAddress, - big.NewInt(1000000000000000000), - } - }, - false, - "", - func() { - log := s.stateDB.Logs()[0] - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[staking.EventTypeRedelegate] - s.Require().Equal(crypto.Keccak256Hash([]byte(event.Sig)), common.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - - optSrcAddr, err := sdk.ValAddressFromBech32(s.validators[0].OperatorAddress) - s.Require().NoError(err) - optSrcHexAddr := common.BytesToAddress(optSrcAddr) - - optDstAddr, err := sdk.ValAddressFromBech32(s.validators[1].OperatorAddress) - s.Require().NoError(err) - optDstHexAddr := common.BytesToAddress(optDstAddr) - - var redelegateEvent staking.EventRedelegate - err = cmn.UnpackLog(s.precompile.ABI, &redelegateEvent, staking.EventTypeRedelegate, *log) - s.Require().NoError(err) - s.Require().Equal(s.address, redelegateEvent.DelegatorAddress) - s.Require().Equal(optSrcHexAddr, redelegateEvent.ValidatorSrcAddress) - s.Require().Equal(optDstHexAddr, redelegateEvent.ValidatorDstAddress) - s.Require().Equal(big.NewInt(1000000000000000000), redelegateEvent.Amount) - }, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - - err := s.CreateAuthorization(s.address, staking.RedelegateAuthz, nil) - s.Require().NoError(err) - - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), 20000) - _, err = s.precompile.Redelegate(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate()) - s.Require().NoError(err) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - tc.postCheck() - } - }) - } -} - -func (s *PrecompileTestSuite) TestCancelUnbondingDelegationEvent() { - methodCancelUnbonding := s.precompile.Methods[staking.CancelUnbondingDelegationMethod] - methodUndelegate := s.precompile.Methods[staking.UndelegateMethod] - - testCases := []struct { - name string - malleate func(contract *vm.Contract) []interface{} - expErr bool - errContains string - postCheck func() - }{ - { - "success - the correct event is emitted", - func(contract *vm.Contract) []interface{} { - err := s.CreateAuthorization(s.address, staking.UndelegateAuthz, nil) - s.Require().NoError(err) - undelegateArgs := []interface{}{ - s.address, - s.validators[0].OperatorAddress, - big.NewInt(1000000000000000000), - } - _, err = s.precompile.Undelegate(s.ctx, s.address, contract, s.stateDB, &methodUndelegate, undelegateArgs) - s.Require().NoError(err) - - return []interface{}{ - s.address, - s.validators[0].OperatorAddress, - big.NewInt(1000000000000000000), - big.NewInt(2), - } - }, - false, - "", - func() { - log := s.stateDB.Logs()[1] - - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[staking.EventTypeCancelUnbondingDelegation] - s.Require().Equal(crypto.Keccak256Hash([]byte(event.Sig)), common.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - - optAddr, err := sdk.ValAddressFromBech32(s.validators[0].OperatorAddress) - s.Require().NoError(err) - optHexAddr := common.BytesToAddress(optAddr) - - // Check event fields match the ones emitted - var cancelUnbondEvent staking.EventCancelUnbonding - err = cmn.UnpackLog(s.precompile.ABI, &cancelUnbondEvent, staking.EventTypeCancelUnbondingDelegation, *log) - s.Require().NoError(err) - s.Require().Equal(s.address, cancelUnbondEvent.DelegatorAddress) - s.Require().Equal(optHexAddr, cancelUnbondEvent.ValidatorAddress) - s.Require().Equal(big.NewInt(1000000000000000000), cancelUnbondEvent.Amount) - s.Require().Equal(big.NewInt(2), cancelUnbondEvent.CreationHeight) - }, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - - err := s.CreateAuthorization(s.address, staking.CancelUnbondingDelegationAuthz, nil) - s.Require().NoError(err) - - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), 20000) - callArgs := tc.malleate(contract) - _, err = s.precompile.CancelUnbondingDelegation(s.ctx, s.address, contract, s.stateDB, &methodCancelUnbonding, callArgs) - s.Require().NoError(err) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - tc.postCheck() - } - }) - } -} diff --git a/precompiles/staking/integration_test.go b/precompiles/staking/integration_test.go deleted file mode 100644 index c76b90f1..00000000 --- a/precompiles/staking/integration_test.go +++ /dev/null @@ -1,2901 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) -package staking_test - -import ( - "fmt" - "math/big" - "time" - - //nolint:revive // dot imports are fine for Ginkgo - . "github.com/onsi/ginkgo/v2" - //nolint:revive // dot imports are fine for Ginkgo - . "github.com/onsi/gomega" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/query" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - compiledcontracts "github.com/evmos/evmos/v16/contracts" - "github.com/evmos/evmos/v16/precompiles/authorization" - cmn "github.com/evmos/evmos/v16/precompiles/common" - "github.com/evmos/evmos/v16/precompiles/distribution" - "github.com/evmos/evmos/v16/precompiles/staking" - "github.com/evmos/evmos/v16/precompiles/staking/testdata" - "github.com/evmos/evmos/v16/precompiles/testutil" - "github.com/evmos/evmos/v16/precompiles/testutil/contracts" - evmosutil "github.com/evmos/evmos/v16/testutil" - testutiltx "github.com/evmos/evmos/v16/testutil/tx" -) - -// General variables used for integration tests -var ( - // valAddr and valAddr2 are the two validator addresses used for testing - valAddr, valAddr2 sdk.ValAddress - - // defaultCallArgs and defaultApproveArgs are the default arguments for calling the smart contract and to - // call the approve method specifically. - // - // NOTE: this has to be populated in a BeforeEach block because the contractAddr would otherwise be a nil address. - defaultCallArgs, defaultApproveArgs contracts.CallArgs - - // defaultLogCheck instantiates a log check arguments struct with the precompile ABI events populated. - defaultLogCheck testutil.LogCheckArgs - // passCheck defines the arguments to check if the precompile returns no error - passCheck testutil.LogCheckArgs - // outOfGasCheck defines the arguments to check if the precompile returns out of gas error - outOfGasCheck testutil.LogCheckArgs -) - -var _ = Describe("Calling staking precompile directly", func() { - var ( - // oneE18Coin is a sdk.Coin with an amount of 1e18 in the test suite's bonding denomination - oneE18Coin = sdk.NewCoin(s.bondDenom, math.NewInt(1e18)) - // twoE18Coin is a sdk.Coin with an amount of 2e18 in the test suite's bonding denomination - twoE18Coin = sdk.NewCoin(s.bondDenom, math.NewInt(2e18)) - ) - - BeforeEach(func() { - s.SetupTest() - s.NextBlock() - - valAddr = s.validators[0].GetOperator() - valAddr2 = s.validators[1].GetOperator() - - defaultCallArgs = contracts.CallArgs{ - ContractAddr: s.precompile.Address(), - ContractABI: s.precompile.ABI, - PrivKey: s.privKey, - } - defaultApproveArgs = defaultCallArgs.WithMethodName(authorization.ApproveMethod) - - defaultLogCheck = testutil.LogCheckArgs{ABIEvents: s.precompile.ABI.Events} - passCheck = defaultLogCheck.WithExpPass(true) - outOfGasCheck = defaultLogCheck.WithErrContains(vm.ErrOutOfGas.Error()) - }) - - Describe("when the precompile is not enabled in the EVM params", func() { - It("should return an error", func() { - // disable the precompile - params := s.app.EvmKeeper.GetParams(s.ctx) - var activePrecompiles []string - for _, precompile := range params.ActivePrecompiles { - if precompile != s.precompile.Address().String() { - activePrecompiles = append(activePrecompiles, precompile) - } - } - params.ActivePrecompiles = activePrecompiles - err := s.app.EvmKeeper.SetParams(s.ctx, params) - Expect(err).To(BeNil(), "error while setting params") - - // try to call the precompile - delegateArgs := defaultCallArgs. - WithMethodName(staking.DelegateMethod). - WithArgs( - s.address, valAddr.String(), big.NewInt(2e18), - ) - - failCheck := defaultLogCheck. - WithErrContains("precompile not enabled") - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, delegateArgs, failCheck) - Expect(err).To(HaveOccurred(), "expected error while calling the precompile") - Expect(err.Error()).To(ContainSubstring("precompile not enabled")) - }) - }) - - Describe("Revert transaction", func() { - It("should run out of gas if the gas limit is too low", func() { - outOfGasArgs := defaultApproveArgs. - WithGasLimit(30000). - WithArgs( - s.precompile.Address(), - abi.MaxUint256, - []string{staking.DelegateMsg}, - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, outOfGasArgs, outOfGasCheck) - Expect(err).To(HaveOccurred(), "error while calling precompile") - }) - }) - - Describe("Execute approve transaction", func() { - // TODO: enable once we check that the spender is not the origin - // It("should return error if the origin is the spender", func() { - // args := defaultApproveArgs.WithArgs( - // s.address, - // abi.MaxUint256, - // []string{staking.DelegateMsg}, - // ) - // - // differentOriginCheck := defaultLogCheck.WithErrContains(cmn.ErrDifferentOrigin, s.address, addr) - // - // _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, args, differentOriginCheck) - // Expect(err).To(BeNil(), "error while calling precompile") - // }) - - It("should return error if the staking method is not supported on the precompile", func() { - approveArgs := defaultApproveArgs.WithArgs( - s.precompile.Address(), abi.MaxUint256, []string{distribution.DelegationRewardsMethod}, - ) - - logCheckArgs := defaultLogCheck.WithErrContains( - cmn.ErrInvalidMsgType, "staking", distribution.DelegationRewardsMethod, - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, approveArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the contract and checking logs") - }) - - It("should approve the delegate method with the max uint256 value", func() { - s.SetupApproval( - s.privKey, s.precompile.Address(), abi.MaxUint256, []string{staking.DelegateMsg}, - ) - - s.ExpectAuthorization(staking.DelegateAuthz, s.precompile.Address(), s.address, nil) - }) - - It("should approve the undelegate method with 1 evmos", func() { - s.SetupApproval( - s.privKey, s.precompile.Address(), big.NewInt(1e18), []string{staking.UndelegateMsg}, - ) - - s.ExpectAuthorization(staking.UndelegateAuthz, s.precompile.Address(), s.address, &oneE18Coin) - }) - - It("should approve the redelegate method with 2 evmos", func() { - s.SetupApproval( - s.privKey, s.precompile.Address(), big.NewInt(2e18), []string{staking.RedelegateMsg}, - ) - - s.ExpectAuthorization(staking.RedelegateAuthz, s.precompile.Address(), s.address, &twoE18Coin) - }) - - It("should approve the cancel unbonding delegation method with 1 evmos", func() { - s.SetupApproval( - s.privKey, s.precompile.Address(), big.NewInt(1e18), []string{staking.CancelUnbondingDelegationMsg}, - ) - - s.ExpectAuthorization(staking.CancelUnbondingDelegationAuthz, s.precompile.Address(), s.address, &oneE18Coin) - }) - }) - - Describe("Execute increase allowance transaction", func() { - // defaultIncreaseArgs are the default arguments to call the increase allowance method. - // - // NOTE: this has to be populated in BeforeEach, because the private key is not initialized outside of it. - var defaultIncreaseArgs contracts.CallArgs - - BeforeEach(func() { - s.SetupApproval( - s.privKey, s.precompile.Address(), big.NewInt(1e18), []string{staking.DelegateMsg}, - ) - - defaultIncreaseArgs = defaultCallArgs.WithMethodName(authorization.IncreaseAllowanceMethod) - }) - - // TODO: enable once we check that the spender is not the origin - // It("should return error if the origin is the spender", func() { - // increaseArgs := defaultCallArgs. - // WithMethodName(authorization.IncreaseAllowanceMethod). - // WithArgs( - // s.address, big.NewInt(1e18), []string{staking.DelegateMsg}, - // ) - // - // _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, increaseArgs, differentOriginCheck) - // Expect(err).To(BeNil(), "error while calling the contract and checking logs") - // }) - - It("Should increase the allowance of the delegate method with 1 evmos", func() { - increaseArgs := defaultCallArgs. - WithMethodName(authorization.IncreaseAllowanceMethod). - WithArgs( - s.precompile.Address(), big.NewInt(1e18), []string{staking.DelegateMsg}, - ) - - logCheckArgs := passCheck.WithExpEvents(authorization.EventTypeAllowanceChange) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, increaseArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the contract and checking logs") - - s.ExpectAuthorization(staking.DelegateAuthz, s.precompile.Address(), s.address, &twoE18Coin) - }) - - It("should return error if the allowance to increase does not exist", func() { - increaseArgs := defaultIncreaseArgs.WithArgs( - s.precompile.Address(), big.NewInt(1e18), []string{staking.UndelegateMsg}, - ) - - logCheckArgs := defaultLogCheck.WithErrContains( - "does not exist", - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, increaseArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the contract and checking logs") - Expect(err.Error()).To(ContainSubstring("does not exist")) - - authz, _ := s.CheckAuthorization(staking.UndelegateAuthz, s.precompile.Address(), s.address) - Expect(authz).To(BeNil(), "expected authorization to not be set") - }) - }) - - Describe("Execute decrease allowance transaction", func() { - // defaultDecreaseArgs are the default arguments to call the decrease allowance method. - // - // NOTE: this has to be populated in BeforeEach, because the private key is not initialized outside of it. - var defaultDecreaseArgs contracts.CallArgs - - BeforeEach(func() { - s.SetupApproval( - s.privKey, s.precompile.Address(), big.NewInt(2e18), []string{staking.DelegateMsg}, - ) - - defaultDecreaseArgs = defaultCallArgs.WithMethodName(authorization.DecreaseAllowanceMethod) - }) - - // TODO: enable once we check that the spender is not the origin - // It("should return error if the origin is the spender", func() { - // addr, _ := testutiltx.NewAddrKey() - // decreaseArgs := defaultDecreaseArgs.WithArgs( - // s.precompile.Address(), big.NewInt(1e18), []string{staking.DelegateMsg}, - // ) - // - // logCheckArgs := defaultLogCheck.WithErrContains( - // cmn.ErrDifferentOrigin, s.address, addr, - // ) - // - // _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, decreaseArgs, logCheckArgs) - // Expect(err).To(BeNil(), "error while calling the contract and checking logs") - // }) - - It("Should decrease the allowance of the delegate method with 1 evmos", func() { - decreaseArgs := defaultDecreaseArgs.WithArgs( - s.precompile.Address(), big.NewInt(1e18), []string{staking.DelegateMsg}, - ) - - logCheckArgs := passCheck.WithExpEvents(authorization.EventTypeAllowanceChange) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, decreaseArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the contract and checking logs") - - s.ExpectAuthorization(staking.DelegateAuthz, s.precompile.Address(), s.address, &oneE18Coin) - }) - - It("should return error if the allowance to decrease does not exist", func() { - decreaseArgs := defaultDecreaseArgs.WithArgs( - s.precompile.Address(), big.NewInt(1e18), []string{staking.UndelegateMsg}, - ) - - logCheckArgs := defaultLogCheck.WithErrContains( - "does not exist", - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, decreaseArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the contract and checking logs") - Expect(err.Error()).To(ContainSubstring("does not exist")) - - authz, _ := s.CheckAuthorization(staking.UndelegateAuthz, s.precompile.Address(), s.address) - Expect(authz).To(BeNil(), "expected authorization to not be set") - }) - }) - - Describe("to revoke an approval", func() { - var ( - // defaultRevokeArgs are the default arguments to call the revoke method. - // - // NOTE: this has to be populated in BeforeEach, because the default call args are not initialized outside of it. - defaultRevokeArgs contracts.CallArgs - - // granteeAddr is the address of the grantee used in the revocation tests. - granteeAddr = testutiltx.GenerateAddress() - ) - - BeforeEach(func() { - defaultRevokeArgs = defaultCallArgs.WithMethodName(authorization.RevokeMethod) - }) - - It("should revoke the approval when executing as the granter", func() { - typeURLs := []string{staking.DelegateMsg} - - s.SetupApproval( - s.privKey, granteeAddr, abi.MaxUint256, typeURLs, - ) - s.ExpectAuthorization(staking.DelegateAuthz, granteeAddr, s.address, nil) - - revokeArgs := defaultRevokeArgs.WithArgs( - granteeAddr, typeURLs, - ) - - revocationCheck := passCheck.WithExpEvents(authorization.EventTypeRevocation) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, revokeArgs, revocationCheck) - Expect(err).To(BeNil(), "error while calling the contract and checking logs") - - // check that the authorization is revoked - authz, _ := s.CheckAuthorization(staking.DelegateAuthz, granteeAddr, s.address) - Expect(authz).To(BeNil(), "expected authorization to be revoked") - }) - - It("should not revoke the approval when trying to revoke for a different message type", func() { - typeURLs := []string{staking.DelegateMsg} - - s.SetupApproval( - s.privKey, granteeAddr, abi.MaxUint256, typeURLs, - ) - s.ExpectAuthorization(staking.DelegateAuthz, granteeAddr, s.address, nil) - - revokeArgs := defaultRevokeArgs.WithArgs( - granteeAddr, []string{staking.UndelegateMsg}, - ) - - notFoundCheck := defaultLogCheck. - WithErrContains("failed to delete grant") - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, revokeArgs, notFoundCheck) - Expect(err).To(HaveOccurred(), "error while calling the contract and checking logs") - - // the authorization should still be there. - s.ExpectAuthorization(staking.DelegateAuthz, granteeAddr, s.address, nil) - }) - - It("should return error if the approval does not exist", func() { - revokeArgs := defaultRevokeArgs.WithArgs( - s.address, []string{staking.DelegateMsg}, - ) - - notFoundCheck := defaultLogCheck. - WithErrContains("failed to delete grant") - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, revokeArgs, notFoundCheck) - Expect(err).To(HaveOccurred(), "error while calling the contract and checking logs") - }) - - It("should not revoke the approval if sent by someone else than the granter", func() { - typeURLs := []string{staking.DelegateMsg} - - // set up an approval with a different key than the one used to sign the transaction. - differentAddr, differentPriv := testutiltx.NewAddrKey() - err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, differentAddr.Bytes(), 1e18) - Expect(err).To(BeNil(), "error while funding account") - - s.NextBlock() - s.SetupApproval( - differentPriv, granteeAddr, abi.MaxUint256, typeURLs, - ) - s.ExpectAuthorization(staking.DelegateAuthz, granteeAddr, differentAddr, nil) - - revokeArgs := defaultRevokeArgs.WithArgs( - differentAddr, typeURLs, - ) - - notFoundCheck := defaultLogCheck. - WithErrContains("failed to delete grant") - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, revokeArgs, notFoundCheck) - Expect(err).To(HaveOccurred(), "error while calling the contract and checking logs") - - // the authorization should still be set - s.ExpectAuthorization(staking.DelegateAuthz, granteeAddr, differentAddr, nil) - }) - }) - - Describe("to delegate", func() { - var ( - // prevDelegation is the delegation that is available prior to the test (an initial delegation is - // added in the test suite setup). - prevDelegation stakingtypes.Delegation - // defaultDelegateArgs are the default arguments for the delegate call - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - defaultDelegateArgs contracts.CallArgs - ) - - BeforeEach(func() { - // get the delegation that is available prior to the test - prevDelegation, _ = s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), valAddr) - - // populate the default delegate args - defaultDelegateArgs = defaultCallArgs.WithMethodName(staking.DelegateMethod) - }) - - Context("as the token owner", func() { - It("should delegate without need for authorization", func() { - delegateArgs := defaultDelegateArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(2e18), - ) - - logCheckArgs := passCheck.WithExpEvents(staking.EventTypeDelegate) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, delegateArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - delegation, found := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), valAddr) - Expect(found).To(BeTrue(), "expected delegation to be found") - expShares := prevDelegation.GetShares().Add(math.LegacyNewDec(2)) - Expect(delegation.GetShares()).To(Equal(expShares), "expected different delegation shares") - }) - - It("should not delegate if the account has no sufficient balance", func() { - // send funds away from account to only have target balance remaining - balance := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - targetBalance := math.NewInt(1e17) - sentBalance := balance.Amount.Sub(targetBalance) - newAddr, _ := testutiltx.NewAccAddressAndKey() - err := s.app.BankKeeper.SendCoins(s.ctx, s.address.Bytes(), newAddr, - sdk.Coins{sdk.Coin{Denom: s.bondDenom, Amount: sentBalance}}) - Expect(err).To(BeNil(), "error while sending coins") - - // try to delegate more than left in account - delegateArgs := defaultDelegateArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(1e18), - ) - - logCheckArgs := defaultLogCheck.WithErrContains("insufficient funds") - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, delegateArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - Expect(err.Error()).To(ContainSubstring("insufficient funds")) - }) - - It("should not delegate if the validator does not exist", func() { - nonExistingAddr := testutiltx.GenerateAddress() - nonExistingValAddr := sdk.ValAddress(nonExistingAddr.Bytes()) - - delegateArgs := defaultDelegateArgs.WithArgs( - s.address, nonExistingValAddr.String(), big.NewInt(2e18), - ) - - logCheckArgs := defaultLogCheck.WithErrContains("validator does not exist") - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, delegateArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - Expect(err.Error()).To(ContainSubstring("validator does not exist")) - }) - }) - - Context("on behalf of another account", func() { - It("should not delegate if delegator address is not the origin", func() { - differentAddr := testutiltx.GenerateAddress() - - delegateArgs := defaultDelegateArgs.WithArgs( - differentAddr, valAddr.String(), big.NewInt(2e18), - ) - - logCheckArgs := defaultLogCheck.WithErrContains( - fmt.Sprintf(staking.ErrDifferentOriginFromDelegator, s.address, differentAddr), - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, delegateArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - }) - }) - }) - - Describe("to undelegate", func() { - // defaultUndelegateArgs are the default arguments for the undelegate call - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - var defaultUndelegateArgs contracts.CallArgs - - BeforeEach(func() { - defaultUndelegateArgs = defaultCallArgs.WithMethodName(staking.UndelegateMethod) - }) - - Context("as the token owner", func() { - It("should undelegate without need for authorization", func() { - undelegations := s.app.StakingKeeper.GetUnbondingDelegationsFromValidator(s.ctx, s.validators[0].GetOperator()) - Expect(undelegations).To(HaveLen(0), "expected no unbonding delegations before test") - - undelegateArgs := defaultUndelegateArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(1e18), - ) - - logCheckArgs := passCheck.WithExpEvents(staking.EventTypeUnbond) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, undelegateArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - undelegations = s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(undelegations).To(HaveLen(1), "expected one undelegation") - Expect(undelegations[0].ValidatorAddress).To(Equal(valAddr.String()), "expected validator address to be %s", valAddr) - }) - - It("should not undelegate if the amount exceeds the delegation", func() { - undelegateArgs := defaultUndelegateArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(2e18), - ) - - logCheckArgs := defaultLogCheck.WithErrContains("invalid shares amount") - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, undelegateArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - Expect(err.Error()).To(ContainSubstring("invalid shares amount")) - }) - - It("should not undelegate if the validator does not exist", func() { - nonExistingAddr := testutiltx.GenerateAddress() - nonExistingValAddr := sdk.ValAddress(nonExistingAddr.Bytes()) - - undelegateArgs := defaultUndelegateArgs.WithArgs( - s.address, nonExistingValAddr.String(), big.NewInt(1e18), - ) - - logCheckArgs := defaultLogCheck.WithErrContains("validator does not exist") - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, undelegateArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - Expect(err.Error()).To(ContainSubstring("validator does not exist")) - }) - }) - - Context("on behalf of another account", func() { - It("should not undelegate if delegator address is not the origin", func() { - differentAddr := testutiltx.GenerateAddress() - - undelegateArgs := defaultUndelegateArgs.WithArgs( - differentAddr, valAddr.String(), big.NewInt(1e18), - ) - - logCheckArgs := defaultLogCheck.WithErrContains( - fmt.Sprintf(staking.ErrDifferentOriginFromDelegator, s.address, differentAddr), - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, undelegateArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - }) - }) - }) - - Describe("to redelegate", func() { - // defaultRedelegateArgs are the default arguments for the redelegate call - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - var defaultRedelegateArgs contracts.CallArgs - - BeforeEach(func() { - defaultRedelegateArgs = defaultCallArgs.WithMethodName(staking.RedelegateMethod) - }) - - Context("as the token owner", func() { - It("should redelegate without need for authorization", func() { - redelegateArgs := defaultRedelegateArgs.WithArgs( - s.address, valAddr.String(), valAddr2.String(), big.NewInt(1e18), - ) - - logCheckArgs := passCheck. - WithExpEvents(staking.EventTypeRedelegate) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - redelegations := s.app.StakingKeeper.GetAllRedelegations(s.ctx, s.address.Bytes(), valAddr, valAddr2) - Expect(redelegations).To(HaveLen(1), "expected one redelegation to be found") - bech32Addr := sdk.AccAddress(s.address.Bytes()) - Expect(redelegations[0].DelegatorAddress).To(Equal(bech32Addr.String()), "expected delegator address to be %s", s.address) - Expect(redelegations[0].ValidatorSrcAddress).To(Equal(valAddr.String()), "expected source validator address to be %s", valAddr) - Expect(redelegations[0].ValidatorDstAddress).To(Equal(valAddr2.String()), "expected destination validator address to be %s", valAddr2) - }) - - It("should not redelegate if the amount exceeds the delegation", func() { - redelegateArgs := defaultRedelegateArgs.WithArgs( - s.address, valAddr.String(), valAddr2.String(), big.NewInt(2e18), - ) - - logCheckArgs := defaultLogCheck.WithErrContains("invalid shares amount") - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - Expect(err.Error()).To(ContainSubstring("invalid shares amount")) - }) - - It("should not redelegate if the validator does not exist", func() { - nonExistingAddr := testutiltx.GenerateAddress() - nonExistingValAddr := sdk.ValAddress(nonExistingAddr.Bytes()) - - redelegateArgs := defaultRedelegateArgs.WithArgs( - s.address, valAddr.String(), nonExistingValAddr.String(), big.NewInt(1e18), - ) - - logCheckArgs := defaultLogCheck.WithErrContains("redelegation destination validator not found") - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - Expect(err.Error()).To(ContainSubstring("redelegation destination validator not found")) - }) - }) - - Context("on behalf of another account", func() { - It("should not redelegate if delegator address is not the origin", func() { - differentAddr := testutiltx.GenerateAddress() - - redelegateArgs := defaultRedelegateArgs.WithArgs( - differentAddr, valAddr.String(), valAddr2.String(), big.NewInt(1e18), - ) - - logCheckArgs := defaultLogCheck.WithErrContains( - fmt.Sprintf(staking.ErrDifferentOriginFromDelegator, s.address, differentAddr), - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - }) - }) - }) - - Describe("to cancel an unbonding delegation", func() { - var ( - // defaultCancelUnbondingArgs are the default arguments for the cancelUnbondingDelegation call - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - defaultCancelUnbondingArgs contracts.CallArgs - - // expCreationHeight is the expected creation height of the unbonding delegation - expCreationHeight = int64(3) - ) - - BeforeEach(func() { - defaultCancelUnbondingArgs = defaultCallArgs.WithMethodName(staking.CancelUnbondingDelegationMethod) - - // Set up an unbonding delegation - undelegateArgs := defaultCallArgs. - WithMethodName(staking.UndelegateMethod). - WithArgs(s.address, valAddr.String(), big.NewInt(1e18)) - - logCheckArgs := passCheck. - WithExpEvents(staking.EventTypeUnbond) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, undelegateArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while setting up an unbonding delegation: %v", err) - - s.NextBlock() - - // Check that the unbonding delegation was created - unbondingDelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(unbondingDelegations).To(HaveLen(1), "expected one unbonding delegation to be found") - Expect(unbondingDelegations[0].DelegatorAddress).To(Equal(sdk.AccAddress(s.address.Bytes()).String()), "expected delegator address to be %s", s.address) - Expect(unbondingDelegations[0].ValidatorAddress).To(Equal(valAddr.String()), "expected validator address to be %s", valAddr) - Expect(unbondingDelegations[0].Entries).To(HaveLen(1), "expected one unbonding delegation entry to be found") - Expect(unbondingDelegations[0].Entries[0].CreationHeight).To(Equal(expCreationHeight), "expected different creation height") - Expect(unbondingDelegations[0].Entries[0].Balance).To(Equal(math.NewInt(1e18)), "expected different balance") - }) - - Context("as the token owner", func() { - It("should cancel unbonding delegation", func() { - delegations := s.app.StakingKeeper.GetValidatorDelegations(s.ctx, s.validators[0].GetOperator()) - Expect(delegations).To(HaveLen(0)) - - cArgs := defaultCancelUnbondingArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(1e18), big.NewInt(expCreationHeight), - ) - - logCheckArgs := passCheck. - WithExpEvents(staking.EventTypeCancelUnbondingDelegation) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, cArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - unbondingDelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(unbondingDelegations).To(HaveLen(0), "expected unbonding delegation to be canceled") - - delegations = s.app.StakingKeeper.GetValidatorDelegations(s.ctx, s.validators[0].GetOperator()) - Expect(delegations).To(HaveLen(1), "expected one delegation to be found") - }) - - It("should not cancel an unbonding delegation if the amount is not correct", func() { - cArgs := defaultCancelUnbondingArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(2e18), big.NewInt(expCreationHeight), - ) - - logCheckArgs := defaultLogCheck.WithErrContains("amount is greater than the unbonding delegation entry balance") - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, cArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - Expect(err.Error()).To(ContainSubstring("amount is greater than the unbonding delegation entry balance")) - - unbondingDelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(unbondingDelegations).To(HaveLen(1), "expected unbonding delegation not to have been canceled") - }) - - It("should not cancel an unbonding delegation if the creation height is not correct", func() { - cArgs := defaultCancelUnbondingArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(1e18), big.NewInt(expCreationHeight+1), - ) - - logCheckArgs := defaultLogCheck.WithErrContains("unbonding delegation entry is not found at block height") - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, cArgs, logCheckArgs) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - Expect(err.Error()).To(ContainSubstring("unbonding delegation entry is not found at block height")) - - unbondingDelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(unbondingDelegations).To(HaveLen(1), "expected unbonding delegation not to have been canceled") - }) - }) - }) - - Describe("to query allowance", func() { - var ( - defaultAllowanceArgs contracts.CallArgs - - differentAddr = testutiltx.GenerateAddress() - ) - - BeforeEach(func() { - defaultAllowanceArgs = defaultCallArgs.WithMethodName(authorization.AllowanceMethod) - }) - - It("should return an empty allowance if none is set", func() { - allowanceArgs := defaultAllowanceArgs.WithArgs( - s.address, differentAddr, staking.CancelUnbondingDelegationMsg, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, allowanceArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var allowanceInt *big.Int - err = s.precompile.UnpackIntoInterface(&allowanceInt, "allowance", ethRes.Ret) - Expect(err).To(BeNil(), "error while unmarshalling the allowance: %v", err) - Expect(allowanceInt.Int64()).To(BeZero(), "expected allowance to be zero") - }) - - It("should return the granted allowance if set", func() { - // setup approval for another address - s.SetupApproval( - s.privKey, differentAddr, big.NewInt(1e18), []string{staking.CancelUnbondingDelegationMsg}, - ) - - // query allowance - allowanceArgs := defaultAllowanceArgs.WithArgs( - differentAddr, s.address, staking.CancelUnbondingDelegationMsg, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, allowanceArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var allowanceInt *big.Int - err = s.precompile.UnpackIntoInterface(&allowanceInt, "allowance", ethRes.Ret) - Expect(err).To(BeNil(), "error while unmarshalling the allowance: %v", err) - Expect(allowanceInt).To(Equal(big.NewInt(1e18)), "expected allowance to be 1e18") - }) - }) - - Describe("Validator queries", func() { - // defaultValidatorArgs are the default arguments for the validator call - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - var defaultValidatorArgs contracts.CallArgs - - BeforeEach(func() { - defaultValidatorArgs = defaultCallArgs.WithMethodName(staking.ValidatorMethod) - }) - - It("should return validator", func() { - validatorArgs := defaultValidatorArgs.WithArgs( - valAddr.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var valOut staking.ValidatorOutput - err = s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - Expect(valOut.Validator.OperatorAddress).To(Equal(valAddr.String()), "expected validator address to match") - Expect(valOut.Validator.DelegatorShares).To(Equal(big.NewInt(1e18)), "expected different delegator shares") - }) - - It("should return an empty validator if the validator is not found", func() { - newValAddr := sdk.ValAddress(testutiltx.GenerateAddress().Bytes()) - validatorArgs := defaultValidatorArgs.WithArgs( - newValAddr.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var valOut staking.ValidatorOutput - err = s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - Expect(valOut.Validator.OperatorAddress).To(Equal(""), "expected validator address to be empty") - Expect(valOut.Validator.Status).To(BeZero(), "expected unspecified bonding status") - }) - }) - - Describe("Validators queries", func() { - var defaultValidatorArgs contracts.CallArgs - - BeforeEach(func() { - defaultValidatorArgs = defaultCallArgs.WithMethodName(staking.ValidatorsMethod) - }) - - It("should return validators (default pagination)", func() { - validatorArgs := defaultValidatorArgs.WithArgs( - stakingtypes.Bonded.String(), - query.PageRequest{}, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var valOut staking.ValidatorsOutput - err = s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorsMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - - Expect(valOut.PageResponse.NextKey).To(BeEmpty()) - Expect(valOut.PageResponse.Total).To(Equal(uint64(len(s.validators)))) - - Expect(valOut.Validators).To(HaveLen(len(s.validators)), "expected two validators to be returned") - // return order can change, that's why each validator is checked individually - for _, val := range valOut.Validators { - s.CheckValidatorOutput(val) - } - }) - - //nolint:dupl // this is a duplicate of the test for smart contract calls to the precompile - It("should return validators w/pagination limit = 1", func() { - const limit uint64 = 1 - validatorArgs := defaultValidatorArgs.WithArgs( - stakingtypes.Bonded.String(), - query.PageRequest{ - Limit: limit, - CountTotal: true, - }, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var valOut staking.ValidatorsOutput - err = s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorsMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - - // no pagination, should return default values - Expect(valOut.PageResponse.NextKey).NotTo(BeEmpty()) - Expect(valOut.PageResponse.Total).To(Equal(uint64(len(s.validators)))) - - Expect(valOut.Validators).To(HaveLen(int(limit)), "expected one validator to be returned") - - // return order can change, that's why each validator is checked individually - for _, val := range valOut.Validators { - s.CheckValidatorOutput(val) - } - }) - - It("should return an error if the bonding type is not known", func() { - validatorArgs := defaultValidatorArgs.WithArgs( - "15", // invalid bonding type - query.PageRequest{}, - ) - - invalidStatusCheck := defaultLogCheck.WithErrContains("invalid validator status 15") - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorArgs, invalidStatusCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - Expect(err.Error()).To(ContainSubstring("invalid validator status 15")) - }) - - It("should return an empty array if there are no validators with the given bonding type", func() { - validatorArgs := defaultValidatorArgs.WithArgs( - stakingtypes.Unbonded.String(), - query.PageRequest{}, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var valOut staking.ValidatorsOutput - err = s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorsMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - - Expect(valOut.PageResponse.NextKey).To(BeEmpty()) - Expect(valOut.PageResponse.Total).To(Equal(uint64(0))) - Expect(valOut.Validators).To(HaveLen(0), "expected no validators to be returned") - }) - }) - - Describe("Delegation queries", func() { - var defaultDelegationArgs contracts.CallArgs - - BeforeEach(func() { - defaultDelegationArgs = defaultCallArgs.WithMethodName(staking.DelegationMethod) - }) - - It("should return a delegation if it is found", func() { - delegationArgs := defaultDelegationArgs.WithArgs( - s.address, - valAddr.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, delegationArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var delOut staking.DelegationOutput - err = s.precompile.UnpackIntoInterface(&delOut, staking.DelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the delegation output: %v", err) - Expect(delOut.Shares).To(Equal(big.NewInt(1e18)), "expected different shares") - Expect(delOut.Balance).To(Equal(cmn.Coin{Denom: s.bondDenom, Amount: big.NewInt(1e18)}), "expected different shares") - }) - - It("should return an empty delegation if it is not found", func() { - newValAddr := sdk.ValAddress(testutiltx.GenerateAddress().Bytes()) - delegationArgs := defaultDelegationArgs.WithArgs( - s.address, newValAddr.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, delegationArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var delOut staking.DelegationOutput - err = s.precompile.UnpackIntoInterface(&delOut, staking.DelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the delegation output: %v", err) - Expect(delOut.Shares.Int64()).To(BeZero(), "expected no shares") - Expect(delOut.Balance.Denom).To(Equal(s.bondDenom), "expected different denomination") - Expect(delOut.Balance.Amount.Int64()).To(BeZero(), "expected a zero amount") - }) - }) - - Describe("UnbondingDelegation queries", func() { - var ( - defaultUnbondingDelegationArgs contracts.CallArgs - - // undelAmount is the amount of tokens to be unbonded - undelAmount = big.NewInt(1e17) - ) - - BeforeEach(func() { - defaultUnbondingDelegationArgs = defaultCallArgs.WithMethodName(staking.UnbondingDelegationMethod) - - // unbond a delegation - s.SetupApproval(s.privKey, s.precompile.Address(), abi.MaxUint256, []string{staking.UndelegateMsg}) - - unbondArgs := defaultCallArgs. - WithMethodName(staking.UndelegateMethod). - WithArgs(s.address, valAddr.String(), undelAmount) - unbondCheck := passCheck.WithExpEvents(staking.EventTypeUnbond) - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, unbondArgs, unbondCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - // check that the unbonding delegation exists - unbondingDelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(unbondingDelegations).To(HaveLen(1), "expected one unbonding delegation") - }) - - It("should return an unbonding delegation if it is found", func() { - unbondingDelegationsArgs := defaultUnbondingDelegationArgs.WithArgs( - s.address, - valAddr.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, unbondingDelegationsArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var unbondingDelegationOutput staking.UnbondingDelegationOutput - err = s.precompile.UnpackIntoInterface(&unbondingDelegationOutput, staking.UnbondingDelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the unbonding delegation output: %v", err) - Expect(unbondingDelegationOutput.UnbondingDelegation.Entries).To(HaveLen(1), "expected one unbonding delegation entry") - // TODO: why are initial balance and balance the same always? - Expect(unbondingDelegationOutput.UnbondingDelegation.Entries[0].InitialBalance).To(Equal(undelAmount), "expected different initial balance") - Expect(unbondingDelegationOutput.UnbondingDelegation.Entries[0].Balance).To(Equal(undelAmount), "expected different balance") - }) - - It("should return an empty slice if the unbonding delegation is not found", func() { - unbondingDelegationsArgs := defaultUnbondingDelegationArgs.WithArgs( - s.address, - valAddr2.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, unbondingDelegationsArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var unbondingDelegationOutput staking.UnbondingDelegationOutput - err = s.precompile.UnpackIntoInterface(&unbondingDelegationOutput, staking.UnbondingDelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the unbonding delegation output: %v", err) - Expect(unbondingDelegationOutput.UnbondingDelegation.Entries).To(HaveLen(0), "expected one unbonding delegation entry") - }) - }) - - Describe("to query a redelegation", func() { - var defaultRedelegationArgs contracts.CallArgs - - BeforeEach(func() { - defaultRedelegationArgs = defaultCallArgs.WithMethodName(staking.RedelegationMethod) - }) - - It("should return the redelegation if it exists", func() { - // approve the redelegation - s.SetupApproval(s.privKey, s.precompile.Address(), abi.MaxUint256, []string{staking.RedelegateMsg}) - - // create a redelegation - redelegateArgs := defaultCallArgs. - WithMethodName(staking.RedelegateMethod). - WithArgs(s.address, valAddr.String(), valAddr2.String(), big.NewInt(1e17)) - - redelegateCheck := passCheck.WithExpEvents(staking.EventTypeRedelegate) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, redelegateCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - // query the redelegation - redelegationArgs := defaultRedelegationArgs.WithArgs( - s.address, - valAddr.String(), - valAddr2.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegationArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var redelegationOutput staking.RedelegationOutput - err = s.precompile.UnpackIntoInterface(&redelegationOutput, staking.RedelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the redelegation output: %v", err) - Expect(redelegationOutput.Redelegation.Entries).To(HaveLen(1), "expected one redelegation entry") - Expect(redelegationOutput.Redelegation.Entries[0].InitialBalance).To(Equal(big.NewInt(1e17)), "expected different initial balance") - Expect(redelegationOutput.Redelegation.Entries[0].SharesDst).To(Equal(big.NewInt(1e17)), "expected different balance") - }) - - It("should return an empty output if the redelegation is not found", func() { - redelegationArgs := defaultRedelegationArgs.WithArgs( - s.address, - valAddr.String(), - valAddr2.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegationArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var redelegationOutput staking.RedelegationOutput - err = s.precompile.UnpackIntoInterface(&redelegationOutput, staking.RedelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the redelegation output: %v", err) - Expect(redelegationOutput.Redelegation.Entries).To(HaveLen(0), "expected no redelegation entries") - }) - }) - - Describe("Redelegations queries", func() { - var ( - // defaultRedelegationsArgs are the default arguments for the redelegations query - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - defaultRedelegationsArgs contracts.CallArgs - - // delAmt is the amount of tokens to be delegated - delAmt = big.NewInt(3e17) - // redelTotalCount is the total number of redelegations - redelTotalCount uint64 = 1 - ) - - BeforeEach(func() { - defaultRedelegationsArgs = defaultCallArgs.WithMethodName(staking.RedelegationsMethod) - // create some redelegations - s.SetupApproval( - s.privKey, s.precompile.Address(), abi.MaxUint256, []string{staking.RedelegateMsg}, - ) - - defaultRedelegateArgs := defaultCallArgs.WithMethodName(staking.RedelegateMethod) - redelegationsArgs := []contracts.CallArgs{ - defaultRedelegateArgs.WithArgs( - s.address, valAddr.String(), valAddr2.String(), delAmt, - ), - defaultRedelegateArgs.WithArgs( - s.address, valAddr.String(), valAddr2.String(), delAmt, - ), - } - - logCheckArgs := passCheck. - WithExpEvents(staking.EventTypeRedelegate) - - for _, args := range redelegationsArgs { - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, args, logCheckArgs) - Expect(err).To(BeNil(), "error while creating redelegation: %v", err) - } - }) - - It("should return all redelegations for delegator (default pagination)", func() { - redelegationArgs := defaultRedelegationsArgs.WithArgs( - s.address, - "", - "", - query.PageRequest{}, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegationArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var redelOut staking.RedelegationsOutput - err = s.precompile.UnpackIntoInterface(&redelOut, staking.RedelegationsMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - - Expect(redelOut.PageResponse.NextKey).To(BeEmpty()) - Expect(redelOut.PageResponse.Total).To(Equal(redelTotalCount)) - - Expect(redelOut.Response).To(HaveLen(int(redelTotalCount)), "expected two redelegations to be returned") - // return order can change - redOrder := []int{0, 1} - if len(redelOut.Response[0].Entries) == 2 { - redOrder = []int{1, 0} - } - - for i, r := range redelOut.Response { - Expect(r.Entries).To(HaveLen(redOrder[i] + 1)) - } - }) - - It("should return all redelegations for delegator w/pagination", func() { - // make 2 queries - // 1st one with pagination limit = 1 - // 2nd using the next page key - var nextPageKey []byte - for i := 0; i < 2; i++ { - var pagination query.PageRequest - if nextPageKey == nil { - pagination.Limit = 1 - pagination.CountTotal = true - } else { - pagination.Key = nextPageKey - } - redelegationArgs := defaultRedelegationsArgs.WithArgs( - s.address, - "", - "", - pagination, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegationArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var redelOut staking.RedelegationsOutput - err = s.precompile.UnpackIntoInterface(&redelOut, staking.RedelegationsMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - - if nextPageKey == nil { - nextPageKey = redelOut.PageResponse.NextKey - Expect(redelOut.PageResponse.Total).To(Equal(redelTotalCount)) - } else { - Expect(redelOut.PageResponse.NextKey).To(BeEmpty()) - Expect(redelOut.PageResponse.Total).To(Equal(uint64(1))) - } - - Expect(redelOut.Response).To(HaveLen(1), "expected two redelegations to be returned") - // return order can change - redOrder := []int{0, 1} - if len(redelOut.Response[0].Entries) == 2 { - redOrder = []int{1, 0} - } - - for i, r := range redelOut.Response { - Expect(r.Entries).To(HaveLen(redOrder[i] + 1)) - } - } - }) - - It("should return an empty array if no redelegation is found for the given source validator", func() { - // NOTE: the way that the functionality is implemented in the Cosmos SDK, the following combinations are - // possible (see https://github.com/evmos/cosmos-sdk/blob/e773cf768844c87245d0c737cda1893a2819dd89/x/staking/keeper/querier.go#L361-L373): - // - // - delegator is NOT empty, source validator is empty, destination validator is empty - // --> filtering for all redelegations of the given delegator - // - delegator is empty, source validator is NOT empty, destination validator is empty - // --> filtering for all redelegations with the given source validator - // - delegator is NOT empty, source validator is NOT empty, destination validator is NOT empty - // --> filtering for all redelegations with the given combination of delegator, source and destination validator - redelegationsArgs := defaultRedelegationsArgs.WithArgs( - common.Address{}, // passing in an empty address to filter for all redelegations from valAddr2 - valAddr2.String(), - "", - query.PageRequest{}, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegationsArgs, passCheck) - Expect(err).To(BeNil(), "expected error while calling the smart contract") - - var redelOut staking.RedelegationsOutput - err = s.precompile.UnpackIntoInterface(&redelOut, staking.RedelegationsMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - - Expect(redelOut.PageResponse.NextKey).To(BeEmpty()) - Expect(redelOut.PageResponse.Total).To(BeZero(), "expected no redelegations to be returned") - - Expect(redelOut.Response).To(HaveLen(0), "expected no redelegations to be returned") - }) - }) - - It("Should refund leftover gas", func() { - balancePre := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - gasPrice := big.NewInt(1e9) - - // Call the precompile with a lot of gas - approveArgs := defaultApproveArgs. - WithGasPrice(gasPrice). - WithArgs(s.precompile.Address(), big.NewInt(1e18), []string{staking.DelegateMsg}) - - approvalCheck := passCheck.WithExpEvents(authorization.EventTypeApproval) - - res, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, approveArgs, approvalCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - s.NextBlock() - - balancePost := s.app.BankKeeper.GetBalance(s.ctx, s.address.Bytes(), s.bondDenom) - difference := balancePre.Sub(balancePost) - - // NOTE: the expected difference is the gas price multiplied by the gas used, because the rest should be refunded - expDifference := gasPrice.Int64() * res.GasUsed - Expect(difference.Amount.Int64()).To(Equal(expDifference), "expected different total transaction cost") - }) -}) - -var _ = Describe("Calling staking precompile via Solidity", func() { - var ( - // contractAddr is the address of the smart contract that will be deployed - contractAddr common.Address - - // approvalCheck is a configuration for the log checker to see if an approval event was emitted. - approvalCheck testutil.LogCheckArgs - // execRevertedCheck defines the default log checking arguments which include the - // standard revert message - execRevertedCheck testutil.LogCheckArgs - // err is a basic error type - err error - - // nonExistingAddr is an address that does not exist in the state of the test suite - nonExistingAddr = testutiltx.GenerateAddress() - // nonExistingVal is a validator address that does not exist in the state of the test suite - nonExistingVal = sdk.ValAddress(nonExistingAddr.Bytes()) - ) - - BeforeEach(func() { - s.SetupTest() - contractAddr, err = s.DeployContract(testdata.StakingCallerContract) - Expect(err).To(BeNil(), "error while deploying the smart contract: %v", err) - valAddr = s.validators[0].GetOperator() - valAddr2 = s.validators[1].GetOperator() - - s.NextBlock() - - // check contract was correctly deployed - cAcc := s.app.EvmKeeper.GetAccount(s.ctx, contractAddr) - Expect(cAcc).ToNot(BeNil(), "contract account should exist") - Expect(cAcc.IsContract()).To(BeTrue(), "account should be a contract") - - // populate default call args - defaultCallArgs = contracts.CallArgs{ - ContractAddr: contractAddr, - ContractABI: testdata.StakingCallerContract.ABI, - PrivKey: s.privKey, - } - // populate default approval args - defaultApproveArgs = defaultCallArgs.WithMethodName("testApprove") - - // populate default log check args - defaultLogCheck = testutil.LogCheckArgs{ - ABIEvents: s.precompile.Events, - } - execRevertedCheck = defaultLogCheck.WithErrContains(vm.ErrExecutionReverted.Error()) - passCheck = defaultLogCheck.WithExpPass(true) - approvalCheck = passCheck.WithExpEvents(authorization.EventTypeApproval) - }) - - Describe("when the precompile is not enabled in the EVM params", func() { - It("should return an error", func() { - // disable the precompile - params := s.app.EvmKeeper.GetParams(s.ctx) - var activePrecompiles []string - for _, precompile := range params.ActivePrecompiles { - if precompile != s.precompile.Address().String() { - activePrecompiles = append(activePrecompiles, precompile) - } - } - params.ActivePrecompiles = activePrecompiles - err := s.app.EvmKeeper.SetParams(s.ctx, params) - Expect(err).To(BeNil(), "error while setting params") - - // try to call the precompile - delegateArgs := defaultCallArgs. - WithMethodName("testDelegate"). - WithArgs( - s.address, valAddr.String(), big.NewInt(2e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, delegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "expected error while calling the precompile") - Expect(err.Error()).To(ContainSubstring(vm.ErrExecutionReverted.Error())) - }) - }) - - Context("approving methods", func() { - Context("with valid input", func() { - It("should approve one method", func() { - approvalArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.DelegateMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(approvalArgs) - }) - - It("should approve all methods", func() { - approvalArgs := defaultApproveArgs. - WithGasLimit(1e8). - WithArgs( - contractAddr, - []string{staking.DelegateMsg, staking.RedelegateMsg, staking.UndelegateMsg, staking.CancelUnbondingDelegationMsg}, - big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(approvalArgs) - }) - - It("should update a previous approval", func() { - approvalArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.DelegateMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(approvalArgs) - - s.NextBlock() - - // update approval - approvalArgs = defaultApproveArgs.WithArgs( - contractAddr, []string{staking.DelegateMsg}, big.NewInt(2e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, approvalArgs, approvalCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - // check approvals - authorization, expirationTime := s.CheckAuthorization(staking.DelegateAuthz, contractAddr, s.address) - Expect(authorization).ToNot(BeNil(), "expected authorization to not be nil") - Expect(expirationTime).ToNot(BeNil(), "expected expiration time to not be nil") - Expect(authorization.MsgTypeURL()).To(Equal(staking.DelegateMsg), "expected authorization msg type url to be %s", staking.DelegateMsg) - Expect(authorization.MaxTokens.Amount).To(Equal(math.NewInt(2e18)), "expected different max tokens after updated approval") - }) - - It("should remove approval when setting amount to zero", func() { - s.SetupApprovalWithContractCalls( - defaultApproveArgs.WithArgs(contractAddr, []string{staking.DelegateMsg}, big.NewInt(1e18)), - ) - - s.NextBlock() - - // check approvals pre-removal - allAuthz, err := s.app.AuthzKeeper.GetAuthorizations(s.ctx, contractAddr.Bytes(), s.address.Bytes()) - Expect(err).To(BeNil(), "error while reading authorizations") - Expect(allAuthz).To(HaveLen(1), "expected no authorizations") - - approveArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.DelegateMsg}, big.NewInt(0), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, approveArgs, approvalCheck) - Expect(err).To(BeNil(), "error while calling the smart contract") - - // check approvals after approving with amount 0 - allAuthz, err = s.app.AuthzKeeper.GetAuthorizations(s.ctx, contractAddr.Bytes(), s.address.Bytes()) - Expect(err).To(BeNil(), "error while reading authorizations") - Expect(allAuthz).To(HaveLen(0), "expected no authorizations") - }) - - It("should not approve if the gas is not enough", func() { - approveArgs := defaultApproveArgs. - WithGasLimit(1e5). - WithArgs( - contractAddr, - []string{ - staking.DelegateMsg, - staking.UndelegateMsg, - staking.RedelegateMsg, - staking.CancelUnbondingDelegationMsg, - }, - big.NewInt(1e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, approveArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract") - }) - }) - - Context("with invalid input", func() { - // TODO: enable once we check that origin is not the sender - // It("shouldn't approve any methods for if the sender is the origin", func() { - // approveArgs := defaultApproveArgs.WithArgs( - // nonExistingAddr, []string{staking.DelegateMsg}, big.NewInt(1e18), - // ) - // - // _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, approveArgs, execRevertedCheck) - // Expect(err).To(BeNil(), "error while calling the smart contract") - // - // // check approvals - // allAuthz, err := s.app.AuthzKeeper.GetAuthorizations(s.ctx, contractAddr.Bytes(), s.address.Bytes()) - // Expect(err).To(BeNil(), "error while reading authorizations") - // Expect(allAuthz).To(HaveLen(0), "expected no authorizations") - // }) - - It("shouldn't approve for invalid methods", func() { - approveArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{"invalid method"}, big.NewInt(1e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, approveArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract") - - // check approvals - allAuthz, err := s.app.AuthzKeeper.GetAuthorizations(s.ctx, contractAddr.Bytes(), s.address.Bytes()) - Expect(err).To(BeNil(), "error while reading authorizations") - Expect(allAuthz).To(HaveLen(0), "expected no authorizations") - }) - }) - }) - - Context("to revoke an approval", func() { - var defaultRevokeArgs contracts.CallArgs - - BeforeEach(func() { - defaultRevokeArgs = defaultCallArgs.WithMethodName("testRevoke") - }) - - It("should revoke when sending as the granter", func() { - // set up an approval to be revoked - cArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.DelegateMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(cArgs) - - s.NextBlock() - - revokeArgs := defaultRevokeArgs.WithArgs(contractAddr, []string{staking.DelegateMsg}) - - revocationCheck := passCheck.WithExpEvents(authorization.EventTypeRevocation) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, revokeArgs, revocationCheck) - Expect(err).To(BeNil(), "error while calling the smart contract") - - // check approvals - authz, _ := s.CheckAuthorization(staking.DelegateAuthz, contractAddr, s.address) - Expect(authz).To(BeNil(), "expected authorization to be revoked") - }) - - It("should not revoke when approval is issued by a different granter", func() { - // Create a delegate authorization where the granter is a different account from the default test suite one - createdAuthz := staking.DelegateAuthz - granteeAddr := testutiltx.GenerateAddress() - granterAddr := testutiltx.GenerateAddress() - validators := s.app.StakingKeeper.GetLastValidators(s.ctx) - valAddrs := make([]sdk.ValAddress, len(validators)) - for i, val := range validators { - valAddrs[i] = val.GetOperator() - } - delegationAuthz, err := stakingtypes.NewStakeAuthorization( - valAddrs, - nil, - createdAuthz, - &sdk.Coin{Denom: sdk.DefaultBondDenom, Amount: math.NewInt(1e18)}, - ) - Expect(err).To(BeNil(), "failed to create authorization") - - expiration := s.ctx.BlockTime().Add(time.Hour * 24 * 365).UTC() - err = s.app.AuthzKeeper.SaveGrant(s.ctx, granteeAddr.Bytes(), granterAddr.Bytes(), delegationAuthz, &expiration) - Expect(err).ToNot(HaveOccurred(), "failed to save authorization") - authz, _ := s.CheckAuthorization(createdAuthz, granteeAddr, granterAddr) - Expect(authz).ToNot(BeNil(), "expected authorization to be created") - - revokeArgs := defaultRevokeArgs.WithArgs(granteeAddr, []string{staking.DelegateMsg}) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, revokeArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract") - - // check approvals - authz, _ = s.CheckAuthorization(createdAuthz, granteeAddr, granterAddr) - Expect(authz).ToNot(BeNil(), "expected authorization not to be revoked") - }) - - It("should revert the execution when no approval is found", func() { - revokeArgs := defaultRevokeArgs.WithArgs(contractAddr, []string{staking.DelegateMsg}) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, revokeArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract") - - // check approvals - authz, _ := s.CheckAuthorization(staking.DelegateAuthz, contractAddr, s.address) - Expect(authz).To(BeNil(), "expected no authorization to be found") - }) - - It("should not revoke if the approval is for a different message type", func() { - // set up an approval - cArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.DelegateMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(cArgs) - - s.NextBlock() - - revokeArgs := defaultRevokeArgs.WithArgs(contractAddr, []string{staking.UndelegateMsg}) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, revokeArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract") - - // check approval is still there - s.ExpectAuthorization( - staking.DelegateAuthz, - contractAddr, - s.address, - &sdk.Coin{Denom: s.bondDenom, Amount: math.NewInt(1e18)}, - ) - }) - }) - - Context("delegating", func() { - var ( - // prevDelegation is the delegation that is available prior to the test (an initial delegation is - // added in the test suite setup). - prevDelegation stakingtypes.Delegation - // defaultDelegateArgs are the default arguments for the delegate call - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - defaultDelegateArgs contracts.CallArgs - ) - - BeforeEach(func() { - // get the delegation that is available prior to the test - prevDelegation, _ = s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), valAddr) - - defaultDelegateArgs = defaultCallArgs.WithMethodName("testDelegate") - }) - - Context("without approval set", func() { - BeforeEach(func() { - authz, _ := s.CheckAuthorization(staking.DelegateAuthz, contractAddr, s.address) - Expect(authz).To(BeNil(), "expected authorization to be nil") - }) - - It("should not delegate", func() { - Expect(s.app.EvmKeeper.GetAccount(s.ctx, contractAddr)).ToNot(BeNil(), "expected contract to exist") - - cArgs := defaultDelegateArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(1e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, cArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - del, _ := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), valAddr) - Expect(del).To(Equal(prevDelegation), "no new delegation to be found") - }) - }) - - Context("with approval set", func() { - BeforeEach(func() { - cArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.DelegateMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(cArgs) - }) - - It("should delegate when not exceeding the allowance", func() { - cArgs := defaultDelegateArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(1e18), - ) - - logCheckArgs := passCheck. - WithExpEvents(staking.EventTypeDelegate) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, cArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - delegation, found := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), valAddr) - Expect(found).To(BeTrue(), "expected delegation to be found") - expShares := prevDelegation.GetShares().Add(math.LegacyNewDec(1)) - Expect(delegation.GetShares()).To(Equal(expShares), "expected delegation shares to be 2") - }) - - It("should not delegate when exceeding the allowance", func() { - cArgs := defaultDelegateArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(2e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, cArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - del, _ := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), valAddr) - Expect(del).To(Equal(prevDelegation), "no new delegation to be found") - }) - - It("should not delegate when sending from a different address", func() { - newAddr, newPriv := testutiltx.NewAccAddressAndKey() - err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, newAddr, 1e18) - Expect(err).To(BeNil(), "error while funding account: %v", err) - - s.NextBlock() - - delegateArgs := defaultDelegateArgs. - WithPrivKey(newPriv). - WithArgs(s.address, valAddr.String(), big.NewInt(1e18)) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, delegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - del, _ := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), valAddr) - Expect(del).To(Equal(prevDelegation), "no new delegation to be found") - }) - - It("should not delegate when validator does not exist", func() { - delegateArgs := defaultDelegateArgs.WithArgs( - s.address, nonExistingVal.String(), big.NewInt(1e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, delegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - del, _ := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), nonExistingVal) - Expect(del).To(BeZero(), "expected no delegation to be found") - }) - - It("shouldn't delegate to a validator that is not in the allow list of the approval", func() { - // create a new validator, which is not included in the active set of the last block - testutil.CreateValidator(s.ctx, s.T(), s.privKey.PubKey(), s.app.StakingKeeper, math.NewInt(100)) - newValAddr := sdk.ValAddress(s.address.Bytes()) - - delegateArgs := defaultDelegateArgs.WithArgs( - s.address, newValAddr.String(), big.NewInt(2e18), - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, delegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - delegation, _ := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), newValAddr) - Expect(delegation.GetShares()).To(Equal(math.LegacyNewDecFromInt(math.NewInt(100))), "expected only the delegation from creating the validator, no more") - }) - }) - }) - - Context("unbonding", func() { - // NOTE: there's no additional setup necessary because the test suite is already set up with - // delegations to the validator - - // defaultUndelegateArgs are the default arguments for the undelegate call - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - var defaultUndelegateArgs contracts.CallArgs - - BeforeEach(func() { - defaultUndelegateArgs = defaultCallArgs.WithMethodName("testUndelegate") - }) - - Context("without approval set", func() { - BeforeEach(func() { - authz, _ := s.CheckAuthorization(staking.UndelegateAuthz, contractAddr, s.address) - Expect(authz).To(BeNil(), "expected authorization to be nil before test execution") - }) - It("should not undelegate", func() { - undelegateArgs := defaultUndelegateArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(1e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, undelegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - undelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(undelegations).To(HaveLen(0), "expected no undelegations to be found") - }) - }) - - Context("with approval set", func() { - BeforeEach(func() { - approveArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.UndelegateMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(approveArgs) - }) - - It("should undelegate when not exceeding the allowance", func() { - undelegateArgs := defaultUndelegateArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(1e18), - ) - - logCheckArgs := defaultLogCheck. - WithExpEvents(staking.EventTypeUnbond). - WithExpPass(true) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, undelegateArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - undelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(undelegations).To(HaveLen(1), "expected one undelegation") - Expect(undelegations[0].ValidatorAddress).To(Equal(valAddr.String()), "expected validator address to be %s", valAddr) - }) - - It("should not undelegate when exceeding the allowance", func() { - undelegateArgs := defaultUndelegateArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(2e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, undelegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - undelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(undelegations).To(HaveLen(0), "expected no undelegations to be found") - }) - - It("should not undelegate if the delegation does not exist", func() { - undelegateArgs := defaultUndelegateArgs.WithArgs( - s.address, nonExistingVal.String(), big.NewInt(1e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, undelegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - undelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(undelegations).To(HaveLen(0), "expected no undelegations to be found") - }) - - It("should not undelegate when called from a different address", func() { - newAddr, newPriv := testutiltx.NewAccAddressAndKey() - err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, newAddr, 1e18) - Expect(err).To(BeNil(), "error while funding account: %v", err) - - s.NextBlock() - - undelegateArgs := defaultUndelegateArgs. - WithPrivKey(newPriv). - WithArgs(s.address, valAddr.String(), big.NewInt(1e18)) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, undelegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - undelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(undelegations).To(HaveLen(0), "expected no undelegations to be found") - }) - }) - }) - - Context("redelegating", func() { - // NOTE: there's no additional setup necessary because the test suite is already set up with - // delegations to the validator - - // defaultRedelegateArgs are the default arguments for the redelegate call - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - var defaultRedelegateArgs contracts.CallArgs - - BeforeEach(func() { - defaultRedelegateArgs = defaultCallArgs.WithMethodName("testRedelegate") - }) - - Context("without approval set", func() { - BeforeEach(func() { - authz, _ := s.CheckAuthorization(staking.UndelegateAuthz, contractAddr, s.address) - Expect(authz).To(BeNil(), "expected authorization to be nil before test execution") - }) - - It("should not redelegate", func() { - redelegateArgs := defaultRedelegateArgs.WithArgs( - s.address, valAddr.String(), valAddr2.String(), big.NewInt(1e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - redelegations := s.app.StakingKeeper.GetAllRedelegations(s.ctx, s.address.Bytes(), valAddr, valAddr2) - Expect(redelegations).To(HaveLen(0), "expected no redelegations to be found") - }) - }) - - Context("with approval set", func() { - BeforeEach(func() { - approveArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.RedelegateMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(approveArgs) - }) - - It("should redelegate when not exceeding the allowance", func() { - redelegateArgs := defaultRedelegateArgs.WithArgs( - s.address, valAddr.String(), valAddr2.String(), big.NewInt(1e18), - ) - - logCheckArgs := defaultLogCheck. - WithExpEvents(staking.EventTypeRedelegate). - WithExpPass(true) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - redelegations := s.app.StakingKeeper.GetAllRedelegations(s.ctx, s.address.Bytes(), valAddr, valAddr2) - Expect(redelegations).To(HaveLen(1), "expected one redelegation to be found") - bech32Addr := sdk.AccAddress(s.address.Bytes()) - Expect(redelegations[0].DelegatorAddress).To(Equal(bech32Addr.String()), "expected delegator address to be %s", s.address) - Expect(redelegations[0].ValidatorSrcAddress).To(Equal(valAddr.String()), "expected source validator address to be %s", valAddr) - Expect(redelegations[0].ValidatorDstAddress).To(Equal(valAddr2.String()), "expected destination validator address to be %s", valAddr2) - }) - - It("should not redelegate when exceeding the allowance", func() { - redelegateArgs := defaultRedelegateArgs.WithArgs( - s.address, valAddr.String(), valAddr2.String(), big.NewInt(2e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - redelegations := s.app.StakingKeeper.GetAllRedelegations(s.ctx, s.address.Bytes(), valAddr, valAddr2) - Expect(redelegations).To(HaveLen(0), "expected no redelegations to be found") - }) - - It("should not redelegate if the delegation does not exist", func() { - redelegateArgs := defaultRedelegateArgs.WithArgs( - s.address, nonExistingVal.String(), valAddr2.String(), big.NewInt(1e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - redelegations := s.app.StakingKeeper.GetAllRedelegations(s.ctx, s.address.Bytes(), nonExistingVal, valAddr2) - Expect(redelegations).To(HaveLen(0), "expected no redelegations to be found") - }) - - It("should not redelegate when calling from a different address", func() { - newAddr, newPriv := testutiltx.NewAccAddressAndKey() - err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, newAddr, 1e18) - Expect(err).To(BeNil(), "error while funding account: %v", err) - - s.NextBlock() - - redelegateArgs := defaultRedelegateArgs. - WithPrivKey(newPriv). - WithArgs(s.address, valAddr.String(), valAddr2.String(), big.NewInt(1e18)) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - redelegations := s.app.StakingKeeper.GetAllRedelegations(s.ctx, s.address.Bytes(), valAddr, valAddr2) - Expect(redelegations).To(HaveLen(0), "expected no redelegations to be found") - }) - - It("should not redelegate when the validator does not exist", func() { - redelegateArgs := defaultRedelegateArgs.WithArgs( - s.address, valAddr.String(), nonExistingVal.String(), big.NewInt(1e18), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - redelegations := s.app.StakingKeeper.GetAllRedelegations(s.ctx, s.address.Bytes(), valAddr, nonExistingVal) - Expect(redelegations).To(HaveLen(0), "expected no redelegations to be found") - }) - }) - }) - - Context("canceling unbonding delegations", func() { - var ( - // defaultCancelUnbondingArgs are the default arguments for the cancelUnbondingDelegation call - // - // NOTE: this has to be set up in the BeforeEach block because the private key is only available then - defaultCancelUnbondingArgs contracts.CallArgs - - // expCreationHeight is the expected creation height of the unbonding delegation - expCreationHeight = int64(4) - ) - - BeforeEach(func() { - defaultCancelUnbondingArgs = defaultCallArgs.WithMethodName("testCancelUnbonding") - - // Set up an unbonding delegation - approvalArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.UndelegateMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(approvalArgs) - - s.NextBlock() - - undelegateArgs := defaultCallArgs. - WithMethodName("testUndelegate"). - WithArgs(s.address, valAddr.String(), big.NewInt(1e18)) - - logCheckArgs := defaultLogCheck. - WithExpEvents(staking.EventTypeUnbond). - WithExpPass(true) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, undelegateArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while setting up an unbonding delegation: %v", err) - - s.NextBlock() - - // Check that the unbonding delegation was created - unbondingDelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(unbondingDelegations).To(HaveLen(1), "expected one unbonding delegation to be found") - Expect(unbondingDelegations[0].DelegatorAddress).To(Equal(sdk.AccAddress(s.address.Bytes()).String()), "expected delegator address to be %s", s.address) - Expect(unbondingDelegations[0].ValidatorAddress).To(Equal(valAddr.String()), "expected validator address to be %s", valAddr) - Expect(unbondingDelegations[0].Entries).To(HaveLen(1), "expected one unbonding delegation entry to be found") - Expect(unbondingDelegations[0].Entries[0].CreationHeight).To(Equal(expCreationHeight), "expected different creation height") - Expect(unbondingDelegations[0].Entries[0].Balance).To(Equal(math.NewInt(1e18)), "expected different balance") - }) - - Context("without approval set", func() { - It("should not cancel unbonding delegations", func() { - cArgs := defaultCancelUnbondingArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(1e18), big.NewInt(expCreationHeight), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, cArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - unbondingDelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(unbondingDelegations).To(HaveLen(1), "expected unbonding delegation not to be canceled") - }) - }) - - Context("with approval set", func() { - BeforeEach(func() { - // Set up an unbonding delegation - approvalArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.CancelUnbondingDelegationMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(approvalArgs) - - s.NextBlock() - }) - - It("should cancel unbonding delegations when not exceeding allowance", func() { - cArgs := defaultCancelUnbondingArgs.WithGasLimit(1e9).WithArgs( - s.address, valAddr.String(), big.NewInt(1e18), big.NewInt(expCreationHeight), - ) - - logCheckArgs := passCheck. - WithExpEvents(staking.EventTypeCancelUnbondingDelegation) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, cArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - unbondingDelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(unbondingDelegations).To(HaveLen(0), "expected unbonding delegation to be canceled") - }) - - It("should not cancel unbonding delegations when exceeding allowance", func() { - approvalArgs := defaultApproveArgs. - WithArgs(contractAddr, []string{staking.CancelUnbondingDelegationMsg}, big.NewInt(1)) - s.SetupApprovalWithContractCalls(approvalArgs) - - cArgs := defaultCancelUnbondingArgs.WithArgs( - s.address, valAddr.String(), big.NewInt(1e18), big.NewInt(expCreationHeight), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, cArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - unbondingDelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(unbondingDelegations).To(HaveLen(1), "expected unbonding delegation to not be canceled") - }) - - It("should not cancel unbonding any delegations when unbonding delegation does not exist", func() { - cancelArgs := defaultCancelUnbondingArgs.WithArgs( - s.address, nonExistingVal.String(), big.NewInt(1e18), big.NewInt(expCreationHeight), - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, cancelArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - unbondingDelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(unbondingDelegations).To(HaveLen(1), "expected unbonding delegation to not be canceled") - }) - - It("should not cancel unbonding delegations when calling from a different address", func() { - newAddr, newPriv := testutiltx.NewAccAddressAndKey() - err := evmosutil.FundAccountWithBaseDenom(s.ctx, s.app.BankKeeper, newAddr, 1e18) - Expect(err).To(BeNil(), "error while funding account: %v", err) - - s.NextBlock() - - cancelUnbondArgs := defaultCancelUnbondingArgs. - WithPrivKey(newPriv). - WithArgs(s.address, valAddr.String(), big.NewInt(1e18), big.NewInt(expCreationHeight)) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, cancelUnbondArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - unbondingDelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(unbondingDelegations).To(HaveLen(1), "expected unbonding delegation to not be canceled") - }) - }) - }) - - Context("querying allowance", func() { - // defaultAllowanceArgs are the default arguments for querying the allowance - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - var defaultAllowanceArgs contracts.CallArgs - - BeforeEach(func() { - defaultAllowanceArgs = defaultCallArgs.WithMethodName("getAllowance") - }) - - It("without approval set it should show no allowance", func() { - allowanceArgs := defaultAllowanceArgs.WithArgs( - contractAddr, staking.CancelUnbondingDelegationMsg, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, allowanceArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var allowanceInt *big.Int - err = s.precompile.UnpackIntoInterface(&allowanceInt, "allowance", ethRes.Ret) - Expect(err).To(BeNil(), "error while unmarshalling the allowance: %v", err) - Expect(allowanceInt.Int64()).To(Equal(int64(0)), "expected empty allowance") - }) - - It("with approval set it should show the granted allowance", func() { - // setup approval - approvalArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.CancelUnbondingDelegationMsg}, big.NewInt(1e18), - ) - - s.SetupApprovalWithContractCalls(approvalArgs) - - // query allowance - allowanceArgs := defaultAllowanceArgs.WithArgs( - contractAddr, staking.CancelUnbondingDelegationMsg, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, allowanceArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var allowanceInt *big.Int - err = s.precompile.UnpackIntoInterface(&allowanceInt, "allowance", ethRes.Ret) - Expect(err).To(BeNil(), "error while unmarshalling the allowance: %v", err) - Expect(allowanceInt).To(Equal(big.NewInt(1e18)), "expected allowance to be 1e18") - }) - }) - - Context("querying validator", func() { - // defaultValidatorArgs are the default arguments for querying the validator - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - var defaultValidatorArgs contracts.CallArgs - - BeforeEach(func() { - defaultValidatorArgs = defaultCallArgs.WithMethodName("getValidator") - }) - - It("with non-existing address should return an empty validator", func() { - validatorArgs := defaultValidatorArgs.WithArgs( - nonExistingVal.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var valOut staking.ValidatorOutput - err = s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - Expect(valOut.Validator.OperatorAddress).To(Equal(""), "expected empty validator address") - Expect(valOut.Validator.Status).To(Equal(uint8(0)), "expected validator status to be 0 (unspecified)") - }) - - It("with existing address should return the validator", func() { - validatorArgs := defaultValidatorArgs.WithArgs( - valAddr.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var valOut staking.ValidatorOutput - err = s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - Expect(valOut.Validator.OperatorAddress).To(Equal(valAddr.String()), "expected validator address to match") - Expect(valOut.Validator.DelegatorShares).To(Equal(big.NewInt(1e18)), "expected different delegator shares") - }) - - It("with status bonded and pagination", func() { - validatorArgs := defaultCallArgs. - WithMethodName("getValidators"). - WithArgs( - stakingtypes.Bonded.String(), - query.PageRequest{ - Limit: 1, - CountTotal: true, - }, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var valOut staking.ValidatorsOutput - err = s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorsMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - Expect(valOut.PageResponse.Total).To(Equal(uint64(len(s.validators)))) - Expect(valOut.PageResponse.NextKey).NotTo(BeEmpty()) - Expect(valOut.Validators[0].DelegatorShares).To(Equal(big.NewInt(1e18)), "expected different delegator shares") - }) - }) - - Context("querying validators", func() { - var defaultValidatorsArgs contracts.CallArgs - - BeforeEach(func() { - defaultValidatorsArgs = defaultCallArgs.WithMethodName("getValidators") - }) - - It("should return validators (default pagination)", func() { - validatorsArgs := defaultValidatorsArgs.WithArgs( - stakingtypes.Bonded.String(), - query.PageRequest{}, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorsArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var valOut staking.ValidatorsOutput - err = s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorsMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - Expect(valOut.PageResponse.Total).To(Equal(uint64(len(s.validators)))) - Expect(valOut.PageResponse.NextKey).To(BeEmpty()) - Expect(valOut.Validators).To(HaveLen(len(s.validators)), "expected all validators to be returned") - // return order can change, that's why each validator is checked individually - for _, val := range valOut.Validators { - s.CheckValidatorOutput(val) - } - }) - - //nolint:dupl // this is a duplicate of the test for EOA calls to the precompile - It("should return validators with pagination limit = 1", func() { - const limit uint64 = 1 - validatorArgs := defaultValidatorsArgs.WithArgs( - stakingtypes.Bonded.String(), - query.PageRequest{ - Limit: limit, - CountTotal: true, - }, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var valOut staking.ValidatorsOutput - err = s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorsMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - - // no pagination, should return default values - Expect(valOut.PageResponse.NextKey).NotTo(BeEmpty()) - Expect(valOut.PageResponse.Total).To(Equal(uint64(len(s.validators)))) - - Expect(valOut.Validators).To(HaveLen(int(limit)), "expected one validator to be returned") - - // return order can change, that's why each validator is checked individually - for _, val := range valOut.Validators { - s.CheckValidatorOutput(val) - } - }) - - It("should revert the execution if the bonding type is not known", func() { - validatorArgs := defaultValidatorsArgs.WithArgs( - "15", // invalid bonding type - query.PageRequest{}, - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - }) - - It("should return an empty array if there are no validators with the given bonding type", func() { - validatorArgs := defaultValidatorsArgs.WithArgs( - stakingtypes.Unbonded.String(), - query.PageRequest{}, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, validatorArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var valOut staking.ValidatorsOutput - err = s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorsMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the validator output: %v", err) - - Expect(valOut.PageResponse.NextKey).To(BeEmpty()) - Expect(valOut.PageResponse.Total).To(Equal(uint64(0))) - Expect(valOut.Validators).To(HaveLen(0), "expected no validators to be returned") - }) - }) - - Context("querying delegation", func() { - // defaultDelegationArgs are the default arguments for querying the delegation - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - var defaultDelegationArgs contracts.CallArgs - - BeforeEach(func() { - defaultDelegationArgs = defaultCallArgs.WithMethodName("getDelegation") - }) - - It("which does not exist should return an empty delegation", func() { - delegationArgs := defaultDelegationArgs.WithArgs( - nonExistingAddr, valAddr.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, delegationArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var delOut staking.DelegationOutput - err = s.precompile.UnpackIntoInterface(&delOut, staking.DelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the delegation output: %v", err) - Expect(delOut.Balance.Amount.Int64()).To(Equal(int64(0)), "expected a different delegation balance") - Expect(delOut.Balance.Denom).To(Equal("aevmos"), "expected a different delegation balance") - }) - - It("which exists should return the delegation", func() { - delegationArgs := defaultDelegationArgs.WithArgs( - s.address, valAddr.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, delegationArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var delOut staking.DelegationOutput - err = s.precompile.UnpackIntoInterface(&delOut, staking.DelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the delegation output: %v", err) - Expect(delOut.Balance).To(Equal( - cmn.Coin{Denom: "aevmos", Amount: big.NewInt(1e18)}), - "expected a different delegation balance", - ) - }) - }) - - Context("querying redelegation", func() { - // defaultRedelegationArgs are the default arguments for querying the redelegation - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - var defaultRedelegationArgs contracts.CallArgs - - BeforeEach(func() { - defaultRedelegationArgs = defaultCallArgs.WithMethodName("getRedelegation") - }) - - It("which does not exist should return an empty redelegation", func() { - redelegationArgs := defaultRedelegationArgs.WithArgs( - s.address, valAddr.String(), nonExistingVal.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegationArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var redOut staking.RedelegationOutput - err = s.precompile.UnpackIntoInterface(&redOut, staking.RedelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the redelegation output: %v", err) - Expect(redOut.Redelegation.Entries).To(HaveLen(0), "expected no redelegation entries") - }) - - It("which exists should return the redelegation", func() { - // set up approval - approvalArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.RedelegateMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(approvalArgs) - - s.NextBlock() - - // set up redelegation - redelegateArgs := defaultCallArgs. - WithMethodName("testRedelegate"). - WithArgs(s.address, valAddr.String(), valAddr2.String(), big.NewInt(1)) - - redelegateCheck := passCheck. - WithExpEvents(staking.EventTypeRedelegate) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, redelegateCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - // check that the redelegation was created - redelegations := s.app.StakingKeeper.GetAllRedelegations(s.ctx, s.address.Bytes(), valAddr, valAddr2) - Expect(redelegations).To(HaveLen(1), "expected one redelegation to be found") - bech32Addr := sdk.AccAddress(s.address.Bytes()) - Expect(redelegations[0].DelegatorAddress).To(Equal(bech32Addr.String()), "expected delegator address to be %s", s.address) - Expect(redelegations[0].ValidatorSrcAddress).To(Equal(valAddr.String()), "expected source validator address to be %s", valAddr) - Expect(redelegations[0].ValidatorDstAddress).To(Equal(valAddr2.String()), "expected destination validator address to be %s", valAddr2) - - // query redelegation - redelegationArgs := defaultRedelegationArgs.WithArgs( - s.address, valAddr.String(), valAddr2.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegationArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var redOut staking.RedelegationOutput - err = s.precompile.UnpackIntoInterface(&redOut, staking.RedelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the redelegation output: %v", err) - Expect(redOut.Redelegation.Entries).To(HaveLen(1), "expected one redelegation entry to be returned") - }) - }) - - Describe("query redelegations", func() { - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - var defaultRedelegationsArgs contracts.CallArgs - - BeforeEach(func() { - defaultRedelegationsArgs = defaultCallArgs.WithMethodName("getRedelegations") - }) - - It("which exists should return all the existing redelegations w/pagination", func() { - // set up approval - approvalArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.RedelegateMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(approvalArgs) - s.NextBlock() - - // set up redelegation - redelegateArgs := defaultCallArgs. - WithMethodName("testRedelegate"). - WithArgs(s.address, valAddr.String(), valAddr2.String(), big.NewInt(1)) - - redelegateCheck := passCheck. - WithExpEvents(staking.EventTypeRedelegate) - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegateArgs, redelegateCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - // check that the redelegation was created - redelegations := s.app.StakingKeeper.GetAllRedelegations(s.ctx, s.address.Bytes(), valAddr, valAddr2) - Expect(redelegations).To(HaveLen(1), "expected one redelegation to be found") - bech32Addr := sdk.AccAddress(s.address.Bytes()) - Expect(redelegations[0].DelegatorAddress).To(Equal(bech32Addr.String()), "expected delegator address to be %s", s.address) - Expect(redelegations[0].ValidatorSrcAddress).To(Equal(valAddr.String()), "expected source validator address to be %s", valAddr) - Expect(redelegations[0].ValidatorDstAddress).To(Equal(valAddr2.String()), "expected destination validator address to be %s", valAddr2) - - // query redelegations by delegator address - redelegationArgs := defaultRedelegationsArgs. - WithArgs( - s.address, "", "", query.PageRequest{Limit: 1, CountTotal: true}, - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, redelegationArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var redOut staking.RedelegationsOutput - err = s.precompile.UnpackIntoInterface(&redOut, staking.RedelegationsMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the redelegation output: %v", err) - Expect(redOut.Response).To(HaveLen(1), "expected one redelegation entry to be returned") - Expect(redOut.Response[0].Entries).To(HaveLen(1), "expected one redelegation entry to be returned") - Expect(redOut.PageResponse.Total).To(Equal(uint64(1))) - Expect(redOut.PageResponse.NextKey).To(BeEmpty()) - }) - }) - - Context("querying unbonding delegation", func() { - // defaultQueryUnbondingArgs are the default arguments for querying the unbonding delegation - // - // NOTE: this has to be populated in the BeforeEach block because the private key is not initialized before - var defaultQueryUnbondingArgs contracts.CallArgs - - BeforeEach(func() { - defaultQueryUnbondingArgs = defaultCallArgs.WithMethodName("getUnbondingDelegation") - - // Set up an unbonding delegation - approvalArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.UndelegateMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(approvalArgs) - - s.NextBlock() - - undelegateArgs := defaultCallArgs. - WithMethodName("testUndelegate"). - WithArgs(s.address, valAddr.String(), big.NewInt(1e18)) - - logCheckArgs := passCheck. - WithExpEvents(staking.EventTypeUnbond) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, undelegateArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while setting up an unbonding delegation: %v", err) - - // Check that the unbonding delegation was created - unbondingDelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(unbondingDelegations).To(HaveLen(1), "expected one unbonding delegation to be found") - Expect(unbondingDelegations[0].DelegatorAddress).To(Equal(sdk.AccAddress(s.address.Bytes()).String()), "expected delegator address to be %s", s.address) - Expect(unbondingDelegations[0].ValidatorAddress).To(Equal(valAddr.String()), "expected validator address to be %s", valAddr) - Expect(unbondingDelegations[0].Entries).To(HaveLen(1), "expected one unbonding delegation entry to be found") - Expect(unbondingDelegations[0].Entries[0].CreationHeight).To(Equal(int64(4)), "expected different creation height") - Expect(unbondingDelegations[0].Entries[0].Balance).To(Equal(math.NewInt(1e18)), "expected different balance") - }) - - It("which does not exist should return an empty unbonding delegation", func() { - queryUnbondingArgs := defaultQueryUnbondingArgs.WithArgs( - s.address, valAddr2.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, queryUnbondingArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var unbondingDelegationOutput staking.UnbondingDelegationOutput - err = s.precompile.UnpackIntoInterface(&unbondingDelegationOutput, staking.UnbondingDelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the unbonding delegation output: %v", err) - Expect(unbondingDelegationOutput.UnbondingDelegation.Entries).To(HaveLen(0), "expected one unbonding delegation entry") - }) - - It("which exists should return the unbonding delegation", func() { - queryUnbondingArgs := defaultQueryUnbondingArgs.WithArgs( - s.address, valAddr.String(), - ) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, queryUnbondingArgs, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var unbondOut staking.UnbondingDelegationOutput - err = s.precompile.UnpackIntoInterface(&unbondOut, staking.UnbondingDelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the unbonding delegation output: %v", err) - Expect(unbondOut.UnbondingDelegation.Entries).To(HaveLen(1), "expected one unbonding delegation entry to be returned") - Expect(unbondOut.UnbondingDelegation.Entries[0].Balance).To(Equal(big.NewInt(1e18)), "expected different balance") - }) - }) - - Context("testing sequential function calls to the precompile", func() { - // NOTE: there's no additional setup necessary because the test suite is already set up with - // delegations to the validator - It("should revert everything if any operation fails", func() { - cArgs := defaultCallArgs. - WithMethodName("testApproveAndThenUndelegate"). - WithGasLimit(1e8). - WithArgs(contractAddr, big.NewInt(250), big.NewInt(500), valAddr.String()) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, cArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - // There should be no authorizations because everything should have been reverted - authz, _ := s.CheckAuthorization(staking.UndelegateAuthz, contractAddr, s.address) - Expect(authz).To(BeNil(), "expected authorization to be nil") - - undelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(undelegations).To(HaveLen(0), "expected no unbonding delegations") - }) - - It("should write to state if all operations succeed", func() { - cArgs := defaultCallArgs. - WithMethodName("testApproveAndThenUndelegate"). - WithGasLimit(1e8). - WithArgs(contractAddr, big.NewInt(1000), big.NewInt(500), valAddr.String()) - - logCheckArgs := passCheck. - WithExpEvents(authorization.EventTypeApproval, staking.EventTypeUnbond) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, cArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - authz, _ := s.CheckAuthorization(staking.UndelegateAuthz, contractAddr, s.address) - Expect(authz).ToNot(BeNil(), "expected authorization not to be nil") - - undelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - Expect(undelegations).To(HaveLen(1), "expected one unbonding delegation") - Expect(undelegations[0].ValidatorAddress).To(Equal(valAddr.String()), "expected different validator address") - }) - }) - - Context("when using special call opcodes", func() { - testcases := []struct { - // calltype is the opcode to use - calltype string - // expTxPass defines if executing transactions should be possible with the given opcode. - // Queries should work for all options. - expTxPass bool - }{ - {"call", true}, - {"callcode", false}, - {"staticcall", false}, - {"delegatecall", false}, - } - - BeforeEach(func() { - // approve undelegate message - approveArgs := defaultApproveArgs.WithArgs( - contractAddr, []string{staking.UndelegateMsg}, big.NewInt(1e18), - ) - s.SetupApprovalWithContractCalls(approveArgs) - - s.NextBlock() - }) - - for _, tc := range testcases { - // NOTE: this is necessary because of Ginkgo behavior -- if not done, the value of tc - // inside the It block will always be the last entry in the testcases slice - testcase := tc - - It(fmt.Sprintf("should not execute transactions for calltype %q", testcase.calltype), func() { - args := defaultCallArgs. - WithMethodName("testCallUndelegate"). - WithArgs(s.address, valAddr.String(), big.NewInt(1e18), testcase.calltype) - - checkArgs := execRevertedCheck - if testcase.expTxPass { - checkArgs = passCheck.WithExpEvents(staking.EventTypeUnbond) - } - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, args, checkArgs) - if testcase.expTxPass { - Expect(err).To(BeNil(), "error while calling the smart contract for calltype %s: %v", testcase.calltype, err) - } else { - Expect(err).To(HaveOccurred(), "error while calling the smart contract for calltype %s: %v", testcase.calltype, err) - } - // check no delegations are unbonding - undelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - - if testcase.expTxPass { - Expect(undelegations).To(HaveLen(1), "expected an unbonding delegation") - Expect(undelegations[0].ValidatorAddress).To(Equal(valAddr.String()), "expected different validator address") - Expect(undelegations[0].DelegatorAddress).To(Equal(sdk.AccAddress(s.address.Bytes()).String()), "expected different delegator address") - } else { - Expect(undelegations).To(HaveLen(0), "expected no unbonding delegations for calltype %s", testcase.calltype) - } - }) - - It(fmt.Sprintf("should execute queries for calltype %q", testcase.calltype), func() { - args := defaultCallArgs. - WithMethodName("testCallDelegation"). - WithArgs(s.address, valAddr.String(), testcase.calltype) - - _, ethRes, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, args, passCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - var delOut staking.DelegationOutput - err = s.precompile.UnpackIntoInterface(&delOut, staking.DelegationMethod, ethRes.Ret) - Expect(err).To(BeNil(), "error while unpacking the delegation output: %v", err) - Expect(delOut.Shares).To(Equal(math.LegacyNewDec(1).BigInt()), "expected different delegation shares") - Expect(delOut.Balance.Amount).To(Equal(big.NewInt(1e18)), "expected different delegation balance") - if testcase.calltype != "callcode" { // having some trouble with returning the denom from inline assembly but that's a very special edge case which might never be used - Expect(delOut.Balance.Denom).To(Equal(s.bondDenom), "expected different denomination") - } - }) - } - }) - - // NOTE: These tests were added to replicate a problematic behavior, that occurred when a contract - // adjusted the state in multiple subsequent function calls, which adjusted the EVM state as well as - // things from the Cosmos SDK state (e.g. a bank balance). - // The result was, that changes made to the Cosmos SDK state have been overwritten during the next function - // call, because the EVM state was not updated in between. - // - // This behavior was fixed by updating the EVM state after each function call. - Context("when triggering multiple state changes in one function", func() { - // delegationAmount is the amount to be delegated - delegationAmount := big.NewInt(1e18) - - BeforeEach(func() { - // Set up funding for the contract address. - // NOTE: we are first asserting that no balance exists and then check successful - // funding afterwards. - balanceBefore := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom) - Expect(balanceBefore.Amount.Int64()).To(BeZero(), "expected contract balance to be 0 before funding") - - err = s.app.BankKeeper.SendCoins( - s.ctx, s.address.Bytes(), contractAddr.Bytes(), - sdk.Coins{sdk.Coin{Denom: s.bondDenom, Amount: math.NewIntFromBigInt(delegationAmount)}}, - ) - Expect(err).To(BeNil(), "error while sending coins: %v", err) - - s.NextBlock() - - balanceAfterFunding := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom) - Expect(balanceAfterFunding.Amount.BigInt()).To(Equal(delegationAmount), "expected different contract balance after funding") - - // Check no delegation exists from the contract to the validator - _, found := s.app.StakingKeeper.GetDelegation(s.ctx, contractAddr.Bytes(), valAddr) - Expect(found).To(BeFalse(), "expected delegation not to be found before testing") - }) - - It("delegating and increasing counter should change the bank balance accordingly", func() { - delegationArgs := defaultCallArgs. - WithGasLimit(1e9). - WithMethodName("testDelegateIncrementCounter"). - WithArgs(valAddr.String(), delegationAmount) - - approvalAndDelegationCheck := passCheck.WithExpEvents( - authorization.EventTypeApproval, staking.EventTypeDelegate, - ) - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, delegationArgs, approvalAndDelegationCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - - del, found := s.app.StakingKeeper.GetDelegation(s.ctx, contractAddr.Bytes(), valAddr) - - Expect(found).To(BeTrue(), "expected delegation to be found") - Expect(del.GetShares().BigInt()).To(Equal(delegationAmount), "expected different delegation shares") - - postBalance := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom) - Expect(postBalance.Amount.Int64()).To(BeZero(), "expected balance to be 0 after contract call") - }) - }) - - Context("when updating the stateDB prior to calling the precompile", func() { - It("should utilize the same contract balance to delegate", func() { - delegationArgs := defaultCallArgs. - WithGasLimit(1e9). - WithMethodName("approveDepositAndDelegate"). - WithArgs(valAddr.String()). - WithAmount(big.NewInt(2e18)) - - approvalAndDelegationCheck := passCheck.WithExpEvents( - authorization.EventTypeApproval, staking.EventTypeDelegate, - ) - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, delegationArgs, approvalAndDelegationCheck) - Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) - balance := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom) - Expect(balance.Amount.Int64()).To(BeZero(), "expected different contract balance after funding") - delegation := s.app.StakingKeeper.GetAllDelegatorDelegations(s.ctx, contractAddr.Bytes()) - Expect(delegation).To(HaveLen(1), "expected one delegation") - Expect(delegation[0].GetShares().BigInt()).To(Equal(big.NewInt(2e18)), "expected different delegation shares") - }) - //nolint:dupl - It("should revert the contract balance to the original value when the precompile fails", func() { - delegationArgs := defaultCallArgs. - WithGasLimit(1e9). - WithMethodName("approveDepositAndDelegateExceedingAllowance"). - WithArgs(valAddr.String()). - WithAmount(big.NewInt(2e18)) - - approvalAndDelegationCheck := defaultLogCheck.WithErrContains(vm.ErrExecutionReverted.Error()) - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, delegationArgs, approvalAndDelegationCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - balance := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom) - Expect(balance.Amount.Int64()).To(BeZero(), "expected different contract balance after funding") - auth, _ := s.app.AuthzKeeper.GetAuthorization(s.ctx, contractAddr.Bytes(), s.address.Bytes(), staking.DelegateMsg) - Expect(auth).To(BeNil(), "expected no authorization") - delegation := s.app.StakingKeeper.GetAllDelegatorDelegations(s.ctx, contractAddr.Bytes()) - Expect(delegation).To(HaveLen(0), "expected no delegations") - }) - - //nolint:dupl - It("should revert the contract balance to the original value when the custom logic after the precompile fails ", func() { - delegationArgs := defaultCallArgs. - WithGasLimit(1e9). - WithMethodName("approveDepositDelegateAndFailCustomLogic"). - WithArgs(valAddr.String()). - WithAmount(big.NewInt(2e18)) - - approvalAndDelegationCheck := defaultLogCheck.WithErrContains(vm.ErrExecutionReverted.Error()) - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, delegationArgs, approvalAndDelegationCheck) - Expect(err).To(HaveOccurred(), "error while calling the smart contract: %v", err) - - balance := s.app.BankKeeper.GetBalance(s.ctx, contractAddr.Bytes(), s.bondDenom) - Expect(balance.Amount.Int64()).To(BeZero(), "expected different contract balance after funding") - auth, _ := s.app.AuthzKeeper.GetAuthorization(s.ctx, contractAddr.Bytes(), s.address.Bytes(), staking.DelegateMsg) - Expect(auth).To(BeNil(), "expected no authorization") - delegation := s.app.StakingKeeper.GetAllDelegatorDelegations(s.ctx, contractAddr.Bytes()) - Expect(delegation).To(HaveLen(0), "expected no delegations") - }) - }) -}) - -// These tests are used to check that when batching multiple state changing transactions -// in one block, both states (Cosmos and EVM) are updated or reverted correctly. -// -// For this purpose, we are deploying an ERC20 contract and updating StakingCaller.sol -// to include a method where an ERC20 balance is sent between accounts as well as -// an interaction with the staking precompile is made. -// -// There are ERC20 tokens minted to the address of the deployed StakingCaller contract, -// which will transfer these to the message sender when successfully executed. -// Using the staking EVM extension, there is an approval made before the ERC20 transfer -// as well as a delegation after the ERC20 transfer. -var _ = Describe("Batching cosmos and eth interactions", func() { - const ( - erc20Name = "Test" - erc20Token = "TTT" - erc20Decimals = uint8(18) - ) - - var ( - // contractAddr is the address of the deployed StakingCaller contract - contractAddr common.Address - // erc20ContractAddr is the address of the deployed ERC20 contract - erc20ContractAddr common.Address - // erc20Contract is the compiled ERC20 contract - erc20Contract = compiledcontracts.ERC20MinterBurnerDecimalsContract - - // err is a standard error - err error - // execRevertedCheck is a standard log check for a reverted transaction - execRevertedCheck = defaultLogCheck.WithErrContains(vm.ErrExecutionReverted.Error()) - - // mintAmount is the amount of ERC20 tokens minted to the StakingCaller contract - mintAmount = big.NewInt(1e18) - // transferredAmount is the amount of ERC20 tokens to transfer during the tests - transferredAmount = big.NewInt(1234e9) - ) - - BeforeEach(func() { - s.SetupTest() - s.NextBlock() - - // Deploy StakingCaller contract - contractAddr, err = evmosutil.DeployContract(s.ctx, s.app, s.privKey, s.queryClientEVM, testdata.StakingCallerContract) - Expect(err).To(BeNil(), "error while deploying the StakingCaller contract") - - // Deploy ERC20 contract - erc20ContractAddr, err = evmosutil.DeployContract(s.ctx, s.app, s.privKey, s.queryClientEVM, erc20Contract, - erc20Name, erc20Token, erc20Decimals, - ) - Expect(err).To(BeNil(), "error while deploying the ERC20 contract") - - // Mint tokens to the StakingCaller contract - mintArgs := contracts.CallArgs{ - ContractAddr: erc20ContractAddr, - ContractABI: erc20Contract.ABI, - MethodName: "mint", - PrivKey: s.privKey, - Args: []interface{}{contractAddr, mintAmount}, - } - - mintCheck := testutil.LogCheckArgs{ - ABIEvents: erc20Contract.ABI.Events, - ExpEvents: []string{"Transfer"}, // minting produces a Transfer event - ExpPass: true, - } - - _, _, err = contracts.CallContractAndCheckLogs(s.ctx, s.app, mintArgs, mintCheck) - Expect(err).To(BeNil(), "error while minting tokens to the StakingCaller contract") - - // Check that the StakingCaller contract has the correct balance - erc20Balance := s.app.Erc20Keeper.BalanceOf(s.ctx, erc20Contract.ABI, erc20ContractAddr, contractAddr) - Expect(erc20Balance).To(Equal(mintAmount), "expected different ERC20 balance for the StakingCaller contract") - - // populate default call args - defaultCallArgs = contracts.CallArgs{ - ContractABI: testdata.StakingCallerContract.ABI, - ContractAddr: contractAddr, - MethodName: "callERC20AndDelegate", - PrivKey: s.privKey, - } - - // populate default log check args - defaultLogCheck = testutil.LogCheckArgs{ - ABIEvents: s.precompile.Events, - } - execRevertedCheck = defaultLogCheck.WithErrContains(vm.ErrExecutionReverted.Error()) - passCheck = defaultLogCheck.WithExpPass(true) - }) - - Describe("when batching multiple transactions", func() { - // validator is the validator address used for testing - var validator sdk.ValAddress - - BeforeEach(func() { - delegations := s.app.StakingKeeper.GetAllDelegatorDelegations(s.ctx, s.address.Bytes()) - Expect(delegations).ToNot(HaveLen(0), "expected address to have delegations") - - validator = delegations[0].GetValidatorAddr() - - _ = erc20ContractAddr - }) - - It("should revert both states if a staking transaction fails", func() { - delegationPre, found := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), validator) - Expect(found).To(BeTrue(), - "expected delegation from %s to validator %s to be found", - sdk.AccAddress(s.address.Bytes()).String(), validator.String(), - ) - - sharesPre := delegationPre.GetShares() - - // NOTE: passing an invalid validator address here should fail AFTER the erc20 transfer was made in the smart contract. - // Therefore this can be used to check that both EVM and Cosmos states are reverted correctly. - failArgs := defaultCallArgs. - WithArgs(erc20ContractAddr, "invalid validator", transferredAmount) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, failArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "expected error while calling the smart contract") - Expect(err.Error()).To(ContainSubstring("execution reverted"), "expected different error message") - - delegationPost, found := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), validator) - Expect(found).To(BeTrue(), - "expected delegation from %s to validator %s to be found after calling the smart contract", - sdk.AccAddress(s.address.Bytes()).String(), validator.String(), - ) - - auths, err := s.app.AuthzKeeper.GetAuthorizations(s.ctx, contractAddr.Bytes(), s.address.Bytes()) - Expect(err).To(BeNil(), "error while getting authorizations: %v", err) - sharesPost := delegationPost.GetShares() - erc20BalancePost := s.app.Erc20Keeper.BalanceOf(s.ctx, erc20Contract.ABI, erc20ContractAddr, s.address) - - Expect(auths).To(BeEmpty(), "expected no authorizations when reverting state") - Expect(sharesPost).To(Equal(sharesPre), "expected shares to be equal when reverting state") - Expect(erc20BalancePost.Int64()).To(BeZero(), "expected erc20 balance of target address to be zero when reverting state") - }) - - It("should revert both states if an ERC20 transaction fails", func() { - delegationPre, found := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), validator) - Expect(found).To(BeTrue(), - "expected delegation from %s to validator %s to be found", - sdk.AccAddress(s.address.Bytes()).String(), validator.String(), - ) - - sharesPre := delegationPre.GetShares() - - // NOTE: trying to transfer more than the balance of the contract should fail AFTER the approval - // for delegating was made in the smart contract. - // Therefore this can be used to check that both EVM and Cosmos states are reverted correctly. - moreThanMintedAmount := new(big.Int).Add(mintAmount, big.NewInt(1)) - failArgs := defaultCallArgs. - WithArgs(erc20ContractAddr, s.validators[0].OperatorAddress, moreThanMintedAmount) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, failArgs, execRevertedCheck) - Expect(err).To(HaveOccurred(), "expected error while calling the smart contract") - Expect(err.Error()).To(ContainSubstring("execution reverted"), "expected different error message") - - delegationPost, found := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), validator) - Expect(found).To(BeTrue(), - "expected delegation from %s to validator %s to be found after calling the smart contract", - sdk.AccAddress(s.address.Bytes()).String(), validator.String(), - ) - - auths, err := s.app.AuthzKeeper.GetAuthorizations(s.ctx, contractAddr.Bytes(), s.address.Bytes()) - Expect(err).To(BeNil(), "error while getting authorizations: %v", err) - sharesPost := delegationPost.GetShares() - erc20BalancePost := s.app.Erc20Keeper.BalanceOf(s.ctx, erc20Contract.ABI, erc20ContractAddr, s.address) - - Expect(auths).To(BeEmpty(), "expected no authorizations when reverting state") - Expect(sharesPost).To(Equal(sharesPre), "expected shares to be equal when reverting state") - Expect(erc20BalancePost.Int64()).To(BeZero(), "expected erc20 balance of target address to be zero when reverting state") - }) - - It("should persist changes in both the cosmos and eth states", func() { - delegationPre, found := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), validator) - Expect(found).To(BeTrue(), - "expected delegation from %s to validator %s to be found", - sdk.AccAddress(s.address.Bytes()).String(), validator.String(), - ) - - sharesPre := delegationPre.GetShares() - - // NOTE: trying to transfer more than the balance of the contract should fail AFTER the approval - // for delegating was made in the smart contract. - // Therefore this can be used to check that both EVM and Cosmos states are reverted correctly. - successArgs := defaultCallArgs. - WithArgs(erc20ContractAddr, s.validators[0].OperatorAddress, transferredAmount) - - // Build combined map of ABI events to check for both ERC20 events as well as precompile events - // - // NOTE: only add the transfer event - when adding all contract events to the combined map, - // the ERC20 Approval event will overwrite the precompile Approval event, which will cause - // the check to fail because of unexpected events in the logs. - combinedABIEvents := s.precompile.Events - combinedABIEvents["Transfer"] = erc20Contract.ABI.Events["Transfer"] - - successCheck := passCheck. - WithABIEvents(combinedABIEvents). - WithExpEvents( - authorization.EventTypeApproval, "Transfer", staking.EventTypeDelegate, - ) - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, successArgs, successCheck) - Expect(err).ToNot(HaveOccurred(), "error while calling the smart contract") - - delegationPost, found := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), validator) - Expect(found).To(BeTrue(), - "expected delegation from %s to validator %s to be found after calling the smart contract", - sdk.AccAddress(s.address.Bytes()).String(), validator.String(), - ) - - auths, err := s.app.AuthzKeeper.GetAuthorizations(s.ctx, contractAddr.Bytes(), s.address.Bytes()) - Expect(err).To(BeNil(), "error while getting authorizations: %v", err) - sharesPost := delegationPost.GetShares() - erc20BalancePost := s.app.Erc20Keeper.BalanceOf(s.ctx, erc20Contract.ABI, erc20ContractAddr, s.address) - - Expect(sharesPost.GT(sharesPre)).To(BeTrue(), "expected shares to be more than before") - Expect(erc20BalancePost).To(Equal(transferredAmount), "expected different erc20 balance of target address") - // NOTE: there should be no authorizations because the full approved amount is delegated - Expect(auths).To(HaveLen(0), "expected no authorization to be found") - }) - }) -}) diff --git a/precompiles/staking/query.go b/precompiles/staking/query.go deleted file mode 100644 index cb8b482b..00000000 --- a/precompiles/staking/query.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package staking - -import ( - "fmt" - "math/big" - "strings" - - sdk "github.com/cosmos/cosmos-sdk/types" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/evmos/evmos/v16/precompiles/authorization" - cmn "github.com/evmos/evmos/v16/precompiles/common" -) - -const ( - // DelegationMethod defines the ABI method name for the staking Delegation - // query. - DelegationMethod = "delegation" - // UnbondingDelegationMethod defines the ABI method name for the staking - // UnbondingDelegationMethod query. - UnbondingDelegationMethod = "unbondingDelegation" - // ValidatorMethod defines the ABI method name for the staking - // Validator query. - ValidatorMethod = "validator" - // ValidatorsMethod defines the ABI method name for the staking - // Validators query. - ValidatorsMethod = "validators" - // RedelegationMethod defines the ABI method name for the staking - // Redelegation query. - RedelegationMethod = "redelegation" - // RedelegationsMethod defines the ABI method name for the staking - // Redelegations query. - RedelegationsMethod = "redelegations" -) - -// Delegation returns the delegation that a delegator has with a specific validator. -func (p Precompile) Delegation( - ctx sdk.Context, - _ *vm.Contract, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - req, err := NewDelegationRequest(args) - if err != nil { - return nil, err - } - - queryServer := stakingkeeper.Querier{Keeper: &p.stakingKeeper} - - res, err := queryServer.Delegation(sdk.WrapSDKContext(ctx), req) - if err != nil { - // If there is no delegation found, return the response with zero values. - if strings.Contains(err.Error(), fmt.Sprintf(ErrNoDelegationFound, req.DelegatorAddr, req.ValidatorAddr)) { - return method.Outputs.Pack(big.NewInt(0), cmn.Coin{Denom: p.stakingKeeper.BondDenom(ctx), Amount: big.NewInt(0)}) - } - - return nil, err - } - - out := new(DelegationOutput).FromResponse(res) - - return out.Pack(method.Outputs) -} - -// UnbondingDelegation returns the delegation currently being unbonded for a delegator from -// a specific validator. -func (p Precompile) UnbondingDelegation( - ctx sdk.Context, - _ *vm.Contract, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - req, err := NewUnbondingDelegationRequest(args) - if err != nil { - return nil, err - } - - queryServer := stakingkeeper.Querier{Keeper: &p.stakingKeeper} - - res, err := queryServer.UnbondingDelegation(sdk.WrapSDKContext(ctx), req) - if err != nil { - // return empty unbonding delegation output if the unbonding delegation is not found - expError := fmt.Sprintf("unbonding delegation with delegator %s not found for validator %s", req.DelegatorAddr, req.ValidatorAddr) - if strings.Contains(err.Error(), expError) { - return method.Outputs.Pack(UnbondingDelegationResponse{}) - } - return nil, err - } - - out := new(UnbondingDelegationOutput).FromResponse(res) - - return method.Outputs.Pack(out.UnbondingDelegation) -} - -// Validator returns the validator information for a given validator address. -func (p Precompile) Validator( - ctx sdk.Context, - method *abi.Method, - _ *vm.Contract, - args []interface{}, -) ([]byte, error) { - req, err := NewValidatorRequest(args) - if err != nil { - return nil, err - } - - queryServer := stakingkeeper.Querier{Keeper: &p.stakingKeeper} - - res, err := queryServer.Validator(sdk.WrapSDKContext(ctx), req) - if err != nil { - // return empty validator info if the validator is not found - expError := fmt.Sprintf("validator %s not found", req.ValidatorAddr) - if strings.Contains(err.Error(), expError) { - return method.Outputs.Pack(DefaultValidatorOutput().Validator) - } - return nil, err - } - - out := new(ValidatorOutput).FromResponse(res) - - return method.Outputs.Pack(out.Validator) -} - -// Validators returns the validators information with a provided status & pagination (optional). -func (p Precompile) Validators( - ctx sdk.Context, - method *abi.Method, - _ *vm.Contract, - args []interface{}, -) ([]byte, error) { - req, err := NewValidatorsRequest(method, args) - if err != nil { - return nil, err - } - - queryServer := stakingkeeper.Querier{Keeper: &p.stakingKeeper} - - res, err := queryServer.Validators(sdk.WrapSDKContext(ctx), req) - if err != nil { - return nil, err - } - - out := new(ValidatorsOutput).FromResponse(res) - - return out.Pack(method.Outputs) -} - -// Redelegation returns the redelegation between two validators for a delegator. -func (p Precompile) Redelegation( - ctx sdk.Context, - method *abi.Method, - _ *vm.Contract, - args []interface{}, -) ([]byte, error) { - req, err := NewRedelegationRequest(args) - if err != nil { - return nil, err - } - - res, _ := p.stakingKeeper.GetRedelegation(ctx, req.DelegatorAddress, req.ValidatorSrcAddress, req.ValidatorDstAddress) - - out := new(RedelegationOutput).FromResponse(res) - - return method.Outputs.Pack(out.Redelegation) -} - -// Redelegations returns the redelegations according to -// the specified criteria (delegator address and/or validator source address -// and/or validator destination address or all existing redelegations) with pagination. -// Pagination is only supported for querying redelegations from a source validator or to query all redelegations. -func (p Precompile) Redelegations( - ctx sdk.Context, - method *abi.Method, - _ *vm.Contract, - args []interface{}, -) ([]byte, error) { - req, err := NewRedelegationsRequest(method, args) - if err != nil { - return nil, err - } - - queryServer := stakingkeeper.Querier{Keeper: &p.stakingKeeper} - - res, err := queryServer.Redelegations(ctx, req) - if err != nil { - return nil, err - } - - out := new(RedelegationsOutput).FromResponse(res) - - return out.Pack(method.Outputs) -} - -// Allowance returns the remaining allowance of a grantee to the contract. -func (p Precompile) Allowance( - ctx sdk.Context, - method *abi.Method, - _ *vm.Contract, - args []interface{}, -) ([]byte, error) { - grantee, granter, msg, err := authorization.CheckAllowanceArgs(args) - if err != nil { - return nil, err - } - - msgAuthz, _ := p.AuthzKeeper.GetAuthorization(ctx, grantee.Bytes(), granter.Bytes(), msg) - - if msgAuthz == nil { - return method.Outputs.Pack(big.NewInt(0)) - } - - stakeAuthz, ok := msgAuthz.(*stakingtypes.StakeAuthorization) - if !ok { - return nil, fmt.Errorf(cmn.ErrInvalidType, "staking authorization", &stakingtypes.StakeAuthorization{}, stakeAuthz) - } - - if stakeAuthz.MaxTokens == nil { - return method.Outputs.Pack(abi.MaxUint256) - } - - return method.Outputs.Pack(stakeAuthz.MaxTokens.Amount.BigInt()) -} diff --git a/precompiles/staking/query_test.go b/precompiles/staking/query_test.go deleted file mode 100644 index 0291ba34..00000000 --- a/precompiles/staking/query_test.go +++ /dev/null @@ -1,752 +0,0 @@ -package staking_test - -import ( - "fmt" - "math/big" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/query" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/evmos/evmos/v16/precompiles/authorization" - cmn "github.com/evmos/evmos/v16/precompiles/common" - "github.com/evmos/evmos/v16/precompiles/staking" - testutiltx "github.com/evmos/evmos/v16/testutil/tx" -) - -func (s *PrecompileTestSuite) TestDelegation() { - method := s.precompile.Methods[staking.DelegationMethod] - - testCases := []struct { - name string - malleate func(operatorAddress string) []interface{} - postCheck func(bz []byte) - gas uint64 - expErr bool - errContains string - }{ - { - "fail - empty input args", - func(operatorAddress string) []interface{} { - return []interface{}{} - }, - func(bz []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 2, 0), - }, - { - "fail - invalid delegator address", - func(operatorAddress string) []interface{} { - return []interface{}{ - "invalid", - operatorAddress, - } - }, - func(bz []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidDelegator, "invalid"), - }, - { - "fail - invalid operator address", - func(operatorAddress string) []interface{} { - return []interface{}{ - s.address, - "invalid", - } - }, - func(bz []byte) {}, - 100000, - true, - "decoding bech32 failed: invalid bech32 string", - }, - { - "success - empty delegation", - func(operatorAddress string) []interface{} { - addr, _ := testutiltx.NewAddrKey() - return []interface{}{ - addr, - operatorAddress, - } - }, - func(bz []byte) { - var delOut staking.DelegationOutput - err := s.precompile.UnpackIntoInterface(&delOut, staking.DelegationMethod, bz) - s.Require().NoError(err, "failed to unpack output") - s.Require().Equal(delOut.Shares.Int64(), big.NewInt(0).Int64()) - }, - 100000, - false, - "", - }, - { - "success", - func(operatorAddress string) []interface{} { - return []interface{}{ - s.address, - operatorAddress, - } - }, - func(bz []byte) { - var delOut staking.DelegationOutput - err := s.precompile.UnpackIntoInterface(&delOut, staking.DelegationMethod, bz) - s.Require().NoError(err, "failed to unpack output") - s.Require().Equal(delOut.Shares, big.NewInt(1e18)) - }, - 100000, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - bz, err := s.precompile.Delegation(s.ctx, contract, &method, tc.malleate(s.validators[0].OperatorAddress)) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestUnbondingDelegation() { - method := s.precompile.Methods[staking.UnbondingDelegationMethod] - - testCases := []struct { - name string - malleate func(operatorAddress string) []interface{} - postCheck func(bz []byte) - gas uint64 - expErr bool - errContains string - }{ - { - "fail - empty input args", - func(operatorAddress string) []interface{} { - return []interface{}{} - }, - func(bz []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 2, 0), - }, - { - "fail - invalid delegator address", - func(operatorAddress string) []interface{} { - return []interface{}{ - "invalid", - operatorAddress, - } - }, - func(bz []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidDelegator, "invalid"), - }, - { - "success - no unbonding delegation found", - func(operatorAddress string) []interface{} { - addr, _ := testutiltx.NewAddrKey() - return []interface{}{ - addr, - operatorAddress, - } - }, - func(data []byte) { - var ubdOut staking.UnbondingDelegationOutput - err := s.precompile.UnpackIntoInterface(&ubdOut, staking.UnbondingDelegationMethod, data) - s.Require().NoError(err, "failed to unpack output") - s.Require().Len(ubdOut.UnbondingDelegation.Entries, 0) - }, - 100000, - false, - "", - }, - { - "success", - func(operatorAddress string) []interface{} { - return []interface{}{ - s.address, - operatorAddress, - } - }, - func(data []byte) { - var ubdOut staking.UnbondingDelegationOutput - err := s.precompile.UnpackIntoInterface(&ubdOut, staking.UnbondingDelegationMethod, data) - s.Require().NoError(err, "failed to unpack output") - s.Require().Len(ubdOut.UnbondingDelegation.Entries, 1) - s.Require().Equal(ubdOut.UnbondingDelegation.Entries[0].CreationHeight, s.ctx.BlockHeight()) - s.Require().Equal(ubdOut.UnbondingDelegation.Entries[0].Balance, big.NewInt(1e18)) - }, - 100000, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - _, err := s.app.StakingKeeper.Undelegate(s.ctx, s.address.Bytes(), s.validators[0].GetOperator(), math.LegacyNewDec(1)) - s.Require().NoError(err) - - bz, err := s.precompile.UnbondingDelegation(s.ctx, contract, &method, tc.malleate(s.validators[0].OperatorAddress)) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotNil(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestValidator() { - method := s.precompile.Methods[staking.ValidatorMethod] - - testCases := []struct { - name string - malleate func(operatorAddress string) []interface{} - postCheck func(bz []byte) - gas uint64 - expErr bool - errContains string - }{ - { - "fail - empty input args", - func(operatorAddress string) []interface{} { - return []interface{}{} - }, - func(_ []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 1, 0), - }, - { - "success", - func(operatorAddress string) []interface{} { - return []interface{}{ - operatorAddress, - } - }, - func(data []byte) { - var valOut staking.ValidatorOutput - err := s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorMethod, data) - s.Require().NoError(err, "failed to unpack output") - s.Require().Equal(valOut.Validator.OperatorAddress, s.validators[0].OperatorAddress) - }, - 100000, - false, - "", - }, - { - name: "success - empty validator", - malleate: func(operatorAddress string) []interface{} { - newAddr, _ := testutiltx.NewAccAddressAndKey() - newValAddr := sdk.ValAddress(newAddr) - return []interface{}{ - newValAddr.String(), - } - }, - postCheck: func(data []byte) { - var valOut staking.ValidatorOutput - err := s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorMethod, data) - s.Require().NoError(err, "failed to unpack output") - s.Require().Equal(valOut.Validator.OperatorAddress, "") - s.Require().Equal(valOut.Validator.Status, uint8(0)) - }, - gas: 100000, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - bz, err := s.precompile.Validator(s.ctx, &method, contract, tc.malleate(s.validators[0].OperatorAddress)) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotNil(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestValidators() { - method := s.precompile.Methods[staking.ValidatorsMethod] - - testCases := []struct { - name string - malleate func() []interface{} - postCheck func(bz []byte) - gas uint64 - expErr bool - errContains string - }{ - { - "fail - empty input args", - func() []interface{} { - return []interface{}{} - }, - func(_ []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 2, 0), - }, - { - "fail - invalid number of arguments", - func() []interface{} { - return []interface{}{ - stakingtypes.Bonded.String(), - } - }, - func(_ []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 2, 1), - }, - { - "success - bonded status & pagination w/countTotal", - func() []interface{} { - return []interface{}{ - stakingtypes.Bonded.String(), - query.PageRequest{ - Limit: 1, - CountTotal: true, - }, - } - }, - func(data []byte) { - const expLen = 1 - var valOut staking.ValidatorsOutput - err := s.precompile.UnpackIntoInterface(&valOut, staking.ValidatorsMethod, data) - s.Require().NoError(err, "failed to unpack output") - - s.Require().Len(valOut.Validators, expLen) - // passed CountTotal = true - s.Require().Equal(len(s.validators), int(valOut.PageResponse.Total)) - s.Require().NotEmpty(valOut.PageResponse.NextKey) - s.assertValidatorsResponse(valOut.Validators, expLen) - }, - 100000, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - bz, err := s.precompile.Validators(s.ctx, &method, contract, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotNil(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestRedelegation() { - method := s.precompile.Methods[staking.RedelegationMethod] - redelegateMethod := s.precompile.Methods[staking.RedelegateMethod] - - testCases := []struct { - name string - malleate func(srcOperatorAddr, destOperatorAddr string) []interface{} - postCheck func(bz []byte) - gas uint64 - expErr bool - errContains string - }{ - { - "fail - empty input args", - func(srcOperatorAddr, destOperatorAddr string) []interface{} { - return []interface{}{} - }, - func(bz []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 3, 0), - }, - { - "fail - invalid delegator address", - func(srcOperatorAddr, destOperatorAddr string) []interface{} { - return []interface{}{ - "invalid", - srcOperatorAddr, - destOperatorAddr, - } - }, - func(bz []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidDelegator, "invalid"), - }, - { - "fail - empty src validator addr", - func(srcOperatorAddr, destOperatorAddr string) []interface{} { - return []interface{}{ - s.address, - "", - destOperatorAddr, - } - }, - func(bz []byte) {}, - 100000, - true, - "empty address string is not allowed", - }, - { - "fail - empty destination addr", - func(srcOperatorAddr, destOperatorAddr string) []interface{} { - return []interface{}{ - s.address, - srcOperatorAddr, - "", - } - }, - func(bz []byte) {}, - 100000, - true, - "empty address string is not allowed", - }, - { - "success", - func(srcOperatorAddr, destOperatorAddr string) []interface{} { - return []interface{}{ - s.address, - srcOperatorAddr, - destOperatorAddr, - } - }, - func(data []byte) { - var redOut staking.RedelegationOutput - err := s.precompile.UnpackIntoInterface(&redOut, staking.RedelegationMethod, data) - s.Require().NoError(err, "failed to unpack output") - s.Require().Len(redOut.Redelegation.Entries, 1) - s.Require().Equal(redOut.Redelegation.Entries[0].CreationHeight, s.ctx.BlockHeight()) - s.Require().Equal(redOut.Redelegation.Entries[0].SharesDst, big.NewInt(1e18)) - }, - 100000, - false, - "", - }, - { - name: "success - no redelegation found", - malleate: func(srcOperatorAddr, _ string) []interface{} { - nonExistentOperator := sdk.ValAddress([]byte("non-existent-operator")) - return []interface{}{ - s.address, - srcOperatorAddr, - nonExistentOperator.String(), - } - }, - postCheck: func(data []byte) { - var redOut staking.RedelegationOutput - err := s.precompile.UnpackIntoInterface(&redOut, staking.RedelegationMethod, data) - s.Require().NoError(err, "failed to unpack output") - s.Require().Len(redOut.Redelegation.Entries, 0) - }, - gas: 100000, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - delegationArgs := []interface{}{ - s.address, - s.validators[0].OperatorAddress, - s.validators[1].OperatorAddress, - big.NewInt(1e18), - } - - err := s.CreateAuthorization(s.address, staking.RedelegateAuthz, nil) - s.Require().NoError(err) - - _, err = s.precompile.Redelegate(s.ctx, s.address, contract, s.stateDB, &redelegateMethod, delegationArgs) - s.Require().NoError(err) - - bz, err := s.precompile.Redelegation(s.ctx, &method, contract, tc.malleate(s.validators[0].OperatorAddress, s.validators[1].OperatorAddress)) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotNil(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestRedelegations() { - var ( - delAmt = big.NewInt(3e17) - redelTotalCount uint64 = 2 - method = s.precompile.Methods[staking.RedelegationsMethod] - ) - - testCases := []struct { - name string - malleate func() []interface{} - postCheck func(bz []byte) - gas uint64 - expErr bool - errContains string - }{ - { - "fail - empty input args", - func() []interface{} { - return []interface{}{} - }, - func(bz []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 4, 0), - }, - { - "fail - invalid delegator address", - func() []interface{} { - return []interface{}{ - common.BytesToAddress([]byte("invalid")), - s.validators[0].OperatorAddress, - s.validators[1].OperatorAddress, - query.PageRequest{}, - } - }, - func(bz []byte) {}, - 100000, - true, - "redelegation not found", - }, - { - "fail - invalid query | all empty args ", - func() []interface{} { - return []interface{}{ - common.Address{}, - "", - "", - query.PageRequest{}, - } - }, - func(data []byte) {}, - 100000, - true, - "invalid query. Need to specify at least a source validator address or delegator address", - }, - { - "fail - invalid query | only destination validator address", - func() []interface{} { - return []interface{}{ - common.Address{}, - "", - s.validators[1].OperatorAddress, - query.PageRequest{}, - } - }, - func(data []byte) {}, - 100000, - true, - "invalid query. Need to specify at least a source validator address or delegator address", - }, - { - "success - specified delegator, source & destination", - func() []interface{} { - return []interface{}{ - s.address, - s.validators[0].OperatorAddress, - s.validators[1].OperatorAddress, - query.PageRequest{}, - } - }, - func(data []byte) { - s.assertRedelegationsOutput(data, 0, delAmt, 2, false) - }, - 100000, - false, - "", - }, - { - "success - specifying only source w/pagination", - func() []interface{} { - return []interface{}{ - common.Address{}, - s.validators[0].OperatorAddress, - "", - query.PageRequest{ - Limit: 1, - CountTotal: true, - }, - } - }, - func(data []byte) { - s.assertRedelegationsOutput(data, redelTotalCount, delAmt, 2, true) - }, - 100000, - false, - "", - }, - { - "success - get all existing redelegations for a delegator w/pagination", - func() []interface{} { - return []interface{}{ - s.address, - "", - "", - query.PageRequest{ - Limit: 1, - CountTotal: true, - }, - } - }, - func(data []byte) { - s.assertRedelegationsOutput(data, redelTotalCount, delAmt, 2, true) - }, - 100000, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - err := s.setupRedelegations(delAmt) - s.Require().NoError(err) - - // query redelegations - bz, err := s.precompile.Redelegations(s.ctx, &method, contract, tc.malleate()) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotNil(bz) - tc.postCheck(bz) - } - }) - } -} - -func (s *PrecompileTestSuite) TestAllowance() { - approvedCoin := sdk.Coin{Denom: s.bondDenom, Amount: math.NewInt(1e18)} - granteeAddr := testutiltx.GenerateAddress() - method := s.precompile.Methods[authorization.AllowanceMethod] - - testCases := []struct { - name string - malleate func() []interface{} - postCheck func(bz []byte) - gas uint64 - expErr bool - errContains string - }{ - { - "fail - empty input args", - func() []interface{} { - return []interface{}{} - }, - func(bz []byte) {}, - 100000, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 3, 0), - }, - { - "success - query delegate method allowance", - func() []interface{} { - err := s.CreateAuthorization(granteeAddr, staking.DelegateAuthz, &approvedCoin) - s.Require().NoError(err) - - return []interface{}{ - granteeAddr, - s.address, - staking.DelegateMsg, - } - }, - func(bz []byte) { - var amountsOut *big.Int - err := s.precompile.UnpackIntoInterface(&amountsOut, authorization.AllowanceMethod, bz) - s.Require().NoError(err, "failed to unpack output") - s.Require().Equal(big.NewInt(1e18), amountsOut, "expected different allowed amount") - }, - 100000, - false, - "", - }, - { - "success - return empty allowance if authorization is not found", - func() []interface{} { - return []interface{}{ - granteeAddr, - s.address, - staking.UndelegateMsg, - } - }, - func(bz []byte) { - var amountsOut *big.Int - err := s.precompile.UnpackIntoInterface(&amountsOut, authorization.AllowanceMethod, bz) - s.Require().NoError(err, "failed to unpack output") - s.Require().Equal(int64(0), amountsOut.Int64(), "expected no allowance") - }, - 100000, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() // reset - contract := vm.NewContract(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - - args := tc.malleate() - bz, err := s.precompile.Allowance(s.ctx, &method, contract, args) - - if tc.expErr { - s.Require().Error(err) - s.Require().Contains(err.Error(), tc.errContains) - } else { - s.Require().NoError(err) - s.Require().NotNil(bz) - tc.postCheck(bz) - } - }) - } -} diff --git a/precompiles/staking/setup_test.go b/precompiles/staking/setup_test.go deleted file mode 100644 index 08ae85b3..00000000 --- a/precompiles/staking/setup_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package staking_test - -import ( - "testing" - - "github.com/cosmos/cosmos-sdk/crypto/keyring" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - sdk "github.com/cosmos/cosmos-sdk/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - evmosapp "github.com/evmos/evmos/v16/app" - "github.com/evmos/evmos/v16/precompiles/staking" - "github.com/evmos/evmos/v16/x/evm/statedb" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" - - //nolint:revive // dot imports are fine for Ginkgo - . "github.com/onsi/ginkgo/v2" - //nolint:revive // dot imports are fine for Ginkgo - . "github.com/onsi/gomega" - - "github.com/stretchr/testify/suite" -) - -var s *PrecompileTestSuite - -type PrecompileTestSuite struct { - suite.Suite - - ctx sdk.Context - app *evmosapp.Evmos - address common.Address - validators []stakingtypes.Validator - ethSigner ethtypes.Signer - privKey cryptotypes.PrivKey - signer keyring.Signer - bondDenom string - - precompile *staking.Precompile - stateDB *statedb.StateDB - - queryClientEVM evmtypes.QueryClient -} - -func TestPrecompileTestSuite(t *testing.T) { - s = new(PrecompileTestSuite) - suite.Run(t, s) - - // Run Ginkgo integration tests - RegisterFailHandler(Fail) - RunSpecs(t, "Precompile Test Suite") -} - -func (s *PrecompileTestSuite) SetupTest() { - s.DoSetupTest() -} diff --git a/precompiles/staking/staking.go b/precompiles/staking/staking.go deleted file mode 100644 index efa998d6..00000000 --- a/precompiles/staking/staking.go +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package staking - -import ( - "embed" - - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/cometbft/cometbft/libs/log" - storetypes "github.com/cosmos/cosmos-sdk/store/types" - authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/evmos/evmos/v16/precompiles/authorization" - cmn "github.com/evmos/evmos/v16/precompiles/common" -) - -var _ vm.PrecompiledContract = &Precompile{} - -// Embed abi json file to the executable binary. Needed when importing as dependency. -// -//go:embed abi.json -var f embed.FS - -// PrecompileAddress defines the contract address of the staking precompile. -const PrecompileAddress = "0x0000000000000000000000000000000000000800" - -// Precompile defines the precompiled contract for staking. -type Precompile struct { - cmn.Precompile - stakingKeeper stakingkeeper.Keeper -} - -// LoadABI loads the staking ABI from the embedded abi.json file -// for the staking precompile. -func LoadABI() (abi.ABI, error) { - return cmn.LoadABI(f, "abi.json") -} - -// NewPrecompile creates a new staking Precompile instance as a -// PrecompiledContract interface. -func NewPrecompile( - stakingKeeper stakingkeeper.Keeper, - authzKeeper authzkeeper.Keeper, -) (*Precompile, error) { - abi, err := LoadABI() - if err != nil { - return nil, err - } - - return &Precompile{ - Precompile: cmn.Precompile{ - ABI: abi, - AuthzKeeper: authzKeeper, - KvGasConfig: storetypes.KVGasConfig(), - TransientKVGasConfig: storetypes.TransientGasConfig(), - ApprovalExpiration: cmn.DefaultExpirationDuration, // should be configurable in the future. - }, - stakingKeeper: stakingKeeper, - }, nil -} - -// RequiredGas returns the required bare minimum gas to execute the precompile. -func (p Precompile) RequiredGas(input []byte) uint64 { - methodID := input[:4] - - method, err := p.MethodById(methodID) - if err != nil { - // This should never happen since this method is going to fail during Run - return 0 - } - - return p.Precompile.RequiredGas(input, p.IsTransaction(method.Name)) -} - -// Address defines the address of the staking compile contract. -// address: 0x0000000000000000000000000000000000000800 -func (Precompile) Address() common.Address { - return common.HexToAddress(PrecompileAddress) -} - -// Run executes the precompiled contract staking methods defined in the ABI. -func (p Precompile) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) (bz []byte, err error) { - ctx, stateDB, method, initialGas, args, err := p.RunSetup(evm, contract, readOnly, p.IsTransaction) - if err != nil { - return nil, err - } - - // This handles any out of gas errors that may occur during the execution of a precompile tx or query. - // It avoids panics and returns the out of gas error so the EVM can continue gracefully. - defer cmn.HandleGasError(ctx, contract, initialGas, &err)() - - if err := stateDB.Commit(); err != nil { - return nil, err - } - - switch method.Name { - // Authorization transactions - case authorization.ApproveMethod: - bz, err = p.Approve(ctx, evm.Origin, stateDB, method, args) - case authorization.RevokeMethod: - bz, err = p.Revoke(ctx, evm.Origin, stateDB, method, args) - case authorization.IncreaseAllowanceMethod: - bz, err = p.IncreaseAllowance(ctx, evm.Origin, stateDB, method, args) - case authorization.DecreaseAllowanceMethod: - bz, err = p.DecreaseAllowance(ctx, evm.Origin, stateDB, method, args) - // Staking transactions - case CreateValidatorMethod: - bz, err = p.CreateValidator(ctx, evm.Origin, contract, stateDB, method, args) - case DelegateMethod: - bz, err = p.Delegate(ctx, evm.Origin, contract, stateDB, method, args) - case UndelegateMethod: - bz, err = p.Undelegate(ctx, evm.Origin, contract, stateDB, method, args) - case RedelegateMethod: - bz, err = p.Redelegate(ctx, evm.Origin, contract, stateDB, method, args) - case CancelUnbondingDelegationMethod: - bz, err = p.CancelUnbondingDelegation(ctx, evm.Origin, contract, stateDB, method, args) - // Staking queries - case DelegationMethod: - bz, err = p.Delegation(ctx, contract, method, args) - case UnbondingDelegationMethod: - bz, err = p.UnbondingDelegation(ctx, contract, method, args) - case ValidatorMethod: - bz, err = p.Validator(ctx, method, contract, args) - case ValidatorsMethod: - bz, err = p.Validators(ctx, method, contract, args) - case RedelegationMethod: - bz, err = p.Redelegation(ctx, method, contract, args) - case RedelegationsMethod: - bz, err = p.Redelegations(ctx, method, contract, args) - // Authorization queries - case authorization.AllowanceMethod: - bz, err = p.Allowance(ctx, method, contract, args) - } - - if err != nil { - return nil, err - } - - cost := ctx.GasMeter().GasConsumed() - initialGas - - if !contract.UseGas(cost) { - return nil, vm.ErrOutOfGas - } - - return bz, nil -} - -// IsTransaction checks if the given method name corresponds to a transaction or query. -// -// Available staking transactions are: -// - CreateValidator -// - Delegate -// - Undelegate -// - Redelegate -// - CancelUnbondingDelegation -// -// Available authorization transactions are: -// - Approve -// - Revoke -// - IncreaseAllowance -// - DecreaseAllowance -func (Precompile) IsTransaction(method string) bool { - switch method { - case CreateValidatorMethod, - DelegateMethod, - UndelegateMethod, - RedelegateMethod, - CancelUnbondingDelegationMethod, - authorization.ApproveMethod, - authorization.RevokeMethod, - authorization.IncreaseAllowanceMethod, - authorization.DecreaseAllowanceMethod: - return true - default: - return false - } -} - -// Logger returns a precompile-specific logger. -func (p Precompile) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("evm extension", "staking") -} diff --git a/precompiles/staking/staking_test.go b/precompiles/staking/staking_test.go deleted file mode 100644 index e5c032f2..00000000 --- a/precompiles/staking/staking_test.go +++ /dev/null @@ -1,474 +0,0 @@ -package staking_test - -import ( - "math/big" - "time" - - "cosmossdk.io/math" - "github.com/evmos/evmos/v16/app" - - "github.com/evmos/evmos/v16/precompiles/authorization" - - ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - - sdk "github.com/cosmos/cosmos-sdk/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/evmos/evmos/v16/precompiles/staking" - "github.com/evmos/evmos/v16/utils" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" -) - -func (s *PrecompileTestSuite) TestIsTransaction() { - testCases := []struct { - name string - method string - isTx bool - }{ - { - authorization.ApproveMethod, - s.precompile.Methods[authorization.ApproveMethod].Name, - true, - }, - { - authorization.IncreaseAllowanceMethod, - s.precompile.Methods[authorization.IncreaseAllowanceMethod].Name, - true, - }, - { - authorization.DecreaseAllowanceMethod, - s.precompile.Methods[authorization.DecreaseAllowanceMethod].Name, - true, - }, - { - staking.CreateValidatorMethod, - s.precompile.Methods[staking.CreateValidatorMethod].Name, - true, - }, - { - staking.DelegateMethod, - s.precompile.Methods[staking.DelegateMethod].Name, - true, - }, - { - staking.UndelegateMethod, - s.precompile.Methods[staking.UndelegateMethod].Name, - true, - }, - { - staking.RedelegateMethod, - s.precompile.Methods[staking.RedelegateMethod].Name, - true, - }, - { - staking.CancelUnbondingDelegationMethod, - s.precompile.Methods[staking.CancelUnbondingDelegationMethod].Name, - true, - }, - { - staking.DelegationMethod, - s.precompile.Methods[staking.DelegationMethod].Name, - false, - }, - { - "invalid", - "invalid", - false, - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.Require().Equal(s.precompile.IsTransaction(tc.method), tc.isTx) - }) - } -} - -func (s *PrecompileTestSuite) TestRequiredGas() { - testcases := []struct { - name string - malleate func() []byte - expGas uint64 - }{ - { - "success - delegate transaction with correct gas estimation", - func() []byte { - input, err := s.precompile.Pack( - staking.DelegateMethod, - s.address, - s.validators[0].GetOperator().String(), - big.NewInt(10000000000), - ) - s.Require().NoError(err) - return input - }, - 7760, - }, - { - "success - undelegate transaction with correct gas estimation", - func() []byte { - input, err := s.precompile.Pack( - staking.UndelegateMethod, - s.address, - s.validators[0].GetOperator().String(), - big.NewInt(1), - ) - s.Require().NoError(err) - return input - }, - 7760, - }, - } - - for _, tc := range testcases { - s.Run(tc.name, func() { - s.SetupTest() - - // malleate contract input - input := tc.malleate() - gas := s.precompile.RequiredGas(input) - - s.Require().Equal(gas, tc.expGas) - }) - } -} - -// TestRun tests the precompile's Run method. -func (s *PrecompileTestSuite) TestRun() { - testcases := []struct { - name string - malleate func() []byte - gas uint64 - readOnly bool - expPass bool - errContains string - }{ - { - "fail - contract gas limit is < gas cost to run a query / tx", - func() []byte { - err := s.CreateAuthorization(s.address, staking.DelegateAuthz, nil) - s.Require().NoError(err) - - input, err := s.precompile.Pack( - staking.DelegateMethod, - s.address, - s.validators[0].GetOperator().String(), - big.NewInt(1000), - ) - s.Require().NoError(err, "failed to pack input") - return input - }, - 8000, - false, - false, - "out of gas", - }, - { - "pass - delegate transaction", - func() []byte { - err := s.CreateAuthorization(s.address, staking.DelegateAuthz, nil) - s.Require().NoError(err) - - input, err := s.precompile.Pack( - staking.DelegateMethod, - s.address, - s.validators[0].GetOperator().String(), - big.NewInt(1000), - ) - s.Require().NoError(err, "failed to pack input") - return input - }, - 1000000, - false, - true, - "", - }, - { - "pass - undelegate transaction", - func() []byte { - err := s.CreateAuthorization(s.address, staking.UndelegateAuthz, nil) - s.Require().NoError(err) - - input, err := s.precompile.Pack( - staking.UndelegateMethod, - s.address, - s.validators[0].GetOperator().String(), - big.NewInt(1), - ) - s.Require().NoError(err, "failed to pack input") - return input - }, - 1000000, - false, - true, - "", - }, - { - "pass - redelegate transaction", - func() []byte { - err := s.CreateAuthorization(s.address, staking.RedelegateAuthz, nil) - s.Require().NoError(err) - - input, err := s.precompile.Pack( - staking.RedelegateMethod, - s.address, - s.validators[0].GetOperator().String(), - s.validators[1].GetOperator().String(), - big.NewInt(1), - ) - s.Require().NoError(err, "failed to pack input") - return input - }, - 1000000, - false, - true, - "failed to redelegate tokens", - }, - { - "pass - cancel unbonding delegation transaction", - func() []byte { - // add unbonding delegation to staking keeper - ubd := stakingtypes.NewUnbondingDelegation( - s.address.Bytes(), - s.validators[0].GetOperator(), - 1000, - time.Now().Add(time.Hour), - math.NewInt(1000), - 0, - ) - s.app.StakingKeeper.SetUnbondingDelegation(s.ctx, ubd) - - err := s.CreateAuthorization(s.address, staking.CancelUnbondingDelegationAuthz, nil) - s.Require().NoError(err) - - // Needs to be called after setting unbonding delegation - // In order to mimic the coins being added to the unboding pool - coin := sdk.NewCoin(utils.BaseDenom, math.NewInt(1000)) - err = s.app.BankKeeper.SendCoinsFromModuleToModule(s.ctx, stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, sdk.Coins{coin}) - s.Require().NoError(err, "failed to send coins from module to module") - - input, err := s.precompile.Pack( - staking.CancelUnbondingDelegationMethod, - s.address, - s.validators[0].GetOperator().String(), - big.NewInt(1000), - big.NewInt(1000), - ) - s.Require().NoError(err, "failed to pack input") - return input - }, - 1000000, - false, - true, - "", - }, - { - "pass - delegation query", - func() []byte { - input, err := s.precompile.Pack( - staking.DelegationMethod, - s.address, - s.validators[0].GetOperator().String(), - ) - s.Require().NoError(err, "failed to pack input") - return input - }, - 1000000, - false, - true, - "", - }, - { - "pass - validator query", - func() []byte { - input, err := s.precompile.Pack( - staking.ValidatorMethod, - s.validators[0].OperatorAddress, - ) - s.Require().NoError(err, "failed to pack input") - return input - }, - 1000000, - false, - true, - "", - }, - { - "pass - redelgation query", - func() []byte { - // add redelegation to staking keeper - redelegation := stakingtypes.NewRedelegation( - s.address.Bytes(), - s.validators[0].GetOperator(), - s.validators[1].GetOperator(), - 1000, - time.Now().Add(time.Hour), - math.NewInt(1000), - math.LegacyNewDec(1), - 0, - ) - - s.app.StakingKeeper.SetRedelegation(s.ctx, redelegation) - - input, err := s.precompile.Pack( - staking.RedelegationMethod, - s.address, - s.validators[0].GetOperator().String(), - s.validators[1].GetOperator().String(), - ) - s.Require().NoError(err, "failed to pack input") - return input - }, - 1000000, - false, - true, - "", - }, - { - "pass - delegation query - read only", - func() []byte { - input, err := s.precompile.Pack( - staking.DelegationMethod, - s.address, - s.validators[0].GetOperator().String(), - ) - s.Require().NoError(err, "failed to pack input") - return input - }, - 1000000, - true, - true, - "", - }, - { - "pass - unbonding delegation query", - func() []byte { - // add unbonding delegation to staking keeper - ubd := stakingtypes.NewUnbondingDelegation( - s.address.Bytes(), - s.validators[0].GetOperator(), - 1000, - time.Now().Add(time.Hour), - math.NewInt(1000), - 0, - ) - s.app.StakingKeeper.SetUnbondingDelegation(s.ctx, ubd) - - // Needs to be called after setting unbonding delegation - // In order to mimic the coins being added to the unboding pool - coin := sdk.NewCoin(utils.BaseDenom, math.NewInt(1000)) - err := s.app.BankKeeper.SendCoinsFromModuleToModule(s.ctx, stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, sdk.Coins{coin}) - s.Require().NoError(err, "failed to send coins from module to module") - - input, err := s.precompile.Pack( - staking.UnbondingDelegationMethod, - s.address, - s.validators[0].GetOperator().String(), - ) - s.Require().NoError(err, "failed to pack input") - return input - }, - 1000000, - true, - true, - "", - }, - { - "fail - delegate method - read only", - func() []byte { - input, err := s.precompile.Pack( - staking.DelegateMethod, - s.address, - s.validators[0].GetOperator().String(), - big.NewInt(1000), - ) - s.Require().NoError(err, "failed to pack input") - return input - }, - 0, - true, - false, - "write protection", - }, - { - "fail - invalid method", - func() []byte { - return []byte("invalid") - }, - 0, - false, - false, - "no method with id", - }, - } - - for _, tc := range testcases { - s.Run(tc.name, func() { - // setup basic test suite - s.SetupTest() - - baseFee := s.app.FeeMarketKeeper.GetBaseFee(s.ctx) - - contract := vm.NewPrecompile(vm.AccountRef(s.address), s.precompile, big.NewInt(0), tc.gas) - contractAddr := contract.Address() - - // malleate testcase - contract.Input = tc.malleate() - - // Build and sign Ethereum transaction - txArgs := evmtypes.EvmTxArgs{ - ChainID: s.app.EvmKeeper.ChainID(), - Nonce: 0, - To: &contractAddr, - Amount: nil, - GasLimit: tc.gas, - GasPrice: app.MainnetMinGasPrices.BigInt(), - GasFeeCap: baseFee, - GasTipCap: big.NewInt(1), - Accesses: ðtypes.AccessList{}, - } - msgEthereumTx := evmtypes.NewTx(&txArgs) - - msgEthereumTx.From = s.address.String() - err := msgEthereumTx.Sign(s.ethSigner, s.signer) - s.Require().NoError(err, "failed to sign Ethereum message") - - // Instantiate config - proposerAddress := s.ctx.BlockHeader().ProposerAddress - cfg, err := s.app.EvmKeeper.EVMConfig(s.ctx, proposerAddress, s.app.EvmKeeper.ChainID()) - s.Require().NoError(err, "failed to instantiate EVM config") - - msg, err := msgEthereumTx.AsMessage(s.ethSigner, baseFee) - s.Require().NoError(err, "failed to instantiate Ethereum message") - - // Instantiate EVM - evm := s.app.EvmKeeper.NewEVM( - s.ctx, msg, cfg, nil, s.stateDB, - ) - - params := s.app.EvmKeeper.GetParams(s.ctx) - activePrecompiles := params.GetActivePrecompilesAddrs() - precompileMap := s.app.EvmKeeper.Precompiles(activePrecompiles...) - err = vm.ValidatePrecompiles(precompileMap, activePrecompiles) - s.Require().NoError(err, "invalid precompiles", activePrecompiles) - evm.WithPrecompiles(precompileMap, activePrecompiles) - - // Run precompiled contract - bz, err := s.precompile.Run(evm, contract, tc.readOnly) - - // Check results - if tc.expPass { - s.Require().NoError(err, "expected no error when running the precompile") - s.Require().NotNil(bz, "expected returned bytes not to be nil") - } else { - s.Require().Error(err, "expected error to be returned when running the precompile") - s.Require().Nil(bz, "expected returned bytes to be nil") - s.Require().ErrorContains(err, tc.errContains) - consumed := s.ctx.GasMeter().GasConsumed() - // LessThanOrEqual because the gas is consumed before the error is returned - s.Require().LessOrEqual(tc.gas, consumed, "expected gas consumed to be equal to gas limit") - - } - }) - } -} diff --git a/precompiles/staking/testdata/StakingCaller.json b/precompiles/staking/testdata/StakingCaller.json deleted file mode 100644 index cbbeee53..00000000 --- a/precompiles/staking/testdata/StakingCaller.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "abi": "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"}],\"name\":\"approveDepositAndDelegate\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"}],\"name\":\"approveDepositAndDelegateExceedingAllowance\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"}],\"name\":\"approveDepositDelegateAndFailCustomLogic\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_contract\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"callERC20AndDelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"counter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_grantee\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"method\",\"type\":\"string\"}],\"name\":\"getAllowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"}],\"name\":\"getDelegation\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"denom\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct Coin\",\"name\":\"balance\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_validatorSrcAddr\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_validatorDstAddr\",\"type\":\"string\"}],\"name\":\"getRedelegation\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"delegatorAddress\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"validatorSrcAddress\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"validatorDstAddress\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"creationHeight\",\"type\":\"int64\"},{\"internalType\":\"int64\",\"name\":\"completionTime\",\"type\":\"int64\"},{\"internalType\":\"uint256\",\"name\":\"initialBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"sharesDst\",\"type\":\"uint256\"}],\"internalType\":\"struct RedelegationEntry[]\",\"name\":\"entries\",\"type\":\"tuple[]\"}],\"internalType\":\"struct RedelegationOutput\",\"name\":\"redelegation\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_delegatorAddr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_validatorSrcAddr\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_validatorDstAddr\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"key\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offset\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"limit\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"countTotal\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reverse\",\"type\":\"bool\"}],\"internalType\":\"struct PageRequest\",\"name\":\"_pageRequest\",\"type\":\"tuple\"}],\"name\":\"getRedelegations\",\"outputs\":[{\"components\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"delegatorAddress\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"validatorSrcAddress\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"validatorDstAddress\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"creationHeight\",\"type\":\"int64\"},{\"internalType\":\"int64\",\"name\":\"completionTime\",\"type\":\"int64\"},{\"internalType\":\"uint256\",\"name\":\"initialBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"sharesDst\",\"type\":\"uint256\"}],\"internalType\":\"struct RedelegationEntry[]\",\"name\":\"entries\",\"type\":\"tuple[]\"}],\"internalType\":\"struct Redelegation\",\"name\":\"redelegation\",\"type\":\"tuple\"},{\"components\":[{\"components\":[{\"internalType\":\"int64\",\"name\":\"creationHeight\",\"type\":\"int64\"},{\"internalType\":\"int64\",\"name\":\"completionTime\",\"type\":\"int64\"},{\"internalType\":\"uint256\",\"name\":\"initialBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"sharesDst\",\"type\":\"uint256\"}],\"internalType\":\"struct RedelegationEntry\",\"name\":\"redelegationEntry\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"internalType\":\"struct RedelegationEntryResponse[]\",\"name\":\"entries\",\"type\":\"tuple[]\"}],\"internalType\":\"struct RedelegationResponse[]\",\"name\":\"response\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"nextKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"total\",\"type\":\"uint64\"}],\"internalType\":\"struct PageResponse\",\"name\":\"pageResponse\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"}],\"name\":\"getUnbondingDelegation\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"delegatorAddress\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"validatorAddress\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"int64\",\"name\":\"creationHeight\",\"type\":\"int64\"},{\"internalType\":\"int64\",\"name\":\"completionTime\",\"type\":\"int64\"},{\"internalType\":\"uint256\",\"name\":\"initialBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"unbondingId\",\"type\":\"uint64\"},{\"internalType\":\"int64\",\"name\":\"unbondingOnHoldRefCount\",\"type\":\"int64\"}],\"internalType\":\"struct UnbondingDelegationEntry[]\",\"name\":\"entries\",\"type\":\"tuple[]\"}],\"internalType\":\"struct UnbondingDelegationOutput\",\"name\":\"unbondingDelegation\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"}],\"name\":\"getValidator\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"operatorAddress\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"consensusPubkey\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"jailed\",\"type\":\"bool\"},{\"internalType\":\"enum BondStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"delegatorShares\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"internalType\":\"int64\",\"name\":\"unbondingHeight\",\"type\":\"int64\"},{\"internalType\":\"int64\",\"name\":\"unbondingTime\",\"type\":\"int64\"},{\"internalType\":\"uint256\",\"name\":\"commission\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSelfDelegation\",\"type\":\"uint256\"}],\"internalType\":\"struct Validator\",\"name\":\"validator\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_status\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"key\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"offset\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"limit\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"countTotal\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"reverse\",\"type\":\"bool\"}],\"internalType\":\"struct PageRequest\",\"name\":\"_pageRequest\",\"type\":\"tuple\"}],\"name\":\"getValidators\",\"outputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"operatorAddress\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"consensusPubkey\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"jailed\",\"type\":\"bool\"},{\"internalType\":\"enum BondStatus\",\"name\":\"status\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"tokens\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"delegatorShares\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"description\",\"type\":\"string\"},{\"internalType\":\"int64\",\"name\":\"unbondingHeight\",\"type\":\"int64\"},{\"internalType\":\"int64\",\"name\":\"unbondingTime\",\"type\":\"int64\"},{\"internalType\":\"uint256\",\"name\":\"commission\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSelfDelegation\",\"type\":\"uint256\"}],\"internalType\":\"struct Validator[]\",\"name\":\"validators\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"nextKey\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"total\",\"type\":\"uint64\"}],\"internalType\":\"struct PageResponse\",\"name\":\"pageResponse\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_methods\",\"type\":\"string[]\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"testApprove\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_approveAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_undelegateAmount\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"}],\"name\":\"testApproveAndThenUndelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_calltype\",\"type\":\"string\"}],\"name\":\"testCallDelegation\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"shares\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"denom\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct Coin\",\"name\":\"coin\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_calltype\",\"type\":\"string\"}],\"name\":\"testCallUndelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_creationHeight\",\"type\":\"uint256\"}],\"name\":\"testCancelUnbonding\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"testDelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"testDelegateIncrementCounter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_validatorSrcAddr\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_validatorDstAddr\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"testRedelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_grantee\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_methods\",\"type\":\"string[]\"}],\"name\":\"testRevoke\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_validatorAddr\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"testUndelegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - "bin": "6080604052604051806020016040528060405180606001604052806023815260200162005c026023913981525060019060016200003e92919062000053565b503480156200004c57600080fd5b50620004a1565b828054828255906000526020600020908101928215620000a0579160200282015b828111156200009f5782518290816200008e9190620003ba565b509160200191906001019062000074565b5b509050620000af9190620000b3565b5090565b5b80821115620000d75760008181620000cd9190620000db565b50600101620000b4565b5090565b508054620000e990620001a9565b6000825580601f10620000fd57506200011e565b601f0160209004906000526020600020908101906200011d919062000121565b5b50565b5b808211156200013c57600081600090555060010162000122565b5090565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620001c257607f821691505b602082108103620001d857620001d76200017a565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620002427fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000203565b6200024e868362000203565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200029b620002956200028f8462000266565b62000270565b62000266565b9050919050565b6000819050919050565b620002b7836200027a565b620002cf620002c682620002a2565b84845462000210565b825550505050565b600090565b620002e6620002d7565b620002f3818484620002ac565b505050565b5b818110156200031b576200030f600082620002dc565b600181019050620002f9565b5050565b601f8211156200036a576200033481620001de565b6200033f84620001f3565b810160208510156200034f578190505b620003676200035e85620001f3565b830182620002f8565b50505b505050565b600082821c905092915050565b60006200038f600019846008026200036f565b1980831691505092915050565b6000620003aa83836200037c565b9150826002028217905092915050565b620003c58262000140565b67ffffffffffffffff811115620003e157620003e06200014b565b5b620003ed8254620001a9565b620003fa8282856200031f565b600060209050601f8311600181146200043257600084156200041d578287015190505b6200042985826200039c565b86555062000499565b601f1984166200044286620001de565b60005b828110156200046c5784890151825560018201915060208501945060208101905062000445565b868310156200048c578489015162000488601f8916826200037c565b8355505b6001600288020188555050505b505050505050565b61575180620004b16000396000f3fe6080604052600436106101355760003560e01c80638939e783116100ab578063cf2753cf1161006f578063cf2753cf14610418578063ec9485df14610456578063f40a214614610493578063f5714e64146104bc578063f700dbd2146104d8578063f732b0651461050157610135565b80638939e7831461032f5780638edb3f8b146103585780638fa111a5146103745780639eab6711146103b1578063b13d4242146103da57610135565b806355dc4b22116100fd57806355dc4b2214610230578063570467ac146102595780635e269bfe1461029657806360deaa2a146102bf57806361bc221a146102db5780637e51b8111461030657610135565b80630a4433e21461013a57806319b16c4c1461016357806331bcbcb3146101a15780633566cb95146101ca578063455b8551146101f3575b600080fd5b34801561014657600080fd5b50610161600480360381019061015c919061221e565b61053f565b005b34801561016f57600080fd5b5061018a600480360381019061018591906123d3565b61060e565b604051610198929190612538565b60405180910390f35b3480156101ad57600080fd5b506101c860048036038101906101c39190612568565b610b0d565b005b3480156101d657600080fd5b506101f160048036038101906101ec91906125d7565b610d9a565b005b3480156101ff57600080fd5b5061021a60048036038101906102159190612633565b610f02565b6040516102279190612856565b60405180910390f35b34801561023c57600080fd5b5061025760048036038101906102529190612878565b610f95565b005b34801561026557600080fd5b50610280600480360381019061027b91906123d3565b611387565b60405161028d9190612a93565b60405180910390f35b3480156102a257600080fd5b506102bd60048036038101906102b89190612ab5565b61141d565b005b6102d960048036038101906102d49190612b38565b6114a8565b005b3480156102e757600080fd5b506102f06115f6565b6040516102fd9190612b81565b60405180910390f35b34801561031257600080fd5b5061032d60048036038101906103289190612568565b6115fc565b005b34801561033b57600080fd5b5061035660048036038101906103519190612568565b611684565b005b610372600480360381019061036d9190612b38565b61170c565b005b34801561038057600080fd5b5061039b60048036038101906103969190612b38565b6118a1565b6040516103a89190612d2b565b60405180910390f35b3480156103bd57600080fd5b506103d860048036038101906103d39190612d4d565b611931565b005b3480156103e657600080fd5b5061040160048036038101906103fc9190612e10565b6119bc565b60405161040f9291906130d9565b60405180910390f35b34801561042457600080fd5b5061043f600480360381019061043a9190612633565b611a54565b60405161044d929190612538565b60405180910390f35b34801561046257600080fd5b5061047d60048036038101906104789190612633565b611aec565b60405161048a9190612b81565b60405180910390f35b34801561049f57600080fd5b506104ba60048036038101906104b59190613110565b611b76565b005b6104d660048036038101906104d19190612b38565b611d52565b005b3480156104e457600080fd5b506104ff60048036038101906104fa9190613193565b611eac565b005b34801561050d57600080fd5b506105286004803603810190610523919061339e565b611f78565b6040516105369291906136b5565b60405180910390f35b600061080073ffffffffffffffffffffffffffffffffffffffff1663b6039895868487876040518563ffffffff1660e01b8152600401610582949392919061384e565b6020604051808303816000875af11580156105a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c591906138a3565b905080610607576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105fe90613953565b60405180910390fd5b5050505050565b6000610618612016565b60006108009050600086866040516024016106349291906139ac565b6040516020818303038152906040527f241774e6000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000856040516020016106c69190613a18565b6040516020818303038152906040528051906020012090506040516020016106ed90613a7b565b6040516020818303038152906040528051906020012081036107d9576000808473ffffffffffffffffffffffffffffffffffffffff16846040516107319190613acc565b600060405180830381855af49150503d806000811461076c576040519150601f19603f3d011682016040523d82523d6000602084013e610771565b606091505b5091509150816107b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ad90613b55565b60405180910390fd5b808060200190518101906107ca9190613c66565b80975081985050505050610b02565b6040516020016107e890613d0e565b6040516020818303038152906040528051906020012081036108d4576000808473ffffffffffffffffffffffffffffffffffffffff168460405161082c9190613acc565b600060405180830381855afa9150503d8060008114610867576040519150601f19603f3d011682016040523d82523d6000602084013e61086c565b606091505b5091509150816108b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a890613d6f565b60405180910390fd5b808060200190518101906108c59190613c66565b80975081985050505050610b01565b6040516020016108e390613ddb565b6040516020818303038152906040528051906020012081036109d1576000808473ffffffffffffffffffffffffffffffffffffffff16846040516109279190613acc565b6000604051808303816000865af19150503d8060008114610964576040519150601f19603f3d011682016040523d82523d6000602084013e610969565b606091505b5091509150816109ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a590613e3c565b60405180910390fd5b808060200190518101906109c29190613c66565b80975081985050505050610b00565b6040516020016109e090613ea8565b604051602081830303815290604052805190602001208103610ac45760006040518060400160405280601a81526020017f64656c65676174696f6e28616464726573732c737472696e6729000000000000815250805190602001209050600060a490506060600060208b01516020808d0101516040518681528e6004820152604060248201526033604482015282606482015281608482015260c081878360008e5af281519c5060608201519450610100820160405280610aa057600080fd5b50505050604051806040016040528083815260200182815250975050505050610aff565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af690613f09565b60405180910390fd5b5b5b5b505050935093915050565b600061080073ffffffffffffffffffffffffffffffffffffffff1663b6039895308460016040518463ffffffff1660e01b8152600401610b4f939291906140d7565b6020604051808303816000875af1158015610b6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9291906138a3565b905080610bd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bcb90614161565b60405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff163384604051602401610c00929190614181565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610c8a9190613acc565b6000604051808303816000865af19150503d8060008114610cc7576040519150601f19603f3d011682016040523d82523d6000602084013e610ccc565b606091505b5050905080610d10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d07906141f6565b60405180910390fd5b61080073ffffffffffffffffffffffffffffffffffffffff166353266bbb3386866040518463ffffffff1660e01b8152600401610d4f93929190614216565b6020604051808303816000875af1158015610d6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9291906138a3565b505050505050565b600061080073ffffffffffffffffffffffffffffffffffffffff1663b6039895308460016040518463ffffffff1660e01b8152600401610ddc939291906140d7565b6020604051808303816000875af1158015610dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1f91906138a3565b905080610e61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e58906142a0565b60405180910390fd5b61080073ffffffffffffffffffffffffffffffffffffffff166353266bbb3085856040518463ffffffff1660e01b8152600401610ea093929190614216565b6020604051808303816000875af1158015610ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee391906138a3565b506001600080828254610ef691906142ef565b92505081905550505050565b610f0a612030565b61080073ffffffffffffffffffffffffffffffffffffffff1663a03ffee184846040518363ffffffff1660e01b8152600401610f479291906139ac565b600060405180830381865afa158015610f64573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610f8d919061457f565b905092915050565b600061080090506000858585604051602401610fb393929190614216565b6040516020818303038152906040527f3edab33c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000836040516020016110459190613a18565b60405160208183030381529060405280519060200120905060405160200161106c90613a7b565b6040516020818303038152906040528051906020012081036111395760008373ffffffffffffffffffffffffffffffffffffffff16836040516110af9190613acc565b600060405180830381855af49150503d80600081146110ea576040519150601f19603f3d011682016040523d82523d6000602084013e6110ef565b606091505b5050905080611133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161112a90613b55565b60405180910390fd5b5061137e565b60405160200161114890613d0e565b6040516020818303038152906040528051906020012081036112155760008373ffffffffffffffffffffffffffffffffffffffff168360405161118b9190613acc565b600060405180830381855afa9150503d80600081146111c6576040519150601f19603f3d011682016040523d82523d6000602084013e6111cb565b606091505b505090508061120f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120690613d6f565b60405180910390fd5b5061137d565b60405160200161122490613ddb565b6040516020818303038152906040528051906020012081036112f35760008373ffffffffffffffffffffffffffffffffffffffff16836040516112679190613acc565b6000604051808303816000865af19150503d80600081146112a4576040519150601f19603f3d011682016040523d82523d6000602084013e6112a9565b606091505b50509050806112ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112e490613e3c565b60405180910390fd5b5061137c565b60405160200161130290613ea8565b6040516020818303038152906040528051906020012081036113405760208201825160008082846000895af28061133857600080fd5b50505061137b565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137290613f09565b60405180910390fd5b5b5b5b50505050505050565b61138f612051565b61080073ffffffffffffffffffffffffffffffffffffffff16637d9f939c8585856040518463ffffffff1660e01b81526004016113ce939291906145c8565b600060405180830381865afa1580156113eb573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906114149190614830565b90509392505050565b61080073ffffffffffffffffffffffffffffffffffffffff166312d58dfe858585856040518563ffffffff1660e01b815260040161145e9493929190614879565b6020604051808303816000875af115801561147d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a191906138a3565b5050505050565b600061080073ffffffffffffffffffffffffffffffffffffffff1663b6039895303460016040518463ffffffff1660e01b81526004016114ea939291906140d7565b6020604051808303816000875af1158015611509573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152d91906138a3565b90508061156f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156690614911565b60405180910390fd5b61080073ffffffffffffffffffffffffffffffffffffffff166353266bbb3084346040518463ffffffff1660e01b81526004016115ae93929190614216565b6020604051808303816000875af11580156115cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f191906138a3565b505050565b60005481565b61080073ffffffffffffffffffffffffffffffffffffffff16633edab33c8484846040518463ffffffff1660e01b815260040161163b93929190614216565b6020604051808303816000875af115801561165a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061167e9190614931565b50505050565b61080073ffffffffffffffffffffffffffffffffffffffff166353266bbb8484846040518463ffffffff1660e01b81526004016116c393929190614216565b6020604051808303816000875af11580156116e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170691906138a3565b50505050565b600061080073ffffffffffffffffffffffffffffffffffffffff1663b6039895323460016040518463ffffffff1660e01b815260040161174e939291906140d7565b6020604051808303816000875af115801561176d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179191906138a3565b9050806117d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117ca90614911565b60405180910390fd5b61080073ffffffffffffffffffffffffffffffffffffffff166353266bbb3084346040518463ffffffff1660e01b815260040161181293929190614216565b6020604051808303816000875af1158015611831573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185591906138a3565b503373ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f1935050505015801561189c573d6000803e3d6000fd5b505050565b6118a9612079565b61080073ffffffffffffffffffffffffffffffffffffffff16630bc82a17836040518263ffffffff1660e01b81526004016118e4919061495e565b600060405180830381865afa158015611901573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061192a9190614b05565b9050919050565b61080073ffffffffffffffffffffffffffffffffffffffff166354b826f5858585856040518563ffffffff1660e01b81526004016119729493929190614b4e565b6020604051808303816000875af1158015611991573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b59190614931565b5050505050565b60606119c66120ed565b61080073ffffffffffffffffffffffffffffffffffffffff1663186b216785856040518363ffffffff1660e01b8152600401611a03929190614cff565b600060405180830381865afa158015611a20573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611a499190614ef3565b915091509250929050565b6000611a5e612016565b61080073ffffffffffffffffffffffffffffffffffffffff1663241774e685856040518363ffffffff1660e01b8152600401611a9b9291906139ac565b600060405180830381865afa158015611ab8573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611ae19190613c66565b915091509250929050565b600061080073ffffffffffffffffffffffffffffffffffffffff1663fc08930c8433856040518463ffffffff1660e01b8152600401611b2d93929190614f6b565b602060405180830381865afa158015611b4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b6e9190614fa9565b905092915050565b6000600167ffffffffffffffff811115611b9357611b926122a8565b5b604051908082528060200260200182016040528015611bc657816020015b6060815260200190600190039081611bb15790505b5090506040518060600160405280602581526020016156f76025913981600081518110611bf657611bf5614fd6565b5b6020026020010181905250600061080073ffffffffffffffffffffffffffffffffffffffff1663b60398958787856040518463ffffffff1660e01b8152600401611c42939291906150b6565b6020604051808303816000875af1158015611c61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c8591906138a3565b905080611cc7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cbe90615166565b60405180910390fd5b61080073ffffffffffffffffffffffffffffffffffffffff16633edab33c3285876040518463ffffffff1660e01b8152600401611d0693929190614216565b6020604051808303816000875af1158015611d25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d499190614931565b50505050505050565b600061080073ffffffffffffffffffffffffffffffffffffffff1663b6039895323460016040518463ffffffff1660e01b8152600401611d94939291906140d7565b6020604051808303816000875af1158015611db3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd791906138a3565b905080611e19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1090614911565b60405180910390fd5b61080073ffffffffffffffffffffffffffffffffffffffff166353266bbb3084600134611e4691906142ef565b6040518463ffffffff1660e01b8152600401611e6493929190614216565b6020604051808303816000875af1158015611e83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea791906138a3565b505050565b600061080073ffffffffffffffffffffffffffffffffffffffff166361dc5c3b8585856040518463ffffffff1660e01b8152600401611eed93929190615186565b6020604051808303816000875af1158015611f0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f3091906138a3565b905080611f72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f699061522a565b60405180910390fd5b50505050565b6060611f826120ed565b61080073ffffffffffffffffffffffffffffffffffffffff166310a2851c878787876040518563ffffffff1660e01b8152600401611fc394939291906152c0565b600060405180830381865afa158015611fe0573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612009919061567e565b9150915094509492505050565b604051806040016040528060608152602001600081525090565b60405180606001604052806060815260200160608152602001606081525090565b6040518060800160405280606081526020016060815260200160608152602001606081525090565b6040518061016001604052806060815260200160608152602001600015158152602001600060038111156120b0576120af612bb7565b5b8152602001600081526020016000815260200160608152602001600060070b8152602001600060070b815260200160008152602001600081525090565b604051806040016040528060608152602001600067ffffffffffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061215082612125565b9050919050565b61216081612145565b811461216b57600080fd5b50565b60008135905061217d81612157565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126121a8576121a7612183565b5b8235905067ffffffffffffffff8111156121c5576121c4612188565b5b6020830191508360208202830111156121e1576121e061218d565b5b9250929050565b6000819050919050565b6121fb816121e8565b811461220657600080fd5b50565b600081359050612218816121f2565b92915050565b600080600080606085870312156122385761223761211b565b5b60006122468782880161216e565b945050602085013567ffffffffffffffff81111561226757612266612120565b5b61227387828801612192565b9350935050604061228687828801612209565b91505092959194509250565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6122e082612297565b810181811067ffffffffffffffff821117156122ff576122fe6122a8565b5b80604052505050565b6000612312612111565b905061231e82826122d7565b919050565b600067ffffffffffffffff82111561233e5761233d6122a8565b5b61234782612297565b9050602081019050919050565b82818337600083830152505050565b600061237661237184612323565b612308565b90508281526020810184848401111561239257612391612292565b5b61239d848285612354565b509392505050565b600082601f8301126123ba576123b9612183565b5b81356123ca848260208601612363565b91505092915050565b6000806000606084860312156123ec576123eb61211b565b5b60006123fa8682870161216e565b935050602084013567ffffffffffffffff81111561241b5761241a612120565b5b612427868287016123a5565b925050604084013567ffffffffffffffff81111561244857612447612120565b5b612454868287016123a5565b9150509250925092565b612467816121e8565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b838110156124a757808201518184015260208101905061248c565b60008484015250505050565b60006124be8261246d565b6124c88185612478565b93506124d8818560208601612489565b6124e181612297565b840191505092915050565b6124f5816121e8565b82525050565b6000604083016000830151848203600086015261251882826124b3565b915050602083015161252d60208601826124ec565b508091505092915050565b600060408201905061254d600083018561245e565b818103602083015261255f81846124fb565b90509392505050565b6000806000606084860312156125815761258061211b565b5b600061258f8682870161216e565b935050602084013567ffffffffffffffff8111156125b0576125af612120565b5b6125bc868287016123a5565b92505060406125cd86828701612209565b9150509250925092565b600080604083850312156125ee576125ed61211b565b5b600083013567ffffffffffffffff81111561260c5761260b612120565b5b612618858286016123a5565b925050602061262985828601612209565b9150509250929050565b6000806040838503121561264a5761264961211b565b5b60006126588582860161216e565b925050602083013567ffffffffffffffff81111561267957612678612120565b5b612685858286016123a5565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60008160070b9050919050565b6126d1816126bb565b82525050565b600067ffffffffffffffff82169050919050565b6126f4816126d7565b82525050565b60c08201600082015161271060008501826126c8565b50602082015161272360208501826126c8565b50604082015161273660408501826124ec565b50606082015161274960608501826124ec565b50608082015161275c60808501826126eb565b5060a082015161276f60a08501826126c8565b50505050565b600061278183836126fa565b60c08301905092915050565b6000602082019050919050565b60006127a58261268f565b6127af818561269a565b93506127ba836126ab565b8060005b838110156127eb5781516127d28882612775565b97506127dd8361278d565b9250506001810190506127be565b5085935050505092915050565b6000606083016000830151848203600086015261281582826124b3565b9150506020830151848203602086015261282f82826124b3565b91505060408301518482036040860152612849828261279a565b9150508091505092915050565b6000602082019050818103600083015261287081846127f8565b905092915050565b600080600080608085870312156128925761289161211b565b5b60006128a08782880161216e565b945050602085013567ffffffffffffffff8111156128c1576128c0612120565b5b6128cd878288016123a5565b93505060406128de87828801612209565b925050606085013567ffffffffffffffff8111156128ff576128fe612120565b5b61290b878288016123a5565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60808201600082015161295960008501826126c8565b50602082015161296c60208501826126c8565b50604082015161297f60408501826124ec565b50606082015161299260608501826124ec565b50505050565b60006129a48383612943565b60808301905092915050565b6000602082019050919050565b60006129c882612917565b6129d28185612922565b93506129dd83612933565b8060005b83811015612a0e5781516129f58882612998565b9750612a00836129b0565b9250506001810190506129e1565b5085935050505092915050565b60006080830160008301518482036000860152612a3882826124b3565b91505060208301518482036020860152612a5282826124b3565b91505060408301518482036040860152612a6c82826124b3565b91505060608301518482036060860152612a8682826129bd565b9150508091505092915050565b60006020820190508181036000830152612aad8184612a1b565b905092915050565b60008060008060808587031215612acf57612ace61211b565b5b6000612add8782880161216e565b945050602085013567ffffffffffffffff811115612afe57612afd612120565b5b612b0a878288016123a5565b9350506040612b1b87828801612209565b9250506060612b2c87828801612209565b91505092959194509250565b600060208284031215612b4e57612b4d61211b565b5b600082013567ffffffffffffffff811115612b6c57612b6b612120565b5b612b78848285016123a5565b91505092915050565b6000602082019050612b96600083018461245e565b92915050565b60008115159050919050565b612bb181612b9c565b82525050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110612bf757612bf6612bb7565b5b50565b6000819050612c0882612be6565b919050565b6000612c1882612bfa565b9050919050565b612c2881612c0d565b82525050565b6000610160830160008301518482036000860152612c4c82826124b3565b91505060208301518482036020860152612c6682826124b3565b9150506040830151612c7b6040860182612ba8565b506060830151612c8e6060860182612c1f565b506080830151612ca160808601826124ec565b5060a0830151612cb460a08601826124ec565b5060c083015184820360c0860152612ccc82826124b3565b91505060e0830151612ce160e08601826126c8565b50610100830151612cf66101008601826126c8565b50610120830151612d0b6101208601826124ec565b50610140830151612d206101408601826124ec565b508091505092915050565b60006020820190508181036000830152612d458184612c2e565b905092915050565b60008060008060808587031215612d6757612d6661211b565b5b6000612d758782880161216e565b945050602085013567ffffffffffffffff811115612d9657612d95612120565b5b612da2878288016123a5565b935050604085013567ffffffffffffffff811115612dc357612dc2612120565b5b612dcf878288016123a5565b9250506060612de087828801612209565b91505092959194509250565b600080fd5b600060a08284031215612e0757612e06612dec565b5b81905092915050565b60008060408385031215612e2757612e2661211b565b5b600083013567ffffffffffffffff811115612e4557612e44612120565b5b612e51858286016123a5565b925050602083013567ffffffffffffffff811115612e7257612e71612120565b5b612e7e85828601612df1565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000610160830160008301518482036000860152612ed282826124b3565b91505060208301518482036020860152612eec82826124b3565b9150506040830151612f016040860182612ba8565b506060830151612f146060860182612c1f565b506080830151612f2760808601826124ec565b5060a0830151612f3a60a08601826124ec565b5060c083015184820360c0860152612f5282826124b3565b91505060e0830151612f6760e08601826126c8565b50610100830151612f7c6101008601826126c8565b50610120830151612f916101208601826124ec565b50610140830151612fa66101408601826124ec565b508091505092915050565b6000612fbd8383612eb4565b905092915050565b6000602082019050919050565b6000612fdd82612e88565b612fe78185612e93565b935083602082028501612ff985612ea4565b8060005b8581101561303557848403895281516130168582612fb1565b945061302183612fc5565b925060208a01995050600181019050612ffd565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b600061306e82613047565b6130788185613052565b9350613088818560208601612489565b61309181612297565b840191505092915050565b600060408301600083015184820360008601526130b98282613063565b91505060208301516130ce60208601826126eb565b508091505092915050565b600060408201905081810360008301526130f38185612fd2565b90508181036020830152613107818461309c565b90509392505050565b6000806000806080858703121561312a5761312961211b565b5b60006131388782880161216e565b945050602061314987828801612209565b935050604061315a87828801612209565b925050606085013567ffffffffffffffff81111561317b5761317a612120565b5b613187878288016123a5565b91505092959194509250565b6000806000604084860312156131ac576131ab61211b565b5b60006131ba8682870161216e565b935050602084013567ffffffffffffffff8111156131db576131da612120565b5b6131e786828701612192565b92509250509250925092565b600080fd5b600080fd5b600067ffffffffffffffff821115613218576132176122a8565b5b61322182612297565b9050602081019050919050565b600061324161323c846131fd565b612308565b90508281526020810184848401111561325d5761325c612292565b5b613268848285612354565b509392505050565b600082601f83011261328557613284612183565b5b813561329584826020860161322e565b91505092915050565b6132a7816126d7565b81146132b257600080fd5b50565b6000813590506132c48161329e565b92915050565b6132d381612b9c565b81146132de57600080fd5b50565b6000813590506132f0816132ca565b92915050565b600060a0828403121561330c5761330b6131f3565b5b61331660a0612308565b9050600082013567ffffffffffffffff811115613336576133356131f8565b5b61334284828501613270565b6000830152506020613356848285016132b5565b602083015250604061336a848285016132b5565b604083015250606061337e848285016132e1565b6060830152506080613392848285016132e1565b60808301525092915050565b600080600080608085870312156133b8576133b761211b565b5b60006133c68782880161216e565b945050602085013567ffffffffffffffff8111156133e7576133e6612120565b5b6133f3878288016123a5565b935050604085013567ffffffffffffffff81111561341457613413612120565b5b613420878288016123a5565b925050606085013567ffffffffffffffff81111561344157613440612120565b5b61344d878288016132f6565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600060808301600083015184820360008601526134a282826124b3565b915050602083015184820360208601526134bc82826124b3565b915050604083015184820360408601526134d682826124b3565b915050606083015184820360608601526134f082826129bd565b9150508091505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60a08201600082015161353f6000850182612943565b50602082015161355260808501826124ec565b50505050565b60006135648383613529565b60a08301905092915050565b6000602082019050919050565b6000613588826134fd565b6135928185613508565b935061359d83613519565b8060005b838110156135ce5781516135b58882613558565b97506135c083613570565b9250506001810190506135a1565b5085935050505092915050565b600060408301600083015184820360008601526135f88282613485565b91505060208301518482036020860152613612828261357d565b9150508091505092915050565b600061362b83836135db565b905092915050565b6000602082019050919050565b600061364b82613459565b6136558185613464565b93508360208202850161366785613475565b8060005b858110156136a35784840389528151613684858261361f565b945061368f83613633565b925060208a0199505060018101905061366b565b50829750879550505050505092915050565b600060408201905081810360008301526136cf8185613640565b905081810360208301526136e3818461309c565b90509392505050565b6136f581612145565b82525050565b600082825260208201905092915050565b6000819050919050565b60006137228385612478565b935061372f838584612354565b61373883612297565b840190509392505050565b6000613750848484613716565b90509392505050565b600080fd5b600080fd5b600080fd5b6000808335600160200384360303811261378557613784613763565b5b83810192508235915060208301925067ffffffffffffffff8211156137ad576137ac613759565b5b6001820236038313156137c3576137c261375e565b5b509250929050565b6000602082019050919050565b60006137e483856136fb565b9350836020840285016137f68461370c565b8060005b8781101561383c5784840389526138118284613768565b61381c868284613743565b9550613827846137cb565b935060208b019a5050506001810190506137fa565b50829750879450505050509392505050565b600060608201905061386360008301876136ec565b613870602083018661245e565b81810360408301526138838184866137d8565b905095945050505050565b60008151905061389d816132ca565b92915050565b6000602082840312156138b9576138b861211b565b5b60006138c78482850161388e565b91505092915050565b600082825260208201905092915050565b7f4661696c656420746f20617070726f7665207374616b696e67206d6574686f6460008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b600061393d6021836138d0565b9150613948826138e1565b604082019050919050565b6000602082019050818103600083015261396c81613930565b9050919050565b600061397e8261246d565b61398881856138d0565b9350613998818560208601612489565b6139a181612297565b840191505092915050565b60006040820190506139c160008301856136ec565b81810360208301526139d38184613973565b90509392505050565b600081905092915050565b60006139f28261246d565b6139fc81856139dc565b9350613a0c818560208601612489565b80840191505092915050565b6000613a2482846139e7565b915081905092915050565b7f64656c656761746563616c6c0000000000000000000000000000000000000000600082015250565b6000613a65600c836139dc565b9150613a7082613a2f565b600c82019050919050565b6000613a8682613a58565b9150819050919050565b600081905092915050565b6000613aa682613047565b613ab08185613a90565b9350613ac0818560208601612489565b80840191505092915050565b6000613ad88284613a9b565b915081905092915050565b7f6661696c65642064656c656761746563616c6c20746f20707265636f6d70696c60008201527f6500000000000000000000000000000000000000000000000000000000000000602082015250565b6000613b3f6021836138d0565b9150613b4a82613ae3565b604082019050919050565b60006020820190508181036000830152613b6e81613b32565b9050919050565b600081519050613b84816121f2565b92915050565b6000613b9d613b9884612323565b612308565b905082815260208101848484011115613bb957613bb8612292565b5b613bc4848285612489565b509392505050565b600082601f830112613be157613be0612183565b5b8151613bf1848260208601613b8a565b91505092915050565b600060408284031215613c1057613c0f6131f3565b5b613c1a6040612308565b9050600082015167ffffffffffffffff811115613c3a57613c396131f8565b5b613c4684828501613bcc565b6000830152506020613c5a84828501613b75565b60208301525092915050565b60008060408385031215613c7d57613c7c61211b565b5b6000613c8b85828601613b75565b925050602083015167ffffffffffffffff811115613cac57613cab612120565b5b613cb885828601613bfa565b9150509250929050565b7f73746174696363616c6c00000000000000000000000000000000000000000000600082015250565b6000613cf8600a836139dc565b9150613d0382613cc2565b600a82019050919050565b6000613d1982613ceb565b9150819050919050565b7f6661696c65642073746174696363616c6c20746f20707265636f6d70696c6500600082015250565b6000613d59601f836138d0565b9150613d6482613d23565b602082019050919050565b60006020820190508181036000830152613d8881613d4c565b9050919050565b7f63616c6c00000000000000000000000000000000000000000000000000000000600082015250565b6000613dc56004836139dc565b9150613dd082613d8f565b600482019050919050565b6000613de682613db8565b9150819050919050565b7f6661696c65642063616c6c20746f20707265636f6d70696c6500000000000000600082015250565b6000613e266019836138d0565b9150613e3182613df0565b602082019050919050565b60006020820190508181036000830152613e5581613e19565b9050919050565b7f63616c6c636f6465000000000000000000000000000000000000000000000000600082015250565b6000613e926008836139dc565b9150613e9d82613e5c565b600882019050919050565b6000613eb382613e85565b9150819050919050565b7f696e76616c69642063616c6c7479706500000000000000000000000000000000600082015250565b6000613ef36010836138d0565b9150613efe82613ebd565b602082019050919050565b60006020820190508181036000830152613f2281613ee6565b9050919050565b600081549050919050565b60008190508160005260206000209050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613f9057607f821691505b602082108103613fa357613fa2613f49565b5b50919050565b60008190508160005260206000209050919050565b60008154613fcb81613f78565b613fd58186612478565b94506001821660008114613ff0576001811461400657614039565b60ff198316865281151560200286019350614039565b61400f85613fa9565b60005b8381101561403157815481890152600182019150602081019050614012565b808801955050505b50505092915050565b600061404e8383613fbe565b905092915050565b6000600182019050919050565b600061406e82613f29565b61407881856136fb565b93508360208202850161408a85613f34565b8060005b858110156140c5578484038952816140a68582614042565b94506140b183614056565b925060208a0199505060018101905061408e565b50829750879550505050505092915050565b60006060820190506140ec60008301866136ec565b6140f9602083018561245e565b818103604083015261410b8184614063565b9050949350505050565b7f64656c65676174696f6e20617070726f76616c206661696c6564000000000000600082015250565b600061414b601a836138d0565b915061415682614115565b602082019050919050565b6000602082019050818103600083015261417a8161413e565b9050919050565b600060408201905061419660008301856136ec565b6141a3602083018461245e565b9392505050565b7f7472616e73666572206661696c65640000000000000000000000000000000000600082015250565b60006141e0600f836138d0565b91506141eb826141aa565b602082019050919050565b6000602082019050818103600083015261420f816141d3565b9050919050565b600060608201905061422b60008301866136ec565b818103602083015261423d8185613973565b905061424c604083018461245e565b949350505050565b7f5374616b696e6720417070726f7665206661696c656400000000000000000000600082015250565b600061428a6016836138d0565b915061429582614254565b602082019050919050565b600060208201905081810360008301526142b98161427d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006142fa826121e8565b9150614305836121e8565b925082820190508082111561431d5761431c6142c0565b5b92915050565b600067ffffffffffffffff82111561433e5761433d6122a8565b5b602082029050602081019050919050565b614358816126bb565b811461436357600080fd5b50565b6000815190506143758161434f565b92915050565b60008151905061438a8161329e565b92915050565b600060c082840312156143a6576143a56131f3565b5b6143b060c0612308565b905060006143c084828501614366565b60008301525060206143d484828501614366565b60208301525060406143e884828501613b75565b60408301525060606143fc84828501613b75565b60608301525060806144108482850161437b565b60808301525060a061442484828501614366565b60a08301525092915050565b600061444361443e84614323565b612308565b90508083825260208201905060c084028301858111156144665761446561218d565b5b835b8181101561448f578061447b8882614390565b84526020840193505060c081019050614468565b5050509392505050565b600082601f8301126144ae576144ad612183565b5b81516144be848260208601614430565b91505092915050565b6000606082840312156144dd576144dc6131f3565b5b6144e76060612308565b9050600082015167ffffffffffffffff811115614507576145066131f8565b5b61451384828501613bcc565b600083015250602082015167ffffffffffffffff811115614537576145366131f8565b5b61454384828501613bcc565b602083015250604082015167ffffffffffffffff811115614567576145666131f8565b5b61457384828501614499565b60408301525092915050565b6000602082840312156145955761459461211b565b5b600082015167ffffffffffffffff8111156145b3576145b2612120565b5b6145bf848285016144c7565b91505092915050565b60006060820190506145dd60008301866136ec565b81810360208301526145ef8185613973565b905081810360408301526146038184613973565b9050949350505050565b600067ffffffffffffffff821115614628576146276122a8565b5b602082029050602081019050919050565b60006080828403121561464f5761464e6131f3565b5b6146596080612308565b9050600061466984828501614366565b600083015250602061467d84828501614366565b602083015250604061469184828501613b75565b60408301525060606146a584828501613b75565b60608301525092915050565b60006146c46146bf8461460d565b612308565b905080838252602082019050608084028301858111156146e7576146e661218d565b5b835b8181101561471057806146fc8882614639565b8452602084019350506080810190506146e9565b5050509392505050565b600082601f83011261472f5761472e612183565b5b815161473f8482602086016146b1565b91505092915050565b60006080828403121561475e5761475d6131f3565b5b6147686080612308565b9050600082015167ffffffffffffffff811115614788576147876131f8565b5b61479484828501613bcc565b600083015250602082015167ffffffffffffffff8111156147b8576147b76131f8565b5b6147c484828501613bcc565b602083015250604082015167ffffffffffffffff8111156147e8576147e76131f8565b5b6147f484828501613bcc565b604083015250606082015167ffffffffffffffff811115614818576148176131f8565b5b6148248482850161471a565b60608301525092915050565b6000602082840312156148465761484561211b565b5b600082015167ffffffffffffffff81111561486457614863612120565b5b61487084828501614748565b91505092915050565b600060808201905061488e60008301876136ec565b81810360208301526148a08186613973565b90506148af604083018561245e565b6148bc606083018461245e565b95945050505050565b7f44656c656761746520417070726f7665206661696c6564000000000000000000600082015250565b60006148fb6017836138d0565b9150614906826148c5565b602082019050919050565b6000602082019050818103600083015261492a816148ee565b9050919050565b6000602082840312156149475761494661211b565b5b600061495584828501614366565b91505092915050565b600060208201905081810360008301526149788184613973565b905092915050565b6004811061498d57600080fd5b50565b60008151905061499f81614980565b92915050565b600061016082840312156149bc576149bb6131f3565b5b6149c7610160612308565b9050600082015167ffffffffffffffff8111156149e7576149e66131f8565b5b6149f384828501613bcc565b600083015250602082015167ffffffffffffffff811115614a1757614a166131f8565b5b614a2384828501613bcc565b6020830152506040614a378482850161388e565b6040830152506060614a4b84828501614990565b6060830152506080614a5f84828501613b75565b60808301525060a0614a7384828501613b75565b60a08301525060c082015167ffffffffffffffff811115614a9757614a966131f8565b5b614aa384828501613bcc565b60c08301525060e0614ab784828501614366565b60e083015250610100614acc84828501614366565b61010083015250610120614ae284828501613b75565b61012083015250610140614af884828501613b75565b6101408301525092915050565b600060208284031215614b1b57614b1a61211b565b5b600082015167ffffffffffffffff811115614b3957614b38612120565b5b614b45848285016149a5565b91505092915050565b6000608082019050614b6360008301876136ec565b8181036020830152614b758186613973565b90508181036040830152614b898185613973565b9050614b98606083018461245e565b95945050505050565b60008083356001602003843603038112614bbe57614bbd613763565b5b83810192508235915060208301925067ffffffffffffffff821115614be657614be5613759565b5b600182023603831315614bfc57614bfb61375e565b5b509250929050565b6000614c108385613052565b9350614c1d838584612354565b614c2683612297565b840190509392505050565b6000614c4060208401846132b5565b905092915050565b6000614c5760208401846132e1565b905092915050565b600060a08301614c726000840184614ba1565b8583036000870152614c85838284614c04565b92505050614c966020840184614c31565b614ca360208601826126eb565b50614cb16040840184614c31565b614cbe60408601826126eb565b50614ccc6060840184614c48565b614cd96060860182612ba8565b50614ce76080840184614c48565b614cf46080860182612ba8565b508091505092915050565b60006040820190508181036000830152614d198185613973565b90508181036020830152614d2d8184614c5f565b90509392505050565b600067ffffffffffffffff821115614d5157614d506122a8565b5b602082029050602081019050919050565b6000614d75614d7084614d36565b612308565b90508083825260208201905060208402830185811115614d9857614d9761218d565b5b835b81811015614ddf57805167ffffffffffffffff811115614dbd57614dbc612183565b5b808601614dca89826149a5565b85526020850194505050602081019050614d9a565b5050509392505050565b600082601f830112614dfe57614dfd612183565b5b8151614e0e848260208601614d62565b91505092915050565b6000614e2a614e25846131fd565b612308565b905082815260208101848484011115614e4657614e45612292565b5b614e51848285612489565b509392505050565b600082601f830112614e6e57614e6d612183565b5b8151614e7e848260208601614e17565b91505092915050565b600060408284031215614e9d57614e9c6131f3565b5b614ea76040612308565b9050600082015167ffffffffffffffff811115614ec757614ec66131f8565b5b614ed384828501614e59565b6000830152506020614ee78482850161437b565b60208301525092915050565b60008060408385031215614f0a57614f0961211b565b5b600083015167ffffffffffffffff811115614f2857614f27612120565b5b614f3485828601614de9565b925050602083015167ffffffffffffffff811115614f5557614f54612120565b5b614f6185828601614e87565b9150509250929050565b6000606082019050614f8060008301866136ec565b614f8d60208301856136ec565b8181036040830152614f9f8184613973565b9050949350505050565b600060208284031215614fbf57614fbe61211b565b5b6000614fcd84828501613b75565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b6000819050602082019050919050565b600061502c83836124b3565b905092915050565b6000602082019050919050565b600061504c82615005565b61505681856136fb565b93508360208202850161506885615010565b8060005b858110156150a457848403895281516150858582615020565b945061509083615034565b925060208a0199505060018101905061506c565b50829750879550505050505092915050565b60006060820190506150cb60008301866136ec565b6150d8602083018561245e565b81810360408301526150ea8184615041565b9050949350505050565b7f6661696c656420746f20617070726f766520756e64656c65676174696f6e206d60008201527f6574686f64000000000000000000000000000000000000000000000000000000602082015250565b60006151506025836138d0565b915061515b826150f4565b604082019050919050565b6000602082019050818103600083015261517f81615143565b9050919050565b600060408201905061519b60008301866136ec565b81810360208301526151ae8184866137d8565b9050949350505050565b7f4661696c656420746f207265766f6b6520617070726f76616c20666f7220737460008201527f616b696e67206d6574686f647300000000000000000000000000000000000000602082015250565b6000615214602d836138d0565b915061521f826151b8565b604082019050919050565b6000602082019050818103600083015261524381615207565b9050919050565b600060a08301600083015184820360008601526152678282613063565b915050602083015161527c60208601826126eb565b50604083015161528f60408601826126eb565b5060608301516152a26060860182612ba8565b5060808301516152b56080860182612ba8565b508091505092915050565b60006080820190506152d560008301876136ec565b81810360208301526152e78186613973565b905081810360408301526152fb8185613973565b9050818103606083015261530f818461524a565b905095945050505050565b600067ffffffffffffffff821115615335576153346122a8565b5b602082029050602081019050919050565b60006080828403121561535c5761535b6131f3565b5b6153666080612308565b9050600082015167ffffffffffffffff811115615386576153856131f8565b5b61539284828501613bcc565b600083015250602082015167ffffffffffffffff8111156153b6576153b56131f8565b5b6153c284828501613bcc565b602083015250604082015167ffffffffffffffff8111156153e6576153e56131f8565b5b6153f284828501613bcc565b604083015250606082015167ffffffffffffffff811115615416576154156131f8565b5b6154228482850161471a565b60608301525092915050565b600067ffffffffffffffff821115615449576154486122a8565b5b602082029050602081019050919050565b600060a082840312156154705761546f6131f3565b5b61547a6040612308565b9050600061548a84828501614639565b600083015250608061549e84828501613b75565b60208301525092915050565b60006154bd6154b88461542e565b612308565b90508083825260208201905060a084028301858111156154e0576154df61218d565b5b835b8181101561550957806154f5888261545a565b84526020840193505060a0810190506154e2565b5050509392505050565b600082601f83011261552857615527612183565b5b81516155388482602086016154aa565b91505092915050565b600060408284031215615557576155566131f3565b5b6155616040612308565b9050600082015167ffffffffffffffff811115615581576155806131f8565b5b61558d84828501615346565b600083015250602082015167ffffffffffffffff8111156155b1576155b06131f8565b5b6155bd84828501615513565b60208301525092915050565b60006155dc6155d78461531a565b612308565b905080838252602082019050602084028301858111156155ff576155fe61218d565b5b835b8181101561564657805167ffffffffffffffff81111561562457615623612183565b5b8086016156318982615541565b85526020850194505050602081019050615601565b5050509392505050565b600082601f83011261566557615664612183565b5b81516156758482602086016155c9565b91505092915050565b600080604083850312156156955761569461211b565b5b600083015167ffffffffffffffff8111156156b3576156b2612120565b5b6156bf85828601615650565b925050602083015167ffffffffffffffff8111156156e0576156df612120565b5b6156ec85828601614e87565b915050925092905056fe2f636f736d6f732e7374616b696e672e763162657461312e4d7367556e64656c6567617465a26469706673582212209f5ff7a1cd36ef190a842d0328bc0ab39b30a165eafcd11a415c09348da2a2d464736f6c634300081200332f636f736d6f732e7374616b696e672e763162657461312e4d736744656c6567617465" -} diff --git a/precompiles/staking/testdata/StakingCaller.sol b/precompiles/staking/testdata/StakingCaller.sol deleted file mode 100644 index a1f08562..00000000 --- a/precompiles/staking/testdata/StakingCaller.sol +++ /dev/null @@ -1,507 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-only -pragma solidity >=0.8.17; - -import "../StakingI.sol" as staking; - -/// @title StakingCaller -/// @author Evmos Core Team -/// @dev This contract is used to test external contract calls to the staking precompile. -contract StakingCaller { - /// counter is used to test the state persistence bug, when EVM and Cosmos state were both changed in the same function. - uint256 public counter; - string[] private delegateMethod = [staking.MSG_DELEGATE]; - - /// @dev This function calls the staking precompile's approve method. - /// @param _addr The address to approve. - /// @param _methods The methods to approve. - function testApprove( - address _addr, - string[] calldata _methods, - uint256 _amount - ) public { - bool success = staking.STAKING_CONTRACT.approve( - _addr, - _amount, - _methods - ); - require(success, "Failed to approve staking methods"); - } - - /// @dev This function calls the staking precompile's revoke method. - /// @param _grantee The address that was approved to spend the funds. - /// @param _methods The methods to revoke. - function testRevoke( - address _grantee, - string[] calldata _methods - ) public { - bool success = staking.STAKING_CONTRACT.revoke( - _grantee, - _methods - ); - require(success, "Failed to revoke approval for staking methods"); - } - - /// @dev This function calls the staking precompile's delegate method. - /// @param _addr The address to approve. - /// @param _validatorAddr The validator address to delegate to. - /// @param _amount The amount to delegate. - function testDelegate( - address _addr, - string memory _validatorAddr, - uint256 _amount - ) public { - staking.STAKING_CONTRACT.delegate(_addr, _validatorAddr, _amount); - } - - /// @dev This function calls the staking precompile's undelegate method. - /// @param _addr The address to approve. - /// @param _validatorAddr The validator address to delegate to. - /// @param _amount The amount to delegate. - function testUndelegate( - address _addr, - string memory _validatorAddr, - uint256 _amount - ) public { - staking.STAKING_CONTRACT.undelegate(_addr, _validatorAddr, _amount); - } - - /// @dev This function calls the staking precompile's redelegate method. - /// @param _addr The address to approve. - /// @param _validatorSrcAddr The validator address to delegate from. - /// @param _validatorDstAddr The validator address to delegate to. - /// @param _amount The amount to delegate. - function testRedelegate( - address _addr, - string memory _validatorSrcAddr, - string memory _validatorDstAddr, - uint256 _amount - ) public { - staking.STAKING_CONTRACT.redelegate( - _addr, - _validatorSrcAddr, - _validatorDstAddr, - _amount - ); - } - - /// @dev This function calls the staking precompile's cancel unbonding delegation method. - /// @param _addr The address to approve. - /// @param _validatorAddr The validator address to delegate from. - /// @param _amount The amount to delegate. - /// @param _creationHeight The creation height of the unbonding delegation. - function testCancelUnbonding( - address _addr, - string memory _validatorAddr, - uint256 _amount, - uint256 _creationHeight - ) public { - staking.STAKING_CONTRACT.cancelUnbondingDelegation( - _addr, - _validatorAddr, - _amount, - _creationHeight - ); - } - - /// @dev This function calls the staking precompile's allowance query method. - /// @param _grantee The address that received the grant. - /// @param method The method to query. - /// @return allowance The allowance. - function getAllowance( - address _grantee, - string memory method - ) public view returns (uint256 allowance) { - return staking.STAKING_CONTRACT.allowance(_grantee, msg.sender, method); - } - - /// @dev This function calls the staking precompile's validator query method. - /// @param _validatorAddr The validator address to query. - /// @return validator The validator. - function getValidator( - string memory _validatorAddr - ) public view returns (staking.Validator memory validator) { - return staking.STAKING_CONTRACT.validator(_validatorAddr); - } - - /// @dev This function calls the staking precompile's validators query method. - /// @param _status The status of the validators to query. - /// @param _pageRequest The page request to query. - /// @return validators The validators. - /// @return pageResponse The page response. - function getValidators( - string memory _status, - staking.PageRequest calldata _pageRequest - ) - public - view - returns ( - staking.Validator[] memory validators, - staking.PageResponse memory pageResponse - ) - { - return staking.STAKING_CONTRACT.validators(_status, _pageRequest); - } - - /// @dev This function calls the staking precompile's delegation query method. - /// @param _addr The address to approve. - /// @param _validatorAddr The validator address to delegate from. - /// @return shares The shares of the delegation. - /// @return balance The balance of the delegation. - function getDelegation( - address _addr, - string memory _validatorAddr - ) public view returns (uint256 shares, staking.Coin memory balance) { - return staking.STAKING_CONTRACT.delegation(_addr, _validatorAddr); - } - - /// @dev This function calls the staking precompile's redelegations query method. - /// @param _addr The address to approve. - /// @param _validatorSrcAddr The validator address to delegate from. - /// @param _validatorDstAddr The validator address to delegate to. - /// @return redelegation The redelegation output. - function getRedelegation( - address _addr, - string memory _validatorSrcAddr, - string memory _validatorDstAddr - ) public view returns (staking.RedelegationOutput memory redelegation) { - return - staking.STAKING_CONTRACT.redelegation( - _addr, - _validatorSrcAddr, - _validatorDstAddr - ); - } - - /// @dev This function calls the staking precompile's redelegations query method. - /// @param _delegatorAddr The delegator address. - /// @param _validatorSrcAddr The validator address to delegate from. - /// @param _validatorDstAddr The validator address to delegate to. - /// @param _pageRequest The page request to query. - /// @return response The redelegation response. - function getRedelegations( - address _delegatorAddr, - string memory _validatorSrcAddr, - string memory _validatorDstAddr, - staking.PageRequest memory _pageRequest - ) - public - view - returns ( - staking.RedelegationResponse[] memory response, - staking.PageResponse memory pageResponse - ) - { - return - staking.STAKING_CONTRACT.redelegations( - _delegatorAddr, - _validatorSrcAddr, - _validatorDstAddr, - _pageRequest - ); - } - - /// @dev This function calls the staking precompile's unbonding delegation query method. - /// @param _addr The address to approve. - /// @param _validatorAddr The validator address to delegate from. - /// @return unbondingDelegation The unbonding delegation output. - function getUnbondingDelegation( - address _addr, - string memory _validatorAddr - ) public view returns (staking.UnbondingDelegationOutput memory unbondingDelegation) { - return - staking.STAKING_CONTRACT.unbondingDelegation(_addr, _validatorAddr); - } - - /// @dev This function calls the staking precompile's approve method to grant approval for an undelegation. - /// Next, the undelegate method is called to execute an unbonding. - /// @param _addr The address to approve. - /// @param _approveAmount The amount to approve. - /// @param _undelegateAmount The amount to undelegate. - /// @param _validatorAddr The validator address to delegate from. - function testApproveAndThenUndelegate( - address _addr, - uint256 _approveAmount, - uint256 _undelegateAmount, - string memory _validatorAddr - ) public { - string[] memory approvedMethods = new string[](1); - approvedMethods[0] = staking.MSG_UNDELEGATE; - bool success = staking.STAKING_CONTRACT.approve( - _addr, - _approveAmount, - approvedMethods - ); - require(success, "failed to approve undelegation method"); - staking.STAKING_CONTRACT.undelegate( - tx.origin, - _validatorAddr, - _undelegateAmount - ); - } - - /// @dev This function is used to test the behaviour when executing transactions using special function calling opcodes, - /// like call, delegatecall, staticcall, and callcode. - /// @param _addr The address to approve. - /// @param _validatorAddr The validator address to delegate from. - /// @param _amount The amount to undelegate. - /// @param _calltype The opcode to use. - function testCallUndelegate( - address _addr, - string memory _validatorAddr, - uint256 _amount, - string memory _calltype - ) public { - address calledContractAddress = staking.STAKING_PRECOMPILE_ADDRESS; - bytes memory payload = abi.encodeWithSignature( - "undelegate(address,string,uint256)", - _addr, - _validatorAddr, - _amount - ); - bytes32 calltypeHash = keccak256(abi.encodePacked(_calltype)); - - if (calltypeHash == keccak256(abi.encodePacked("delegatecall"))) { - (bool success, ) = calledContractAddress.delegatecall(payload); - require(success, "failed delegatecall to precompile"); - } else if (calltypeHash == keccak256(abi.encodePacked("staticcall"))) { - (bool success, ) = calledContractAddress.staticcall(payload); - require(success, "failed staticcall to precompile"); - } else if (calltypeHash == keccak256(abi.encodePacked("call"))) { - (bool success, ) = calledContractAddress.call(payload); - require(success, "failed call to precompile"); - } else if (calltypeHash == keccak256(abi.encodePacked("callcode"))) { - // NOTE: callcode is deprecated and now only available via inline assembly - assembly { - // Load the function signature and argument data onto the stack - let ptr := add(payload, 0x20) - let len := mload(payload) - - // Invoke the contract at calledContractAddress in the context of the current contract - // using CALLCODE opcode and the loaded function signature and argument data - let success := callcode( - gas(), - calledContractAddress, - 0, - ptr, - len, - 0, - 0 - ) - - // Check if the call was successful and revert the transaction if it failed - if iszero(success) { - revert(0, 0) - } - } - } else { - revert("invalid calltype"); - } - } - - /// @dev This function is used to test the behaviour when executing queries using special function calling opcodes, - /// like call, delegatecall, staticcall, and callcode. - /// @param _addr The address of the delegator. - /// @param _validatorAddr The validator address to query for. - /// @param _calltype The opcode to use. - function testCallDelegation( - address _addr, - string memory _validatorAddr, - string memory _calltype - ) public returns (uint256 shares, staking.Coin memory coin) { - address calledContractAddress = staking.STAKING_PRECOMPILE_ADDRESS; - bytes memory payload = abi.encodeWithSignature( - "delegation(address,string)", - _addr, - _validatorAddr - ); - bytes32 calltypeHash = keccak256(abi.encodePacked(_calltype)); - - if (calltypeHash == keccak256(abi.encodePacked("delegatecall"))) { - (bool success, bytes memory data) = calledContractAddress - .delegatecall(payload); - require(success, "failed delegatecall to precompile"); - (shares, coin) = abi.decode(data, (uint256, staking.Coin)); - } else if (calltypeHash == keccak256(abi.encodePacked("staticcall"))) { - (bool success, bytes memory data) = calledContractAddress - .staticcall(payload); - require(success, "failed staticcall to precompile"); - (shares, coin) = abi.decode(data, (uint256, staking.Coin)); - } else if (calltypeHash == keccak256(abi.encodePacked("call"))) { - (bool success, bytes memory data) = calledContractAddress.call( - payload - ); - require(success, "failed call to precompile"); - (shares, coin) = abi.decode(data, (uint256, staking.Coin)); - } else if (calltypeHash == keccak256(abi.encodePacked("callcode"))) { - //Function signature - bytes4 sig = bytes4(keccak256(bytes("delegation(address,string)"))); - // Length of the input data is 164 bytes on 32bytes chunks: - // Memory location - // 0 - 4 byte signature x - // 1 - 0x0000..address x + 0x04 - // 2 - 0x0000..00 x + 0x24 - // 3 - 0x40..0000 x + 0x44 - // 4 - val_addr_chunk1 x + 0x64 - // 5 - val_addr_chunk2..000 x + 0x84 - uint256 len = 164; - // Coin type includes denom & amount - // need to get these separately from the bytes response - string memory denom; - uint256 amt; - - // NOTE: callcode is deprecated and now only available via inline assembly - assembly { - let chunk1 := mload(add(_validatorAddr, 32)) // first 32 bytes of validator address string - let chunk2 := mload(add(add(_validatorAddr, 32), 32)) // remaining 19 bytes of val address string - - // Load the function signature and argument data onto the stack - let x := mload(0x40) // Find empty storage location using "free memory pointer" - mstore(x, sig) // Place function signature at begining of empty storage - mstore(add(x, 0x04), _addr) // Place the address (input param) after the function sig - mstore(add(x, 0x24), 0x40) // These are needed for - mstore(add(x, 0x44), 0x33) // bytes unpacking - mstore(add(x, 0x64), chunk1) // Place the validator address in 2 chunks (input param) - mstore(add(x, 0x84), chunk2) // because mstore stores 32bytes - - // Invoke the contract at calledContractAddress in the context of the current contract - // using CALLCODE opcode and the loaded function signature and argument data - let success := callcode( - gas(), - calledContractAddress, // to addr - 0, // no value - x, // inputs are stored at location x - len, // inputs length - x, //store output over input (saves space) - 0xC0 // output length for this call - ) - - // output length for this call is 192 bytes splitted on these 32 bytes chunks: - // 1 - 0x00..amt -> @ 0x40 - // 2 - 0x000..00 -> @ 0x60 - // 3 - 0x40..000 -> @ 0x80 - // 4 - 0x00..amt -> @ 0xC0 - // 5 - 0x00..denom -> @ 0xE0 TODO: cannot get the return value - - shares := mload(x) // Assign shares output value - 32 bytes long - amt := mload(add(x, 0x60)) // Assign output value to c - 64 bytes long (string & uint256) - - mstore(0x40, add(x, 0x100)) // Set storage pointer to empty space - - // Check if the call was successful and revert the transaction if it failed - if iszero(success) { - revert(0, 0) - } - } - coin = staking.Coin(denom, amt); // NOTE: this is returning a blank denom because unpacking the denom is not straightforward and hasn't been solved, which is okay for this generic test case - } else { - revert("invalid calltype"); - } - - return (shares, coin); - } - - /// @dev This function showcased, that there was a bug in the EVM implementation, that occured when - /// Cosmos state is modified in the same transaction as state information inside - /// the EVM. - /// @param _validatorAddr Address of the validator to delegate to - /// @param _amount Amount to delegate - function testDelegateIncrementCounter( - string memory _validatorAddr, - uint256 _amount - ) public { - bool successStk = staking.STAKING_CONTRACT.approve( - address(this), - _amount, - delegateMethod - ); - require(successStk, "Staking Approve failed"); - staking.STAKING_CONTRACT.delegate( - address(this), - _validatorAddr, - _amount - ); - counter += 1; - } - - /// @dev This function showcases the possibility to deposit into the contract - /// and immediately delegate to a validator using the same balance in the same transaction. - function approveDepositAndDelegate(string memory _validatorAddr) payable public { - bool successTx = staking.STAKING_CONTRACT.approve( - address(this), - msg.value, - delegateMethod - ); - require(successTx, "Delegate Approve failed"); - staking.STAKING_CONTRACT.delegate( - address(this), - _validatorAddr, - msg.value - ); - } - - /// @dev This function is suppose to fail because the amount to delegate is - /// higher than the amount approved. - function approveDepositAndDelegateExceedingAllowance(string memory _validatorAddr) payable public { - bool successTx = staking.STAKING_CONTRACT.approve( - tx.origin, - msg.value, - delegateMethod - ); - require(successTx, "Delegate Approve failed"); - staking.STAKING_CONTRACT.delegate( - address(this), - _validatorAddr, - msg.value + 1 - ); - } - - /// @dev This function is suppose to fail because the amount to delegate is - /// higher than the amount approved. - function approveDepositDelegateAndFailCustomLogic(string memory _validatorAddr) payable public { - bool successTx = staking.STAKING_CONTRACT.approve( - tx.origin, - msg.value, - delegateMethod - ); - require(successTx, "Delegate Approve failed"); - staking.STAKING_CONTRACT.delegate( - address(this), - _validatorAddr, - msg.value - ); - // This should fail since the balance is already spent in the previous call - payable(msg.sender).transfer(msg.value); - } - - /// @dev This function is used to check that both the cosmos and evm state are correctly - /// updated for a successful transaction or reverted for a failed transaction. - /// To test this, deploy an ERC20 token contract to chain and mint some tokens to this - /// contract's address. - /// This contract will then transfer some tokens to the msg.sender address as well as - /// set up a delegation approval and stake funds using the staking EVM extension. - /// @param _contract Address of the ERC20 to call - /// @param _validatorAddr Address of the validator to delegate to - function callERC20AndDelegate( - address _contract, - string memory _validatorAddr, - uint256 _amount - ) public { - bool successApprove = staking.STAKING_CONTRACT.approve( - address(this), - _amount, - delegateMethod - ); - require(successApprove, "delegation approval failed"); - - (bool success, ) = _contract.call( - abi.encodeWithSignature("transfer(address,uint256)", msg.sender, _amount) - ); - require(success, "transfer failed"); - - staking.STAKING_CONTRACT.delegate( - msg.sender, - _validatorAddr, - _amount - ); - } -} diff --git a/precompiles/staking/testdata/staking_caller.go b/precompiles/staking/testdata/staking_caller.go deleted file mode 100644 index 8545296f..00000000 --- a/precompiles/staking/testdata/staking_caller.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package testdata - -import ( - _ "embed" // embed compiled smart contract - "encoding/json" - - evmtypes "github.com/evmos/evmos/v16/x/evm/types" -) - -var ( - //go:embed StakingCaller.json - StakingCallerJSON []byte - - // StakingCallerContract is the compiled contract calling the staking precompile - StakingCallerContract evmtypes.CompiledContract -) - -func init() { - err := json.Unmarshal(StakingCallerJSON, &StakingCallerContract) - if err != nil { - panic(err) - } - - if len(StakingCallerContract.Bin) == 0 { - panic("failed to load smart contract that calls staking precompile") - } -} diff --git a/precompiles/staking/tx.go b/precompiles/staking/tx.go deleted file mode 100644 index b4fed3d0..00000000 --- a/precompiles/staking/tx.go +++ /dev/null @@ -1,422 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package staking - -import ( - "fmt" - "math/big" - "time" - - sdk "github.com/cosmos/cosmos-sdk/types" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/evmos/evmos/v16/precompiles/authorization" - "github.com/evmos/evmos/v16/x/evm/statedb" -) - -const ( - // CreateValidatorMethod defines the ABI method name for the staking create validator transaction - CreateValidatorMethod = "createValidator" - // DelegateMethod defines the ABI method name for the staking Delegate - // transaction. - DelegateMethod = "delegate" - // UndelegateMethod defines the ABI method name for the staking Undelegate - // transaction. - UndelegateMethod = "undelegate" - // RedelegateMethod defines the ABI method name for the staking Redelegate - // transaction. - RedelegateMethod = "redelegate" - // CancelUnbondingDelegationMethod defines the ABI method name for the staking - // CancelUnbondingDelegation transaction. - CancelUnbondingDelegationMethod = "cancelUnbondingDelegation" -) - -const ( - // DelegateAuthz defines the authorization type for the staking Delegate - DelegateAuthz = stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_DELEGATE - // UndelegateAuthz defines the authorization type for the staking Undelegate - UndelegateAuthz = stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_UNDELEGATE - // RedelegateAuthz defines the authorization type for the staking Redelegate - RedelegateAuthz = stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_REDELEGATE - // CancelUnbondingDelegationAuthz defines the authorization type for the staking - CancelUnbondingDelegationAuthz = stakingtypes.AuthorizationType_AUTHORIZATION_TYPE_CANCEL_UNBONDING_DELEGATION -) - -// CreateValidator performs create validator. -func (p Precompile) CreateValidator( - ctx sdk.Context, - origin common.Address, - _ *vm.Contract, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - msg, delegatorHexAddr, err := NewMsgCreateValidator(args, p.stakingKeeper.BondDenom(ctx)) - if err != nil { - return nil, err - } - - p.Logger(ctx).Debug( - "tx called", - "method", method.Name, - "commission", msg.Commission.String(), - "min_self_delegation", msg.MinSelfDelegation.String(), - "delegator_address", delegatorHexAddr.String(), - "validator_address", msg.ValidatorAddress, - "pubkey", msg.Pubkey.String(), - "value", msg.Value.Amount.String(), - ) - - // we only allow the tx signer "origin" to create their own validator. - if origin != delegatorHexAddr { - return nil, fmt.Errorf(ErrDifferentOriginFromDelegator, origin.String(), delegatorHexAddr.String()) - } - - // Execute the transaction using the message server - msgSrv := stakingkeeper.NewMsgServerImpl(&p.stakingKeeper) - if _, err = msgSrv.CreateValidator(sdk.WrapSDKContext(ctx), msg); err != nil { - return nil, err - } - - // Emit the event for the delegate transaction - if err = p.EmitCreateValidatorEvent(ctx, stateDB, msg, delegatorHexAddr); err != nil { - return nil, err - } - - return method.Outputs.Pack(true) -} - -// Delegate performs a delegation of coins from a delegator to a validator. -func (p Precompile) Delegate( - ctx sdk.Context, - origin common.Address, - contract *vm.Contract, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - msg, delegatorHexAddr, err := NewMsgDelegate(args, p.stakingKeeper.BondDenom(ctx)) - if err != nil { - return nil, err - } - - p.Logger(ctx).Debug( - "tx called", - "method", method.Name, - "args", fmt.Sprintf( - "{ delegator_address: %s, validator_address: %s, amount: %s }", - delegatorHexAddr, - msg.ValidatorAddress, - msg.Amount.Amount, - ), - ) - - var ( - // stakeAuthz is the authorization grant for the caller and the delegator address - stakeAuthz *stakingtypes.StakeAuthorization - // expiration is the expiration time of the authorization grant - expiration *time.Time - - // isCallerOrigin is true when the contract caller is the same as the origin - isCallerOrigin = contract.CallerAddress == origin - // isCallerDelegator is true when the contract caller is the same as the delegator - isCallerDelegator = contract.CallerAddress == delegatorHexAddr - ) - - // The provided delegator address should always be equal to the origin address. - // In case the contract caller address is the same as the delegator address provided, - // update the delegator address to be equal to the origin address. - // Otherwise, if the provided delegator address is different from the origin address, - // return an error because is a forbidden operation - if isCallerDelegator { - delegatorHexAddr = origin - } else if origin != delegatorHexAddr { - return nil, fmt.Errorf(ErrDifferentOriginFromDelegator, origin.String(), delegatorHexAddr.String()) - } - - // no need to have authorization when the contract caller is the same as origin (owner of funds) - if !isCallerOrigin { - // Check if the authorization grant exists for the caller and the origin - stakeAuthz, expiration, err = authorization.CheckAuthzAndAllowanceForGranter(ctx, p.AuthzKeeper, contract.CallerAddress, delegatorHexAddr, &msg.Amount, DelegateMsg) - if err != nil { - return nil, err - } - } - - // Execute the transaction using the message server - msgSrv := stakingkeeper.NewMsgServerImpl(&p.stakingKeeper) - if _, err = msgSrv.Delegate(sdk.WrapSDKContext(ctx), msg); err != nil { - p.Logger(ctx).Error("failed to delegate", "error", err) - return nil, err - } - - // Only update the authorization if the contract caller is different from the origin - if !isCallerOrigin { - if err := p.UpdateStakingAuthorization(ctx, contract.CallerAddress, delegatorHexAddr, stakeAuthz, expiration, DelegateMsg, msg); err != nil { - return nil, err - } - } - - // TODO: recheck whether this is necessary - // Emit the event for the delegate transaction - // if err = p.EmitDelegateEvent(ctx, stateDB, msg, delegatorHexAddr); err != nil { - // return nil, err - // } - - // NOTE: This ensures that the changes in the bank keeper are correctly mirrored to the EVM stateDB. - // This prevents the stateDB from overwriting the changed balance in the bank keeper when committing the EVM state. - if isCallerDelegator { - var convertedAmount big.Int - convertedAmount.Mul(msg.Amount.Amount.BigInt(), big.NewInt(1e12)) - p.Logger(ctx).Info("Subtracting balance from the delegator", "address", contract.CallerAddress, "amount", convertedAmount) - stateDB.(*statedb.StateDB).SubBalance(contract.CallerAddress, &convertedAmount) - } - - return method.Outputs.Pack(true) -} - -// Undelegate performs the undelegation of coins from a validator for a delegate. -// The provided amount cannot be negative. This is validated in the msg.ValidateBasic() function. -func (p Precompile) Undelegate( - ctx sdk.Context, - origin common.Address, - contract *vm.Contract, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - msg, delegatorHexAddr, err := NewMsgUndelegate(args, p.stakingKeeper.BondDenom(ctx)) - if err != nil { - return nil, err - } - - p.Logger(ctx).Debug( - "tx called", - "method", method.Name, - "args", fmt.Sprintf( - "{ delegator_address: %s, validator_address: %s, amount: %s }", - delegatorHexAddr, - msg.ValidatorAddress, - msg.Amount.Amount, - ), - ) - - var ( - // stakeAuthz is the authorization grant for the caller and the delegator address - stakeAuthz *stakingtypes.StakeAuthorization - // expiration is the expiration time of the authorization grant - expiration *time.Time - - // isCallerOrigin is true when the contract caller is the same as the origin - isCallerOrigin = contract.CallerAddress == origin - // isCallerDelegator is true when the contract caller is the same as the delegator - isCallerDelegator = contract.CallerAddress == delegatorHexAddr - ) - - // The provided delegator address should always be equal to the origin address. - // In case the contract caller address is the same as the delegator address provided, - // update the delegator address to be equal to the origin address. - // Otherwise, if the provided delegator address is different from the origin address, - // return an error because is a forbidden operation - if isCallerDelegator { - delegatorHexAddr = origin - } else if origin != delegatorHexAddr { - return nil, fmt.Errorf(ErrDifferentOriginFromDelegator, origin.String(), delegatorHexAddr.String()) - } - - // no need to have authorization when the contract caller is the same as origin (owner of funds) - if !isCallerOrigin { - // Check if the authorization grant exists for the caller and the origin - stakeAuthz, expiration, err = authorization.CheckAuthzAndAllowanceForGranter(ctx, p.AuthzKeeper, contract.CallerAddress, delegatorHexAddr, &msg.Amount, UndelegateMsg) - if err != nil { - return nil, err - } - } - - // Execute the transaction using the message server - msgSrv := stakingkeeper.NewMsgServerImpl(&p.stakingKeeper) - res, err := msgSrv.Undelegate(sdk.WrapSDKContext(ctx), msg) - if err != nil { - return nil, err - } - - // Only update the authorization if the contract caller is different from the origin - if !isCallerOrigin { - if err := p.UpdateStakingAuthorization(ctx, contract.CallerAddress, delegatorHexAddr, stakeAuthz, expiration, UndelegateMsg, msg); err != nil { - return nil, err - } - } - - // TODO: recheck whether this is necessary - // Emit the event for the undelegate transaction - // if err = p.EmitUnbondEvent(ctx, stateDB, msg, delegatorHexAddr, res.CompletionTime.UTC().Unix()); err != nil { - // return nil, err - // } - - return method.Outputs.Pack(res.CompletionTime.UTC().Unix()) -} - -// Redelegate performs a redelegation of coins for a delegate from a source validator -// to a destination validator. -// The provided amount cannot be negative. This is validated in the msg.ValidateBasic() function. -func (p Precompile) Redelegate( - ctx sdk.Context, - origin common.Address, - contract *vm.Contract, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - msg, delegatorHexAddr, err := NewMsgRedelegate(args, p.stakingKeeper.BondDenom(ctx)) - if err != nil { - return nil, err - } - - p.Logger(ctx).Debug( - "tx called", - "method", method.Name, - "args", fmt.Sprintf( - "{ delegator_address: %s, validator_src_address: %s, validator_dst_address: %s, amount: %s }", - delegatorHexAddr, - msg.ValidatorSrcAddress, - msg.ValidatorDstAddress, - msg.Amount.Amount, - ), - ) - - var ( - // stakeAuthz is the authorization grant for the caller and the delegator address - stakeAuthz *stakingtypes.StakeAuthorization - // expiration is the expiration time of the authorization grant - expiration *time.Time - - // isCallerOrigin is true when the contract caller is the same as the origin - isCallerOrigin = contract.CallerAddress == origin - // isCallerDelegator is true when the contract caller is the same as the delegator - isCallerDelegator = contract.CallerAddress == delegatorHexAddr - ) - - // The provided delegator address should always be equal to the origin address. - // In case the contract caller address is the same as the delegator address provided, - // update the delegator address to be equal to the origin address. - // Otherwise, if the provided delegator address is different from the origin address, - // return an error because is a forbidden operation - if isCallerDelegator { - delegatorHexAddr = origin - } else if origin != delegatorHexAddr { - return nil, fmt.Errorf(ErrDifferentOriginFromDelegator, origin.String(), delegatorHexAddr.String()) - } - - // no need to have authorization when the contract caller is the same as origin (owner of funds) - if !isCallerOrigin { - // Check if the authorization grant exists for the caller and the origin - stakeAuthz, expiration, err = authorization.CheckAuthzAndAllowanceForGranter(ctx, p.AuthzKeeper, contract.CallerAddress, delegatorHexAddr, &msg.Amount, RedelegateMsg) - if err != nil { - return nil, err - } - } - - msgSrv := stakingkeeper.NewMsgServerImpl(&p.stakingKeeper) - res, err := msgSrv.BeginRedelegate(sdk.WrapSDKContext(ctx), msg) - if err != nil { - return nil, err - } - - // Only update the authorization if the contract caller is different from the origin - if !isCallerOrigin { - if err := p.UpdateStakingAuthorization(ctx, contract.CallerAddress, delegatorHexAddr, stakeAuthz, expiration, RedelegateMsg, msg); err != nil { - return nil, err - } - } - - // TODO: recheck whether this is necessary - // if err = p.EmitRedelegateEvent(ctx, stateDB, msg, delegatorHexAddr, res.CompletionTime.UTC().Unix()); err != nil { - // return nil, err - // } - - return method.Outputs.Pack(res.CompletionTime.UTC().Unix()) -} - -// CancelUnbondingDelegation will cancel the unbonding of a delegation and delegate -// back to the validator being unbonded from. -// The provided amount cannot be negative. This is validated in the msg.ValidateBasic() function. -func (p Precompile) CancelUnbondingDelegation( - ctx sdk.Context, - origin common.Address, - contract *vm.Contract, - stateDB vm.StateDB, - method *abi.Method, - args []interface{}, -) ([]byte, error) { - msg, delegatorHexAddr, err := NewMsgCancelUnbondingDelegation(args, p.stakingKeeper.BondDenom(ctx)) - if err != nil { - return nil, err - } - - p.Logger(ctx).Debug( - "tx called", - "method", method.Name, - "args", fmt.Sprintf( - "{ delegator_address: %s, validator_address: %s, amount: %s, creation_height: %d }", - delegatorHexAddr, - msg.ValidatorAddress, - msg.Amount.Amount, - msg.CreationHeight, - ), - ) - - var ( - // stakeAuthz is the authorization grant for the caller and the delegator address - stakeAuthz *stakingtypes.StakeAuthorization - // expiration is the expiration time of the authorization grant - expiration *time.Time - - // isCallerOrigin is true when the contract caller is the same as the origin - isCallerOrigin = contract.CallerAddress == origin - // isCallerDelegator is true when the contract caller is the same as the delegator - isCallerDelegator = contract.CallerAddress == delegatorHexAddr - ) - - // The provided delegator address should always be equal to the origin address. - // In case the contract caller address is the same as the delegator address provided, - // update the delegator address to be equal to the origin address. - // Otherwise, if the provided delegator address is different from the origin address, - // return an error because is a forbidden operation - if isCallerDelegator { - delegatorHexAddr = origin - } else if origin != delegatorHexAddr { - return nil, fmt.Errorf(ErrDifferentOriginFromDelegator, origin.String(), delegatorHexAddr.String()) - } - - // no need to have authorization when the contract caller is the same as origin (owner of funds) - if !isCallerOrigin { - // Check if the authorization grant exists for the caller and the origin - stakeAuthz, expiration, err = authorization.CheckAuthzAndAllowanceForGranter(ctx, p.AuthzKeeper, contract.CallerAddress, delegatorHexAddr, &msg.Amount, CancelUnbondingDelegationMsg) - if err != nil { - return nil, err - } - } - - msgSrv := stakingkeeper.NewMsgServerImpl(&p.stakingKeeper) - if _, err = msgSrv.CancelUnbondingDelegation(sdk.WrapSDKContext(ctx), msg); err != nil { - return nil, err - } - - // Only update the authorization if the contract caller is different from the origin - if !isCallerOrigin { - if err := p.UpdateStakingAuthorization(ctx, contract.CallerAddress, delegatorHexAddr, stakeAuthz, expiration, CancelUnbondingDelegationMsg, msg); err != nil { - return nil, err - } - } - - // TODO: recheck whether this is necessary - // if err = p.EmitCancelUnbondingDelegationEvent(ctx, stateDB, msg, delegatorHexAddr); err != nil { - // return nil, err - // } - - return method.Outputs.Pack(true) -} diff --git a/precompiles/staking/tx_test.go b/precompiles/staking/tx_test.go deleted file mode 100644 index 187f7273..00000000 --- a/precompiles/staking/tx_test.go +++ /dev/null @@ -1,972 +0,0 @@ -package staking_test - -import ( - "encoding/base64" - "fmt" - "math/big" - - "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - geth "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - cmn "github.com/evmos/evmos/v16/precompiles/common" - "github.com/evmos/evmos/v16/precompiles/staking" - "github.com/evmos/evmos/v16/precompiles/testutil" - evmosutiltx "github.com/evmos/evmos/v16/testutil/tx" -) - -func (s *PrecompileTestSuite) TestCreateValidator() { - var ( - method = s.precompile.Methods[staking.CreateValidatorMethod] - description = staking.Description{ - Moniker: "node0", - Identity: "", - Website: "", - SecurityContact: "", - Details: "", - } - commission = staking.Commission{ - Rate: math.LegacyOneDec().BigInt(), - MaxRate: math.LegacyOneDec().BigInt(), - MaxChangeRate: math.LegacyOneDec().BigInt(), - } - minSelfDelegation = big.NewInt(1) - delegatorAddress = s.address - validatorAddress = sdk.ValAddress(s.address.Bytes()).String() - pubkey = "nfJ0axJC9dhta1MAE1EBFaVdxxkYzxYrBaHuJVjG//M=" - value = big.NewInt(1205000000000000000) - ) - - testCases := []struct { - name string - malleate func() []interface{} - gas uint64 - postCheck func(data []byte) - expError bool - errContains string - }{ - { - "fail - empty input args", - func() []interface{} { - return []interface{}{} - }, - 200000, - func(data []byte) {}, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 7, 0), - }, - { - "fail - different origin than delegator", - func() []interface{} { - differentAddr := evmosutiltx.GenerateAddress() - return []interface{}{ - description, - commission, - minSelfDelegation, - differentAddr, - sdk.ValAddress(differentAddr.Bytes()).String(), - pubkey, - value, - } - }, - 200000, - func(data []byte) {}, - true, - "is not the same as delegator address", - }, - { - "fail - invalid description", - func() []interface{} { - return []interface{}{ - "", - commission, - minSelfDelegation, - delegatorAddress, - validatorAddress, - pubkey, - value, - } - }, - 200000, - func(data []byte) {}, - true, - "invalid description", - }, - { - "fail - invalid commission", - func() []interface{} { - return []interface{}{ - description, - "", - minSelfDelegation, - delegatorAddress, - validatorAddress, - pubkey, - value, - } - }, - 200000, - func(data []byte) {}, - true, - "invalid commission", - }, - { - "fail - invalid min self delegation", - func() []interface{} { - return []interface{}{ - description, - commission, - "", - delegatorAddress, - validatorAddress, - pubkey, - value, - } - }, - 200000, - func(data []byte) {}, - true, - "invalid amount", - }, - { - "fail - invalid delegator address", - func() []interface{} { - return []interface{}{ - description, - commission, - minSelfDelegation, - "", - validatorAddress, - pubkey, - value, - } - }, - 200000, - func(data []byte) {}, - true, - "invalid delegator address", - }, - { - "fail - invalid validator address", - func() []interface{} { - return []interface{}{ - description, - commission, - minSelfDelegation, - delegatorAddress, - 1205, - pubkey, - value, - } - }, - 200000, - func(data []byte) {}, - true, - "invalid type for", - }, - { - "fail - invalid pubkey", - func() []interface{} { - return []interface{}{ - description, - commission, - minSelfDelegation, - delegatorAddress, - validatorAddress, - 1205, - value, - } - }, - 200000, - func(data []byte) {}, - true, - "invalid type for", - }, - { - "fail - pubkey decoding error", - func() []interface{} { - return []interface{}{ - description, - commission, - minSelfDelegation, - delegatorAddress, - validatorAddress, - "bHVrZQ=", // base64.StdEncoding.DecodeString error - value, - } - }, - 200000, - func(data []byte) {}, - true, - "illegal base64 data", - }, - { - "fail - invalid value", - func() []interface{} { - return []interface{}{ - description, - commission, - minSelfDelegation, - delegatorAddress, - validatorAddress, - pubkey, - "", - } - }, - 200000, - func(data []byte) {}, - true, - "invalid amount", - }, - { - "success", - func() []interface{} { - return []interface{}{ - description, - commission, - minSelfDelegation, - delegatorAddress, - validatorAddress, - pubkey, - value, - } - }, - 200000, - func(data []byte) { - success, err := s.precompile.Unpack(staking.CreateValidatorMethod, data) - s.Require().NoError(err) - s.Require().Equal(success[0], true) - - log := s.stateDB.Logs()[0] - s.Require().Equal(log.Address, s.precompile.Address()) - - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[staking.EventTypeCreateValidator] - s.Require().Equal(crypto.Keccak256Hash([]byte(event.Sig)), geth.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - - // Check the fully unpacked event matches the one emitted - var createValidatorEvent staking.EventCreateValidator - err = cmn.UnpackLog(s.precompile.ABI, &createValidatorEvent, staking.EventTypeCreateValidator, *log) - s.Require().NoError(err) - s.Require().Equal(s.address, createValidatorEvent.DelegatorAddress) - s.Require().Equal(s.address, createValidatorEvent.ValidatorAddress) - s.Require().Equal(value, createValidatorEvent.Value) - }, - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - // reset sender - delegatorAddress = s.address - validatorAddress = sdk.ValAddress(s.address.Bytes()).String() - - var contract *vm.Contract - contract, s.ctx = testutil.NewPrecompileContract(s.T(), s.ctx, s.address, s.precompile, tc.gas) - - bz, err := s.precompile.CreateValidator(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate()) - - // query the validator in the staking keeper - validator := s.app.StakingKeeper.Validator(s.ctx, s.address.Bytes()) - if tc.expError { - s.Require().ErrorContains(err, tc.errContains) - s.Require().Empty(bz) - s.Require().Nil(validator) - } else { - s.Require().NoError(err) - s.Require().NotNil(validator, "expected validator not to be nil") - tc.postCheck(bz) - - isBonded := validator.IsBonded() - s.Require().Equal(false, isBonded, "expected validator bonded to be %t; got %t", false, isBonded) - - consPubKey, err := validator.ConsPubKey() - s.Require().NoError(err) - consPubKeyBase64 := base64.StdEncoding.EncodeToString(consPubKey.Bytes()) - s.Require().Equal(pubkey, consPubKeyBase64, "expected validator pubkey to be %s; got %s", pubkey, consPubKeyBase64) - - operator := validator.GetOperator().String() - s.Require().Equal(validatorAddress, operator, "expected validator operator to be %s; got %s", validatorAddress, operator) - - commissionRate := validator.GetCommission() - s.Require().Equal(commission.Rate.String(), commissionRate.BigInt().String(), "expected validator commission rate to be %s; got %s", commission.Rate.String(), commissionRate.String()) - - valMinSelfDelegation := validator.GetMinSelfDelegation() - s.Require().Equal(minSelfDelegation.String(), valMinSelfDelegation.String(), "expected validator min self delegation to be %s; got %s", minSelfDelegation.String(), valMinSelfDelegation.String()) - - moniker := validator.GetMoniker() - s.Require().Equal(description.Moniker, moniker, "expected validator moniker to be %s; got %s", description.Moniker, moniker) - - jailed := validator.IsJailed() - s.Require().Equal(false, jailed, "expected validator jailed to be %t; got %t", false, jailed) - } - }) - } -} - -func (s *PrecompileTestSuite) TestDelegate() { - method := s.precompile.Methods[staking.DelegateMethod] - - testCases := []struct { - name string - malleate func(operatorAddress string) []interface{} - gas uint64 - expDelegationShares *big.Int - postCheck func(data []byte) - expError bool - errContains string - }{ - { - "fail - empty input args", - func(operatorAddress string) []interface{} { - return []interface{}{} - }, - 200000, - big.NewInt(0), - func(data []byte) {}, - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 3, 0), - }, - // TODO: check case if authorization does not exist - { - name: "fail - different origin than delegator", - malleate: func(operatorAddress string) []interface{} { - differentAddr := evmosutiltx.GenerateAddress() - return []interface{}{ - differentAddr, - operatorAddress, - big.NewInt(1e18), - } - }, - gas: 200000, - expError: true, - errContains: "is not the same as delegator address", - }, - { - "fail - invalid delegator address", - func(operatorAddress string) []interface{} { - return []interface{}{ - "", - operatorAddress, - big.NewInt(1), - } - }, - 200000, - big.NewInt(1), - func(data []byte) {}, - true, - fmt.Sprintf(cmn.ErrInvalidDelegator, ""), - }, - { - "fail - invalid amount", - func(operatorAddress string) []interface{} { - return []interface{}{ - s.address, - operatorAddress, - nil, - } - }, - 200000, - big.NewInt(1), - func(data []byte) {}, - true, - fmt.Sprintf(cmn.ErrInvalidAmount, nil), - }, - { - "fail - delegation failed because of insufficient funds", - func(operatorAddress string) []interface{} { - err := s.CreateAuthorization(s.address, staking.DelegateAuthz, nil) - s.Require().NoError(err) - return []interface{}{ - s.address, - operatorAddress, - big.NewInt(9e18), - } - }, - 200000, - big.NewInt(15), - func(data []byte) {}, - true, - "insufficient funds", - }, - // TODO: adjust tests to work with authorizations (currently does not work because origin == precompile caller which needs no authorization) - // { - // "fail - delegation should not be possible to validators outside of the allow list", - // func(string) []interface{} { - // err := s.CreateAuthorization(s.address, staking.DelegateAuthz, nil) - // s.Require().NoError(err) - // - // // Create new validator --> this is not included in the authorized allow list - // testutil.CreateValidator(s.ctx, s.T(), s.privKey.PubKey(), s.app.StakingKeeper, math.NewInt(100)) - // newValAddr := sdk.ValAddress(s.address.Bytes()) - // - // return []interface{}{ - // s.address, - // newValAddr.String(), - // big.NewInt(1e18), - // } - // }, - // 200000, - // big.NewInt(15), - // func(data []byte) {}, - // true, - // "cannot delegate/undelegate", - // }, - { - "success", - func(operatorAddress string) []interface{} { - err := s.CreateAuthorization(s.address, staking.DelegateAuthz, nil) - s.Require().NoError(err) - return []interface{}{ - s.address, - operatorAddress, - big.NewInt(1e18), - } - }, - 20000, - big.NewInt(2), - func(data []byte) { - success, err := s.precompile.Unpack(staking.DelegateMethod, data) - s.Require().NoError(err) - s.Require().Equal(success[0], true) - - log := s.stateDB.Logs()[0] - s.Require().Equal(log.Address, s.precompile.Address()) - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[staking.EventTypeDelegate] - s.Require().Equal(crypto.Keccak256Hash([]byte(event.Sig)), geth.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - }, - false, - "", - }, - // TODO: adjust tests to work with authorizations (currently does not work because origin == precompile caller which needs no authorization) - // { - // "success - delegate and update the authorization for the delegator", - // func(operatorAddress string) []interface{} { - // err := s.CreateAuthorization(s.address, staking.DelegateAuthz, &sdk.Coin{Denom: utils.BaseDenom, Amount: math.NewInt(2e18)}) - // s.Require().NoError(err) - // return []interface{}{ - // s.address, - // operatorAddress, - // big.NewInt(1e18), - // } - // }, - // 20000, - // big.NewInt(2), - // func(data []byte) { - // authorization, _ := s.app.AuthzKeeper.GetAuthorization(s.ctx, s.address.Bytes(), s.address.Bytes(), staking.DelegateMsg) - // s.Require().NotNil(authorization) - // stakeAuthorization := authorization.(*stakingtypes.StakeAuthorization) - // s.Require().Equal(math.NewInt(1e18), stakeAuthorization.MaxTokens.Amount) - // }, - // false, - // "", - // }, - // { - // "success - delegate and delete the authorization for the delegator", - // func(operatorAddress string) []interface{} { - // err := s.CreateAuthorization(s.address, staking.DelegateAuthz, &sdk.Coin{Denom: utils.BaseDenom, Amount: math.NewInt(1e18)}) - // s.Require().NoError(err) - // return []interface{}{ - // s.address, - // operatorAddress, - // big.NewInt(1e18), - // } - // }, - // 20000, - // big.NewInt(2), - // func(data []byte) { - // authorization, _ := s.app.AuthzKeeper.GetAuthorization(s.ctx, s.address.Bytes(), s.address.Bytes(), staking.DelegateMsg) - // s.Require().Nil(authorization) - // }, - // false, - // "", - // }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - var contract *vm.Contract - contract, s.ctx = testutil.NewPrecompileContract(s.T(), s.ctx, s.address, s.precompile, tc.gas) - - bz, err := s.precompile.Delegate(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate(s.validators[0].OperatorAddress)) - - // query the delegation in the staking keeper - delegation := s.app.StakingKeeper.Delegation(s.ctx, s.address.Bytes(), s.validators[0].GetOperator()) - if tc.expError { - s.Require().ErrorContains(err, tc.errContains) - s.Require().Empty(bz) - s.Require().Equal(s.validators[0].DelegatorShares, delegation.GetShares()) - } else { - s.Require().NoError(err) - s.Require().NotNil(delegation, "expected delegation not to be nil") - tc.postCheck(bz) - - expDelegationAmt := math.NewIntFromBigInt(tc.expDelegationShares) - delegationAmt := delegation.GetShares().TruncateInt() - - s.Require().Equal(expDelegationAmt, delegationAmt, "expected delegation amount to be %d; got %d", expDelegationAmt, delegationAmt) - } - }) - } -} - -func (s *PrecompileTestSuite) TestUndelegate() { - method := s.precompile.Methods[staking.UndelegateMethod] - - testCases := []struct { - name string - malleate func(operatorAddress string) []interface{} - postCheck func(data []byte) - gas uint64 - expUndelegationShares *big.Int - expError bool - errContains string - }{ - { - "fail - empty input args", - func(operatorAddress string) []interface{} { - return []interface{}{} - }, - func(data []byte) {}, - 200000, - big.NewInt(0), - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 3, 0), - }, - // TODO: check case if authorization does not exist - { - name: "fail - different origin than delegator", - malleate: func(operatorAddress string) []interface{} { - differentAddr := evmosutiltx.GenerateAddress() - return []interface{}{ - differentAddr, - operatorAddress, - big.NewInt(1000000000000000000), - } - }, - gas: 200000, - expError: true, - errContains: "is not the same as delegator", - }, - { - "fail - invalid delegator address", - func(operatorAddress string) []interface{} { - return []interface{}{ - "", - operatorAddress, - big.NewInt(1), - } - }, - func(data []byte) {}, - 200000, - big.NewInt(1), - true, - fmt.Sprintf(cmn.ErrInvalidDelegator, ""), - }, - { - "fail - invalid amount", - func(operatorAddress string) []interface{} { - return []interface{}{ - s.address, - operatorAddress, - nil, - } - }, - func(data []byte) {}, - 200000, - big.NewInt(1), - true, - fmt.Sprintf(cmn.ErrInvalidAmount, nil), - }, - { - "success", - func(operatorAddress string) []interface{} { - err := s.CreateAuthorization(s.address, staking.UndelegateAuthz, nil) - s.Require().NoError(err) - return []interface{}{ - s.address, - operatorAddress, - big.NewInt(1000000000000000000), - } - }, - func(data []byte) { - args, err := s.precompile.Unpack(staking.UndelegateMethod, data) - s.Require().NoError(err, "failed to unpack output") - s.Require().Len(args, 1) - completionTime, ok := args[0].(int64) - s.Require().True(ok, "completion time type %T", args[0]) - params := s.app.StakingKeeper.GetParams(s.ctx) - expCompletionTime := s.ctx.BlockTime().Add(params.UnbondingTime).UTC().Unix() - s.Require().Equal(expCompletionTime, completionTime) - // Check the event emitted - log := s.stateDB.Logs()[0] - s.Require().Equal(log.Address, s.precompile.Address()) - }, - 20000, - big.NewInt(1000000000000000000), - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - var contract *vm.Contract - contract, s.ctx = testutil.NewPrecompileContract(s.T(), s.ctx, s.address, s.precompile, tc.gas) - - bz, err := s.precompile.Undelegate(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate(s.validators[0].OperatorAddress)) - - // query the unbonding delegations in the staking keeper - undelegations := s.app.StakingKeeper.GetAllUnbondingDelegations(s.ctx, s.address.Bytes()) - - if tc.expError { - s.Require().ErrorContains(err, tc.errContains) - s.Require().Empty(bz) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - tc.postCheck(bz) - - bech32Addr, err := sdk.Bech32ifyAddressBytes("evmos", s.address.Bytes()) - s.Require().NoError(err) - s.Require().Equal(undelegations[0].DelegatorAddress, bech32Addr) - s.Require().Equal(undelegations[0].ValidatorAddress, s.validators[0].OperatorAddress) - s.Require().Equal(undelegations[0].Entries[0].Balance, math.NewIntFromBigInt(tc.expUndelegationShares)) - } - }) - } -} - -func (s *PrecompileTestSuite) TestRedelegate() { - method := s.precompile.Methods[staking.RedelegateMethod] - - testCases := []struct { - name string - malleate func(srcOperatorAddr, dstOperatorAddr string) []interface{} - postCheck func(data []byte) - gas uint64 - expRedelegationShares *big.Int - expError bool - errContains string - }{ - { - "fail - empty input args", - func(srcOperatorAddr, dstOperatorAddr string) []interface{} { - return []interface{}{} - }, - func(data []byte) {}, - 200000, - big.NewInt(0), - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 4, 0), - }, - // TODO: check case if authorization does not exist - { - name: "fail - different origin than delegator", - malleate: func(srcOperatorAddr, dstOperatorAddr string) []interface{} { - differentAddr := evmosutiltx.GenerateAddress() - return []interface{}{ - differentAddr, - srcOperatorAddr, - dstOperatorAddr, - big.NewInt(1000000000000000000), - } - }, - gas: 200000, - expError: true, - errContains: "is not the same as delegator", - }, - { - "fail - invalid delegator address", - func(srcOperatorAddr, dstOperatorAddr string) []interface{} { - return []interface{}{ - "", - srcOperatorAddr, - dstOperatorAddr, - big.NewInt(1), - } - }, - func(data []byte) {}, - 200000, - big.NewInt(1), - true, - fmt.Sprintf(cmn.ErrInvalidDelegator, ""), - }, - { - "fail - invalid amount", - func(srcOperatorAddr, dstOperatorAddr string) []interface{} { - return []interface{}{ - s.address, - srcOperatorAddr, - dstOperatorAddr, - nil, - } - }, - func(data []byte) {}, - 200000, - big.NewInt(1), - true, - fmt.Sprintf(cmn.ErrInvalidAmount, nil), - }, - { - "fail - invalid shares amount", - func(srcOperatorAddr, dstOperatorAddr string) []interface{} { - return []interface{}{ - s.address, - srcOperatorAddr, - dstOperatorAddr, - big.NewInt(-1), - } - }, - func(data []byte) {}, - 200000, - big.NewInt(1), - true, - "invalid shares amount", - }, - { - "success", - func(srcOperatorAddr, dstOperatorAddr string) []interface{} { - err := s.CreateAuthorization(s.address, staking.RedelegateAuthz, nil) - s.Require().NoError(err) - return []interface{}{ - s.address, - srcOperatorAddr, - dstOperatorAddr, - big.NewInt(1000000000000000000), - } - }, - func(data []byte) { - args, err := s.precompile.Unpack(staking.RedelegateMethod, data) - s.Require().NoError(err, "failed to unpack output") - s.Require().Len(args, 1) - completionTime, ok := args[0].(int64) - s.Require().True(ok, "completion time type %T", args[0]) - params := s.app.StakingKeeper.GetParams(s.ctx) - expCompletionTime := s.ctx.BlockTime().Add(params.UnbondingTime).UTC().Unix() - s.Require().Equal(expCompletionTime, completionTime) - }, - 200000, - big.NewInt(1), - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - var contract *vm.Contract - contract, s.ctx = testutil.NewPrecompileContract(s.T(), s.ctx, s.address, s.precompile, tc.gas) - - bz, err := s.precompile.Redelegate(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate(s.validators[0].OperatorAddress, s.validators[1].OperatorAddress)) - - // query the redelegations in the staking keeper - redelegations := s.app.StakingKeeper.GetRedelegations(s.ctx, s.address.Bytes(), 5) - - if tc.expError { - s.Require().ErrorContains(err, tc.errContains) - s.Require().Empty(bz) - } else { - s.Require().NoError(err) - s.Require().NotEmpty(bz) - - bech32Addr, err := sdk.Bech32ifyAddressBytes("evmos", s.address.Bytes()) - s.Require().NoError(err) - s.Require().Equal(redelegations[0].DelegatorAddress, bech32Addr) - s.Require().Equal(redelegations[0].ValidatorSrcAddress, s.validators[0].OperatorAddress) - s.Require().Equal(redelegations[0].ValidatorDstAddress, s.validators[1].OperatorAddress) - s.Require().Equal(redelegations[0].Entries[0].SharesDst, math.LegacyNewDecFromBigInt(tc.expRedelegationShares)) - } - }) - } -} - -func (s *PrecompileTestSuite) TestCancelUnbondingDelegation() { - method := s.precompile.Methods[staking.CancelUnbondingDelegationMethod] - undelegateMethod := s.precompile.Methods[staking.UndelegateMethod] - - testCases := []struct { - name string - malleate func(operatorAddress string) []interface{} - postCheck func(data []byte) - gas uint64 - expDelegatedShares *big.Int - expError bool - errContains string - }{ - { - "fail - empty input args", - func(operatorAddress string) []interface{} { - return []interface{}{} - }, - func(data []byte) {}, - 200000, - big.NewInt(0), - true, - fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 4, 0), - }, - { - "fail - invalid delegator address", - func(operatorAddress string) []interface{} { - return []interface{}{ - "", - operatorAddress, - big.NewInt(1), - big.NewInt(1), - } - }, - func(data []byte) {}, - 200000, - big.NewInt(1), - true, - fmt.Sprintf(cmn.ErrInvalidDelegator, ""), - }, - { - "fail - creation height", - func(operatorAddress string) []interface{} { - return []interface{}{ - s.address, - operatorAddress, - big.NewInt(1), - nil, - } - }, - func(data []byte) {}, - 200000, - big.NewInt(1), - true, - "invalid creation height", - }, - { - "fail - invalid amount", - func(operatorAddress string) []interface{} { - return []interface{}{ - s.address, - operatorAddress, - nil, - big.NewInt(1), - } - }, - func(data []byte) {}, - 200000, - big.NewInt(1), - true, - fmt.Sprintf(cmn.ErrInvalidAmount, nil), - }, - { - "fail - invalid amount", - func(operatorAddress string) []interface{} { - return []interface{}{ - s.address, - operatorAddress, - nil, - big.NewInt(1), - } - }, - func(data []byte) {}, - 200000, - big.NewInt(1), - true, - fmt.Sprintf(cmn.ErrInvalidAmount, nil), - }, - { - "fail - invalid shares amount", - func(operatorAddress string) []interface{} { - return []interface{}{ - s.address, - operatorAddress, - big.NewInt(-1), - big.NewInt(1), - } - }, - func(data []byte) {}, - 200000, - big.NewInt(1), - true, - "invalid amount: invalid request", - }, - { - "success", - func(operatorAddress string) []interface{} { - err := s.CreateAuthorization(s.address, staking.DelegateAuthz, nil) - s.Require().NoError(err) - return []interface{}{ - s.address, - operatorAddress, - big.NewInt(1), - big.NewInt(2), - } - }, - func(data []byte) { - success, err := s.precompile.Unpack(staking.CancelUnbondingDelegationMethod, data) - s.Require().NoError(err) - s.Require().Equal(success[0], true) - }, - 200000, - big.NewInt(1), - false, - "", - }, - } - - for _, tc := range testCases { - s.Run(tc.name, func() { - s.SetupTest() - - var contract *vm.Contract - contract, s.ctx = testutil.NewPrecompileContract(s.T(), s.ctx, s.address, s.precompile, tc.gas) - - if tc.expError { - bz, err := s.precompile.CancelUnbondingDelegation(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate(s.validators[0].OperatorAddress)) - s.Require().ErrorContains(err, tc.errContains) - s.Require().Empty(bz) - } else { - undelegateArgs := []interface{}{ - s.address, - s.validators[0].OperatorAddress, - big.NewInt(1000000000000000000), - } - - err := s.CreateAuthorization(s.address, staking.UndelegateAuthz, nil) - s.Require().NoError(err) - - _, err = s.precompile.Undelegate(s.ctx, s.address, contract, s.stateDB, &undelegateMethod, undelegateArgs) - s.Require().NoError(err) - - _, found := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), s.validators[0].GetOperator()) - s.Require().False(found) - - err = s.CreateAuthorization(s.address, staking.CancelUnbondingDelegationAuthz, nil) - s.Require().NoError(err) - - bz, err := s.precompile.CancelUnbondingDelegation(s.ctx, s.address, contract, s.stateDB, &method, tc.malleate(s.validators[0].OperatorAddress)) - s.Require().NoError(err) - tc.postCheck(bz) - - delegation, found := s.app.StakingKeeper.GetDelegation(s.ctx, s.address.Bytes(), s.validators[0].GetOperator()) - s.Require().True(found) - - bech32Addr, err := sdk.Bech32ifyAddressBytes("evmos", s.address.Bytes()) - s.Require().NoError(err) - s.Require().Equal(delegation.DelegatorAddress, bech32Addr) - s.Require().Equal(delegation.ValidatorAddress, s.validators[0].OperatorAddress) - s.Require().Equal(delegation.Shares, math.LegacyNewDecFromBigInt(tc.expDelegatedShares)) - - } - }) - } -} diff --git a/precompiles/staking/types.go b/precompiles/staking/types.go deleted file mode 100644 index 86c554c0..00000000 --- a/precompiles/staking/types.go +++ /dev/null @@ -1,844 +0,0 @@ -// Copyright Tharsis Labs Ltd.(Evmos) -// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) - -package staking - -import ( - "encoding/base64" - "errors" - "fmt" - "math/big" - - "cosmossdk.io/math" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/query" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - cmn "github.com/evmos/evmos/v16/precompiles/common" - - "github.com/aura-nw/aura/precompiles/util" -) - -// EventCreateValidator defines the event data for the staking CreateValidator transaction. -type EventCreateValidator struct { - DelegatorAddress common.Address - ValidatorAddress common.Address - Value *big.Int -} - -// EventDelegate defines the event data for the staking Delegate transaction. -type EventDelegate struct { - DelegatorAddress common.Address - ValidatorAddress common.Address - Amount *big.Int - NewShares *big.Int -} - -// EventUnbond defines the event data for the staking Undelegate transaction. -type EventUnbond struct { - DelegatorAddress common.Address - ValidatorAddress common.Address - Amount *big.Int - CompletionTime *big.Int -} - -// EventRedelegate defines the event data for the staking Redelegate transaction. -type EventRedelegate struct { - DelegatorAddress common.Address - ValidatorSrcAddress common.Address - ValidatorDstAddress common.Address - Amount *big.Int - CompletionTime *big.Int -} - -// EventCancelUnbonding defines the event data for the staking CancelUnbond transaction. -type EventCancelUnbonding struct { - DelegatorAddress common.Address - ValidatorAddress common.Address - Amount *big.Int - CreationHeight *big.Int -} - -// Description use golang type alias defines a validator description. -type Description = struct { - Moniker string "json:\"moniker\"" - Identity string "json:\"identity\"" - Website string "json:\"website\"" - SecurityContact string "json:\"securityContact\"" - Details string "json:\"details\"" -} - -// Commission use golang type alias defines a validator commission. -// since solidity does not support decimals, after passing in the big int, convert the big int into a decimal with a precision of 18 -type Commission = struct { - Rate *big.Int "json:\"rate\"" - MaxRate *big.Int "json:\"maxRate\"" - MaxChangeRate *big.Int "json:\"maxChangeRate\"" -} - -// NewMsgCreateValidator creates a new MsgCreateValidator instance and does sanity checks -// on the given arguments before populating the message. -func NewMsgCreateValidator(args []interface{}, denom string) (*stakingtypes.MsgCreateValidator, common.Address, error) { - if len(args) != 7 { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 7, len(args)) - } - - description := stakingtypes.Description{} - if descriptionInput, ok := args[0].(Description); ok { - description.Moniker = descriptionInput.Moniker - description.Identity = descriptionInput.Identity - description.Website = descriptionInput.Website - description.SecurityContact = descriptionInput.SecurityContact - description.Details = descriptionInput.Details - } else { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidDescription, args[0]) - } - - commission := stakingtypes.CommissionRates{} - if commissionInput, ok := args[1].(Commission); ok { - commission.Rate = math.LegacyNewDecFromBigIntWithPrec(commissionInput.Rate, math.LegacyPrecision) - commission.MaxRate = math.LegacyNewDecFromBigIntWithPrec(commissionInput.MaxRate, math.LegacyPrecision) - commission.MaxChangeRate = math.LegacyNewDecFromBigIntWithPrec(commissionInput.MaxChangeRate, math.LegacyPrecision) - } else { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidCommission, args[1]) - } - - minSelfDelegation, ok := args[2].(*big.Int) - if !ok { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidAmount, args[2]) - } - - delegatorAddress, ok := args[3].(common.Address) - if !ok || delegatorAddress == (common.Address{}) { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidDelegator, args[3]) - } - - validatorAddress, ok := args[4].(string) - if !ok { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidType, "validatorAddress", "string", args[4]) - } - - // use cli `evmosd tendermint show-validator` get pubkey - pubkeyBase64Str, ok := args[5].(string) - if !ok { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidType, "pubkey", "string", args[5]) - } - pubkeyBytes, err := base64.StdEncoding.DecodeString(pubkeyBase64Str) - if err != nil { - return nil, common.Address{}, err - } - - var ed25519pk cryptotypes.PubKey = &ed25519.PubKey{Key: pubkeyBytes} - pubkey, err := codectypes.NewAnyWithValue(ed25519pk) - if err != nil { - return nil, common.Address{}, err - } - - value, ok := args[6].(*big.Int) - if !ok { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidAmount, args[6]) - } - - msg := &stakingtypes.MsgCreateValidator{ - Description: description, - Commission: commission, - MinSelfDelegation: math.NewIntFromBigInt(minSelfDelegation), - DelegatorAddress: sdk.AccAddress(delegatorAddress.Bytes()).String(), - ValidatorAddress: validatorAddress, - Pubkey: pubkey, - Value: sdk.Coin{Denom: denom, Amount: math.NewIntFromBigInt(value)}, - } - - if err := msg.ValidateBasic(); err != nil { - return nil, common.Address{}, err - } - - return msg, delegatorAddress, nil -} - -// convertAmountForAura converts the given amount to a valid amount for Aura. -// Aura has a decimal of 6, while Evmos has a decimal of 18. -// So we need to convert the amount to a valid amount for Aura. -// The amount must be divisible by 10^12. -func convertAmountForAura(amount *big.Int) (math.Int, error) { - var m big.Int - // check if amount is divisible by 10^12 - m.Mod(amount, big.NewInt(1e12)) - if m.Cmp(big.NewInt(0)) != 0 { - return math.NewInt(0), fmt.Errorf("Amount should be divisible by 10^12: %s", amount) - } - - var newAmount big.Int - newAmount.Div(amount, big.NewInt(1e12)) - - return math.NewIntFromBigInt(&newAmount), nil -} - -// NewMsgDelegate creates a new MsgDelegate instance and does sanity checks -// on the given arguments before populating the message. -func NewMsgDelegate(args []interface{}, denom string) (*stakingtypes.MsgDelegate, common.Address, error) { - delegatorAddr, validatorAddress, amount, err := checkDelegationUndelegationArgs(args) - if err != nil { - return nil, common.Address{}, err - } - - msgAmount, err := convertAmountForAura(amount) - if err != nil { - return nil, common.Address{}, err - } - - msg := &stakingtypes.MsgDelegate{ - DelegatorAddress: sdk.AccAddress(delegatorAddr.Bytes()).String(), - ValidatorAddress: validatorAddress, - Amount: sdk.Coin{ - Denom: denom, - Amount: msgAmount, - }, - } - - if err = msg.ValidateBasic(); err != nil { - return nil, common.Address{}, err - } - - return msg, delegatorAddr, nil -} - -// NewMsgUndelegate creates a new MsgUndelegate instance and does sanity checks -// on the given arguments before populating the message. -func NewMsgUndelegate(args []interface{}, denom string) (*stakingtypes.MsgUndelegate, common.Address, error) { - delegatorAddr, validatorAddress, amount, err := checkDelegationUndelegationArgs(args) - if err != nil { - return nil, common.Address{}, err - } - - msgAmount, err := convertAmountForAura(amount) - if err != nil { - return nil, common.Address{}, err - } - - msg := &stakingtypes.MsgUndelegate{ - DelegatorAddress: sdk.AccAddress(delegatorAddr.Bytes()).String(), - ValidatorAddress: validatorAddress, - Amount: sdk.Coin{ - Denom: denom, - Amount: msgAmount, - }, - } - - if err = msg.ValidateBasic(); err != nil { - return nil, common.Address{}, err - } - - return msg, delegatorAddr, nil -} - -// NewMsgRedelegate creates a new MsgRedelegate instance and does sanity checks -// on the given arguments before populating the message. -func NewMsgRedelegate(args []interface{}, denom string) (*stakingtypes.MsgBeginRedelegate, common.Address, error) { - if len(args) != 4 { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 4, len(args)) - } - - delegatorAddr, ok := args[0].(common.Address) - if !ok || delegatorAddr == (common.Address{}) { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - validatorSrcAddress, ok := args[1].(string) - if !ok { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidType, "validatorSrcAddress", "string", args[1]) - } - - validatorDstAddress, ok := args[2].(string) - if !ok { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidType, "validatorDstAddress", "string", args[2]) - } - - amount, ok := args[3].(*big.Int) - if !ok { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidAmount, args[3]) - } - - msgAmount, err := convertAmountForAura(amount) - if err != nil { - return nil, common.Address{}, err - } - - msg := &stakingtypes.MsgBeginRedelegate{ - DelegatorAddress: sdk.AccAddress(delegatorAddr.Bytes()).String(), // bech32 formatted - ValidatorSrcAddress: validatorSrcAddress, - ValidatorDstAddress: validatorDstAddress, - Amount: sdk.Coin{ - Denom: denom, - Amount: msgAmount, - }, - } - - if err := msg.ValidateBasic(); err != nil { - return nil, common.Address{}, err - } - - return msg, delegatorAddr, nil -} - -// NewMsgCancelUnbondingDelegation creates a new MsgCancelUnbondingDelegation instance and does sanity checks -// on the given arguments before populating the message. -func NewMsgCancelUnbondingDelegation(args []interface{}, denom string) (*stakingtypes.MsgCancelUnbondingDelegation, common.Address, error) { - if len(args) != 4 { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 4, len(args)) - } - - delegatorAddr, ok := args[0].(common.Address) - if !ok || delegatorAddr == (common.Address{}) { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - validatorAddress, ok := args[1].(string) - if !ok { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidType, "validatorAddress", "string", args[1]) - } - - amount, ok := args[2].(*big.Int) - if !ok { - return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidAmount, args[2]) - } - - msgAmount, err := convertAmountForAura(amount) - if err != nil { - return nil, common.Address{}, err - } - - creationHeight, ok := args[3].(*big.Int) - if !ok { - return nil, common.Address{}, fmt.Errorf("invalid creation height") - } - - msg := &stakingtypes.MsgCancelUnbondingDelegation{ - DelegatorAddress: sdk.AccAddress(delegatorAddr.Bytes()).String(), // bech32 formatted - ValidatorAddress: validatorAddress, - Amount: sdk.Coin{ - Denom: denom, - Amount: msgAmount, - }, - CreationHeight: creationHeight.Int64(), - } - - if err := msg.ValidateBasic(); err != nil { - return nil, common.Address{}, err - } - - return msg, delegatorAddr, nil -} - -// NewDelegationRequest creates a new QueryDelegationRequest instance and does sanity checks -// on the given arguments before populating the request. -func NewDelegationRequest(args []interface{}) (*stakingtypes.QueryDelegationRequest, error) { - if len(args) != 2 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 2, len(args)) - } - - delegatorAddr, ok := args[0].(common.Address) - if !ok || delegatorAddr == (common.Address{}) { - return nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - validatorAddress, ok := args[1].(string) - if !ok { - return nil, fmt.Errorf(cmn.ErrInvalidType, "validatorAddress", "string", args[1]) - } - - return &stakingtypes.QueryDelegationRequest{ - DelegatorAddr: sdk.AccAddress(delegatorAddr.Bytes()).String(), // bech32 formatted - ValidatorAddr: validatorAddress, - }, nil -} - -// NewValidatorRequest create a new QueryValidatorRequest instance and does sanity checks -// on the given arguments before populating the request. -func NewValidatorRequest(args []interface{}) (*stakingtypes.QueryValidatorRequest, error) { - if len(args) != 1 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 1, len(args)) - } - - validatorAddress, ok := args[0].(string) - if !ok { - return nil, fmt.Errorf(cmn.ErrInvalidType, "validatorAddress", "string", args[0]) - } - - return &stakingtypes.QueryValidatorRequest{ValidatorAddr: validatorAddress}, nil -} - -// NewValidatorsRequest create a new QueryValidatorsRequest instance and does sanity checks -// on the given arguments before populating the request. -func NewValidatorsRequest(method *abi.Method, args []interface{}) (*stakingtypes.QueryValidatorsRequest, error) { - if len(args) != 2 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 2, len(args)) - } - - var input ValidatorsInput - if err := method.Inputs.Copy(&input, args); err != nil { - return nil, fmt.Errorf("error while unpacking args to ValidatorsInput struct: %s", err) - } - - return &stakingtypes.QueryValidatorsRequest{ - Status: input.Status, - Pagination: &input.PageRequest, - }, nil -} - -// NewRedelegationRequest create a new QueryRedelegationRequest instance and does sanity checks -// on the given arguments before populating the request. -func NewRedelegationRequest(args []interface{}) (*RedelegationRequest, error) { - if len(args) != 3 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 3, len(args)) - } - - delegatorAddr, ok := args[0].(common.Address) - if !ok || delegatorAddr == (common.Address{}) { - return nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - validatorSrcAddress, ok := args[1].(string) - if !ok { - return nil, fmt.Errorf(cmn.ErrInvalidType, "validatorSrcAddress", "string", args[1]) - } - - validatorSrcAddr, err := sdk.ValAddressFromBech32(validatorSrcAddress) - if err != nil { - return nil, err - } - - validatorDstAddress, ok := args[2].(string) - if !ok { - return nil, fmt.Errorf(cmn.ErrInvalidType, "validatorDstAddress", "string", args[2]) - } - - validatorDstAddr, err := sdk.ValAddressFromBech32(validatorDstAddress) - if err != nil { - return nil, err - } - - return &RedelegationRequest{ - DelegatorAddress: delegatorAddr.Bytes(), // bech32 formatted - ValidatorSrcAddress: validatorSrcAddr, - ValidatorDstAddress: validatorDstAddr, - }, nil -} - -// NewRedelegationsRequest create a new QueryRedelegationsRequest instance and does sanity checks -// on the given arguments before populating the request. -func NewRedelegationsRequest(method *abi.Method, args []interface{}) (*stakingtypes.QueryRedelegationsRequest, error) { - if len(args) != 4 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 4, len(args)) - } - - // delAddr, srcValAddr & dstValAddr - // can be empty strings. The query will return the - // corresponding redelegations according to the addresses specified - // however, cannot pass all as empty strings, need to provide at least - // the delegator address or the source validator address - var input RedelegationsInput - if err := method.Inputs.Copy(&input, args); err != nil { - return nil, fmt.Errorf("error while unpacking args to RedelegationsInput struct: %s", err) - } - - var ( - // delegatorAddr is the string representation of the delegator address - delegatorAddr = "" - // emptyAddr is an empty address - emptyAddr = common.Address{}.Hex() - ) - if input.DelegatorAddress.Hex() != emptyAddr { - delegatorAddr = sdk.AccAddress(input.DelegatorAddress.Bytes()).String() // bech32 formatted - } - - if delegatorAddr == "" && input.SrcValidatorAddress == "" && input.DstValidatorAddress == "" || - delegatorAddr == "" && input.SrcValidatorAddress == "" && input.DstValidatorAddress != "" { - return nil, errors.New("invalid query. Need to specify at least a source validator address or delegator address") - } - - return &stakingtypes.QueryRedelegationsRequest{ - DelegatorAddr: delegatorAddr, // bech32 formatted - SrcValidatorAddr: input.SrcValidatorAddress, - DstValidatorAddr: input.DstValidatorAddress, - Pagination: &input.PageRequest, - }, nil -} - -// RedelegationRequest is a struct that contains the information to pass into a redelegation query. -type RedelegationRequest struct { - DelegatorAddress sdk.AccAddress - ValidatorSrcAddress sdk.ValAddress - ValidatorDstAddress sdk.ValAddress -} - -// RedelegationsRequest is a struct that contains the information to pass into a redelegations query. -type RedelegationsRequest struct { - DelegatorAddress sdk.AccAddress - MaxRetrieve int64 -} - -// UnbondingDelegationEntry is a struct that contains the information about an unbonding delegation entry. -type UnbondingDelegationEntry struct { - CreationHeight int64 - CompletionTime int64 - InitialBalance *big.Int - Balance *big.Int - UnbondingId uint64 //nolint - UnbondingOnHoldRefCount int64 -} - -// UnbondingDelegationResponse is a struct that contains the information about an unbonding delegation. -type UnbondingDelegationResponse struct { - DelegatorAddress string - ValidatorAddress string - Entries []UnbondingDelegationEntry -} - -// UnbondingDelegationOutput is the output response returned by the query method. -type UnbondingDelegationOutput struct { - UnbondingDelegation UnbondingDelegationResponse -} - -// FromResponse populates the DelegationOutput from a QueryDelegationResponse. -func (do *UnbondingDelegationOutput) FromResponse(res *stakingtypes.QueryUnbondingDelegationResponse) *UnbondingDelegationOutput { - do.UnbondingDelegation.Entries = make([]UnbondingDelegationEntry, len(res.Unbond.Entries)) - do.UnbondingDelegation.ValidatorAddress = res.Unbond.ValidatorAddress - do.UnbondingDelegation.DelegatorAddress = res.Unbond.DelegatorAddress - for i, entry := range res.Unbond.Entries { - do.UnbondingDelegation.Entries[i] = UnbondingDelegationEntry{ - UnbondingId: entry.UnbondingId, - UnbondingOnHoldRefCount: entry.UnbondingOnHoldRefCount, - CreationHeight: entry.CreationHeight, - CompletionTime: entry.CompletionTime.UTC().Unix(), - InitialBalance: util.AuraToEvmBigInt(entry.InitialBalance.BigInt()), - Balance: util.AuraToEvmBigInt(entry.Balance.BigInt()), - } - } - return do -} - -// DelegationOutput is a struct to represent the key information from -// a delegation response. -type DelegationOutput struct { - Shares *big.Int - Balance cmn.Coin -} - -// FromResponse populates the DelegationOutput from a QueryDelegationResponse. -func (do *DelegationOutput) FromResponse(res *stakingtypes.QueryDelegationResponse) *DelegationOutput { - do.Shares = res.DelegationResponse.Delegation.Shares.BigInt() - do.Balance = cmn.Coin{ - // TODO: for consistency, we will change type of balance to BigInt - // the unit will be the same as the token unit with 18 decimals - // the denom here is just for compatibility with the current implementation and should not be used - Denom: res.DelegationResponse.Balance.Denom, - Amount: util.AuraToEvmBigInt(res.DelegationResponse.Balance.Amount.BigInt()), - } - return do -} - -// Pack packs a given slice of abi arguments into a byte array. -func (do *DelegationOutput) Pack(args abi.Arguments) ([]byte, error) { - return args.Pack(do.Shares, do.Balance) -} - -// ValidatorInfo is a struct to represent the key information from -// a validator response. -type ValidatorInfo struct { - OperatorAddress string `abi:"operatorAddress"` - ConsensusPubkey string `abi:"consensusPubkey"` - Jailed bool `abi:"jailed"` - Status uint8 `abi:"status"` - Tokens *big.Int `abi:"tokens"` - DelegatorShares *big.Int `abi:"delegatorShares"` // TODO: Decimal - Description string `abi:"description"` - UnbondingHeight int64 `abi:"unbondingHeight"` - UnbondingTime int64 `abi:"unbondingTime"` - Commission *big.Int `abi:"commission"` - MinSelfDelegation *big.Int `abi:"minSelfDelegation"` -} - -type ValidatorOutput struct { - Validator ValidatorInfo -} - -// DefaultValidatorOutput returns a ValidatorOutput with default values. -func DefaultValidatorOutput() ValidatorOutput { - return ValidatorOutput{ - ValidatorInfo{ - OperatorAddress: "", - ConsensusPubkey: "", - Jailed: false, - Status: uint8(0), - Tokens: big.NewInt(0), - DelegatorShares: big.NewInt(0), - Description: "", - UnbondingHeight: int64(0), - UnbondingTime: int64(0), - Commission: big.NewInt(0), - MinSelfDelegation: big.NewInt(0), - }, - } -} - -// FromResponse populates the ValidatorOutput from a QueryValidatorResponse. -func (vo *ValidatorOutput) FromResponse(res *stakingtypes.QueryValidatorResponse) ValidatorOutput { - return ValidatorOutput{ - Validator: ValidatorInfo{ - OperatorAddress: res.Validator.OperatorAddress, - ConsensusPubkey: FormatConsensusPubkey(res.Validator.ConsensusPubkey), - Jailed: res.Validator.Jailed, - Status: uint8(stakingtypes.BondStatus_value[res.Validator.Status.String()]), - Tokens: util.AuraToEvmBigInt(res.Validator.Tokens.BigInt()), - DelegatorShares: res.Validator.DelegatorShares.BigInt(), // TODO: Decimal - // TODO: create description type, - Description: res.Validator.Description.Details, - UnbondingHeight: res.Validator.UnbondingHeight, - UnbondingTime: res.Validator.UnbondingTime.UTC().Unix(), - Commission: res.Validator.Commission.CommissionRates.Rate.BigInt(), - MinSelfDelegation: util.AuraToEvmBigInt(res.Validator.MinSelfDelegation.BigInt()), - }, - } -} - -// ValidatorsInput is a struct to represent the input information for -// the validators query. Needed to unpack arguments into the PageRequest struct. -type ValidatorsInput struct { - Status string - PageRequest query.PageRequest -} - -// ValidatorsOutput is a struct to represent the key information from -// a validators response. -type ValidatorsOutput struct { - Validators []ValidatorInfo - PageResponse query.PageResponse -} - -// FromResponse populates the ValidatorsOutput from a QueryValidatorsResponse. -func (vo *ValidatorsOutput) FromResponse(res *stakingtypes.QueryValidatorsResponse) *ValidatorsOutput { - vo.Validators = make([]ValidatorInfo, len(res.Validators)) - for i, v := range res.Validators { - vo.Validators[i] = ValidatorInfo{ - OperatorAddress: v.OperatorAddress, - ConsensusPubkey: FormatConsensusPubkey(v.ConsensusPubkey), - Jailed: v.Jailed, - Status: uint8(stakingtypes.BondStatus_value[v.Status.String()]), - Tokens: util.AuraToEvmBigInt(v.Tokens.BigInt()), - DelegatorShares: v.DelegatorShares.BigInt(), - Description: v.Description.Details, - UnbondingHeight: v.UnbondingHeight, - UnbondingTime: v.UnbondingTime.UTC().Unix(), - Commission: v.Commission.CommissionRates.Rate.BigInt(), - MinSelfDelegation: util.AuraToEvmBigInt(v.MinSelfDelegation.BigInt()), - } - } - - if res.Pagination != nil { - vo.PageResponse.Total = res.Pagination.Total - vo.PageResponse.NextKey = res.Pagination.NextKey - } - - return vo -} - -// Pack packs a given slice of abi arguments into a byte array. -func (vo *ValidatorsOutput) Pack(args abi.Arguments) ([]byte, error) { - return args.Pack(vo.Validators, vo.PageResponse) -} - -// RedelegationEntry is a struct to represent the key information from -// a redelegation entry response. -type RedelegationEntry struct { - CreationHeight int64 - CompletionTime int64 - InitialBalance *big.Int - SharesDst *big.Int -} - -// RedelegationValues is a struct to represent the key information from -// a redelegation response. -type RedelegationValues struct { - DelegatorAddress string - ValidatorSrcAddress string - ValidatorDstAddress string - Entries []RedelegationEntry -} - -// RedelegationOutput returns the output for a redelegation query. -type RedelegationOutput struct { - Redelegation RedelegationValues -} - -// FromResponse populates the RedelegationOutput from a QueryRedelegationsResponse. -func (ro *RedelegationOutput) FromResponse(res stakingtypes.Redelegation) *RedelegationOutput { - ro.Redelegation.Entries = make([]RedelegationEntry, len(res.Entries)) - ro.Redelegation.DelegatorAddress = res.DelegatorAddress - ro.Redelegation.ValidatorSrcAddress = res.ValidatorSrcAddress - ro.Redelegation.ValidatorDstAddress = res.ValidatorDstAddress - for i, entry := range res.Entries { - ro.Redelegation.Entries[i] = RedelegationEntry{ - CreationHeight: entry.CreationHeight, - CompletionTime: entry.CompletionTime.UTC().Unix(), - InitialBalance: util.AuraToEvmBigInt(entry.InitialBalance.BigInt()), - SharesDst: entry.SharesDst.BigInt(), - } - } - return ro -} - -// RedelegationEntryResponse is equivalent to a RedelegationEntry except that it -// contains a balance in addition to shares which is more suitable for client -// responses. -type RedelegationEntryResponse struct { - RedelegationEntry RedelegationEntry - Balance *big.Int -} - -// Redelegation contains the list of a particular delegator's redelegating bonds -// from a particular source validator to a particular destination validator. -type Redelegation struct { - DelegatorAddress string - ValidatorSrcAddress string - ValidatorDstAddress string - Entries []RedelegationEntry -} - -// RedelegationResponse is equivalent to a Redelegation except that its entries -// contain a balance in addition to shares which is more suitable for client -// responses. -type RedelegationResponse struct { - Redelegation Redelegation - Entries []RedelegationEntryResponse -} - -// RedelegationsInput is a struct to represent the input information for -// the redelegations query. Needed to unpack arguments into the PageRequest struct. -type RedelegationsInput struct { - DelegatorAddress common.Address - SrcValidatorAddress string - DstValidatorAddress string - PageRequest query.PageRequest -} - -// RedelegationsOutput is a struct to represent the key information from -// a redelegations response. -type RedelegationsOutput struct { - Response []RedelegationResponse - PageResponse query.PageResponse -} - -// FromResponse populates the RedelgationsOutput from a QueryRedelegationsResponse. -func (ro *RedelegationsOutput) FromResponse(res *stakingtypes.QueryRedelegationsResponse) *RedelegationsOutput { - ro.Response = make([]RedelegationResponse, len(res.RedelegationResponses)) - for i, resp := range res.RedelegationResponses { - // for each RedelegationResponse - // there's a RedelegationEntryResponse array ('Entries' field) - entries := make([]RedelegationEntryResponse, len(resp.Entries)) - for j, e := range resp.Entries { - entries[j] = RedelegationEntryResponse{ - RedelegationEntry: RedelegationEntry{ - CreationHeight: e.RedelegationEntry.CreationHeight, - CompletionTime: e.RedelegationEntry.CompletionTime.Unix(), - InitialBalance: util.AuraToEvmBigInt(e.RedelegationEntry.InitialBalance.BigInt()), - SharesDst: e.RedelegationEntry.SharesDst.BigInt(), - }, - Balance: util.AuraToEvmBigInt(e.Balance.BigInt()), - } - } - - // the Redelegation field has also an 'Entries' field of type RedelegationEntry - redelEntries := make([]RedelegationEntry, len(resp.Redelegation.Entries)) - for j, e := range resp.Redelegation.Entries { - redelEntries[j] = RedelegationEntry{ - CreationHeight: e.CreationHeight, - CompletionTime: e.CompletionTime.Unix(), - InitialBalance: util.AuraToEvmBigInt(e.InitialBalance.BigInt()), - SharesDst: e.SharesDst.BigInt(), - } - } - - ro.Response[i] = RedelegationResponse{ - Entries: entries, - Redelegation: Redelegation{ - DelegatorAddress: resp.Redelegation.DelegatorAddress, - ValidatorSrcAddress: resp.Redelegation.ValidatorSrcAddress, - ValidatorDstAddress: resp.Redelegation.ValidatorDstAddress, - Entries: redelEntries, - }, - } - } - - if res.Pagination != nil { - ro.PageResponse.Total = res.Pagination.Total - ro.PageResponse.NextKey = res.Pagination.NextKey - } - - return ro -} - -// Pack packs a given slice of abi arguments into a byte array. -func (ro *RedelegationsOutput) Pack(args abi.Arguments) ([]byte, error) { - return args.Pack(ro.Response, ro.PageResponse) -} - -// NewUnbondingDelegationRequest creates a new QueryUnbondingDelegationRequest instance and does sanity checks -// on the given arguments before populating the request. -func NewUnbondingDelegationRequest(args []interface{}) (*stakingtypes.QueryUnbondingDelegationRequest, error) { - if len(args) != 2 { - return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 2, len(args)) - } - - delegatorAddr, ok := args[0].(common.Address) - if !ok || delegatorAddr == (common.Address{}) { - return nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - validatorAddress, ok := args[1].(string) - if !ok { - return nil, fmt.Errorf(cmn.ErrInvalidType, "validatorAddress", "string", args[1]) - } - - return &stakingtypes.QueryUnbondingDelegationRequest{ - DelegatorAddr: sdk.AccAddress(delegatorAddr.Bytes()).String(), // bech32 formatted - ValidatorAddr: validatorAddress, - }, nil -} - -// checkDelegationUndelegationArgs checks the arguments for the delegation and undelegation functions. -func checkDelegationUndelegationArgs(args []interface{}) (common.Address, string, *big.Int, error) { - if len(args) != 3 { - return common.Address{}, "", nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 3, len(args)) - } - - delegatorAddr, ok := args[0].(common.Address) - if !ok || delegatorAddr == (common.Address{}) { - return common.Address{}, "", nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) - } - - validatorAddress, ok := args[1].(string) - if !ok { - return common.Address{}, "", nil, fmt.Errorf(cmn.ErrInvalidType, "validatorAddress", "string", args[1]) - } - - amount, ok := args[2].(*big.Int) - if !ok { - return common.Address{}, "", nil, fmt.Errorf(cmn.ErrInvalidAmount, args[2]) - } - - return delegatorAddr, validatorAddress, amount, nil -} - -// FormatConsensusPubkey format ConsensusPubkey into a base64 string -func FormatConsensusPubkey(consensusPubkey *codectypes.Any) string { - ed25519pk, ok := consensusPubkey.GetCachedValue().(cryptotypes.PubKey) - if ok { - return base64.StdEncoding.EncodeToString(ed25519pk.Bytes()) - } - return consensusPubkey.String() -} diff --git a/precompiles/staking/utils_test.go b/precompiles/staking/utils_test.go deleted file mode 100644 index 98d40462..00000000 --- a/precompiles/staking/utils_test.go +++ /dev/null @@ -1,516 +0,0 @@ -package staking_test - -import ( - "encoding/json" - "math/big" - "time" - - //nolint:revive // dot imports are fine for Ginkgo - . "github.com/onsi/gomega" - - "cosmossdk.io/math" - abci "github.com/cometbft/cometbft/abci/types" - "github.com/cometbft/cometbft/crypto/tmhash" - tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/cosmos-sdk/baseapp" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" - "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/testutil/mock" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" - evmosapp "github.com/evmos/evmos/v16/app" - "github.com/evmos/evmos/v16/precompiles/authorization" - cmn "github.com/evmos/evmos/v16/precompiles/common" - "github.com/evmos/evmos/v16/precompiles/staking" - "github.com/evmos/evmos/v16/precompiles/testutil" - "github.com/evmos/evmos/v16/precompiles/testutil/contracts" - evmosutil "github.com/evmos/evmos/v16/testutil" - testutiltx "github.com/evmos/evmos/v16/testutil/tx" - evmostypes "github.com/evmos/evmos/v16/types" - "github.com/evmos/evmos/v16/utils" - "github.com/evmos/evmos/v16/x/evm/statedb" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" - inflationtypes "github.com/evmos/evmos/v16/x/inflation/v1/types" - "golang.org/x/exp/slices" -) - -// SetupWithGenesisValSet initializes a new EvmosApp with a validator set and genesis accounts -// that also act as delegators. For simplicity, each validator is bonded with a delegation -// of one consensus engine unit (10^6) in the default token of the simapp from first genesis -// account. A Nop logger is set in SimApp. -func (s *PrecompileTestSuite) SetupWithGenesisValSet(valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) { - appI, genesisState := evmosapp.SetupTestingApp(cmn.DefaultChainID)() - app, ok := appI.(*evmosapp.Evmos) - s.Require().True(ok) - - // set genesis accounts - authGenesis := authtypes.NewGenesisState(authtypes.DefaultParams(), genAccs) - genesisState[authtypes.ModuleName] = app.AppCodec().MustMarshalJSON(authGenesis) - - validators := make([]stakingtypes.Validator, 0, len(valSet.Validators)) - delegations := make([]stakingtypes.Delegation, 0, len(valSet.Validators)) - - bondAmt := sdk.TokensFromConsensusPower(1, evmostypes.PowerReduction) - - for _, val := range valSet.Validators { - pk, err := cryptocodec.FromTmPubKeyInterface(val.PubKey) - s.Require().NoError(err) - pkAny, err := codectypes.NewAnyWithValue(pk) - s.Require().NoError(err) - validator := stakingtypes.Validator{ - OperatorAddress: sdk.ValAddress(val.Address).String(), - ConsensusPubkey: pkAny, - Jailed: false, - Status: stakingtypes.Bonded, - Tokens: bondAmt, - DelegatorShares: math.LegacyOneDec(), - Description: stakingtypes.Description{}, - UnbondingHeight: int64(0), - UnbondingTime: time.Unix(0, 0).UTC(), - Commission: stakingtypes.NewCommission(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()), - MinSelfDelegation: math.ZeroInt(), - } - validators = append(validators, validator) - delegations = append(delegations, stakingtypes.NewDelegation(genAccs[0].GetAddress(), val.Address.Bytes(), math.LegacyOneDec())) - } - s.validators = validators - - // set validators and delegations - stakingParams := stakingtypes.DefaultParams() - // set bond demon to be aevmos - stakingParams.BondDenom = utils.BaseDenom - stakingGenesis := stakingtypes.NewGenesisState(stakingParams, validators, delegations) - genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(stakingGenesis) - - totalBondAmt := math.ZeroInt() - for range validators { - totalBondAmt = totalBondAmt.Add(bondAmt) - } - totalSupply := sdk.NewCoins() - for _, b := range balances { - // add genesis acc tokens and delegated tokens to total supply - totalSupply = totalSupply.Add(b.Coins.Add(sdk.NewCoin(utils.BaseDenom, totalBondAmt))...) - } - - // add bonded amount to bonded pool module account - balances = append(balances, banktypes.Balance{ - Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(), - Coins: sdk.Coins{sdk.NewCoin(utils.BaseDenom, totalBondAmt)}, - }) - - // update total supply - bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{}, []banktypes.SendEnabled{}) - genesisState[banktypes.ModuleName] = app.AppCodec().MustMarshalJSON(bankGenesis) - - stateBytes, err := json.MarshalIndent(genesisState, "", " ") - s.Require().NoError(err) - - header := evmosutil.NewHeader( - 2, - time.Now().UTC(), - cmn.DefaultChainID, - sdk.ConsAddress(validators[0].GetOperator()), - tmhash.Sum([]byte("app")), - tmhash.Sum([]byte("validators")), - ) - - // init chain will set the validator set and initialize the genesis accounts - app.InitChain( - abci.RequestInitChain{ - ChainId: cmn.DefaultChainID, - Validators: []abci.ValidatorUpdate{}, - ConsensusParams: evmosapp.DefaultConsensusParams, - AppStateBytes: stateBytes, - }, - ) - - // create Context - s.ctx = app.BaseApp.NewContext(false, header) - - // commit genesis changes - app.Commit() - app.BeginBlock(abci.RequestBeginBlock{Header: header}) - - s.app = app -} - -func (s *PrecompileTestSuite) DoSetupTest() { - nValidators := 3 - signers := make(map[string]tmtypes.PrivValidator, nValidators) - validators := make([]*tmtypes.Validator, 0, nValidators) - - for i := 0; i < nValidators; i++ { - privVal := mock.NewPV() - pubKey, err := privVal.GetPubKey() - s.Require().NoError(err) - signers[pubKey.Address().String()] = privVal - validator := tmtypes.NewValidator(pubKey, 1) - validators = append(validators, validator) - } - - valSet := tmtypes.NewValidatorSet(validators) - - // generate genesis account - addr, priv := testutiltx.NewAddrKey() - s.privKey = priv - s.address = addr - s.signer = testutiltx.NewSigner(priv) - - baseAcc := authtypes.NewBaseAccount(priv.PubKey().Address().Bytes(), priv.PubKey(), 0, 0) - - acc := &evmostypes.EthAccount{ - BaseAccount: baseAcc, - CodeHash: common.BytesToHash(evmtypes.EmptyCodeHash).Hex(), - } - - amount := sdk.TokensFromConsensusPower(5, evmostypes.PowerReduction) - - balance := banktypes.Balance{ - Address: acc.GetAddress().String(), - Coins: sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, amount)), - } - - s.SetupWithGenesisValSet(valSet, []authtypes.GenesisAccount{acc}, balance) - - // Create StateDB - s.stateDB = statedb.New(s.ctx, s.app.EvmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(s.ctx.HeaderHash().Bytes()))) - - // bond denom - stakingParams := s.app.StakingKeeper.GetParams(s.ctx) - stakingParams.BondDenom = utils.BaseDenom - s.bondDenom = stakingParams.BondDenom - err := s.app.StakingKeeper.SetParams(s.ctx, stakingParams) - s.Require().NoError(err) - - s.ethSigner = ethtypes.LatestSignerForChainID(s.app.EvmKeeper.ChainID()) - - precompile, err := staking.NewPrecompile(s.app.StakingKeeper, s.app.AuthzKeeper) - s.Require().NoError(err) - s.precompile = precompile - - coins := sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(5000000000000000000))) - distrCoins := sdk.NewCoins(sdk.NewCoin(utils.BaseDenom, math.NewInt(2000000000000000000))) - err = s.app.BankKeeper.MintCoins(s.ctx, inflationtypes.ModuleName, coins) - s.Require().NoError(err) - err = s.app.BankKeeper.SendCoinsFromModuleToModule(s.ctx, inflationtypes.ModuleName, authtypes.FeeCollectorName, distrCoins) - s.Require().NoError(err) - - queryHelperEvm := baseapp.NewQueryServerTestHelper(s.ctx, s.app.InterfaceRegistry()) - evmtypes.RegisterQueryServer(queryHelperEvm, s.app.EvmKeeper) - s.queryClientEVM = evmtypes.NewQueryClient(queryHelperEvm) -} - -// ApproveAndCheckAuthz is a helper function to approve a given authorization method and check if the authorization was created. -func (s *PrecompileTestSuite) ApproveAndCheckAuthz(method abi.Method, msgType string, amount *big.Int) { - approveArgs := []interface{}{ - s.address, - amount, - []string{msgType}, - } - resp, err := s.precompile.Approve(s.ctx, s.address, s.stateDB, &method, approveArgs) - s.Require().NoError(err) - s.Require().Equal(resp, cmn.TrueValue) - - auth, _ := s.CheckAuthorization(staking.DelegateAuthz, s.address, s.address) - s.Require().NotNil(auth) - s.Require().Equal(auth.AuthorizationType, staking.DelegateAuthz) - s.Require().Equal(auth.MaxTokens, &sdk.Coin{Denom: s.bondDenom, Amount: math.NewIntFromBigInt(amount)}) -} - -// CheckAuthorization is a helper function to check if the authorization is set and if it is the correct type. -func (s *PrecompileTestSuite) CheckAuthorization(authorizationType stakingtypes.AuthorizationType, grantee, granter common.Address) (*stakingtypes.StakeAuthorization, *time.Time) { - stakingAuthz := stakingtypes.StakeAuthorization{AuthorizationType: authorizationType} - auth, expirationTime := s.app.AuthzKeeper.GetAuthorization(s.ctx, grantee.Bytes(), granter.Bytes(), stakingAuthz.MsgTypeURL()) - - stakeAuthorization, ok := auth.(*stakingtypes.StakeAuthorization) - if !ok { - return nil, expirationTime - } - - return stakeAuthorization, expirationTime -} - -// CreateAuthorization is a helper function to create a new authorization of the given type for a spender address -// (=grantee). -// The authorization will be created to spend the given Coin. -// For testing purposes, this function will create a new authorization for all available validators, -// that are not jailed. -func (s *PrecompileTestSuite) CreateAuthorization(grantee common.Address, authzType stakingtypes.AuthorizationType, coin *sdk.Coin) error { - // Get all available validators and filter out jailed validators - validators := make([]sdk.ValAddress, 0) - s.app.StakingKeeper.IterateValidators( - s.ctx, func(_ int64, validator stakingtypes.ValidatorI) (stop bool) { - if validator.IsJailed() { - return - } - validators = append(validators, validator.GetOperator()) - return - }, - ) - - stakingAuthz, err := stakingtypes.NewStakeAuthorization(validators, nil, authzType, coin) - if err != nil { - return err - } - - expiration := time.Now().Add(cmn.DefaultExpirationDuration).UTC() - err = s.app.AuthzKeeper.SaveGrant(s.ctx, grantee.Bytes(), s.address.Bytes(), stakingAuthz, &expiration) - if err != nil { - return err - } - - return nil -} - -// SetupApproval sets up an approval, that authorizes the grantee to spend the given amount for the granter -// in transactions, that target the specified message types. -func (s *PrecompileTestSuite) SetupApproval( - granterPriv types.PrivKey, - grantee common.Address, - amount *big.Int, - msgTypes []string, -) { - approveArgs := contracts.CallArgs{ - ContractAddr: s.precompile.Address(), - ContractABI: s.precompile.ABI, - PrivKey: granterPriv, - MethodName: authorization.ApproveMethod, - Args: []interface{}{ - grantee, amount, msgTypes, - }, - } - - logCheckArgs := testutil.LogCheckArgs{ - ABIEvents: s.precompile.Events, - ExpEvents: []string{authorization.EventTypeApproval}, - ExpPass: true, - } - - res, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, approveArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while calling the contract to approve") - - s.NextBlock() - - // Check if the approval event is emitted - granterAddr := common.BytesToAddress(granterPriv.PubKey().Address().Bytes()) - testutil.CheckAuthorizationEvents( - s.precompile.Events[authorization.EventTypeApproval], - s.precompile.Address(), - granterAddr, - grantee, - res, - s.ctx.BlockHeight()-1, - msgTypes, - amount, - ) -} - -// SetupApprovalWithContractCalls is a helper function used to setup the allowance for the given spender. -func (s *PrecompileTestSuite) SetupApprovalWithContractCalls(approvalArgs contracts.CallArgs) { - msgTypes, ok := approvalArgs.Args[1].([]string) - Expect(ok).To(BeTrue(), "failed to convert msgTypes to []string") - expAmount, ok := approvalArgs.Args[2].(*big.Int) - Expect(ok).To(BeTrue(), "failed to convert amount to big.Int") - - logCheckArgs := testutil.LogCheckArgs{ - ABIEvents: s.precompile.Events, - ExpEvents: []string{authorization.EventTypeApproval}, - ExpPass: true, - } - - _, _, err := contracts.CallContractAndCheckLogs(s.ctx, s.app, approvalArgs, logCheckArgs) - Expect(err).To(BeNil(), "error while approving: %v", err) - - // iterate over args - var expectedAuthz stakingtypes.AuthorizationType - for _, msgType := range msgTypes { - switch msgType { - case staking.DelegateMsg: - expectedAuthz = staking.DelegateAuthz - case staking.UndelegateMsg: - expectedAuthz = staking.UndelegateAuthz - case staking.RedelegateMsg: - expectedAuthz = staking.RedelegateAuthz - case staking.CancelUnbondingDelegationMsg: - expectedAuthz = staking.CancelUnbondingDelegationAuthz - } - authz, expirationTime := s.CheckAuthorization(expectedAuthz, approvalArgs.ContractAddr, s.address) - Expect(authz).ToNot(BeNil(), "expected authorization to be set") - Expect(authz.MaxTokens.Amount).To(Equal(math.NewInt(expAmount.Int64())), "expected different allowance") - Expect(authz.MsgTypeURL()).To(Equal(msgType), "expected different message type") - Expect(expirationTime).ToNot(BeNil(), "expected expiration time to not be nil") - } -} - -// DeployContract deploys a contract that calls the staking precompile's methods for testing purposes. -func (s *PrecompileTestSuite) DeployContract(contract evmtypes.CompiledContract) (addr common.Address, err error) { - addr, err = evmosutil.DeployContract( - s.ctx, - s.app, - s.privKey, - s.queryClientEVM, - contract, - ) - return -} - -// NextBlock commits the current block and sets up the next block. -func (s *PrecompileTestSuite) NextBlock() { - var err error - s.ctx, err = evmosutil.CommitAndCreateNewCtx(s.ctx, s.app, time.Second, nil) - Expect(err).To(BeNil(), "failed to commit block") -} - -// CheckAllowanceChangeEvent is a helper function used to check the allowance change event arguments. -func (s *PrecompileTestSuite) CheckAllowanceChangeEvent(log *ethtypes.Log, methods []string, amounts []*big.Int) { - s.Require().Equal(log.Address, s.precompile.Address()) - // Check event signature matches the one emitted - event := s.precompile.ABI.Events[authorization.EventTypeAllowanceChange] - s.Require().Equal(event.ID, common.HexToHash(log.Topics[0].Hex())) - s.Require().Equal(log.BlockNumber, uint64(s.ctx.BlockHeight())) - - var approvalEvent authorization.EventAllowanceChange - err := cmn.UnpackLog(s.precompile.ABI, &approvalEvent, authorization.EventTypeAllowanceChange, *log) - s.Require().NoError(err) - s.Require().Equal(s.address, approvalEvent.Grantee) - s.Require().Equal(s.address, approvalEvent.Granter) - s.Require().Equal(len(methods), len(approvalEvent.Methods)) - - for i, method := range methods { - s.Require().Equal(method, approvalEvent.Methods[i]) - s.Require().Equal(amounts[i], approvalEvent.Values[i]) - } -} - -// ExpectAuthorization is a helper function for tests using the Ginkgo BDD style tests, to check that the -// authorization is correctly set. -func (s *PrecompileTestSuite) ExpectAuthorization(authorizationType stakingtypes.AuthorizationType, grantee, granter common.Address, maxTokens *sdk.Coin) { - authz, expirationTime := s.CheckAuthorization(authorizationType, grantee, granter) - Expect(authz).ToNot(BeNil(), "expected authorization to be set") - Expect(authz.AuthorizationType).To(Equal(authorizationType), "expected different authorization type") - Expect(authz.MaxTokens).To(Equal(maxTokens), "expected different max tokens") - Expect(expirationTime).ToNot(BeNil(), "expected expiration time to be not be nil") -} - -// assertValidatorsResponse asserts all the fields on the validators response -func (s *PrecompileTestSuite) assertValidatorsResponse(validators []staking.ValidatorInfo, expLen int) { - // returning order can change - valOrder := []int{0, 1} - if validators[0].OperatorAddress != s.validators[0].OperatorAddress { - valOrder = []int{1, 0} - } - for i := 0; i < expLen; i++ { - j := valOrder[i] - s.Require().Equal(s.validators[j].OperatorAddress, validators[i].OperatorAddress) - s.Require().Equal(uint8(s.validators[j].Status), validators[i].Status) - s.Require().Equal(s.validators[j].Tokens.Uint64(), validators[i].Tokens.Uint64()) - s.Require().Equal(s.validators[j].DelegatorShares.BigInt(), validators[i].DelegatorShares) - s.Require().Equal(s.validators[j].Jailed, validators[i].Jailed) - s.Require().Equal(s.validators[j].UnbondingHeight, validators[i].UnbondingHeight) - s.Require().Equal(int64(0), validators[i].UnbondingTime) - s.Require().Equal(int64(0), validators[i].Commission.Int64()) - s.Require().Equal(int64(0), validators[i].MinSelfDelegation.Int64()) - s.Require().Equal(validators[i].ConsensusPubkey, staking.FormatConsensusPubkey(s.validators[j].ConsensusPubkey)) - } -} - -// assertRedelegation asserts the redelegationOutput struct and its fields -func (s *PrecompileTestSuite) assertRedelegationsOutput(data []byte, redelTotalCount uint64, expAmt *big.Int, expCreationHeight int64, hasPagination bool) { - var redOut staking.RedelegationsOutput - err := s.precompile.UnpackIntoInterface(&redOut, staking.RedelegationsMethod, data) - s.Require().NoError(err, "failed to unpack output") - - s.Require().Len(redOut.Response, 1) - // check pagination - total count should be 2 - s.Require().Equal(redelTotalCount, redOut.PageResponse.Total) - if hasPagination { - s.Require().NotEmpty(redOut.PageResponse.NextKey) - } else { - s.Require().Empty(redOut.PageResponse.NextKey) - } - // check redelegation entry - // order may change, one redelegation has 2 entries - // and the other has one - if len(redOut.Response[0].Entries) == 2 { - s.assertRedelegation(redOut.Response[0], - 2, - s.validators[0].OperatorAddress, - s.validators[1].OperatorAddress, - expAmt, - expCreationHeight, - ) - } else { - s.assertRedelegation(redOut.Response[0], - 1, - s.validators[0].OperatorAddress, - sdk.ValAddress(s.address.Bytes()).String(), - expAmt, - expCreationHeight, - ) - } -} - -// assertRedelegation asserts all the fields on the redelegations response -// should specify the amount of entries expected and the expected amount for this -// the same amount is considered for all entries -func (s *PrecompileTestSuite) assertRedelegation(res staking.RedelegationResponse, entriesCount int, expValSrcAddr, expValDstAddr string, expAmt *big.Int, expCreationHeight int64) { - // check response - s.Require().Equal(res.Redelegation.DelegatorAddress, sdk.AccAddress(s.address.Bytes()).String()) - s.Require().Equal(res.Redelegation.ValidatorSrcAddress, expValSrcAddr) - s.Require().Equal(res.Redelegation.ValidatorDstAddress, expValDstAddr) - // check redelegation entries - should be empty - s.Require().Empty(res.Redelegation.Entries) - // check response entries, should be 2 - s.Require().Len(res.Entries, entriesCount) - // check redelegation entries - for _, e := range res.Entries { - s.Require().Equal(e.Balance, expAmt) - s.Require().True(e.RedelegationEntry.CompletionTime > 1600000000) - s.Require().Equal(expCreationHeight, e.RedelegationEntry.CreationHeight) - s.Require().Equal(e.RedelegationEntry.InitialBalance, expAmt) - } -} - -// setupRedelegations setups 2 entries for redelegation from validator[0] -// to validator[1], creates a validator using s.address -// and creates a redelegation from validator[0] to the new validator -func (s *PrecompileTestSuite) setupRedelegations(redelAmt *big.Int) error { - msg := stakingtypes.MsgBeginRedelegate{ - DelegatorAddress: sdk.AccAddress(s.address.Bytes()).String(), - ValidatorSrcAddress: s.validators[0].OperatorAddress, - ValidatorDstAddress: s.validators[1].OperatorAddress, - Amount: sdk.NewCoin(s.bondDenom, math.NewIntFromBigInt(redelAmt)), - } - - msgSrv := stakingkeeper.NewMsgServerImpl(&s.app.StakingKeeper) - // create 2 entries for same redelegation - for i := 0; i < 2; i++ { - if _, err := msgSrv.BeginRedelegate(s.ctx, &msg); err != nil { - return err - } - } - - // create a validator with s.address and s.privKey - // then create a redelegation from validator[0] to this new validator - testutil.CreateValidator(s.ctx, s.T(), s.privKey.PubKey(), s.app.StakingKeeper, math.NewInt(100)) - msg.ValidatorDstAddress = sdk.ValAddress(s.address.Bytes()).String() - _, err := msgSrv.BeginRedelegate(s.ctx, &msg) - return err -} - -// CheckValidatorOutput checks that the given validator output -func (s *PrecompileTestSuite) CheckValidatorOutput(valOut staking.ValidatorInfo) { - validatorAddrs := make([]string, len(s.validators)) - for i, v := range s.validators { - validatorAddrs[i] = v.OperatorAddress - } - Expect(slices.Contains(validatorAddrs, valOut.OperatorAddress)).To(BeTrue(), "operator address not found in test suite validators") - Expect(valOut.DelegatorShares).To(Equal(big.NewInt(1e18)), "expected different delegator shares") -} diff --git a/precompiles/util/util.go b/precompiles/util/util.go deleted file mode 100644 index c24d8b05..00000000 --- a/precompiles/util/util.go +++ /dev/null @@ -1,38 +0,0 @@ -package util - -import ( - "math/big" - - "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/types" - cmn "github.com/evmos/evmos/v16/precompiles/common" -) - -func EvmToAuraBigInt(amount *big.Int) *big.Int { - return new(big.Int).Div(amount, big.NewInt(1e12)) -} - -func AuraToEvmBigInt(amount *big.Int) *big.Int { - return new(big.Int).Mul(amount, big.NewInt(1e12)) -} - -func EvmToAuraInt(amount math.Int) math.Int { - return amount.Quo(types.NewInt(1e12)) -} - -func AuraToEvmInt(amount math.Int) math.Int { - return amount.Mul(types.NewInt(1e12)) -} - -func NewDecCoinsResponseEVM(amount types.DecCoins) []cmn.DecCoin { - // Create a new output for each coin and add it to the output array. - outputs := make([]cmn.DecCoin, len(amount)) - for i, coin := range amount { - outputs[i] = cmn.DecCoin{ - Denom: coin.Denom, - Amount: AuraToEvmBigInt(coin.Amount.TruncateInt().BigInt()), - Precision: math.LegacyPrecision, - } - } - return outputs -} diff --git a/tests/evm/init-node.sh b/tests/evm/init-node.sh index 6eefdc05..830acb98 100755 --- a/tests/evm/init-node.sh +++ b/tests/evm/init-node.sh @@ -137,7 +137,7 @@ jq -r '.app_state.bank.supply[0].amount="100000000"' "$GENESIS" >"$TMP_GENESIS" jq -r --arg ibc_denom "$IBC_DENOM" '.app_state.bank.supply[0].denom=$ibc_denom' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" # set list of evm precompile contracts -jq '.app_state.evm.params.active_precompiles=[ "0x0000000000000000000000000000000000000400", "0x0000000000000000000000000000000000000800", "0x0000000000000000000000000000000000000801", "0x0000000000000000000000000000000000000802" ]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" +jq '.app_state.evm.params.active_precompiles=[]' "$GENESIS" >"$TMP_GENESIS" && mv "$TMP_GENESIS" "$GENESIS" # set custom pruning settings if [ "$PRUNING" = "custom" ]; then diff --git a/tests/testutil.go b/tests/testutil.go index f0bd3a8a..b9732975 100644 --- a/tests/testutil.go +++ b/tests/testutil.go @@ -25,7 +25,7 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" - "github.com/evmos/evmos/v16/encoding" + "github.com/evmos/evmos/v18/encoding" ) // EmptyAppOptions is a stub implementing AppOptions diff --git a/x/evmutil/client/cli/evm.go b/x/evmutil/client/cli/evm.go index 61c113ae..e1357a24 100644 --- a/x/evmutil/client/cli/evm.go +++ b/x/evmutil/client/cli/evm.go @@ -13,11 +13,11 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/evmos/evmos/v16/crypto/hd" - "github.com/evmos/evmos/v16/server/config" - etherminttypes "github.com/evmos/evmos/v16/types" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" - feemarkettypes "github.com/evmos/evmos/v16/x/feemarket/types" + "github.com/evmos/evmos/v18/crypto/hd" + "github.com/evmos/evmos/v18/server/config" + etherminttypes "github.com/evmos/evmos/v18/types" + evmtypes "github.com/evmos/evmos/v18/x/evm/types" + feemarkettypes "github.com/evmos/evmos/v18/x/feemarket/types" ) // CanSignEthTx returns an error if the signing key algorithm is not eth_secp256k1. diff --git a/x/evmutil/keeper/bank_keeper.go b/x/evmutil/keeper/bank_keeper.go index f4fdef07..e46b0b4b 100644 --- a/x/evmutil/keeper/bank_keeper.go +++ b/x/evmutil/keeper/bank_keeper.go @@ -7,17 +7,17 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" + evmtypes "github.com/evmos/evmos/v18/x/evm/types" "github.com/aura-nw/aura/x/evmutil/types" ) const ( // EvmDenom is the gas denom used by the evm - EvmDenom = "aeaura" + EvmDenom = "aaura" // CosmosDenom is the gas denom used by the kava app - CosmosDenom = "ueaura" + CosmosDenom = "uaura" ) // ConversionMultiplier is the conversion multiplier between akava and ukava diff --git a/x/evmutil/keeper/bank_keeper_test.go.disabled b/x/evmutil/keeper/bank_keeper_test.go.disabled index db4d928e..565688a1 100644 --- a/x/evmutil/keeper/bank_keeper_test.go.disabled +++ b/x/evmutil/keeper/bank_keeper_test.go.disabled @@ -11,7 +11,7 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" + evmtypes "github.com/evmos/evmos/v18/x/evm/types" "github.com/aura-nw/aura/x/evmutil/keeper" "github.com/aura-nw/aura/x/evmutil/testutil" diff --git a/x/evmutil/keeper/evm.go b/x/evmutil/keeper/evm.go index 8367f77d..96cade8d 100644 --- a/x/evmutil/keeper/evm.go +++ b/x/evmutil/keeper/evm.go @@ -24,8 +24,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/evmos/evmos/v16/server/config" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" + "github.com/evmos/evmos/v18/server/config" + evmtypes "github.com/evmos/evmos/v18/x/evm/types" "github.com/aura-nw/aura/x/evmutil/types" ) diff --git a/x/evmutil/keeper/grpc_query.go b/x/evmutil/keeper/grpc_query.go index 08de9b00..fcbc2bdf 100644 --- a/x/evmutil/keeper/grpc_query.go +++ b/x/evmutil/keeper/grpc_query.go @@ -1,3 +1,20 @@ +// Derived from https://github.com/Kava-Labs/kava/blob/d500cd12362edd0c64e8065fbc595cd9399b08c2/x/evmutil/keeper/grpc_query.go +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Modifications: +// - Removed unused queries + package keeper import ( diff --git a/x/evmutil/keeper/invariants.go b/x/evmutil/keeper/invariants.go index f785f90c..8414dfa6 100644 --- a/x/evmutil/keeper/invariants.go +++ b/x/evmutil/keeper/invariants.go @@ -1,3 +1,20 @@ +// Derived from https://github.com/Kava-Labs/kava/blob/d500cd12362edd0c64e8065fbc595cd9399b08c2/x/evmutil/keeper/grpc_query.go +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Modifications: +// - Removed BackedCoinInvariant + package keeper import ( diff --git a/x/evmutil/keeper/keeper.go b/x/evmutil/keeper/keeper.go index e800104a..7a12932d 100644 --- a/x/evmutil/keeper/keeper.go +++ b/x/evmutil/keeper/keeper.go @@ -1,3 +1,21 @@ +// Derived from https://github.com/Kava-Labs/kava/blob/d500cd12362edd0c64e8065fbc595cd9399b08c2/x/evmutil/keeper/grpc_query.go +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Modifications: +// - Removed SetDeployedCosmosCoinContract +// - Remove GetDeployedCosmosCoinContract + package keeper import ( diff --git a/x/evmutil/keeper/migrations.go b/x/evmutil/keeper/migrations.go index 3be1ada6..c3aeb0a0 100644 --- a/x/evmutil/keeper/migrations.go +++ b/x/evmutil/keeper/migrations.go @@ -1,3 +1,20 @@ +// Derived from https://github.com/Kava-Labs/kava/blob/d500cd12362edd0c64e8065fbc595cd9399b08c2/x/evmutil/keeper/grpc_query.go +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Modifications: +// - Removed Migrate1to2 + package keeper // Migrator is a struct for handling in-place store migrations. diff --git a/x/evmutil/keeper/params.go b/x/evmutil/keeper/params.go index ab779417..a4a04cdc 100644 --- a/x/evmutil/keeper/params.go +++ b/x/evmutil/keeper/params.go @@ -1,3 +1,20 @@ +// Derived from https://github.com/Kava-Labs/kava/blob/d500cd12362edd0c64e8065fbc595cd9399b08c2/x/evmutil/keeper/grpc_query.go +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Modifications: +// - Removed all param queries + package keeper import ( diff --git a/x/evmutil/testutil/suite.go.disabled b/x/evmutil/testutil/suite.go.disabled index af1ca460..90e928a6 100644 --- a/x/evmutil/testutil/suite.go.disabled +++ b/x/evmutil/testutil/suite.go.disabled @@ -28,12 +28,12 @@ // ethtypes "github.com/ethereum/go-ethereum/core/types" // "github.com/ethereum/go-ethereum/core/vm" // "github.com/ethereum/go-ethereum/crypto" -// "github.com/evmos/evmos/v16/crypto/ethsecp256k1" -// "github.com/evmos/evmos/v16/server/config" -// etherminttests "github.com/evmos/evmos/v16/testutil/tx" -// etherminttypes "github.com/evmos/evmos/v16/types" -// evmtypes "github.com/evmos/evmos/v16/x/evm/types" -// feemarkettypes "github.com/evmos/evmos/v16/x/feemarket/types" +// "github.com/evmos/evmos/v18/crypto/ethsecp256k1" +// "github.com/evmos/evmos/v18/server/config" +// etherminttests "github.com/evmos/evmos/v18/testutil/tx" +// etherminttypes "github.com/evmos/evmos/v18/types" +// evmtypes "github.com/evmos/evmos/v18/x/evm/types" +// feemarkettypes "github.com/evmos/evmos/v18/x/feemarket/types" // "github.com/stretchr/testify/suite" // "github.com/aura-nw/aura/x/evmutil/keeper" diff --git a/x/evmutil/types/contract.go b/x/evmutil/types/contract.go index a3a0e275..31330a40 100644 --- a/x/evmutil/types/contract.go +++ b/x/evmutil/types/contract.go @@ -21,7 +21,7 @@ import ( "fmt" "github.com/ethereum/go-ethereum/common" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" + evmtypes "github.com/evmos/evmos/v18/x/evm/types" ) var ( diff --git a/x/evmutil/types/expected_keepers.go b/x/evmutil/types/expected_keepers.go index 5c045d1a..5974d339 100644 --- a/x/evmutil/types/expected_keepers.go +++ b/x/evmutil/types/expected_keepers.go @@ -7,7 +7,7 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/vm" - evmtypes "github.com/evmos/evmos/v16/x/evm/types" + evmtypes "github.com/evmos/evmos/v18/x/evm/types" ) // AccountKeeper defines the expected account keeper interface