From 66a252e6ddc5cb3069c5bd2835ab7e6310303dd9 Mon Sep 17 00:00:00 2001 From: Rahul Ghangas Date: Mon, 1 Jun 2026 12:23:08 +0000 Subject: [PATCH 1/5] feat: solidity only community pool with minimal scheduler --- x/erc20/types/msg_test.go | 9 +- x/feemarket/types/msg_test.go | 10 +- x/svip/keeper/msg_server_test.go | 7 +- x/svip/types/msgs_test.go | 17 +- x/vm/keeper/abci.go | 2 + x/vm/keeper/call_evm.go | 72 +++- x/vm/keeper/msg_server.go | 24 +- x/vm/keeper/scheduler.go | 98 +++++ x/vm/keeper/scheduler_test.go | 65 +++ x/vm/types/evm.pb.go | 690 ++++++++++++++++++++++++------- x/vm/types/params.go | 39 ++ x/vm/types/params_test.go | 37 ++ 12 files changed, 899 insertions(+), 171 deletions(-) create mode 100644 x/vm/keeper/scheduler.go create mode 100644 x/vm/keeper/scheduler_test.go diff --git a/x/erc20/types/msg_test.go b/x/erc20/types/msg_test.go index 28b9c4ad..4d4730b7 100644 --- a/x/erc20/types/msg_test.go +++ b/x/erc20/types/msg_test.go @@ -261,7 +261,7 @@ func (suite *MsgsTestSuite) TestMsgUpdateValidateBasic() { { "pass - valid msg", &types.MsgUpdateParams{ - Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Authority: govAuthority(), Params: types.DefaultParams(), }, true, @@ -279,3 +279,10 @@ func (suite *MsgsTestSuite) TestMsgUpdateValidateBasic() { }) } } + +func govAuthority() string { + return sdk.MustBech32ifyAddressBytes( + sdk.GetConfig().GetBech32AccountAddrPrefix(), + authtypes.NewModuleAddress(govtypes.ModuleName), + ) +} diff --git a/x/feemarket/types/msg_test.go b/x/feemarket/types/msg_test.go index 930324e9..3493b514 100644 --- a/x/feemarket/types/msg_test.go +++ b/x/feemarket/types/msg_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/suite" + sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -34,7 +35,7 @@ func (suite *MsgsTestSuite) TestMsgUpdateValidateBasic() { { "pass - valid msg", &MsgUpdateParams{ - Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Authority: govAuthority(), Params: DefaultParams(), }, true, @@ -52,3 +53,10 @@ func (suite *MsgsTestSuite) TestMsgUpdateValidateBasic() { }) } } + +func govAuthority() string { + return sdk.MustBech32ifyAddressBytes( + sdk.GetConfig().GetBech32AccountAddrPrefix(), + authtypes.NewModuleAddress(govtypes.ModuleName), + ) +} diff --git a/x/svip/keeper/msg_server_test.go b/x/svip/keeper/msg_server_test.go index 8ecd137c..af1b242c 100644 --- a/x/svip/keeper/msg_server_test.go +++ b/x/svip/keeper/msg_server_test.go @@ -18,7 +18,10 @@ import ( ) func govAuthority() string { - return authtypes.NewModuleAddress(govtypes.ModuleName).String() + return sdk.MustBech32ifyAddressBytes( + sdk.GetConfig().GetBech32AccountAddrPrefix(), + authtypes.NewModuleAddress(govtypes.ModuleName), + ) } func TestUpdateParams_InvalidAuthority(t *testing.T) { @@ -320,7 +323,7 @@ func TestFundPool_WrongDenom(t *testing.T) { td := newMockedTestData(t) srv := keeper.NewMsgServerImpl(td.keeper) - depositor := authtypes.NewModuleAddress(govtypes.ModuleName).String() + depositor := govAuthority() _, err := srv.FundPool(td.ctx, &types.MsgFundPool{ Depositor: depositor, diff --git a/x/svip/types/msgs_test.go b/x/svip/types/msgs_test.go index 9ba31b46..67fb8cfe 100644 --- a/x/svip/types/msgs_test.go +++ b/x/svip/types/msgs_test.go @@ -22,7 +22,7 @@ func TestMsgsTestSuite(t *testing.T) { } func (suite *MsgsTestSuite) TestMsgUpdateParamsValidateBasic() { - govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + govAddr := govAuthority() testCases := []struct { name string @@ -59,7 +59,7 @@ func (suite *MsgsTestSuite) TestMsgUpdateParamsValidateBasic() { } func (suite *MsgsTestSuite) TestMsgActivateValidateBasic() { - govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + govAddr := govAuthority() testCases := []struct { name string @@ -83,7 +83,7 @@ func (suite *MsgsTestSuite) TestMsgActivateValidateBasic() { } func (suite *MsgsTestSuite) TestMsgReactivateValidateBasic() { - govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + govAddr := govAuthority() testCases := []struct { name string @@ -107,7 +107,7 @@ func (suite *MsgsTestSuite) TestMsgReactivateValidateBasic() { } func (suite *MsgsTestSuite) TestMsgPauseValidateBasic() { - govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + govAddr := govAuthority() testCases := []struct { name string @@ -131,7 +131,7 @@ func (suite *MsgsTestSuite) TestMsgPauseValidateBasic() { } func (suite *MsgsTestSuite) TestMsgFundPoolValidateBasic() { - validAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + validAddr := govAuthority() testCases := []struct { name string @@ -183,3 +183,10 @@ func (suite *MsgsTestSuite) TestMsgFundPoolValidateBasic() { }) } } + +func govAuthority() string { + return sdk.MustBech32ifyAddressBytes( + sdk.GetConfig().GetBech32AccountAddrPrefix(), + authtypes.NewModuleAddress(govtypes.ModuleName), + ) +} diff --git a/x/vm/keeper/abci.go b/x/vm/keeper/abci.go index 6520ddb5..b57ba852 100644 --- a/x/vm/keeper/abci.go +++ b/x/vm/keeper/abci.go @@ -44,6 +44,8 @@ func (k *Keeper) BeginBlock(ctx sdk.Context) (err error) { func (k *Keeper) EndBlock(ctx sdk.Context) (err error) { ctx, span := ctx.StartSpan(tracer, "EndBlock", trace.WithAttributes(attribute.Int64("block_num", ctx.BlockHeight()))) defer func() { evmtrace.EndSpanErr(span, err) }() + k.RunScheduler(ctx) + if k.evmMempool != nil && !k.evmMempool.HasEventBus() { k.evmMempool.GetBlockchain().NotifyNewBlock() } diff --git a/x/vm/keeper/call_evm.go b/x/vm/keeper/call_evm.go index 80e7488e..ed0fd515 100644 --- a/x/vm/keeper/call_evm.go +++ b/x/vm/keeper/call_evm.go @@ -1,6 +1,7 @@ package keeper import ( + "fmt" "math/big" "github.com/ethereum/go-ethereum/accounts/abi" @@ -75,13 +76,17 @@ func (k Keeper) CallEVMWithData( if err != nil { return nil, err } + gasLimit, err := evmCallGasLimit(gasCap) + if err != nil { + return nil, err + } msg := core.Message{ From: from, To: contract, Nonce: nonce, Value: big.NewInt(0), - GasLimit: config.DefaultGasCap, + GasLimit: gasLimit, GasPrice: big.NewInt(0), GasTipCap: big.NewInt(0), GasFeeCap: big.NewInt(0), @@ -103,3 +108,68 @@ func (k Keeper) CallEVMWithData( return res, nil } + +// CallEVMSystemWithData performs a bounded system EVM call. State changes are +// committed only when the VM execution succeeds. +func (k Keeper) CallEVMSystemWithData( + ctx sdk.Context, + from common.Address, + contract common.Address, + data []byte, + gasLimit uint64, +) (_ *types.MsgEthereumTxResponse, err error) { + ctx, span := ctx.StartSpan(tracer, "CallEVMSystemWithData", trace.WithAttributes( + attribute.String("from", from.Hex()), + attribute.String("contract", contract.Hex()), + attribute.Int("data_size", len(data)), + attribute.String("gas_limit", fmt.Sprintf("%d", gasLimit)), + )) + defer func() { evmtrace.EndSpanErr(span, err) }() + if gasLimit == 0 { + return nil, fmt.Errorf("system EVM gas limit must be greater than zero") + } + cachedCtx, commit := ctx.CacheContext() + fromAcc := sdk.AccAddress(from.Bytes()) + if !k.accountKeeper.HasAccount(cachedCtx, fromAcc) { + k.accountKeeper.SetAccount(cachedCtx, k.accountKeeper.NewAccountWithAddress(cachedCtx, fromAcc)) + } + nonce, err := k.accountKeeper.GetSequence(cachedCtx, fromAcc) + if err != nil { + return nil, err + } + to := contract + msg := core.Message{ + From: from, + To: &to, + Nonce: nonce, + Value: big.NewInt(0), + GasLimit: gasLimit, + GasPrice: big.NewInt(0), + GasTipCap: big.NewInt(0), + GasFeeCap: big.NewInt(0), + Data: data, + AccessList: ethtypes.AccessList{}, + } + res, err := k.ApplyMessage(cachedCtx, msg, nil, true, true) + if err != nil { + return res, err + } + if res.Failed() { + return res, errorsmod.Wrap(types.ErrVMExecution, res.VmError) + } + commit() + return res, nil +} + +func evmCallGasLimit(gasCap *big.Int) (uint64, error) { + if gasCap == nil { + return config.DefaultGasCap, nil + } + if gasCap.Sign() <= 0 { + return 0, fmt.Errorf("gas cap must be greater than zero") + } + if !gasCap.IsUint64() { + return 0, fmt.Errorf("gas cap overflows uint64: %s", gasCap) + } + return gasCap.Uint64(), nil +} diff --git a/x/vm/keeper/msg_server.go b/x/vm/keeper/msg_server.go index 39b790e2..3da49f2a 100644 --- a/x/vm/keeper/msg_server.go +++ b/x/vm/keeper/msg_server.go @@ -22,10 +22,10 @@ import ( ) var ( - vmMeter = otel.Meter("evm/x/vm/keeper") - ethTxCounter metric.Int64Counter - ethGasCounter metric.Float64Counter - ethGasRatio metric.Float64Gauge + vmMeter = otel.Meter("evm/x/vm/keeper") + ethTxCounter metric.Int64Counter + ethGasCounter metric.Float64Counter + ethGasRatio metric.Float64Gauge ) func init() { @@ -131,8 +131,12 @@ func (k *Keeper) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) )) defer func() { evmtrace.EndSpanErr(span, err) }() - if k.authority.String() != req.Authority { - return nil, errorsmod.Wrapf(govtypes.ErrInvalidSigner, "invalid authority, expected %s, got %s", k.authority.String(), req.Authority) + authority, err := k.accountKeeper.AddressCodec().BytesToString(k.authority) + if err != nil { + return nil, err + } + if authority != req.Authority { + return nil, errorsmod.Wrapf(govtypes.ErrInvalidSigner, "invalid authority, expected %s, got %s", authority, req.Authority) } if err := k.SetParams(ctx, req.Params); err != nil { @@ -154,8 +158,12 @@ func (k *Keeper) RegisterPreinstalls(goCtx context.Context, req *types.MsgRegist attribute.String("authority", req.Authority), )) defer func() { evmtrace.EndSpanErr(span, err) }() - if k.authority.String() != req.Authority { - return nil, errorsmod.Wrapf(govtypes.ErrInvalidSigner, "invalid authority, expected %s, got %s", k.authority.String(), req.Authority) + authority, err := k.accountKeeper.AddressCodec().BytesToString(k.authority) + if err != nil { + return nil, err + } + if authority != req.Authority { + return nil, errorsmod.Wrapf(govtypes.ErrInvalidSigner, "invalid authority, expected %s, got %s", authority, req.Authority) } if err := k.AddPreinstalls(ctx, req.Preinstalls); err != nil { diff --git a/x/vm/keeper/scheduler.go b/x/vm/keeper/scheduler.go new file mode 100644 index 00000000..7205c5ab --- /dev/null +++ b/x/vm/keeper/scheduler.go @@ -0,0 +1,98 @@ +package keeper + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + + "github.com/cosmos/evm/x/vm/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + EventTypeEVMScheduler = "evm_scheduler" + AttributeKeyTargetContract = "target_contract" + AttributeKeySuccess = "success" + AttributeKeyGasUsed = "gas_used" + AttributeKeyVMError = "vm_error" + AttributeKeyError = "error" +) + +var pokeSelector = crypto.Keccak256([]byte("poke(uint256)"))[:4] + +func shouldRunScheduler(ctx sdk.Context, params types.EVMSchedulerParams) bool { + if !params.Enabled || params.TargetContract == "" || params.CadenceBlocks == 0 { + return false + } + if ctx.BlockHeight() < 0 { + return false + } + return uint64(ctx.BlockHeight())%params.CadenceBlocks == 0 //nolint:gosec // non-negative checked above +} + +// RunScheduler performs the configured bounded EndBlock EVM call. It never +// returns an error because scheduler failures must not halt consensus. +func (k Keeper) RunScheduler(ctx sdk.Context) { + params := k.GetParams(ctx).Scheduler + if !shouldRunScheduler(ctx, params) { + return + } + defer func() { + if r := recover(); r != nil { + errText := fmt.Sprintf("panic: %v", r) + k.Logger(ctx).Error("evm scheduler panicked", "target", params.TargetContract, "err", errText) + k.emitSchedulerEvent(ctx, params.TargetContract, false, 0, "", errText) + } + }() + + moduleAddr := k.accountKeeper.GetModuleAddress(types.ModuleName) + if moduleAddr == nil { + k.emitSchedulerEvent(ctx, params.TargetContract, false, 0, "", "evm module account not found") + return + } + + target := common.HexToAddress(params.TargetContract) + res, err := k.CallEVMSystemWithData( + ctx, + common.BytesToAddress(moduleAddr.Bytes()), + target, + pokeCalldata(params.MaxOps), + params.GasCap, + ) + if err != nil { + vmErr := "" + gasUsed := uint64(0) + if res != nil { + vmErr = res.VmError + gasUsed = res.GasUsed + } + k.Logger(ctx).Error("evm scheduler call failed", "target", params.TargetContract, "err", err) + k.emitSchedulerEvent(ctx, params.TargetContract, false, gasUsed, vmErr, err.Error()) + return + } + k.emitSchedulerEvent(ctx, params.TargetContract, true, res.GasUsed, "", "") +} + +func pokeCalldata(maxOps uint32) []byte { + data := make([]byte, 4, 36) + copy(data, pokeSelector) + return append(data, common.LeftPadBytes(new(big.Int).SetUint64(uint64(maxOps)).Bytes(), 32)...) +} + +func (k Keeper) emitSchedulerEvent(ctx sdk.Context, target string, success bool, gasUsed uint64, vmErr, errText string) { + attrs := []sdk.Attribute{ + sdk.NewAttribute(AttributeKeyTargetContract, target), + sdk.NewAttribute(AttributeKeySuccess, fmt.Sprintf("%t", success)), + sdk.NewAttribute(AttributeKeyGasUsed, fmt.Sprintf("%d", gasUsed)), + } + if vmErr != "" { + attrs = append(attrs, sdk.NewAttribute(AttributeKeyVMError, vmErr)) + } + if errText != "" { + attrs = append(attrs, sdk.NewAttribute(AttributeKeyError, errText)) + } + ctx.EventManager().EmitEvent(sdk.NewEvent(EventTypeEVMScheduler, attrs...)) +} diff --git a/x/vm/keeper/scheduler_test.go b/x/vm/keeper/scheduler_test.go new file mode 100644 index 00000000..b36bfe01 --- /dev/null +++ b/x/vm/keeper/scheduler_test.go @@ -0,0 +1,65 @@ +package keeper + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/evm/contracts" + vmtypes "github.com/cosmos/evm/x/vm/types" + + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + + storetypes "cosmossdk.io/store/types" + + "github.com/cosmos/cosmos-sdk/testutil" +) + +func TestShouldRunScheduler(t *testing.T) { + key := storetypes.NewKVStoreKey("scheduler_test") + ctx := testutil.DefaultContext(key, storetypes.NewTransientStoreKey("scheduler_transient")).WithBlockHeader(cmtproto.Header{Height: 12}) + + params := vmtypes.EVMSchedulerParams{ + Enabled: true, + TargetContract: "0x0000000000000000000000000000000000001000", + GasCap: vmtypes.DefaultSchedulerGasCap, + MaxOps: vmtypes.DefaultSchedulerMaxOps, + CadenceBlocks: 3, + } + require.True(t, shouldRunScheduler(ctx, params)) + + params.CadenceBlocks = 5 + require.False(t, shouldRunScheduler(ctx, params)) + + params.CadenceBlocks = 3 + params.Enabled = false + require.False(t, shouldRunScheduler(ctx, params)) + + params.Enabled = true + params.TargetContract = "" + require.False(t, shouldRunScheduler(ctx, params)) +} + +func TestPokeCalldata(t *testing.T) { + data := pokeCalldata(32) + pokeMethod, ok := contracts.StakedBondVaultContract.ABI.Methods["poke"] + require.True(t, ok) + require.Equal(t, pokeMethod.ID, pokeSelector) + require.Len(t, data, 36) + require.Equal(t, pokeSelector, data[:4]) + require.Equal(t, byte(32), data[35]) +} + +func TestEVMCallGasLimit(t *testing.T) { + limit, err := evmCallGasLimit(nil) + require.NoError(t, err) + require.NotZero(t, limit) + + limit, err = evmCallGasLimit(big.NewInt(123)) + require.NoError(t, err) + require.Equal(t, uint64(123), limit) + + _, err = evmCallGasLimit(big.NewInt(0)) + require.ErrorContains(t, err, "greater than zero") +} diff --git a/x/vm/types/evm.pb.go b/x/vm/types/evm.pb.go index 28450b4f..38302414 100644 --- a/x/vm/types/evm.pb.go +++ b/x/vm/types/evm.pb.go @@ -73,6 +73,9 @@ type Params struct { ActiveStaticPrecompiles []string `protobuf:"bytes,9,rep,name=active_static_precompiles,json=activeStaticPrecompiles,proto3" json:"active_static_precompiles,omitempty"` HistoryServeWindow uint64 `protobuf:"varint,10,opt,name=history_serve_window,json=historyServeWindow,proto3" json:"history_serve_window,omitempty"` ExtendedDenomOptions *ExtendedDenomOptions `protobuf:"bytes,11,opt,name=extended_denom_options,json=extendedDenomOptions,proto3" json:"extended_denom_options,omitempty"` + // scheduler defines an optional bounded EndBlock EVM call used for + // contract-owned maintenance such as vault settlement. + Scheduler EVMSchedulerParams `protobuf:"bytes,12,opt,name=scheduler,proto3" json:"scheduler"` } func (m *Params) Reset() { *m = Params{} } @@ -157,6 +160,13 @@ func (m *Params) GetExtendedDenomOptions() *ExtendedDenomOptions { return nil } +func (m *Params) GetScheduler() EVMSchedulerParams { + if m != nil { + return m.Scheduler + } + return EVMSchedulerParams{} +} + type ExtendedDenomOptions struct { ExtendedDenom string `protobuf:"bytes,1,opt,name=extended_denom,json=extendedDenom,proto3" json:"extended_denom,omitempty"` } @@ -201,6 +211,87 @@ func (m *ExtendedDenomOptions) GetExtendedDenom() string { return "" } +type EVMSchedulerParams struct { + // enabled controls whether EndBlock attempts the configured call. + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + // target_contract is the EVM contract called with poke(uint256). + TargetContract string `protobuf:"bytes,2,opt,name=target_contract,json=targetContract,proto3" json:"target_contract,omitempty"` + // gas_cap is the EVM gas limit for the scheduler call. + GasCap uint64 `protobuf:"varint,3,opt,name=gas_cap,json=gasCap,proto3" json:"gas_cap,omitempty"` + // max_ops is passed as the poke(uint256) argument. + MaxOps uint32 `protobuf:"varint,4,opt,name=max_ops,json=maxOps,proto3" json:"max_ops,omitempty"` + // cadence_blocks runs the call only when block_height % cadence_blocks == 0. + CadenceBlocks uint64 `protobuf:"varint,5,opt,name=cadence_blocks,json=cadenceBlocks,proto3" json:"cadence_blocks,omitempty"` +} + +func (m *EVMSchedulerParams) Reset() { *m = EVMSchedulerParams{} } +func (m *EVMSchedulerParams) String() string { return proto.CompactTextString(m) } +func (*EVMSchedulerParams) ProtoMessage() {} +func (*EVMSchedulerParams) Descriptor() ([]byte, []int) { + return fileDescriptor_d1129b8db63d55c7, []int{2} +} +func (m *EVMSchedulerParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EVMSchedulerParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EVMSchedulerParams.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *EVMSchedulerParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_EVMSchedulerParams.Merge(m, src) +} +func (m *EVMSchedulerParams) XXX_Size() int { + return m.Size() +} +func (m *EVMSchedulerParams) XXX_DiscardUnknown() { + xxx_messageInfo_EVMSchedulerParams.DiscardUnknown(m) +} + +var xxx_messageInfo_EVMSchedulerParams proto.InternalMessageInfo + +func (m *EVMSchedulerParams) GetEnabled() bool { + if m != nil { + return m.Enabled + } + return false +} + +func (m *EVMSchedulerParams) GetTargetContract() string { + if m != nil { + return m.TargetContract + } + return "" +} + +func (m *EVMSchedulerParams) GetGasCap() uint64 { + if m != nil { + return m.GasCap + } + return 0 +} + +func (m *EVMSchedulerParams) GetMaxOps() uint32 { + if m != nil { + return m.MaxOps + } + return 0 +} + +func (m *EVMSchedulerParams) GetCadenceBlocks() uint64 { + if m != nil { + return m.CadenceBlocks + } + return 0 +} + // AccessControl defines the permission policy of the EVM // for creating and calling contracts type AccessControl struct { @@ -214,7 +305,7 @@ func (m *AccessControl) Reset() { *m = AccessControl{} } func (m *AccessControl) String() string { return proto.CompactTextString(m) } func (*AccessControl) ProtoMessage() {} func (*AccessControl) Descriptor() ([]byte, []int) { - return fileDescriptor_d1129b8db63d55c7, []int{2} + return fileDescriptor_d1129b8db63d55c7, []int{3} } func (m *AccessControl) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -275,7 +366,7 @@ func (m *AccessControlType) Reset() { *m = AccessControlType{} } func (m *AccessControlType) String() string { return proto.CompactTextString(m) } func (*AccessControlType) ProtoMessage() {} func (*AccessControlType) Descriptor() ([]byte, []int) { - return fileDescriptor_d1129b8db63d55c7, []int{3} + return fileDescriptor_d1129b8db63d55c7, []int{4} } func (m *AccessControlType) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -385,7 +476,7 @@ func (m *ChainConfig) Reset() { *m = ChainConfig{} } func (m *ChainConfig) String() string { return proto.CompactTextString(m) } func (*ChainConfig) ProtoMessage() {} func (*ChainConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_d1129b8db63d55c7, []int{4} + return fileDescriptor_d1129b8db63d55c7, []int{5} } func (m *ChainConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -454,7 +545,7 @@ func (m *State) Reset() { *m = State{} } func (m *State) String() string { return proto.CompactTextString(m) } func (*State) ProtoMessage() {} func (*State) Descriptor() ([]byte, []int) { - return fileDescriptor_d1129b8db63d55c7, []int{5} + return fileDescriptor_d1129b8db63d55c7, []int{6} } func (m *State) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -511,7 +602,7 @@ func (m *TransactionLogs) Reset() { *m = TransactionLogs{} } func (m *TransactionLogs) String() string { return proto.CompactTextString(m) } func (*TransactionLogs) ProtoMessage() {} func (*TransactionLogs) Descriptor() ([]byte, []int) { - return fileDescriptor_d1129b8db63d55c7, []int{6} + return fileDescriptor_d1129b8db63d55c7, []int{7} } func (m *TransactionLogs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -589,7 +680,7 @@ func (m *Log) Reset() { *m = Log{} } func (m *Log) String() string { return proto.CompactTextString(m) } func (*Log) ProtoMessage() {} func (*Log) Descriptor() ([]byte, []int) { - return fileDescriptor_d1129b8db63d55c7, []int{7} + return fileDescriptor_d1129b8db63d55c7, []int{8} } func (m *Log) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -711,7 +802,7 @@ func (m *TxResult) Reset() { *m = TxResult{} } func (m *TxResult) String() string { return proto.CompactTextString(m) } func (*TxResult) ProtoMessage() {} func (*TxResult) Descriptor() ([]byte, []int) { - return fileDescriptor_d1129b8db63d55c7, []int{8} + return fileDescriptor_d1129b8db63d55c7, []int{9} } func (m *TxResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -752,7 +843,7 @@ func (m *AccessTuple) Reset() { *m = AccessTuple{} } func (m *AccessTuple) String() string { return proto.CompactTextString(m) } func (*AccessTuple) ProtoMessage() {} func (*AccessTuple) Descriptor() ([]byte, []int) { - return fileDescriptor_d1129b8db63d55c7, []int{9} + return fileDescriptor_d1129b8db63d55c7, []int{10} } func (m *AccessTuple) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -812,7 +903,7 @@ func (m *TraceConfig) Reset() { *m = TraceConfig{} } func (m *TraceConfig) String() string { return proto.CompactTextString(m) } func (*TraceConfig) ProtoMessage() {} func (*TraceConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_d1129b8db63d55c7, []int{10} + return fileDescriptor_d1129b8db63d55c7, []int{11} } func (m *TraceConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -933,7 +1024,7 @@ func (m *Preinstall) Reset() { *m = Preinstall{} } func (m *Preinstall) String() string { return proto.CompactTextString(m) } func (*Preinstall) ProtoMessage() {} func (*Preinstall) Descriptor() ([]byte, []int) { - return fileDescriptor_d1129b8db63d55c7, []int{11} + return fileDescriptor_d1129b8db63d55c7, []int{12} } func (m *Preinstall) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -994,7 +1085,7 @@ func (m *EvmCoinInfo) Reset() { *m = EvmCoinInfo{} } func (m *EvmCoinInfo) String() string { return proto.CompactTextString(m) } func (*EvmCoinInfo) ProtoMessage() {} func (*EvmCoinInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_d1129b8db63d55c7, []int{12} + return fileDescriptor_d1129b8db63d55c7, []int{13} } func (m *EvmCoinInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1055,6 +1146,7 @@ func init() { proto.RegisterEnum("cosmos.evm.vm.v1.AccessType", AccessType_name, AccessType_value) proto.RegisterType((*Params)(nil), "cosmos.evm.vm.v1.Params") proto.RegisterType((*ExtendedDenomOptions)(nil), "cosmos.evm.vm.v1.ExtendedDenomOptions") + proto.RegisterType((*EVMSchedulerParams)(nil), "cosmos.evm.vm.v1.EVMSchedulerParams") proto.RegisterType((*AccessControl)(nil), "cosmos.evm.vm.v1.AccessControl") proto.RegisterType((*AccessControlType)(nil), "cosmos.evm.vm.v1.AccessControlType") proto.RegisterType((*ChainConfig)(nil), "cosmos.evm.vm.v1.ChainConfig") @@ -1071,139 +1163,147 @@ func init() { func init() { proto.RegisterFile("cosmos/evm/vm/v1/evm.proto", fileDescriptor_d1129b8db63d55c7) } var fileDescriptor_d1129b8db63d55c7 = []byte{ - // 2111 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x58, 0x4d, 0x6f, 0x1b, 0xc7, - 0x19, 0x16, 0xc5, 0x95, 0xb4, 0x1c, 0x52, 0xd4, 0x7a, 0x44, 0xcb, 0x34, 0xed, 0x68, 0xd5, 0x4d, - 0x5b, 0xa8, 0x46, 0x2a, 0x59, 0x72, 0xd4, 0x1a, 0x4e, 0xd3, 0x42, 0x94, 0x98, 0x56, 0xaa, 0x6c, - 0x0b, 0x43, 0x35, 0x46, 0x8a, 0x14, 0x8b, 0xe1, 0xee, 0x78, 0xb9, 0xd1, 0xee, 0x0e, 0xb1, 0xb3, - 0xa4, 0xc5, 0xfe, 0x81, 0x06, 0xee, 0x25, 0xed, 0xdd, 0x40, 0x80, 0x5e, 0x72, 0xcc, 0x4f, 0xe8, - 0x31, 0xc7, 0x1c, 0x8b, 0x02, 0x5d, 0x14, 0xf4, 0x21, 0x80, 0x8e, 0xfa, 0x05, 0xc5, 0x7c, 0xf0, - 0x5b, 0x61, 0x15, 0x40, 0xb0, 0xe7, 0x79, 0x3f, 0x9e, 0x67, 0x3e, 0xde, 0xdd, 0x79, 0x97, 0xa0, - 0xe2, 0x50, 0x16, 0x52, 0xb6, 0x4d, 0x3a, 0xe1, 0x36, 0xff, 0xdb, 0xe1, 0xa3, 0xad, 0x56, 0x4c, - 0x13, 0x0a, 0x0d, 0xe9, 0xdb, 0xe2, 0x16, 0xfe, 0xb7, 0x53, 0xb9, 0x85, 0x43, 0x3f, 0xa2, 0xdb, - 0xe2, 0x5f, 0x19, 0x54, 0x29, 0x79, 0xd4, 0xa3, 0x62, 0xb8, 0xcd, 0x47, 0xd2, 0x6a, 0xfd, 0x5d, - 0x03, 0x8b, 0xa7, 0x38, 0xc6, 0x21, 0x83, 0x3b, 0x20, 0x47, 0x3a, 0xa1, 0xed, 0x92, 0x88, 0x86, - 0xe5, 0xcc, 0x46, 0x66, 0x33, 0x57, 0x2d, 0x5d, 0xa5, 0xa6, 0xd1, 0xc5, 0x61, 0xf0, 0xc4, 0x1a, - 0xb8, 0x2c, 0xa4, 0x93, 0x4e, 0x78, 0xc8, 0x87, 0x70, 0x1f, 0x00, 0x72, 0x91, 0xc4, 0xd8, 0x26, - 0x7e, 0x8b, 0x95, 0xb5, 0x8d, 0xec, 0x66, 0xb6, 0x6a, 0xf5, 0x52, 0x33, 0x57, 0xe3, 0xd6, 0xda, - 0xd1, 0x29, 0xbb, 0x4a, 0xcd, 0x5b, 0x8a, 0x60, 0x10, 0x68, 0xa1, 0x9c, 0x00, 0x35, 0xbf, 0xc5, - 0xe0, 0x2e, 0x28, 0x70, 0x6a, 0xa7, 0x89, 0xa3, 0x88, 0x04, 0xac, 0xbc, 0xb4, 0x91, 0xdd, 0xcc, - 0x55, 0x57, 0x7a, 0xa9, 0x99, 0xaf, 0x7d, 0xfc, 0xf4, 0x40, 0x99, 0x51, 0x9e, 0x74, 0xc2, 0x3e, - 0x80, 0x7f, 0x02, 0x45, 0xec, 0x38, 0x84, 0x31, 0xdb, 0xa1, 0x51, 0x12, 0xd3, 0xa0, 0xac, 0x6f, - 0x64, 0x36, 0xf3, 0xbb, 0xe6, 0xd6, 0xe4, 0x46, 0x6c, 0xed, 0x8b, 0xb8, 0x03, 0x19, 0x56, 0xbd, - 0xfd, 0x4d, 0x6a, 0xce, 0xf5, 0x52, 0x73, 0x79, 0xcc, 0x8c, 0x96, 0xf1, 0x28, 0x84, 0x4f, 0xc0, - 0x5d, 0xec, 0x24, 0x7e, 0x87, 0xd8, 0x2c, 0xc1, 0x89, 0xef, 0xd8, 0xad, 0x98, 0x38, 0x34, 0x6c, - 0xf9, 0x01, 0x61, 0xe5, 0x1c, 0x9f, 0x1f, 0xba, 0x23, 0x03, 0xea, 0xc2, 0x7f, 0x3a, 0x74, 0xc3, - 0x87, 0xa0, 0xd4, 0xf4, 0x59, 0x42, 0xe3, 0xae, 0xcd, 0x48, 0xdc, 0x21, 0xf6, 0x2b, 0x3f, 0x72, - 0xe9, 0xab, 0x32, 0xd8, 0xc8, 0x6c, 0x6a, 0x08, 0x2a, 0x5f, 0x9d, 0xbb, 0x5e, 0x08, 0x0f, 0xfc, - 0x14, 0xac, 0x91, 0x8b, 0x84, 0x44, 0x2e, 0x71, 0xe5, 0x06, 0xdb, 0xb4, 0x95, 0xf8, 0x34, 0x62, - 0xe5, 0xbc, 0x58, 0xd4, 0x4f, 0xa7, 0x17, 0x55, 0x53, 0xf1, 0xe2, 0x10, 0x9e, 0xcb, 0x68, 0x54, - 0x22, 0xd7, 0x58, 0x9f, 0xdc, 0x7b, 0xfd, 0xdd, 0xd7, 0x0f, 0xd6, 0x46, 0x6a, 0xe7, 0x82, 0x57, - 0x8f, 0x3c, 0xf1, 0x63, 0x4d, 0x9f, 0x37, 0xb2, 0xc7, 0x9a, 0x9e, 0x35, 0xb4, 0x63, 0x4d, 0x5f, - 0x30, 0x16, 0x8f, 0x35, 0x7d, 0xd1, 0x58, 0xb2, 0x3e, 0x04, 0xa5, 0xeb, 0x24, 0xe0, 0x4f, 0x40, - 0x71, 0x7c, 0xaa, 0xb2, 0x4c, 0xd0, 0xf2, 0x98, 0xb4, 0xf5, 0xb7, 0x0c, 0x18, 0xdf, 0x60, 0xb8, - 0x0f, 0x16, 0x9d, 0x98, 0xe0, 0x84, 0x88, 0x84, 0xfc, 0xee, 0xbb, 0xff, 0xe7, 0xa0, 0xce, 0xba, - 0x2d, 0x52, 0xd5, 0xf8, 0x61, 0x21, 0x95, 0x08, 0x3f, 0x04, 0x9a, 0x83, 0x83, 0xa0, 0x3c, 0xff, - 0x43, 0x09, 0x44, 0x9a, 0xf5, 0x9f, 0x0c, 0xb8, 0x35, 0x15, 0x01, 0x1d, 0x90, 0x57, 0x85, 0x94, - 0x74, 0x5b, 0x72, 0x72, 0xc5, 0xdd, 0xfb, 0xdf, 0xc7, 0x2d, 0x48, 0x7f, 0xdc, 0x4b, 0x4d, 0x30, - 0xc4, 0x57, 0xa9, 0x09, 0x65, 0x7d, 0x8f, 0x10, 0x59, 0x08, 0xe0, 0x41, 0x04, 0x74, 0xc0, 0xea, - 0x78, 0xb5, 0xda, 0x81, 0xcf, 0x92, 0xf2, 0xbc, 0x28, 0xf4, 0x47, 0xbd, 0xd4, 0x1c, 0x9f, 0xd8, - 0x89, 0xcf, 0x92, 0xab, 0xd4, 0xac, 0x8c, 0xb1, 0x8e, 0x66, 0x5a, 0xe8, 0x16, 0x9e, 0x4c, 0xb0, - 0xbe, 0x32, 0x40, 0xfe, 0xa0, 0x89, 0xfd, 0xe8, 0x80, 0x46, 0x2f, 0x7d, 0x0f, 0x7e, 0x0a, 0x56, - 0x9a, 0x34, 0x24, 0x2c, 0x21, 0xd8, 0xb5, 0x1b, 0x01, 0x75, 0xce, 0xd5, 0x23, 0xfd, 0xe8, 0xdf, - 0xa9, 0x79, 0x5b, 0x2e, 0x90, 0xb9, 0xe7, 0x5b, 0x3e, 0xdd, 0x0e, 0x71, 0xd2, 0xdc, 0x3a, 0x8a, - 0xb8, 0xe8, 0x9a, 0x14, 0x9d, 0xc8, 0xb4, 0x50, 0x71, 0x60, 0xa9, 0x72, 0x03, 0x6c, 0x82, 0xa2, - 0x8b, 0xa9, 0xfd, 0x92, 0xc6, 0xe7, 0x8a, 0x7c, 0x5e, 0x90, 0x57, 0xbf, 0x97, 0xbc, 0x97, 0x9a, - 0x85, 0xc3, 0xfd, 0xe7, 0x1f, 0xd1, 0xf8, 0x5c, 0x50, 0x5c, 0xa5, 0xe6, 0x6d, 0x29, 0x36, 0x4e, - 0x64, 0xa1, 0x82, 0x8b, 0xe9, 0x20, 0x0c, 0xbe, 0x00, 0xc6, 0x20, 0x80, 0xb5, 0x5b, 0x2d, 0x1a, - 0x27, 0xe5, 0xec, 0x46, 0x66, 0x53, 0xaf, 0xfe, 0xbc, 0x97, 0x9a, 0x45, 0x45, 0x59, 0x97, 0x9e, - 0xab, 0xd4, 0xbc, 0x33, 0x41, 0xaa, 0x72, 0x2c, 0x54, 0x54, 0xb4, 0x2a, 0x14, 0x36, 0x40, 0x81, - 0xf8, 0xad, 0x9d, 0xbd, 0x87, 0x6a, 0x01, 0x9a, 0x58, 0xc0, 0x6f, 0x66, 0x2d, 0x20, 0x5f, 0x3b, - 0x3a, 0xdd, 0xd9, 0x7b, 0xd8, 0x9f, 0xff, 0xaa, 0x7a, 0xaf, 0x8d, 0xb0, 0x58, 0x28, 0x2f, 0xa1, - 0x9c, 0x7c, 0x5f, 0x63, 0x4f, 0x69, 0x2c, 0xde, 0x54, 0x63, 0xef, 0x3a, 0x8d, 0xbd, 0x71, 0x8d, - 0xbd, 0x71, 0x8d, 0xc7, 0x4a, 0x63, 0xe9, 0xa6, 0x1a, 0x8f, 0xaf, 0xd3, 0x78, 0x3c, 0xae, 0x21, - 0x63, 0x78, 0x31, 0x35, 0xba, 0x7f, 0xc6, 0x51, 0xe2, 0xb7, 0x43, 0x25, 0xa3, 0xdf, 0xb8, 0x98, - 0x26, 0x32, 0x2d, 0x54, 0x1c, 0x58, 0x24, 0xfb, 0x39, 0x28, 0x39, 0x34, 0x62, 0x09, 0xb7, 0x45, - 0xb4, 0x15, 0x10, 0x25, 0x91, 0x13, 0x12, 0x8f, 0x67, 0x49, 0xdc, 0x93, 0x12, 0xd7, 0xa5, 0x5b, - 0x68, 0x75, 0xdc, 0x2c, 0xc5, 0x6c, 0x60, 0xb4, 0x48, 0x42, 0x62, 0xd6, 0x68, 0xc7, 0x9e, 0x12, - 0x02, 0x42, 0xe8, 0xfd, 0x59, 0x42, 0xaa, 0xac, 0x26, 0x53, 0x2d, 0xb4, 0x32, 0x34, 0x49, 0x81, - 0x4f, 0x40, 0xd1, 0xe7, 0xaa, 0x8d, 0x76, 0xa0, 0xe8, 0xf3, 0x82, 0x7e, 0x77, 0x16, 0xbd, 0x7a, - 0x14, 0xc6, 0x13, 0x2d, 0xb4, 0xdc, 0x37, 0x48, 0x6a, 0x17, 0xc0, 0xb0, 0xed, 0xc7, 0xb6, 0x17, - 0x60, 0xc7, 0x27, 0xb1, 0xa2, 0x2f, 0x08, 0xfa, 0x5f, 0xcc, 0xa2, 0xbf, 0x2b, 0xe9, 0xa7, 0x93, - 0x2d, 0x64, 0x70, 0xe3, 0x6f, 0xa5, 0x4d, 0xaa, 0xd4, 0x41, 0xa1, 0x41, 0xe2, 0xc0, 0x8f, 0x14, - 0xff, 0xb2, 0xe0, 0x7f, 0x38, 0x8b, 0x5f, 0x55, 0xd0, 0x68, 0x9a, 0x85, 0xf2, 0x12, 0x0e, 0x48, - 0x03, 0x1a, 0xb9, 0xb4, 0x4f, 0x7a, 0xeb, 0xc6, 0xa4, 0xa3, 0x69, 0x16, 0xca, 0x4b, 0x28, 0x49, - 0x3d, 0xb0, 0x8a, 0xe3, 0x98, 0xbe, 0x9a, 0xd8, 0x10, 0x28, 0xb8, 0x7f, 0x39, 0x8b, 0xbb, 0xff, - 0x72, 0x9d, 0xce, 0xe6, 0x2f, 0x57, 0x6e, 0x1d, 0xdb, 0x12, 0x17, 0x40, 0x2f, 0xc6, 0xdd, 0x09, - 0x9d, 0xd2, 0x8d, 0x37, 0x7e, 0x3a, 0xd9, 0x42, 0x06, 0x37, 0x8e, 0xa9, 0x7c, 0x06, 0x4a, 0x21, - 0x89, 0x3d, 0x62, 0x47, 0x24, 0x61, 0xad, 0xc0, 0x4f, 0x94, 0xce, 0xed, 0x1b, 0x3f, 0x07, 0xd7, - 0xa5, 0x5b, 0x08, 0x0a, 0xf3, 0x33, 0x65, 0x95, 0x5a, 0x77, 0x81, 0xee, 0xf0, 0xdb, 0xc2, 0xf6, - 0xdd, 0x72, 0x59, 0xb4, 0x26, 0x4b, 0x02, 0x1f, 0xb9, 0xb0, 0x04, 0x16, 0xe4, 0xdd, 0x7e, 0x57, - 0xdc, 0xed, 0x12, 0xc0, 0x0a, 0xd0, 0x5d, 0xe2, 0xf8, 0x21, 0x0e, 0x58, 0xb9, 0x22, 0x12, 0x06, - 0x18, 0x7e, 0x0c, 0x96, 0x59, 0x13, 0x47, 0x5e, 0x13, 0xfb, 0x76, 0xe2, 0x87, 0xa4, 0x7c, 0x4f, - 0xcc, 0x78, 0x67, 0xd6, 0x8c, 0x4b, 0x72, 0xc6, 0x63, 0x79, 0x16, 0x2a, 0xf4, 0xf1, 0x99, 0x1f, - 0x12, 0x78, 0x0a, 0xf2, 0x0e, 0x8e, 0x9c, 0x76, 0x24, 0x59, 0xef, 0x0b, 0xd6, 0xed, 0x59, 0xac, - 0xea, 0x2a, 0x1e, 0xc9, 0xb2, 0x10, 0x90, 0xa8, 0xcf, 0xd8, 0x8a, 0xb1, 0xd7, 0x26, 0x92, 0xf1, - 0x9d, 0x1b, 0x33, 0x8e, 0x64, 0x59, 0x08, 0x48, 0xd4, 0x67, 0xec, 0x90, 0xf8, 0x3c, 0x50, 0x8c, - 0xeb, 0x37, 0x66, 0x1c, 0xc9, 0xb2, 0x10, 0x90, 0x48, 0x30, 0x3e, 0x05, 0x80, 0x32, 0x7c, 0x8e, - 0x25, 0xa1, 0x29, 0x08, 0xb7, 0x66, 0x11, 0xaa, 0xfe, 0x7a, 0x98, 0x64, 0xa1, 0x9c, 0x00, 0x9c, - 0x6e, 0xd0, 0xd7, 0xad, 0x19, 0x77, 0x8e, 0x35, 0xfd, 0x8e, 0x51, 0xb6, 0xb6, 0xc1, 0x02, 0xef, - 0x5b, 0x09, 0x34, 0x40, 0xf6, 0x9c, 0x74, 0x55, 0x0f, 0xc7, 0x87, 0xfc, 0xec, 0x3b, 0x38, 0x68, - 0x13, 0x79, 0x9d, 0x23, 0x09, 0xac, 0x53, 0xb0, 0x72, 0x16, 0xe3, 0x88, 0xf1, 0x9e, 0x97, 0x46, - 0x27, 0xd4, 0x63, 0x10, 0x02, 0xad, 0x89, 0x59, 0x53, 0xe5, 0x8a, 0x31, 0xfc, 0x19, 0xd0, 0x02, - 0xea, 0x31, 0xd1, 0xd8, 0xe4, 0x77, 0x6f, 0x4f, 0x77, 0x51, 0x27, 0xd4, 0x43, 0x22, 0xc4, 0xfa, - 0x4b, 0x16, 0x64, 0x4f, 0xa8, 0x07, 0xcb, 0x60, 0x09, 0xbb, 0x6e, 0x4c, 0x18, 0x53, 0x4c, 0x7d, - 0x08, 0xd7, 0xc0, 0x62, 0x42, 0x5b, 0xbe, 0x23, 0xe9, 0x72, 0x48, 0x21, 0x2e, 0xec, 0xe2, 0x04, - 0x8b, 0x1e, 0xa0, 0x80, 0xc4, 0x98, 0x7f, 0x42, 0x88, 0x52, 0xb7, 0xa3, 0x76, 0xd8, 0x20, 0xb1, - 0xb8, 0xca, 0xb5, 0xea, 0xca, 0x65, 0x6a, 0xe6, 0x85, 0xfd, 0x99, 0x30, 0xa3, 0x51, 0x00, 0xdf, - 0x03, 0x4b, 0xc9, 0x85, 0x2d, 0xd6, 0xb0, 0x20, 0xb6, 0x78, 0xf5, 0x32, 0x35, 0x57, 0x92, 0xe1, - 0x32, 0x7f, 0x87, 0x59, 0x13, 0x2d, 0x26, 0x17, 0xfc, 0x7f, 0xb8, 0x0d, 0xf4, 0xe4, 0xc2, 0xf6, - 0x23, 0x97, 0x5c, 0x88, 0x4b, 0x5c, 0xab, 0x96, 0x2e, 0x53, 0xd3, 0x18, 0x09, 0x3f, 0xe2, 0x3e, - 0xb4, 0x94, 0x5c, 0x88, 0x01, 0x7c, 0x0f, 0x00, 0x39, 0x25, 0xa1, 0x20, 0xef, 0xe4, 0xe5, 0xcb, - 0xd4, 0xcc, 0x09, 0xab, 0xe0, 0x1e, 0x0e, 0xa1, 0x05, 0x16, 0x24, 0xb7, 0x2e, 0xb8, 0x0b, 0x97, - 0xa9, 0xa9, 0x07, 0xd4, 0x93, 0x9c, 0xd2, 0xc5, 0xb7, 0x2a, 0x26, 0x21, 0xed, 0x10, 0x57, 0x5c, - 0x8c, 0x3a, 0xea, 0x43, 0xf8, 0x01, 0x58, 0x91, 0x5a, 0xfc, 0xec, 0x59, 0x82, 0xc3, 0x96, 0xfc, - 0xda, 0xa8, 0xc2, 0xcb, 0xd4, 0x2c, 0x0a, 0xd7, 0x59, 0xdf, 0x83, 0x26, 0xb0, 0xf5, 0xc5, 0x3c, - 0xd0, 0xcf, 0x2e, 0x10, 0x61, 0xed, 0x20, 0x81, 0x1f, 0x01, 0x43, 0x34, 0x9a, 0xd8, 0x49, 0xec, - 0xb1, 0x73, 0xa9, 0xde, 0x1b, 0xde, 0x81, 0x93, 0x11, 0x16, 0x5a, 0xe9, 0x9b, 0xf6, 0xd5, 0xe1, - 0x95, 0xc0, 0x42, 0x23, 0xa0, 0x34, 0x14, 0x65, 0x54, 0x40, 0x12, 0xc0, 0x17, 0x62, 0xcb, 0x45, - 0x89, 0x64, 0x45, 0x13, 0xff, 0xa3, 0xe9, 0x12, 0x99, 0xa8, 0xb3, 0xea, 0x3d, 0xde, 0xc2, 0x5f, - 0xa5, 0x66, 0x51, 0x6a, 0xab, 0x7c, 0xeb, 0xab, 0xef, 0xbe, 0x7e, 0x90, 0xe1, 0xa7, 0x23, 0x8a, - 0xd1, 0x00, 0xd9, 0x98, 0x24, 0xe2, 0xd8, 0x0b, 0x88, 0x0f, 0xf9, 0xdb, 0x2a, 0x26, 0x1d, 0x12, - 0x27, 0xc4, 0x15, 0xc7, 0xab, 0xa3, 0x01, 0xe6, 0xaf, 0x3e, 0x0f, 0x33, 0xbb, 0xcd, 0x88, 0x2b, - 0xcf, 0x12, 0x2d, 0x79, 0x98, 0xfd, 0x81, 0x11, 0xf7, 0x89, 0xf6, 0xf9, 0x97, 0xe6, 0x9c, 0x85, - 0x41, 0x5e, 0xf5, 0xf7, 0xed, 0x56, 0x40, 0x66, 0xd4, 0xe8, 0x2e, 0x28, 0xf0, 0xaf, 0x39, 0xec, - 0x11, 0xfb, 0x9c, 0x74, 0x55, 0xa5, 0xca, 0xba, 0x53, 0xf6, 0xdf, 0x93, 0x2e, 0x43, 0xa3, 0x40, - 0x49, 0x7c, 0xa9, 0x81, 0xfc, 0x59, 0x8c, 0x1d, 0xa2, 0xba, 0x75, 0x5e, 0xed, 0x1c, 0xc6, 0x4a, - 0x42, 0x21, 0xae, 0xcd, 0x0f, 0x95, 0xb6, 0x13, 0xf5, 0x44, 0xf6, 0x21, 0xcf, 0x88, 0x09, 0xb9, - 0x20, 0x8e, 0xd8, 0x4b, 0x0d, 0x29, 0x04, 0xf7, 0xc0, 0xb2, 0xeb, 0x33, 0xdc, 0x08, 0xc4, 0xc7, - 0xab, 0x73, 0x2e, 0x97, 0x5f, 0x35, 0x2e, 0x53, 0xb3, 0xa0, 0x1c, 0x75, 0x6e, 0x47, 0x63, 0x88, - 0xd7, 0xd0, 0x30, 0x4d, 0xcc, 0x56, 0xec, 0x8d, 0x2e, 0x6b, 0x68, 0x10, 0x2a, 0x3c, 0x68, 0x02, - 0xcb, 0x1b, 0xa3, 0xd1, 0xf6, 0x44, 0xf9, 0xea, 0x48, 0x02, 0x6e, 0x0d, 0xfc, 0xd0, 0x4f, 0x44, - 0xb9, 0x2e, 0x20, 0x09, 0xe0, 0x07, 0x20, 0x47, 0x3b, 0x24, 0x8e, 0x7d, 0x97, 0x30, 0x51, 0xa6, - 0xf9, 0xdd, 0x77, 0xa6, 0xcb, 0x60, 0xe4, 0x4b, 0x06, 0x0d, 0xe3, 0xf9, 0xe2, 0x48, 0x24, 0x26, - 0x19, 0x92, 0x90, 0xc6, 0x5d, 0xd1, 0x5a, 0xa9, 0xc5, 0x49, 0xc7, 0x53, 0x61, 0x47, 0x63, 0x08, - 0x56, 0x01, 0x54, 0x69, 0x31, 0x49, 0xda, 0x71, 0x64, 0x8b, 0x37, 0x48, 0x41, 0xe4, 0x8a, 0xe7, - 0x58, 0x7a, 0x91, 0x70, 0x1e, 0xe2, 0x04, 0xa3, 0x29, 0x0b, 0xfc, 0x35, 0x80, 0xf2, 0x4c, 0xec, - 0xcf, 0x18, 0x8d, 0xf8, 0xf7, 0xd8, 0x4b, 0xdf, 0x53, 0xbd, 0x91, 0xd0, 0x97, 0x5e, 0x35, 0x67, - 0x43, 0xa2, 0x63, 0x46, 0xd5, 0x2a, 0x8e, 0x35, 0x5d, 0x33, 0x16, 0x8e, 0x35, 0x7d, 0xc9, 0xd0, - 0x07, 0xfb, 0xa7, 0x56, 0x81, 0x56, 0xfb, 0x78, 0x64, 0x7a, 0xd6, 0x33, 0x00, 0x4e, 0x63, 0xe2, - 0xf3, 0x0e, 0x36, 0x08, 0xf8, 0x6b, 0x2f, 0xc2, 0x21, 0xe9, 0xbf, 0x6f, 0xf9, 0x78, 0xb4, 0x30, - 0xe7, 0xc7, 0x0b, 0x13, 0x02, 0xcd, 0xa1, 0x2e, 0x11, 0xa5, 0x91, 0x43, 0x62, 0x6c, 0xfd, 0x35, - 0x03, 0xf2, 0xb5, 0x4e, 0x78, 0x40, 0xfd, 0xe8, 0x28, 0x7a, 0x49, 0x87, 0xd7, 0x7c, 0x66, 0xf4, - 0x9a, 0x9f, 0xfe, 0xc2, 0x9f, 0xbf, 0xe6, 0x0b, 0x1f, 0xbe, 0x2b, 0xaa, 0xac, 0x15, 0xe0, 0xae, - 0x8a, 0x92, 0x4a, 0x05, 0x65, 0x3c, 0x9c, 0x6a, 0x19, 0xf8, 0xb3, 0xb9, 0x3c, 0x6c, 0x19, 0x1e, - 0xfc, 0x33, 0x03, 0x46, 0x3e, 0xa2, 0xe1, 0xaf, 0x40, 0x65, 0xff, 0xe0, 0xa0, 0x56, 0xaf, 0xdb, - 0x67, 0x9f, 0x9c, 0xd6, 0xec, 0xd3, 0x1a, 0x7a, 0x7a, 0x54, 0xaf, 0x1f, 0x3d, 0x7f, 0x76, 0x52, - 0xab, 0xd7, 0x8d, 0xb9, 0xca, 0xfd, 0xd7, 0x6f, 0x36, 0xca, 0xc3, 0xf8, 0x53, 0x12, 0x87, 0x3e, - 0x63, 0x3e, 0x8d, 0x02, 0xbe, 0xdc, 0xf7, 0xc1, 0xda, 0x68, 0x36, 0xaa, 0xd5, 0xcf, 0xd0, 0xd1, - 0xc1, 0x59, 0xed, 0xd0, 0xc8, 0x54, 0xca, 0xaf, 0xdf, 0x6c, 0x94, 0x86, 0x99, 0x88, 0xb0, 0x24, - 0xf6, 0x1d, 0xfe, 0x1e, 0x78, 0x0c, 0xca, 0xd7, 0x6b, 0xd6, 0x0e, 0x8d, 0xf9, 0x4a, 0xe5, 0xf5, - 0x9b, 0x8d, 0xb5, 0xeb, 0x14, 0x89, 0x5b, 0xd1, 0x3e, 0xff, 0xc7, 0xfa, 0x5c, 0xf5, 0xc9, 0x37, - 0xbd, 0xf5, 0xcc, 0xb7, 0xbd, 0xf5, 0xcc, 0x7f, 0x7b, 0xeb, 0x99, 0x2f, 0xde, 0xae, 0xcf, 0x7d, - 0xfb, 0x76, 0x7d, 0xee, 0x5f, 0x6f, 0xd7, 0xe7, 0xfe, 0xb8, 0xe1, 0xf9, 0x49, 0xb3, 0xdd, 0xd8, - 0x72, 0x68, 0xb8, 0x3d, 0xf9, 0xcb, 0x4b, 0xd2, 0x6d, 0x11, 0xd6, 0x58, 0x14, 0x3f, 0xbe, 0x3d, - 0xfa, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x48, 0x59, 0x0f, 0x70, 0xd5, 0x13, 0x00, 0x00, + // 2232 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x58, 0x5d, 0x6f, 0x1b, 0xc7, + 0xd5, 0x16, 0xa5, 0x95, 0xb4, 0x1c, 0x52, 0xd4, 0x7a, 0x44, 0xcb, 0x34, 0x9d, 0x68, 0xf5, 0x6e, + 0xf2, 0xb6, 0x6a, 0x90, 0x4a, 0x96, 0x1c, 0xb5, 0x86, 0xd3, 0xb4, 0x10, 0x25, 0xa6, 0x95, 0x6a, + 0xd9, 0xc2, 0x50, 0xb5, 0x91, 0x22, 0xc5, 0x62, 0xb8, 0x3b, 0x5e, 0x6e, 0xb4, 0xbb, 0xb3, 0xd8, + 0x59, 0xd2, 0x64, 0xff, 0x40, 0x03, 0xf7, 0x26, 0xfd, 0x01, 0x06, 0x02, 0xf4, 0x26, 0x97, 0xfe, + 0x09, 0xbd, 0xcc, 0x65, 0x2e, 0x8b, 0x02, 0x5d, 0xb4, 0xf2, 0x45, 0x00, 0x5d, 0xea, 0x17, 0x14, + 0xf3, 0xc1, 0x6f, 0x45, 0x55, 0x01, 0xc1, 0x9e, 0xe7, 0xcc, 0x39, 0xcf, 0x33, 0x1f, 0x67, 0x67, + 0xce, 0x10, 0x54, 0x1d, 0xca, 0x42, 0xca, 0xb6, 0x48, 0x27, 0xdc, 0xe2, 0x7f, 0xdb, 0xbc, 0xb5, + 0x19, 0x27, 0x34, 0xa5, 0xd0, 0x90, 0x7d, 0x9b, 0xdc, 0xc2, 0xff, 0xb6, 0xab, 0xb7, 0x70, 0xe8, + 0x47, 0x74, 0x4b, 0xfc, 0x2b, 0x9d, 0xaa, 0x65, 0x8f, 0x7a, 0x54, 0x34, 0xb7, 0x78, 0x4b, 0x5a, + 0xad, 0x7f, 0x6b, 0x60, 0xe1, 0x04, 0x27, 0x38, 0x64, 0x70, 0x1b, 0xe4, 0x49, 0x27, 0xb4, 0x5d, + 0x12, 0xd1, 0xb0, 0x92, 0x5b, 0xcf, 0x6d, 0xe4, 0x6b, 0xe5, 0xcb, 0xcc, 0x34, 0x7a, 0x38, 0x0c, + 0x1e, 0x59, 0x83, 0x2e, 0x0b, 0xe9, 0xa4, 0x13, 0x1e, 0xf0, 0x26, 0xdc, 0x03, 0x80, 0x74, 0xd3, + 0x04, 0xdb, 0xc4, 0x8f, 0x59, 0x45, 0x5b, 0x9f, 0xdb, 0x98, 0xab, 0x59, 0xe7, 0x99, 0x99, 0xaf, + 0x73, 0x6b, 0xfd, 0xf0, 0x84, 0x5d, 0x66, 0xe6, 0x2d, 0x45, 0x30, 0x70, 0xb4, 0x50, 0x5e, 0x80, + 0xba, 0x1f, 0x33, 0xb8, 0x03, 0x8a, 0x9c, 0xda, 0x69, 0xe1, 0x28, 0x22, 0x01, 0xab, 0x2c, 0xae, + 0xcf, 0x6d, 0xe4, 0x6b, 0xcb, 0xe7, 0x99, 0x59, 0xa8, 0x3f, 0x3b, 0xde, 0x57, 0x66, 0x54, 0x20, + 0x9d, 0xb0, 0x0f, 0xe0, 0x1f, 0x40, 0x09, 0x3b, 0x0e, 0x61, 0xcc, 0x76, 0x68, 0x94, 0x26, 0x34, + 0xa8, 0xe8, 0xeb, 0xb9, 0x8d, 0xc2, 0x8e, 0xb9, 0x39, 0xb9, 0x10, 0x9b, 0x7b, 0xc2, 0x6f, 0x5f, + 0xba, 0xd5, 0x6e, 0x7f, 0x9b, 0x99, 0x33, 0xe7, 0x99, 0xb9, 0x34, 0x66, 0x46, 0x4b, 0x78, 0x14, + 0xc2, 0x47, 0xe0, 0x2e, 0x76, 0x52, 0xbf, 0x43, 0x6c, 0x96, 0xe2, 0xd4, 0x77, 0xec, 0x38, 0x21, + 0x0e, 0x0d, 0x63, 0x3f, 0x20, 0xac, 0x92, 0xe7, 0xe3, 0x43, 0x77, 0xa4, 0x43, 0x43, 0xf4, 0x9f, + 0x0c, 0xbb, 0xe1, 0x7d, 0x50, 0x6e, 0xf9, 0x2c, 0xa5, 0x49, 0xcf, 0x66, 0x24, 0xe9, 0x10, 0xfb, + 0xa5, 0x1f, 0xb9, 0xf4, 0x65, 0x05, 0xac, 0xe7, 0x36, 0x34, 0x04, 0x55, 0x5f, 0x83, 0x77, 0x3d, + 0x17, 0x3d, 0xf0, 0x73, 0xb0, 0x4a, 0xba, 0x29, 0x89, 0x5c, 0xe2, 0xca, 0x05, 0xb6, 0x69, 0x9c, + 0xfa, 0x34, 0x62, 0x95, 0x82, 0x98, 0xd4, 0x8f, 0xa6, 0x27, 0x55, 0x57, 0xfe, 0x62, 0x13, 0x9e, + 0x4a, 0x6f, 0x54, 0x26, 0x57, 0x58, 0xe1, 0x31, 0xc8, 0x33, 0xa7, 0x45, 0xdc, 0x76, 0x40, 0x92, + 0x4a, 0x51, 0x10, 0xbe, 0x7f, 0x05, 0xe1, 0xb3, 0xe3, 0x46, 0xdf, 0x4b, 0x66, 0x43, 0x2d, 0xcf, + 0x97, 0xea, 0x9b, 0xef, 0xdf, 0x7c, 0x90, 0x43, 0x43, 0x86, 0x47, 0xf7, 0x5e, 0x7d, 0xff, 0xe6, + 0x83, 0xd5, 0x91, 0x54, 0xec, 0xf2, 0x64, 0x94, 0x21, 0x47, 0x9a, 0x3e, 0x6b, 0xcc, 0x1d, 0x69, + 0xfa, 0x9c, 0xa1, 0x1d, 0x69, 0xfa, 0xbc, 0xb1, 0x70, 0xa4, 0xe9, 0x0b, 0xc6, 0xa2, 0xf5, 0x09, + 0x28, 0x5f, 0x35, 0x62, 0xf8, 0xff, 0xa0, 0x34, 0x3e, 0x73, 0x99, 0x75, 0x68, 0x69, 0x6c, 0x26, + 0xd6, 0x9b, 0x1c, 0x80, 0xd3, 0x03, 0x84, 0x15, 0xb0, 0x48, 0x22, 0xdc, 0x0c, 0x88, 0x2b, 0xc2, + 0x74, 0xd4, 0x87, 0xf0, 0xc7, 0x60, 0x39, 0xc5, 0x89, 0x47, 0x52, 0x99, 0x1e, 0xd8, 0x49, 0x2b, + 0xb3, 0x82, 0xb8, 0x24, 0xcd, 0xfb, 0xca, 0x0a, 0xef, 0x80, 0x45, 0x0f, 0x33, 0xdb, 0xc1, 0x71, + 0x65, 0x4e, 0xec, 0xcf, 0x82, 0x87, 0xd9, 0x3e, 0x8e, 0x79, 0x47, 0x88, 0xbb, 0x36, 0x15, 0x49, + 0x9d, 0xdb, 0x58, 0x42, 0x0b, 0x21, 0xee, 0x3e, 0x8d, 0xc5, 0x90, 0x1d, 0xec, 0x92, 0xc8, 0x21, + 0x76, 0x33, 0xa0, 0xce, 0x19, 0xab, 0xcc, 0x8b, 0xc0, 0x25, 0x65, 0xad, 0x09, 0xa3, 0xf5, 0x97, + 0x1c, 0x18, 0x4f, 0x31, 0xb8, 0x07, 0x16, 0x9c, 0x84, 0xe0, 0x94, 0x88, 0xc1, 0x16, 0x76, 0xde, + 0xfb, 0x2f, 0xa9, 0x7a, 0xda, 0x8b, 0x49, 0x4d, 0xe3, 0x7b, 0x80, 0x54, 0x20, 0xfc, 0x04, 0x68, + 0x0e, 0x0e, 0x02, 0x31, 0x97, 0xff, 0x89, 0x40, 0x84, 0x59, 0xff, 0xcc, 0x81, 0x5b, 0x53, 0x1e, + 0xd0, 0x01, 0x05, 0xf5, 0x29, 0xa5, 0xbd, 0x58, 0x0e, 0xae, 0xb4, 0xf3, 0xce, 0x0f, 0x71, 0x0b, + 0xd2, 0xf7, 0xcf, 0x33, 0x13, 0x0c, 0xf1, 0x65, 0x66, 0x42, 0xf9, 0x85, 0x8f, 0x10, 0x59, 0x08, + 0xe0, 0x81, 0x07, 0x74, 0xc0, 0xca, 0xf8, 0xf7, 0x6a, 0x07, 0x3e, 0xe3, 0x9b, 0xc2, 0x3f, 0xf5, + 0x07, 0xe7, 0x99, 0x39, 0x3e, 0xb0, 0xc7, 0x3e, 0x4b, 0x2f, 0x33, 0xb3, 0x3a, 0xc6, 0x3a, 0x1a, + 0x69, 0xa1, 0x5b, 0x78, 0x32, 0xc0, 0xfa, 0xc6, 0x00, 0x85, 0xfd, 0x16, 0xf6, 0xa3, 0x7d, 0x1a, + 0xbd, 0xf0, 0x3d, 0xf8, 0x39, 0x58, 0x6e, 0xd1, 0x90, 0xb0, 0x94, 0x60, 0x57, 0x6e, 0x96, 0x3a, + 0xd4, 0x1e, 0xfc, 0x23, 0x33, 0x6f, 0xcb, 0x09, 0x32, 0xf7, 0x6c, 0xd3, 0xa7, 0x5b, 0x21, 0x4e, + 0x5b, 0x9b, 0x87, 0x11, 0x17, 0x5d, 0x95, 0xa2, 0x13, 0x91, 0x16, 0x2a, 0x0d, 0x2c, 0x62, 0x8b, + 0x61, 0x0b, 0x94, 0x5c, 0x4c, 0xed, 0x17, 0x34, 0x39, 0x53, 0xe4, 0x22, 0xc5, 0x6a, 0xb5, 0x1f, + 0x24, 0x3f, 0xcf, 0xcc, 0xe2, 0xc1, 0xde, 0xd3, 0x4f, 0x69, 0x72, 0x26, 0x28, 0x2e, 0x33, 0xf3, + 0xb6, 0x14, 0x1b, 0x27, 0xb2, 0x50, 0xd1, 0xc5, 0x74, 0xe0, 0x06, 0x9f, 0x03, 0x63, 0xe0, 0xc0, + 0xda, 0x71, 0x4c, 0x93, 0x54, 0x64, 0xab, 0x5e, 0xfb, 0xe9, 0x79, 0x66, 0x96, 0x14, 0x65, 0x43, + 0xf6, 0x5c, 0x66, 0xe6, 0x9d, 0x09, 0x52, 0x15, 0x63, 0xa1, 0x92, 0xa2, 0x55, 0xae, 0xb0, 0x09, + 0x8a, 0xc4, 0x8f, 0xb7, 0x77, 0xef, 0xab, 0x09, 0x68, 0x62, 0x02, 0xbf, 0xba, 0x6e, 0x02, 0x85, + 0xfa, 0xe1, 0xc9, 0xf6, 0xee, 0xfd, 0xfe, 0xf8, 0x57, 0xd4, 0xc9, 0x3e, 0xc2, 0x62, 0xa1, 0x82, + 0x84, 0x72, 0xf0, 0x7d, 0x8d, 0x5d, 0xa5, 0xb1, 0x70, 0x53, 0x8d, 0xdd, 0xab, 0x34, 0x76, 0xc7, + 0x35, 0x76, 0xc7, 0x35, 0x1e, 0x2a, 0x8d, 0xc5, 0x9b, 0x6a, 0x3c, 0xbc, 0x4a, 0xe3, 0xe1, 0xb8, + 0x86, 0xf4, 0xe1, 0xc9, 0xd4, 0xec, 0xfd, 0x11, 0x47, 0xa9, 0xdf, 0x0e, 0x95, 0x8c, 0x7e, 0xe3, + 0x64, 0x9a, 0x88, 0xb4, 0x50, 0x69, 0x60, 0x91, 0xec, 0x67, 0xa0, 0xec, 0xd0, 0x88, 0xa5, 0xdc, + 0x16, 0xd1, 0x38, 0x50, 0x87, 0x4b, 0x25, 0x2f, 0x24, 0x1e, 0x5e, 0x27, 0x71, 0x4f, 0x4a, 0x5c, + 0x15, 0x6e, 0xa1, 0x95, 0x71, 0xb3, 0x14, 0xb3, 0x81, 0x11, 0x93, 0x94, 0x24, 0xac, 0xd9, 0x4e, + 0x3c, 0x25, 0x04, 0x84, 0xd0, 0x47, 0xd7, 0x09, 0xa9, 0xb4, 0x9a, 0x0c, 0xb5, 0xd0, 0xf2, 0xd0, + 0x24, 0x05, 0x3e, 0x03, 0x25, 0x9f, 0xab, 0x36, 0xdb, 0x81, 0xa2, 0x2f, 0x08, 0xfa, 0x9d, 0xeb, + 0xe8, 0xd5, 0xa7, 0x30, 0x1e, 0x68, 0xa1, 0xa5, 0xbe, 0x41, 0x52, 0xbb, 0x00, 0x86, 0x6d, 0x3f, + 0xb1, 0xbd, 0x00, 0x3b, 0x3e, 0x49, 0x14, 0x7d, 0x51, 0xd0, 0xff, 0xec, 0x3a, 0xfa, 0xbb, 0x92, + 0x7e, 0x3a, 0xd8, 0x42, 0x06, 0x37, 0xfe, 0x5a, 0xda, 0xa4, 0x4a, 0x03, 0x14, 0x9b, 0x24, 0x09, + 0xfc, 0x48, 0xf1, 0x2f, 0x09, 0xfe, 0xfb, 0xd7, 0xf1, 0xab, 0x0c, 0x1a, 0x0d, 0xb3, 0x50, 0x41, + 0xc2, 0x01, 0x69, 0x40, 0x23, 0x97, 0xf6, 0x49, 0x6f, 0xdd, 0x98, 0x74, 0x34, 0xcc, 0x42, 0x05, + 0x09, 0x25, 0xa9, 0x07, 0x56, 0x70, 0x92, 0xd0, 0x97, 0x13, 0x0b, 0x02, 0x05, 0xf7, 0xcf, 0xaf, + 0xe3, 0xee, 0x1f, 0xae, 0xd3, 0xd1, 0xfc, 0x70, 0xe5, 0xd6, 0xb1, 0x25, 0x71, 0x01, 0xf4, 0x12, + 0xdc, 0x9b, 0xd0, 0x29, 0xdf, 0x78, 0xe1, 0xa7, 0x83, 0x2d, 0x64, 0x70, 0xe3, 0x98, 0xca, 0x17, + 0xa0, 0x1c, 0x92, 0xc4, 0x23, 0x76, 0x44, 0x52, 0x16, 0x07, 0x7e, 0xaa, 0x74, 0x6e, 0xdf, 0xf8, + 0x3b, 0xb8, 0x2a, 0xdc, 0x42, 0x50, 0x98, 0x9f, 0x28, 0xab, 0xd4, 0xba, 0x0b, 0x74, 0x87, 0xdf, + 0x16, 0xb6, 0xef, 0x56, 0x2a, 0xe2, 0x0e, 0x5f, 0x14, 0xf8, 0xd0, 0x85, 0x65, 0x30, 0x2f, 0xcb, + 0x91, 0xbb, 0xa2, 0x6a, 0x90, 0x00, 0x56, 0x81, 0xee, 0x12, 0xc7, 0x0f, 0x71, 0xc0, 0x2a, 0x55, + 0x11, 0x30, 0xc0, 0xf0, 0x19, 0x58, 0x62, 0x2d, 0x1c, 0x79, 0x2d, 0xec, 0xdb, 0xa9, 0x1f, 0x92, + 0xca, 0x3d, 0x31, 0xe2, 0xed, 0xeb, 0x46, 0x5c, 0x96, 0x23, 0x1e, 0x8b, 0xb3, 0x50, 0xb1, 0x8f, + 0x4f, 0xfd, 0x90, 0xc0, 0x13, 0x50, 0x70, 0x70, 0xe4, 0xb4, 0x23, 0xc9, 0xfa, 0x8e, 0x60, 0xdd, + 0xba, 0x8e, 0x55, 0x5d, 0xc5, 0x23, 0x51, 0x16, 0x02, 0x12, 0xf5, 0x19, 0xe3, 0x04, 0x7b, 0x6d, + 0x22, 0x19, 0xdf, 0xbd, 0x31, 0xe3, 0x48, 0x94, 0x85, 0x80, 0x44, 0x7d, 0xc6, 0x0e, 0x49, 0xce, + 0x02, 0xc5, 0xb8, 0x76, 0x63, 0xc6, 0x91, 0x28, 0x0b, 0x01, 0x89, 0x04, 0xe3, 0x31, 0x00, 0x94, + 0xe1, 0x33, 0x2c, 0x09, 0x4d, 0x41, 0xb8, 0x79, 0x1d, 0xa1, 0x7a, 0x61, 0x0c, 0x83, 0x2c, 0x94, + 0x17, 0x80, 0xd3, 0x0d, 0x4a, 0xd1, 0x55, 0xe3, 0xce, 0x91, 0xa6, 0xdf, 0x31, 0x2a, 0xd6, 0x16, + 0x98, 0xe7, 0x95, 0x3b, 0x81, 0x06, 0x98, 0x3b, 0x23, 0x3d, 0x55, 0x76, 0xf2, 0x26, 0xdf, 0xfb, + 0x0e, 0x0e, 0xda, 0x44, 0x55, 0x8c, 0x12, 0x58, 0x27, 0x60, 0xf9, 0x34, 0xc1, 0x11, 0xe3, 0x55, + 0x3f, 0x8d, 0x1e, 0x53, 0x8f, 0x41, 0x08, 0xb4, 0x16, 0x66, 0x2d, 0x15, 0x2b, 0xda, 0xf0, 0x27, + 0x40, 0x0b, 0xa8, 0xc7, 0x44, 0x61, 0x53, 0xd8, 0xb9, 0x3d, 0x5d, 0x45, 0x3d, 0xa6, 0x1e, 0x12, + 0x2e, 0xd6, 0x9f, 0xe6, 0xc0, 0xdc, 0x63, 0xea, 0xf1, 0x2a, 0x16, 0xbb, 0x6e, 0x42, 0x18, 0x53, + 0x4c, 0x7d, 0x08, 0x57, 0xc1, 0x42, 0x4a, 0x63, 0xdf, 0x91, 0x74, 0x79, 0xa4, 0x10, 0x17, 0x76, + 0x71, 0x8a, 0x45, 0x0d, 0x50, 0x44, 0xa2, 0xcd, 0x1f, 0x51, 0x22, 0xd5, 0xed, 0xa8, 0x1d, 0x36, + 0x49, 0x22, 0xae, 0x72, 0xad, 0xb6, 0x7c, 0x91, 0x99, 0x05, 0x61, 0x7f, 0x22, 0xcc, 0x68, 0x14, + 0xc0, 0x0f, 0xc1, 0x62, 0xda, 0xb5, 0xc5, 0x1c, 0xe6, 0xc5, 0x12, 0xaf, 0x5c, 0x64, 0xe6, 0x72, + 0x3a, 0x9c, 0xe6, 0x6f, 0x30, 0x6b, 0xa1, 0x85, 0xb4, 0xcb, 0xff, 0x87, 0x5b, 0x40, 0x4f, 0xbb, + 0xb6, 0x1f, 0xb9, 0xa4, 0x2b, 0x2e, 0x71, 0xad, 0x56, 0xbe, 0xc8, 0x4c, 0x63, 0xc4, 0xfd, 0x90, + 0xf7, 0xa1, 0xc5, 0xb4, 0x2b, 0x1a, 0xf0, 0x43, 0x00, 0xe4, 0x90, 0x84, 0x82, 0xbc, 0x93, 0x97, + 0x2e, 0x32, 0x33, 0x2f, 0xac, 0x82, 0x7b, 0xd8, 0x84, 0x16, 0x98, 0x97, 0xdc, 0xba, 0xe0, 0x2e, + 0x5e, 0x64, 0xa6, 0x1e, 0x50, 0x4f, 0x72, 0xca, 0x2e, 0xbe, 0x54, 0x09, 0x09, 0x69, 0x87, 0xb8, + 0xe2, 0x62, 0xd4, 0x51, 0x1f, 0xc2, 0x8f, 0xc1, 0xb2, 0xd4, 0xe2, 0x7b, 0xcf, 0x52, 0x1c, 0xc6, + 0xf2, 0xbd, 0x55, 0x83, 0x17, 0x99, 0x59, 0x12, 0x5d, 0xa7, 0xfd, 0x1e, 0x34, 0x81, 0xad, 0xaf, + 0x66, 0x81, 0x7e, 0xda, 0x45, 0x84, 0xb5, 0x83, 0x14, 0x7e, 0x0a, 0x8c, 0xfe, 0x9b, 0xc1, 0x1e, + 0xdb, 0x97, 0xda, 0xbd, 0xe1, 0x1d, 0x38, 0xe9, 0x61, 0xa1, 0xe5, 0xbe, 0x69, 0x4f, 0x6d, 0x5e, + 0x19, 0xcc, 0x37, 0x03, 0x4a, 0x43, 0x91, 0x46, 0x45, 0x24, 0x01, 0x7c, 0x2e, 0x96, 0x5c, 0xa4, + 0xc8, 0x9c, 0x28, 0xe2, 0xff, 0x6f, 0x3a, 0x45, 0x26, 0xf2, 0xac, 0x76, 0x8f, 0x97, 0xf0, 0x97, + 0x99, 0x59, 0x92, 0xda, 0x2a, 0xde, 0x92, 0x2f, 0xb3, 0x85, 0xb4, 0x2b, 0x92, 0xd1, 0x00, 0x73, + 0x09, 0x49, 0xc5, 0xb6, 0x17, 0x11, 0x6f, 0xf2, 0xd3, 0x2a, 0x21, 0x1d, 0x92, 0xa4, 0xc4, 0x15, + 0xdb, 0xab, 0xa3, 0x01, 0xe6, 0x47, 0x1f, 0x7f, 0xf6, 0xb4, 0x19, 0x71, 0xe5, 0x5e, 0x22, 0xfe, + 0x0c, 0xfa, 0x1d, 0x23, 0xee, 0x23, 0xed, 0xcb, 0xaf, 0xcd, 0x19, 0x0b, 0x83, 0x82, 0xaa, 0xef, + 0xdb, 0x71, 0x40, 0xae, 0xc9, 0xd1, 0x1d, 0x50, 0xe4, 0xef, 0x59, 0xec, 0x11, 0xfb, 0x8c, 0xf4, + 0x54, 0xa6, 0xca, 0xbc, 0x53, 0xf6, 0xdf, 0x92, 0x1e, 0x43, 0xa3, 0x40, 0x49, 0x7c, 0xad, 0x81, + 0xc2, 0x69, 0x82, 0x1d, 0xa2, 0xaa, 0x75, 0x9e, 0xed, 0x1c, 0x26, 0x4a, 0x42, 0x21, 0xae, 0xcd, + 0x37, 0x95, 0xb6, 0xfb, 0x6f, 0xb8, 0x3e, 0xe4, 0x11, 0x09, 0x21, 0x5d, 0xe2, 0xf4, 0xdf, 0x6e, + 0x12, 0xc1, 0x5d, 0xb0, 0xe4, 0xfa, 0x8c, 0xbf, 0x04, 0xf9, 0xf3, 0xdd, 0x39, 0x93, 0xd3, 0xaf, + 0x19, 0x17, 0x99, 0x59, 0x54, 0x1d, 0x0d, 0x6e, 0x47, 0x63, 0x88, 0xe7, 0xd0, 0x30, 0x4c, 0x8c, + 0x56, 0xac, 0x8d, 0x2e, 0x73, 0x68, 0xe0, 0x2a, 0x7a, 0xd0, 0x04, 0x96, 0x37, 0x46, 0xb3, 0xed, + 0x89, 0xf4, 0xd5, 0x91, 0x04, 0xdc, 0x1a, 0xf8, 0xa1, 0x9f, 0x8a, 0x74, 0x9d, 0x47, 0x12, 0xc0, + 0x8f, 0x41, 0x9e, 0x76, 0x48, 0x92, 0xf8, 0x2e, 0x61, 0x22, 0x4d, 0x0b, 0x3b, 0xef, 0x4e, 0xa7, + 0xc1, 0xc8, 0x4b, 0x06, 0x0d, 0xfd, 0xf9, 0xe4, 0xe4, 0x2b, 0xd7, 0x0e, 0x49, 0x48, 0x93, 0x9e, + 0x28, 0xad, 0xd4, 0xe4, 0x64, 0xc7, 0xb1, 0xb0, 0xa3, 0x31, 0x04, 0x6b, 0x00, 0xaa, 0xb0, 0x84, + 0xa4, 0xed, 0x24, 0xb2, 0xc5, 0x09, 0x52, 0x14, 0xb1, 0xe2, 0x3b, 0x96, 0xbd, 0x48, 0x74, 0x1e, + 0xe0, 0x14, 0xa3, 0x29, 0x0b, 0xfc, 0x25, 0x80, 0x72, 0x4f, 0xec, 0x2f, 0x18, 0x8d, 0xf8, 0x7b, + 0xec, 0x85, 0xef, 0xa9, 0xda, 0x48, 0xe8, 0xcb, 0x5e, 0x35, 0x66, 0x43, 0xa2, 0x23, 0x46, 0xd5, + 0x2c, 0x8e, 0x34, 0x5d, 0x33, 0xe6, 0x8f, 0x34, 0x7d, 0xd1, 0xd0, 0x07, 0xeb, 0xa7, 0x66, 0x81, + 0x56, 0xfa, 0x78, 0x64, 0x78, 0xd6, 0x13, 0x00, 0x4e, 0x12, 0xe2, 0xf3, 0x0a, 0x36, 0x08, 0xf8, + 0xb1, 0x17, 0xe1, 0x90, 0xf4, 0xcf, 0x5b, 0xde, 0x1e, 0x4d, 0xcc, 0xd9, 0xf1, 0xc4, 0x84, 0x40, + 0x73, 0xa8, 0x4b, 0x44, 0x6a, 0xe4, 0x91, 0x68, 0x5b, 0x7f, 0xce, 0x81, 0x42, 0xbd, 0x13, 0xee, + 0x53, 0x3f, 0x3a, 0x8c, 0x5e, 0xd0, 0xe1, 0x35, 0x9f, 0x1b, 0xbd, 0xe6, 0xa7, 0x7f, 0x94, 0x98, + 0xbd, 0xe2, 0x47, 0x09, 0xf8, 0x9e, 0xc8, 0xb2, 0x38, 0xc0, 0x3d, 0xe5, 0x25, 0x95, 0x8a, 0xca, + 0x78, 0x30, 0x55, 0x32, 0xc8, 0xdf, 0x11, 0x06, 0xf8, 0x83, 0xbf, 0xe5, 0xc0, 0xc8, 0x23, 0x1a, + 0xfe, 0x02, 0x54, 0xf7, 0xf6, 0xf7, 0xeb, 0x8d, 0x86, 0x7d, 0xfa, 0xd9, 0x49, 0xdd, 0x3e, 0xa9, + 0xa3, 0xe3, 0xc3, 0x46, 0xe3, 0xf0, 0xe9, 0x93, 0xc7, 0xf5, 0x46, 0xc3, 0x98, 0xa9, 0xbe, 0xf3, + 0xea, 0xf5, 0x7a, 0x65, 0xe8, 0x7f, 0x42, 0x92, 0xd0, 0x67, 0xcc, 0xa7, 0x51, 0xc0, 0xa7, 0xfb, + 0x11, 0x58, 0x1d, 0x8d, 0x46, 0xf5, 0xc6, 0x29, 0x3a, 0xdc, 0x3f, 0xad, 0x1f, 0x18, 0xb9, 0x6a, + 0xe5, 0xd5, 0xeb, 0xf5, 0xf2, 0x30, 0x12, 0x11, 0x96, 0x26, 0xbe, 0xc3, 0xcf, 0x81, 0x87, 0xa0, + 0x72, 0xb5, 0x66, 0xfd, 0xc0, 0x98, 0xad, 0x56, 0x5f, 0xbd, 0x5e, 0x5f, 0xbd, 0x4a, 0x91, 0xb8, + 0x55, 0xed, 0xcb, 0xbf, 0xae, 0xcd, 0xd4, 0x1e, 0x7d, 0x7b, 0xbe, 0x96, 0xfb, 0xee, 0x7c, 0x2d, + 0xf7, 0xaf, 0xf3, 0xb5, 0xdc, 0x57, 0x6f, 0xd7, 0x66, 0xbe, 0x7b, 0xbb, 0x36, 0xf3, 0xf7, 0xb7, + 0x6b, 0x33, 0xbf, 0x5f, 0xf7, 0xfc, 0xb4, 0xd5, 0x6e, 0x6e, 0x3a, 0x34, 0xdc, 0x9a, 0xfc, 0xb1, + 0x28, 0xed, 0xc5, 0x84, 0x35, 0x17, 0xc4, 0xcf, 0x8f, 0x0f, 0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, + 0xc8, 0xd1, 0xb7, 0xd9, 0xd7, 0x14, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -1226,6 +1326,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.Scheduler.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvm(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x62 if m.ExtendedDenomOptions != nil { { size, err := m.ExtendedDenomOptions.MarshalToSizedBuffer(dAtA[:i]) @@ -1272,21 +1382,21 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { } } if len(m.ExtraEIPs) > 0 { - dAtA4 := make([]byte, len(m.ExtraEIPs)*10) - var j3 int + dAtA5 := make([]byte, len(m.ExtraEIPs)*10) + var j4 int for _, num1 := range m.ExtraEIPs { num := uint64(num1) for num >= 1<<7 { - dAtA4[j3] = uint8(uint64(num)&0x7f | 0x80) + dAtA5[j4] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j3++ + j4++ } - dAtA4[j3] = uint8(num) - j3++ + dAtA5[j4] = uint8(num) + j4++ } - i -= j3 - copy(dAtA[i:], dAtA4[:j3]) - i = encodeVarintEvm(dAtA, i, uint64(j3)) + i -= j4 + copy(dAtA[i:], dAtA5[:j4]) + i = encodeVarintEvm(dAtA, i, uint64(j4)) i-- dAtA[i] = 0x22 } @@ -1330,6 +1440,61 @@ func (m *ExtendedDenomOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *EVMSchedulerParams) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EVMSchedulerParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EVMSchedulerParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.CadenceBlocks != 0 { + i = encodeVarintEvm(dAtA, i, uint64(m.CadenceBlocks)) + i-- + dAtA[i] = 0x28 + } + if m.MaxOps != 0 { + i = encodeVarintEvm(dAtA, i, uint64(m.MaxOps)) + i-- + dAtA[i] = 0x20 + } + if m.GasCap != 0 { + i = encodeVarintEvm(dAtA, i, uint64(m.GasCap)) + i-- + dAtA[i] = 0x18 + } + if len(m.TargetContract) > 0 { + i -= len(m.TargetContract) + copy(dAtA[i:], m.TargetContract) + i = encodeVarintEvm(dAtA, i, uint64(len(m.TargetContract))) + i-- + dAtA[i] = 0x12 + } + if m.Enabled { + i-- + if m.Enabled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *AccessControl) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2261,6 +2426,8 @@ func (m *Params) Size() (n int) { l = m.ExtendedDenomOptions.Size() n += 1 + l + sovEvm(uint64(l)) } + l = m.Scheduler.Size() + n += 1 + l + sovEvm(uint64(l)) return n } @@ -2277,6 +2444,31 @@ func (m *ExtendedDenomOptions) Size() (n int) { return n } +func (m *EVMSchedulerParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Enabled { + n += 2 + } + l = len(m.TargetContract) + if l > 0 { + n += 1 + l + sovEvm(uint64(l)) + } + if m.GasCap != 0 { + n += 1 + sovEvm(uint64(m.GasCap)) + } + if m.MaxOps != 0 { + n += 1 + sovEvm(uint64(m.MaxOps)) + } + if m.CadenceBlocks != 0 { + n += 1 + sovEvm(uint64(m.CadenceBlocks)) + } + return n +} + func (m *AccessControl) Size() (n int) { if m == nil { return 0 @@ -2926,6 +3118,39 @@ func (m *Params) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Scheduler", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvm + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Scheduler.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipEvm(dAtA[iNdEx:]) @@ -3029,6 +3254,165 @@ func (m *ExtendedDenomOptions) Unmarshal(dAtA []byte) error { } return nil } +func (m *EVMSchedulerParams) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EVMSchedulerParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EVMSchedulerParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Enabled = bool(v != 0) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TargetContract", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthEvm + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvm + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TargetContract = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GasCap", wireType) + } + m.GasCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GasCap |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxOps", wireType) + } + m.MaxOps = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxOps |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CadenceBlocks", wireType) + } + m.CadenceBlocks = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvm + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CadenceBlocks |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipEvm(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvm + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *AccessControl) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/vm/types/params.go b/x/vm/types/params.go index 0a7bb471..b0155722 100644 --- a/x/vm/types/params.go +++ b/x/vm/types/params.go @@ -5,6 +5,7 @@ import ( "math/big" "slices" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" @@ -50,6 +51,12 @@ var ( const DefaultHistoryServeWindow = 8192 // same as EIP-2935 +const ( + DefaultSchedulerGasCap uint64 = 5_000_000 + DefaultSchedulerMaxOps uint32 = 32 + DefaultSchedulerCadenceBlocks uint64 = 1 +) + // NewParams creates a new Params instance func NewParams( extraEIPs []int64, @@ -75,6 +82,13 @@ func DefaultParams() Params { AccessControl: DefaultAccessControl, HistoryServeWindow: DefaultHistoryServeWindow, ExtendedDenomOptions: &ExtendedDenomOptions{ExtendedDenom: sdk.DefaultBondDenom}, + Scheduler: EVMSchedulerParams{ + Enabled: false, + TargetContract: "", + GasCap: DefaultSchedulerGasCap, + MaxOps: DefaultSchedulerMaxOps, + CadenceBlocks: DefaultSchedulerCadenceBlocks, + }, } } @@ -104,10 +118,35 @@ func (p Params) Validate() error { if err := p.AccessControl.Validate(); err != nil { return err } + if err := p.Scheduler.Validate(); err != nil { + return err + } return validateChannels(p.EVMChannels) } +func (p EVMSchedulerParams) Validate() error { + if p.TargetContract != "" && !common.IsHexAddress(p.TargetContract) { + return fmt.Errorf("invalid scheduler target contract: %s", p.TargetContract) + } + if !p.Enabled { + return nil + } + if p.TargetContract == "" || common.HexToAddress(p.TargetContract) == (common.Address{}) { + return fmt.Errorf("scheduler target contract must be non-zero when enabled") + } + if p.GasCap == 0 { + return fmt.Errorf("scheduler gas cap must be greater than zero") + } + if p.MaxOps == 0 { + return fmt.Errorf("scheduler max ops must be greater than zero") + } + if p.CadenceBlocks == 0 { + return fmt.Errorf("scheduler cadence blocks must be greater than zero") + } + return nil +} + // EIPs returns the ExtraEIPS as a int slice func (p Params) EIPs() []int { eips := make([]int, len(p.ExtraEIPs)) diff --git a/x/vm/types/params_test.go b/x/vm/types/params_test.go index 020b19e3..d8c12d93 100644 --- a/x/vm/types/params_test.go +++ b/x/vm/types/params_test.go @@ -32,6 +32,19 @@ func TestParamsValidate(t *testing.T) { params: Params{}, expPass: true, }, + { + name: "valid scheduler", + params: Params{ + Scheduler: EVMSchedulerParams{ + Enabled: true, + TargetContract: "0x0000000000000000000000000000000000001000", + GasCap: DefaultSchedulerGasCap, + MaxOps: DefaultSchedulerMaxOps, + CadenceBlocks: DefaultSchedulerCadenceBlocks, + }, + }, + expPass: true, + }, { name: "invalid eip", params: Params{ @@ -39,6 +52,30 @@ func TestParamsValidate(t *testing.T) { }, errContains: "EIP 1000000 is not activateable, valid EIPs are", }, + { + name: "enabled scheduler empty target", + params: Params{ + Scheduler: EVMSchedulerParams{ + Enabled: true, + GasCap: DefaultSchedulerGasCap, + MaxOps: DefaultSchedulerMaxOps, + CadenceBlocks: DefaultSchedulerCadenceBlocks, + }, + }, + errContains: "scheduler target contract must be non-zero when enabled", + }, + { + name: "enabled scheduler zero gas", + params: Params{ + Scheduler: EVMSchedulerParams{ + Enabled: true, + TargetContract: "0x0000000000000000000000000000000000001000", + MaxOps: DefaultSchedulerMaxOps, + CadenceBlocks: DefaultSchedulerCadenceBlocks, + }, + }, + errContains: "scheduler gas cap must be greater than zero", + }, { name: "unsorted precompiles", params: Params{ From 1c308aa8812fee84cba9b04496bc8679043808e3 Mon Sep 17 00:00:00 2001 From: Rahul Ghangas Date: Mon, 1 Jun 2026 12:24:57 +0000 Subject: [PATCH 2/5] feat: solidity only community pool with minimal scheduler --- api/cosmos/evm/vm/v1/evm.pulsar.go | 1537 ++++++++++++++----- contracts/solidity/StakedBondVault.json | 1789 +++++++++++++++++++++++ contracts/solidity/StakedBondVault.sol | 490 +++++++ contracts/staked_bond_vault.go | 27 + evmd/app.go | 10 +- proto/cosmos/evm/vm/v1/evm.proto | 19 +- 6 files changed, 3504 insertions(+), 368 deletions(-) create mode 100644 contracts/solidity/StakedBondVault.json create mode 100644 contracts/solidity/StakedBondVault.sol create mode 100644 contracts/staked_bond_vault.go diff --git a/api/cosmos/evm/vm/v1/evm.pulsar.go b/api/cosmos/evm/vm/v1/evm.pulsar.go index 7e5c9a62..33b6c8f8 100644 --- a/api/cosmos/evm/vm/v1/evm.pulsar.go +++ b/api/cosmos/evm/vm/v1/evm.pulsar.go @@ -161,6 +161,7 @@ var ( fd_Params_active_static_precompiles protoreflect.FieldDescriptor fd_Params_history_serve_window protoreflect.FieldDescriptor fd_Params_extended_denom_options protoreflect.FieldDescriptor + fd_Params_scheduler protoreflect.FieldDescriptor ) func init() { @@ -173,6 +174,7 @@ func init() { fd_Params_active_static_precompiles = md_Params.Fields().ByName("active_static_precompiles") fd_Params_history_serve_window = md_Params.Fields().ByName("history_serve_window") fd_Params_extended_denom_options = md_Params.Fields().ByName("extended_denom_options") + fd_Params_scheduler = md_Params.Fields().ByName("scheduler") } var _ protoreflect.Message = (*fastReflection_Params)(nil) @@ -282,6 +284,12 @@ func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, proto return } } + if x.Scheduler != nil { + value := protoreflect.ValueOfMessage(x.Scheduler.ProtoReflect()) + if !f(fd_Params_scheduler, value) { + return + } + } } // Has reports whether a field is populated. @@ -311,6 +319,8 @@ func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { return x.HistoryServeWindow != uint64(0) case "cosmos.evm.vm.v1.Params.extended_denom_options": return x.ExtendedDenomOptions != nil + case "cosmos.evm.vm.v1.Params.scheduler": + return x.Scheduler != nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.Params")) @@ -341,6 +351,8 @@ func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { x.HistoryServeWindow = uint64(0) case "cosmos.evm.vm.v1.Params.extended_denom_options": x.ExtendedDenomOptions = nil + case "cosmos.evm.vm.v1.Params.scheduler": + x.Scheduler = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.Params")) @@ -387,6 +399,9 @@ func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) pro case "cosmos.evm.vm.v1.Params.extended_denom_options": value := x.ExtendedDenomOptions return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "cosmos.evm.vm.v1.Params.scheduler": + value := x.Scheduler + return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.Params")) @@ -427,6 +442,8 @@ func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value proto x.HistoryServeWindow = value.Uint() case "cosmos.evm.vm.v1.Params.extended_denom_options": x.ExtendedDenomOptions = value.Message().Interface().(*ExtendedDenomOptions) + case "cosmos.evm.vm.v1.Params.scheduler": + x.Scheduler = value.Message().Interface().(*EVMSchedulerParams) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.Params")) @@ -475,6 +492,11 @@ func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protore x.ExtendedDenomOptions = new(ExtendedDenomOptions) } return protoreflect.ValueOfMessage(x.ExtendedDenomOptions.ProtoReflect()) + case "cosmos.evm.vm.v1.Params.scheduler": + if x.Scheduler == nil { + x.Scheduler = new(EVMSchedulerParams) + } + return protoreflect.ValueOfMessage(x.Scheduler.ProtoReflect()) case "cosmos.evm.vm.v1.Params.evm_denom": panic(fmt.Errorf("field evm_denom of message cosmos.evm.vm.v1.Params is not mutable")) case "cosmos.evm.vm.v1.Params.history_serve_window": @@ -511,6 +533,9 @@ func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protor case "cosmos.evm.vm.v1.Params.extended_denom_options": m := new(ExtendedDenomOptions) return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "cosmos.evm.vm.v1.Params.scheduler": + m := new(EVMSchedulerParams) + return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.Params")) @@ -614,6 +639,10 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { l = options.Size(x.ExtendedDenomOptions) n += 1 + l + runtime.Sov(uint64(l)) } + if x.Scheduler != nil { + l = options.Size(x.Scheduler) + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -643,6 +672,20 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if x.Scheduler != nil { + encoded, err := options.Marshal(x.Scheduler) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x62 + } if x.ExtendedDenomOptions != nil { encoded, err := options.Marshal(x.ExtendedDenomOptions) if err != nil { @@ -1034,6 +1077,42 @@ func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err } iNdEx = postIndex + case 12: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Scheduler", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Scheduler == nil { + x.Scheduler = &EVMSchedulerParams{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Scheduler); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -1333,10 +1412,526 @@ func (x *fastReflection_ExtendedDenomOptions) ProtoMethods() *protoiface.Methods var n int var l int _ = l - l = len(x.ExtendedDenom) + l = len(x.ExtendedDenom) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*ExtendedDenomOptions) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.ExtendedDenom) > 0 { + i -= len(x.ExtendedDenom) + copy(dAtA[i:], x.ExtendedDenom) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ExtendedDenom))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*ExtendedDenomOptions) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ExtendedDenomOptions: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ExtendedDenomOptions: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExtendedDenom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.ExtendedDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_EVMSchedulerParams protoreflect.MessageDescriptor + fd_EVMSchedulerParams_enabled protoreflect.FieldDescriptor + fd_EVMSchedulerParams_target_contract protoreflect.FieldDescriptor + fd_EVMSchedulerParams_gas_cap protoreflect.FieldDescriptor + fd_EVMSchedulerParams_max_ops protoreflect.FieldDescriptor + fd_EVMSchedulerParams_cadence_blocks protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_vm_v1_evm_proto_init() + md_EVMSchedulerParams = File_cosmos_evm_vm_v1_evm_proto.Messages().ByName("EVMSchedulerParams") + fd_EVMSchedulerParams_enabled = md_EVMSchedulerParams.Fields().ByName("enabled") + fd_EVMSchedulerParams_target_contract = md_EVMSchedulerParams.Fields().ByName("target_contract") + fd_EVMSchedulerParams_gas_cap = md_EVMSchedulerParams.Fields().ByName("gas_cap") + fd_EVMSchedulerParams_max_ops = md_EVMSchedulerParams.Fields().ByName("max_ops") + fd_EVMSchedulerParams_cadence_blocks = md_EVMSchedulerParams.Fields().ByName("cadence_blocks") +} + +var _ protoreflect.Message = (*fastReflection_EVMSchedulerParams)(nil) + +type fastReflection_EVMSchedulerParams EVMSchedulerParams + +func (x *EVMSchedulerParams) ProtoReflect() protoreflect.Message { + return (*fastReflection_EVMSchedulerParams)(x) +} + +func (x *EVMSchedulerParams) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_EVMSchedulerParams_messageType fastReflection_EVMSchedulerParams_messageType +var _ protoreflect.MessageType = fastReflection_EVMSchedulerParams_messageType{} + +type fastReflection_EVMSchedulerParams_messageType struct{} + +func (x fastReflection_EVMSchedulerParams_messageType) Zero() protoreflect.Message { + return (*fastReflection_EVMSchedulerParams)(nil) +} +func (x fastReflection_EVMSchedulerParams_messageType) New() protoreflect.Message { + return new(fastReflection_EVMSchedulerParams) +} +func (x fastReflection_EVMSchedulerParams_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_EVMSchedulerParams +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_EVMSchedulerParams) Descriptor() protoreflect.MessageDescriptor { + return md_EVMSchedulerParams +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_EVMSchedulerParams) Type() protoreflect.MessageType { + return _fastReflection_EVMSchedulerParams_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_EVMSchedulerParams) New() protoreflect.Message { + return new(fastReflection_EVMSchedulerParams) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_EVMSchedulerParams) Interface() protoreflect.ProtoMessage { + return (*EVMSchedulerParams)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_EVMSchedulerParams) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Enabled != false { + value := protoreflect.ValueOfBool(x.Enabled) + if !f(fd_EVMSchedulerParams_enabled, value) { + return + } + } + if x.TargetContract != "" { + value := protoreflect.ValueOfString(x.TargetContract) + if !f(fd_EVMSchedulerParams_target_contract, value) { + return + } + } + if x.GasCap != uint64(0) { + value := protoreflect.ValueOfUint64(x.GasCap) + if !f(fd_EVMSchedulerParams_gas_cap, value) { + return + } + } + if x.MaxOps != uint32(0) { + value := protoreflect.ValueOfUint32(x.MaxOps) + if !f(fd_EVMSchedulerParams_max_ops, value) { + return + } + } + if x.CadenceBlocks != uint64(0) { + value := protoreflect.ValueOfUint64(x.CadenceBlocks) + if !f(fd_EVMSchedulerParams_cadence_blocks, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_EVMSchedulerParams) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.vm.v1.EVMSchedulerParams.enabled": + return x.Enabled != false + case "cosmos.evm.vm.v1.EVMSchedulerParams.target_contract": + return x.TargetContract != "" + case "cosmos.evm.vm.v1.EVMSchedulerParams.gas_cap": + return x.GasCap != uint64(0) + case "cosmos.evm.vm.v1.EVMSchedulerParams.max_ops": + return x.MaxOps != uint32(0) + case "cosmos.evm.vm.v1.EVMSchedulerParams.cadence_blocks": + return x.CadenceBlocks != uint64(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.EVMSchedulerParams")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.EVMSchedulerParams does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_EVMSchedulerParams) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.vm.v1.EVMSchedulerParams.enabled": + x.Enabled = false + case "cosmos.evm.vm.v1.EVMSchedulerParams.target_contract": + x.TargetContract = "" + case "cosmos.evm.vm.v1.EVMSchedulerParams.gas_cap": + x.GasCap = uint64(0) + case "cosmos.evm.vm.v1.EVMSchedulerParams.max_ops": + x.MaxOps = uint32(0) + case "cosmos.evm.vm.v1.EVMSchedulerParams.cadence_blocks": + x.CadenceBlocks = uint64(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.EVMSchedulerParams")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.EVMSchedulerParams does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_EVMSchedulerParams) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.vm.v1.EVMSchedulerParams.enabled": + value := x.Enabled + return protoreflect.ValueOfBool(value) + case "cosmos.evm.vm.v1.EVMSchedulerParams.target_contract": + value := x.TargetContract + return protoreflect.ValueOfString(value) + case "cosmos.evm.vm.v1.EVMSchedulerParams.gas_cap": + value := x.GasCap + return protoreflect.ValueOfUint64(value) + case "cosmos.evm.vm.v1.EVMSchedulerParams.max_ops": + value := x.MaxOps + return protoreflect.ValueOfUint32(value) + case "cosmos.evm.vm.v1.EVMSchedulerParams.cadence_blocks": + value := x.CadenceBlocks + return protoreflect.ValueOfUint64(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.EVMSchedulerParams")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.EVMSchedulerParams does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_EVMSchedulerParams) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.vm.v1.EVMSchedulerParams.enabled": + x.Enabled = value.Bool() + case "cosmos.evm.vm.v1.EVMSchedulerParams.target_contract": + x.TargetContract = value.Interface().(string) + case "cosmos.evm.vm.v1.EVMSchedulerParams.gas_cap": + x.GasCap = value.Uint() + case "cosmos.evm.vm.v1.EVMSchedulerParams.max_ops": + x.MaxOps = uint32(value.Uint()) + case "cosmos.evm.vm.v1.EVMSchedulerParams.cadence_blocks": + x.CadenceBlocks = value.Uint() + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.EVMSchedulerParams")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.EVMSchedulerParams does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_EVMSchedulerParams) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.vm.v1.EVMSchedulerParams.enabled": + panic(fmt.Errorf("field enabled of message cosmos.evm.vm.v1.EVMSchedulerParams is not mutable")) + case "cosmos.evm.vm.v1.EVMSchedulerParams.target_contract": + panic(fmt.Errorf("field target_contract of message cosmos.evm.vm.v1.EVMSchedulerParams is not mutable")) + case "cosmos.evm.vm.v1.EVMSchedulerParams.gas_cap": + panic(fmt.Errorf("field gas_cap of message cosmos.evm.vm.v1.EVMSchedulerParams is not mutable")) + case "cosmos.evm.vm.v1.EVMSchedulerParams.max_ops": + panic(fmt.Errorf("field max_ops of message cosmos.evm.vm.v1.EVMSchedulerParams is not mutable")) + case "cosmos.evm.vm.v1.EVMSchedulerParams.cadence_blocks": + panic(fmt.Errorf("field cadence_blocks of message cosmos.evm.vm.v1.EVMSchedulerParams is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.EVMSchedulerParams")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.EVMSchedulerParams does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_EVMSchedulerParams) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.vm.v1.EVMSchedulerParams.enabled": + return protoreflect.ValueOfBool(false) + case "cosmos.evm.vm.v1.EVMSchedulerParams.target_contract": + return protoreflect.ValueOfString("") + case "cosmos.evm.vm.v1.EVMSchedulerParams.gas_cap": + return protoreflect.ValueOfUint64(uint64(0)) + case "cosmos.evm.vm.v1.EVMSchedulerParams.max_ops": + return protoreflect.ValueOfUint32(uint32(0)) + case "cosmos.evm.vm.v1.EVMSchedulerParams.cadence_blocks": + return protoreflect.ValueOfUint64(uint64(0)) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.EVMSchedulerParams")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.EVMSchedulerParams does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_EVMSchedulerParams) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.vm.v1.EVMSchedulerParams", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_EVMSchedulerParams) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_EVMSchedulerParams) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_EVMSchedulerParams) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_EVMSchedulerParams) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*EVMSchedulerParams) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Enabled { + n += 2 + } + l = len(x.TargetContract) if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } + if x.GasCap != 0 { + n += 1 + runtime.Sov(uint64(x.GasCap)) + } + if x.MaxOps != 0 { + n += 1 + runtime.Sov(uint64(x.MaxOps)) + } + if x.CadenceBlocks != 0 { + n += 1 + runtime.Sov(uint64(x.CadenceBlocks)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -1347,7 +1942,7 @@ func (x *fastReflection_ExtendedDenomOptions) ProtoMethods() *protoiface.Methods } marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { - x := input.Message.Interface().(*ExtendedDenomOptions) + x := input.Message.Interface().(*EVMSchedulerParams) if x == nil { return protoiface.MarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -1366,12 +1961,37 @@ func (x *fastReflection_ExtendedDenomOptions) ProtoMethods() *protoiface.Methods i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } - if len(x.ExtendedDenom) > 0 { - i -= len(x.ExtendedDenom) - copy(dAtA[i:], x.ExtendedDenom) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ExtendedDenom))) + if x.CadenceBlocks != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.CadenceBlocks)) i-- - dAtA[i] = 0xa + dAtA[i] = 0x28 + } + if x.MaxOps != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.MaxOps)) + i-- + dAtA[i] = 0x20 + } + if x.GasCap != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.GasCap)) + i-- + dAtA[i] = 0x18 + } + if len(x.TargetContract) > 0 { + i -= len(x.TargetContract) + copy(dAtA[i:], x.TargetContract) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.TargetContract))) + i-- + dAtA[i] = 0x12 + } + if x.Enabled { + i-- + if x.Enabled { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 } if input.Buf != nil { input.Buf = append(input.Buf, dAtA...) @@ -1384,7 +2004,7 @@ func (x *fastReflection_ExtendedDenomOptions) ProtoMethods() *protoiface.Methods }, nil } unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { - x := input.Message.Interface().(*ExtendedDenomOptions) + x := input.Message.Interface().(*EVMSchedulerParams) if x == nil { return protoiface.UnmarshalOutput{ NoUnkeyedLiterals: input.NoUnkeyedLiterals, @@ -1416,15 +2036,35 @@ func (x *fastReflection_ExtendedDenomOptions) ProtoMethods() *protoiface.Methods fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ExtendedDenomOptions: wiretype end group for non-group") + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: EVMSchedulerParams: wiretype end group for non-group") } if fieldNum <= 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ExtendedDenomOptions: illegal tag %d (wire type %d)", fieldNum, wire) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: EVMSchedulerParams: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.Enabled = bool(v != 0) + case 2: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExtendedDenom", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field TargetContract", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1452,8 +2092,65 @@ func (x *fastReflection_ExtendedDenomOptions) ProtoMethods() *protoiface.Methods if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.ExtendedDenom = string(dAtA[iNdEx:postIndex]) + x.TargetContract = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field GasCap", wireType) + } + x.GasCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.GasCap |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field MaxOps", wireType) + } + x.MaxOps = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.MaxOps |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CadenceBlocks", wireType) + } + x.CadenceBlocks = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.CadenceBlocks |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -1511,7 +2208,7 @@ func (x *AccessControl) ProtoReflect() protoreflect.Message { } func (x *AccessControl) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[2] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2071,7 +2768,7 @@ func (x *AccessControlType) ProtoReflect() protoreflect.Message { } func (x *AccessControlType) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[3] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2597,7 +3294,7 @@ func (x *ChainConfig) ProtoReflect() protoreflect.Message { } func (x *ChainConfig) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[4] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4427,7 +5124,7 @@ func (x *State) ProtoReflect() protoreflect.Message { } func (x *State) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[5] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4962,7 +5659,7 @@ func (x *TransactionLogs) ProtoReflect() protoreflect.Message { } func (x *TransactionLogs) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[6] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5531,7 +6228,7 @@ func (x *Log) ProtoReflect() protoreflect.Message { } func (x *Log) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[7] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6461,7 +7158,7 @@ func (x *TxResult) ProtoReflect() protoreflect.Message { } func (x *TxResult) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[8] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7232,7 +7929,7 @@ func (x *AccessTuple) ProtoReflect() protoreflect.Message { } func (x *AccessTuple) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[9] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7748,7 +8445,7 @@ func (x *TraceConfig) ProtoReflect() protoreflect.Message { } func (x *TraceConfig) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[10] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8725,7 +9422,7 @@ func (x *Preinstall) ProtoReflect() protoreflect.Message { } func (x *Preinstall) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[11] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9275,7 +9972,7 @@ func (x *EvmCoinInfo) ProtoReflect() protoreflect.Message { } func (x *EvmCoinInfo) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[12] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9931,6 +10628,9 @@ type Params struct { ActiveStaticPrecompiles []string `protobuf:"bytes,9,rep,name=active_static_precompiles,json=activeStaticPrecompiles,proto3" json:"active_static_precompiles,omitempty"` HistoryServeWindow uint64 `protobuf:"varint,10,opt,name=history_serve_window,json=historyServeWindow,proto3" json:"history_serve_window,omitempty"` ExtendedDenomOptions *ExtendedDenomOptions `protobuf:"bytes,11,opt,name=extended_denom_options,json=extendedDenomOptions,proto3" json:"extended_denom_options,omitempty"` + // scheduler defines an optional bounded EndBlock EVM call used for + // contract-owned maintenance such as vault settlement. + Scheduler *EVMSchedulerParams `protobuf:"bytes,12,opt,name=scheduler,proto3" json:"scheduler,omitempty"` } func (x *Params) Reset() { @@ -10002,6 +10702,13 @@ func (x *Params) GetExtendedDenomOptions() *ExtendedDenomOptions { return nil } +func (x *Params) GetScheduler() *EVMSchedulerParams { + if x != nil { + return x.Scheduler + } + return nil +} + type ExtendedDenomOptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -10037,6 +10744,78 @@ func (x *ExtendedDenomOptions) GetExtendedDenom() string { return "" } +type EVMSchedulerParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // enabled controls whether EndBlock attempts the configured call. + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + // target_contract is the EVM contract called with poke(uint256). + TargetContract string `protobuf:"bytes,2,opt,name=target_contract,json=targetContract,proto3" json:"target_contract,omitempty"` + // gas_cap is the EVM gas limit for the scheduler call. + GasCap uint64 `protobuf:"varint,3,opt,name=gas_cap,json=gasCap,proto3" json:"gas_cap,omitempty"` + // max_ops is passed as the poke(uint256) argument. + MaxOps uint32 `protobuf:"varint,4,opt,name=max_ops,json=maxOps,proto3" json:"max_ops,omitempty"` + // cadence_blocks runs the call only when block_height % cadence_blocks == 0. + CadenceBlocks uint64 `protobuf:"varint,5,opt,name=cadence_blocks,json=cadenceBlocks,proto3" json:"cadence_blocks,omitempty"` +} + +func (x *EVMSchedulerParams) Reset() { + *x = EVMSchedulerParams{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EVMSchedulerParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EVMSchedulerParams) ProtoMessage() {} + +// Deprecated: Use EVMSchedulerParams.ProtoReflect.Descriptor instead. +func (*EVMSchedulerParams) Descriptor() ([]byte, []int) { + return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{2} +} + +func (x *EVMSchedulerParams) GetEnabled() bool { + if x != nil { + return x.Enabled + } + return false +} + +func (x *EVMSchedulerParams) GetTargetContract() string { + if x != nil { + return x.TargetContract + } + return "" +} + +func (x *EVMSchedulerParams) GetGasCap() uint64 { + if x != nil { + return x.GasCap + } + return 0 +} + +func (x *EVMSchedulerParams) GetMaxOps() uint32 { + if x != nil { + return x.MaxOps + } + return 0 +} + +func (x *EVMSchedulerParams) GetCadenceBlocks() uint64 { + if x != nil { + return x.CadenceBlocks + } + return 0 +} + // AccessControl defines the permission policy of the EVM // for creating and calling contracts type AccessControl struct { @@ -10053,7 +10832,7 @@ type AccessControl struct { func (x *AccessControl) Reset() { *x = AccessControl{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[2] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10067,7 +10846,7 @@ func (*AccessControl) ProtoMessage() {} // Deprecated: Use AccessControl.ProtoReflect.Descriptor instead. func (*AccessControl) Descriptor() ([]byte, []int) { - return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{2} + return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{3} } func (x *AccessControl) GetCreate() *AccessControlType { @@ -10105,7 +10884,7 @@ type AccessControlType struct { func (x *AccessControlType) Reset() { *x = AccessControlType{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[3] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10119,7 +10898,7 @@ func (*AccessControlType) ProtoMessage() {} // Deprecated: Use AccessControlType.ProtoReflect.Descriptor instead. func (*AccessControlType) Descriptor() ([]byte, []int) { - return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{3} + return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{4} } func (x *AccessControlType) GetAccessType() AccessType { @@ -10206,7 +10985,7 @@ type ChainConfig struct { func (x *ChainConfig) Reset() { *x = ChainConfig{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[4] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10220,7 +10999,7 @@ func (*ChainConfig) ProtoMessage() {} // Deprecated: Use ChainConfig.ProtoReflect.Descriptor instead. func (*ChainConfig) Descriptor() ([]byte, []int) { - return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{4} + return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{5} } func (x *ChainConfig) GetHomesteadBlock() string { @@ -10406,7 +11185,7 @@ type State struct { func (x *State) Reset() { *x = State{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[5] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10420,7 +11199,7 @@ func (*State) ProtoMessage() {} // Deprecated: Use State.ProtoReflect.Descriptor instead. func (*State) Descriptor() ([]byte, []int) { - return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{5} + return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{6} } func (x *State) GetKey() string { @@ -10454,7 +11233,7 @@ type TransactionLogs struct { func (x *TransactionLogs) Reset() { *x = TransactionLogs{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[6] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10468,7 +11247,7 @@ func (*TransactionLogs) ProtoMessage() {} // Deprecated: Use TransactionLogs.ProtoReflect.Descriptor instead. func (*TransactionLogs) Descriptor() ([]byte, []int) { - return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{6} + return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{7} } func (x *TransactionLogs) GetHash() string { @@ -10523,7 +11302,7 @@ type Log struct { func (x *Log) Reset() { *x = Log{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[7] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10537,7 +11316,7 @@ func (*Log) ProtoMessage() {} // Deprecated: Use Log.ProtoReflect.Descriptor instead. func (*Log) Descriptor() ([]byte, []int) { - return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{7} + return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{8} } func (x *Log) GetAddress() string { @@ -10636,7 +11415,7 @@ type TxResult struct { func (x *TxResult) Reset() { *x = TxResult{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[8] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10650,7 +11429,7 @@ func (*TxResult) ProtoMessage() {} // Deprecated: Use TxResult.ProtoReflect.Descriptor instead. func (*TxResult) Descriptor() ([]byte, []int) { - return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{8} + return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{9} } func (x *TxResult) GetContractAddress() string { @@ -10710,7 +11489,7 @@ type AccessTuple struct { func (x *AccessTuple) Reset() { *x = AccessTuple{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[9] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10724,7 +11503,7 @@ func (*AccessTuple) ProtoMessage() {} // Deprecated: Use AccessTuple.ProtoReflect.Descriptor instead. func (*AccessTuple) Descriptor() ([]byte, []int) { - return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{9} + return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{10} } func (x *AccessTuple) GetAddress() string { @@ -10775,7 +11554,7 @@ type TraceConfig struct { func (x *TraceConfig) Reset() { *x = TraceConfig{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[10] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10789,7 +11568,7 @@ func (*TraceConfig) ProtoMessage() {} // Deprecated: Use TraceConfig.ProtoReflect.Descriptor instead. func (*TraceConfig) Descriptor() ([]byte, []int) { - return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{10} + return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{11} } func (x *TraceConfig) GetTracer() string { @@ -10887,7 +11666,7 @@ type Preinstall struct { func (x *Preinstall) Reset() { *x = Preinstall{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[11] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10901,7 +11680,7 @@ func (*Preinstall) ProtoMessage() {} // Deprecated: Use Preinstall.ProtoReflect.Descriptor instead. func (*Preinstall) Descriptor() ([]byte, []int) { - return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{11} + return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{12} } func (x *Preinstall) GetName() string { @@ -10939,7 +11718,7 @@ type EvmCoinInfo struct { func (x *EvmCoinInfo) Reset() { *x = EvmCoinInfo{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[12] + mi := &file_cosmos_evm_vm_v1_evm_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10953,7 +11732,7 @@ func (*EvmCoinInfo) ProtoMessage() {} // Deprecated: Use EvmCoinInfo.ProtoReflect.Descriptor instead. func (*EvmCoinInfo) Descriptor() ([]byte, []int) { - return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{12} + return file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP(), []int{13} } func (x *EvmCoinInfo) GetDenom() string { @@ -10992,7 +11771,7 @@ var file_cosmos_evm_vm_v1_evm_proto_rawDesc = []byte{ 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, - 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x92, 0x04, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, + 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe1, 0x04, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x31, 0x0a, 0x09, 0x65, 0x76, 0x6d, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x14, 0xf2, 0xde, 0x1f, 0x10, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x65, 0x76, 0x6d, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x22, 0x52, 0x08, 0x65, 0x76, 0x6d, @@ -11022,296 +11801,312 @@ var file_cosmos_evm_vm_v1_evm_proto_rawDesc = []byte{ 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x14, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x44, 0x65, 0x6e, 0x6f, 0x6d, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x1b, 0x8a, 0xe7, 0xb0, 0x2a, 0x16, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x78, 0x2f, 0x76, 0x6d, 0x2f, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, - 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x22, 0x3d, 0x0a, 0x14, - 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, - 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, - 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x22, 0x91, 0x01, 0x0a, 0x0d, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x41, 0x0a, - 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, - 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x54, 0x79, - 0x70, 0x65, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x12, 0x3d, 0x0a, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, - 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, - 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x54, - 0x79, 0x70, 0x65, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x22, - 0xdd, 0x01, 0x0a, 0x11, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x63, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x42, 0x24, 0xe2, 0xde, 0x1f, 0x0a, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0xf2, 0xde, 0x1f, 0x12, 0x79, 0x61, 0x6d, 0x6c, - 0x3a, 0x22, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x52, 0x0a, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x63, 0x0a, 0x13, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x6c, 0x69, 0x73, - 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0x33, 0xe2, 0xde, 0x1f, 0x11, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0xf2, 0xde, - 0x1f, 0x1a, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x52, 0x11, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x22, - 0xa8, 0x10, 0x0a, 0x0b, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x5c, 0x0a, 0x0f, 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4d, 0x0a, 0x09, 0x73, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x56, + 0x4d, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x09, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x3a, 0x1b, 0x8a, 0xe7, 0xb0, 0x2a, 0x16, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x78, 0x2f, 0x76, 0x6d, 0x2f, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, + 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x22, 0x3d, 0x0a, 0x14, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x5f, + 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x64, 0x65, 0x64, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x22, 0xb0, 0x01, 0x0a, 0x12, 0x45, + 0x56, 0x4d, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x67, 0x61, 0x73, 0x5f, 0x63, 0x61, 0x70, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x67, 0x61, 0x73, 0x43, 0x61, 0x70, 0x12, 0x17, 0x0a, + 0x07, 0x6d, 0x61, 0x78, 0x5f, 0x6f, 0x70, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, + 0x6d, 0x61, 0x78, 0x4f, 0x70, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x61, 0x64, 0x65, 0x6e, 0x63, + 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, + 0x63, 0x61, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x22, 0x91, 0x01, + 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, + 0x41, 0x0a, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x54, 0x79, 0x70, 0x65, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x12, 0x3d, 0x0a, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x54, 0x79, 0x70, 0x65, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x04, 0x63, 0x61, 0x6c, + 0x6c, 0x22, 0xdd, 0x01, 0x0a, 0x11, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x63, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x42, 0x24, 0xe2, 0xde, 0x1f, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0xf2, 0xde, 0x1f, 0x12, 0x79, 0x61, + 0x6d, 0x6c, 0x3a, 0x22, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, + 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x63, 0x0a, 0x13, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x6c, + 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0x33, 0xe2, 0xde, 0x1f, 0x11, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x4c, 0x69, 0x73, 0x74, + 0xf2, 0xde, 0x1f, 0x1a, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x52, 0x11, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x4c, 0x69, 0x73, + 0x74, 0x22, 0xa8, 0x10, 0x0a, 0x0b, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x5c, 0x0a, 0x0f, 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x61, 0x64, 0x5f, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xda, 0xde, 0x1f, 0x15, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, + 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x16, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x68, + 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, + 0x0e, 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, + 0x68, 0x0a, 0x0e, 0x64, 0x61, 0x6f, 0x5f, 0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x42, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, + 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x0c, 0x44, 0x41, 0x4f, 0x46, 0x6f, 0x72, 0x6b, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0xf2, 0xde, 0x1f, 0x15, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x64, 0x61, 0x6f, 0x5f, + 0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0c, 0x64, 0x61, 0x6f, + 0x46, 0x6f, 0x72, 0x6b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x57, 0x0a, 0x10, 0x64, 0x61, 0x6f, + 0x5f, 0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x42, 0x2d, 0xe2, 0xde, 0x1f, 0x0e, 0x44, 0x41, 0x4f, 0x46, 0x6f, 0x72, 0x6b, + 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0xf2, 0xde, 0x1f, 0x17, 0x79, 0x61, 0x6d, 0x6c, 0x3a, + 0x22, 0x64, 0x61, 0x6f, 0x5f, 0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x22, 0x52, 0x0e, 0x64, 0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x53, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x12, 0x62, 0x0a, 0x0c, 0x65, 0x69, 0x70, 0x31, 0x35, 0x30, 0x5f, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3f, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, - 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x16, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x68, 0x6f, 0x6d, - 0x65, 0x73, 0x74, 0x65, 0x61, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0e, 0x68, - 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x68, 0x0a, - 0x0e, 0x64, 0x61, 0x6f, 0x5f, 0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x42, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, - 0xe2, 0xde, 0x1f, 0x0c, 0x44, 0x41, 0x4f, 0x46, 0x6f, 0x72, 0x6b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0xf2, 0xde, 0x1f, 0x15, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x64, 0x61, 0x6f, 0x5f, 0x66, 0x6f, - 0x72, 0x6b, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0c, 0x64, 0x61, 0x6f, 0x46, 0x6f, - 0x72, 0x6b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x57, 0x0a, 0x10, 0x64, 0x61, 0x6f, 0x5f, 0x66, - 0x6f, 0x72, 0x6b, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x42, 0x2d, 0xe2, 0xde, 0x1f, 0x0e, 0x44, 0x41, 0x4f, 0x46, 0x6f, 0x72, 0x6b, 0x53, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0xf2, 0xde, 0x1f, 0x17, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x64, - 0x61, 0x6f, 0x5f, 0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x22, - 0x52, 0x0e, 0x64, 0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x12, 0x62, 0x0a, 0x0c, 0x65, 0x69, 0x70, 0x31, 0x35, 0x30, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3f, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, + 0x49, 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x0b, 0x45, 0x49, 0x50, 0x31, 0x35, 0x30, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0xf2, 0xde, 0x1f, 0x13, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x65, 0x69, 0x70, 0x31, + 0x35, 0x30, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0b, 0x65, 0x69, 0x70, 0x31, 0x35, + 0x30, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x62, 0x0a, 0x0c, 0x65, 0x69, 0x70, 0x31, 0x35, 0x35, + 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3f, 0xda, 0xde, + 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, + 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x0b, 0x45, 0x49, 0x50, 0x31, 0x35, + 0x35, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0xf2, 0xde, 0x1f, 0x13, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, + 0x65, 0x69, 0x70, 0x31, 0x35, 0x35, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0b, 0x65, + 0x69, 0x70, 0x31, 0x35, 0x35, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x62, 0x0a, 0x0c, 0x65, 0x69, + 0x70, 0x31, 0x35, 0x38, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x3f, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, + 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x0b, 0x45, + 0x49, 0x50, 0x31, 0x35, 0x38, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0xf2, 0xde, 0x1f, 0x13, 0x79, 0x61, + 0x6d, 0x6c, 0x3a, 0x22, 0x65, 0x69, 0x70, 0x31, 0x35, 0x38, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x22, 0x52, 0x0b, 0x65, 0x69, 0x70, 0x31, 0x35, 0x38, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x5c, + 0x0a, 0x0f, 0x62, 0x79, 0x7a, 0x61, 0x6e, 0x74, 0x69, 0x75, 0x6d, 0x5f, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, + 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x16, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x62, 0x79, 0x7a, 0x61, + 0x6e, 0x74, 0x69, 0x75, 0x6d, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0e, 0x62, 0x79, + 0x7a, 0x61, 0x6e, 0x74, 0x69, 0x75, 0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x6b, 0x0a, 0x14, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x70, 0x6c, 0x65, 0x5f, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xda, 0xde, 0x1f, 0x15, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, + 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x1b, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x70, 0x6c, 0x65, 0x5f, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x13, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, + 0x6f, 0x70, 0x6c, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x5f, 0x0a, 0x10, 0x70, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x62, 0x75, 0x72, 0x67, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x34, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, + 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, + 0x1f, 0x17, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x70, 0x65, 0x74, 0x65, 0x72, 0x73, 0x62, 0x75, + 0x72, 0x67, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0f, 0x70, 0x65, 0x74, 0x65, 0x72, + 0x73, 0x62, 0x75, 0x72, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x59, 0x0a, 0x0e, 0x69, 0x73, + 0x74, 0x61, 0x6e, 0x62, 0x75, 0x6c, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x32, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, + 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, + 0x15, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x6c, 0x5f, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0d, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x6c, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x64, 0x0a, 0x12, 0x6d, 0x75, 0x69, 0x72, 0x5f, 0x67, 0x6c, + 0x61, 0x63, 0x69, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x36, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, + 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x19, + 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x6d, 0x75, 0x69, 0x72, 0x5f, 0x67, 0x6c, 0x61, 0x63, 0x69, + 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x10, 0x6d, 0x75, 0x69, 0x72, 0x47, + 0x6c, 0x61, 0x63, 0x69, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x53, 0x0a, 0x0c, 0x62, + 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x30, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, + 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x13, + 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x62, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x22, 0x52, 0x0b, 0x62, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x12, 0x53, 0x0a, 0x0c, 0x6c, 0x6f, 0x6e, 0x64, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x42, 0x30, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, - 0x74, 0xe2, 0xde, 0x1f, 0x0b, 0x45, 0x49, 0x50, 0x31, 0x35, 0x30, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0xf2, 0xde, 0x1f, 0x13, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x65, 0x69, 0x70, 0x31, 0x35, 0x30, - 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0b, 0x65, 0x69, 0x70, 0x31, 0x35, 0x30, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x62, 0x0a, 0x0c, 0x65, 0x69, 0x70, 0x31, 0x35, 0x35, 0x5f, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3f, 0xda, 0xde, 0x1f, 0x15, + 0x74, 0xf2, 0xde, 0x1f, 0x13, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x6c, 0x6f, 0x6e, 0x64, 0x6f, + 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0b, 0x6c, 0x6f, 0x6e, 0x64, 0x6f, 0x6e, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x67, 0x0a, 0x13, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x5f, 0x67, + 0x6c, 0x61, 0x63, 0x69, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x12, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x37, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, + 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, + 0x1a, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x5f, 0x67, 0x6c, 0x61, + 0x63, 0x69, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x11, 0x61, 0x72, 0x72, + 0x6f, 0x77, 0x47, 0x6c, 0x61, 0x63, 0x69, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x64, + 0x0a, 0x12, 0x67, 0x72, 0x61, 0x79, 0x5f, 0x67, 0x6c, 0x61, 0x63, 0x69, 0x65, 0x72, 0x5f, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x42, 0x36, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, - 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x0b, 0x45, 0x49, 0x50, 0x31, 0x35, 0x35, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0xf2, 0xde, 0x1f, 0x13, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x65, 0x69, - 0x70, 0x31, 0x35, 0x35, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0b, 0x65, 0x69, 0x70, - 0x31, 0x35, 0x35, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x62, 0x0a, 0x0c, 0x65, 0x69, 0x70, 0x31, - 0x35, 0x38, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3f, - 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, - 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x0b, 0x45, 0x49, 0x50, - 0x31, 0x35, 0x38, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0xf2, 0xde, 0x1f, 0x13, 0x79, 0x61, 0x6d, 0x6c, - 0x3a, 0x22, 0x65, 0x69, 0x70, 0x31, 0x35, 0x38, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, - 0x0b, 0x65, 0x69, 0x70, 0x31, 0x35, 0x38, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x5c, 0x0a, 0x0f, - 0x62, 0x79, 0x7a, 0x61, 0x6e, 0x74, 0x69, 0x75, 0x6d, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, - 0xf2, 0xde, 0x1f, 0x16, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x62, 0x79, 0x7a, 0x61, 0x6e, 0x74, - 0x69, 0x75, 0x6d, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0e, 0x62, 0x79, 0x7a, 0x61, - 0x6e, 0x74, 0x69, 0x75, 0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x6b, 0x0a, 0x14, 0x63, 0x6f, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x70, 0x6c, 0x65, 0x5f, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, - 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x1b, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x63, 0x6f, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x70, 0x6c, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x22, 0x52, 0x13, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x70, - 0x6c, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x5f, 0x0a, 0x10, 0x70, 0x65, 0x74, 0x65, 0x72, - 0x73, 0x62, 0x75, 0x72, 0x67, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x34, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, - 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x17, - 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x70, 0x65, 0x74, 0x65, 0x72, 0x73, 0x62, 0x75, 0x72, 0x67, - 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0f, 0x70, 0x65, 0x74, 0x65, 0x72, 0x73, 0x62, - 0x75, 0x72, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x59, 0x0a, 0x0e, 0x69, 0x73, 0x74, 0x61, - 0x6e, 0x62, 0x75, 0x6c, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x32, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, - 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x15, 0x79, - 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x6c, 0x5f, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0d, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x6c, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x12, 0x64, 0x0a, 0x12, 0x6d, 0x75, 0x69, 0x72, 0x5f, 0x67, 0x6c, 0x61, 0x63, - 0x69, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x36, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, - 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x19, 0x79, 0x61, - 0x6d, 0x6c, 0x3a, 0x22, 0x6d, 0x75, 0x69, 0x72, 0x5f, 0x67, 0x6c, 0x61, 0x63, 0x69, 0x65, 0x72, - 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x10, 0x6d, 0x75, 0x69, 0x72, 0x47, 0x6c, 0x61, - 0x63, 0x69, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x53, 0x0a, 0x0c, 0x62, 0x65, 0x72, - 0x6c, 0x69, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x30, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, - 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x13, 0x79, 0x61, - 0x6d, 0x6c, 0x3a, 0x22, 0x62, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x22, 0x52, 0x0b, 0x62, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x53, - 0x0a, 0x0c, 0x6c, 0x6f, 0x6e, 0x64, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x11, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x30, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, - 0xde, 0x1f, 0x13, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x6c, 0x6f, 0x6e, 0x64, 0x6f, 0x6e, 0x5f, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x0b, 0x6c, 0x6f, 0x6e, 0x64, 0x6f, 0x6e, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x12, 0x67, 0x0a, 0x13, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x5f, 0x67, 0x6c, 0x61, - 0x63, 0x69, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x37, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, - 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x1a, 0x79, - 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x5f, 0x67, 0x6c, 0x61, 0x63, 0x69, - 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x11, 0x61, 0x72, 0x72, 0x6f, 0x77, - 0x47, 0x6c, 0x61, 0x63, 0x69, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x64, 0x0a, 0x12, - 0x67, 0x72, 0x61, 0x79, 0x5f, 0x67, 0x6c, 0x61, 0x63, 0x69, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x42, 0x36, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, - 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x19, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x67, 0x72, 0x61, - 0x79, 0x5f, 0x67, 0x6c, 0x61, 0x63, 0x69, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, - 0x52, 0x10, 0x67, 0x72, 0x61, 0x79, 0x47, 0x6c, 0x61, 0x63, 0x69, 0x65, 0x72, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x12, 0x6a, 0x0a, 0x14, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x5f, 0x6e, 0x65, 0x74, 0x73, - 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x38, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, - 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x1b, 0x79, - 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x5f, 0x6e, 0x65, 0x74, 0x73, 0x70, - 0x6c, 0x69, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x12, 0x6d, 0x65, 0x72, 0x67, - 0x65, 0x4e, 0x65, 0x74, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x19, - 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x18, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6e, - 0x6f, 0x6d, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x12, - 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x18, 0x1a, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x12, 0x56, 0x0a, 0x0d, 0x73, - 0x68, 0x61, 0x6e, 0x67, 0x68, 0x61, 0x69, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1b, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x31, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, + 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x19, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x67, + 0x72, 0x61, 0x79, 0x5f, 0x67, 0x6c, 0x61, 0x63, 0x69, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x22, 0x52, 0x10, 0x67, 0x72, 0x61, 0x79, 0x47, 0x6c, 0x61, 0x63, 0x69, 0x65, 0x72, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x6a, 0x0a, 0x14, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x5f, 0x6e, 0x65, + 0x74, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x15, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x38, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, - 0x14, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x73, 0x68, 0x61, 0x6e, 0x67, 0x68, 0x61, 0x69, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x6e, 0x67, 0x68, 0x61, 0x69, 0x54, - 0x69, 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x0b, 0x63, 0x61, 0x6e, 0x63, 0x75, 0x6e, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, - 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x12, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x63, 0x61, 0x6e, - 0x63, 0x75, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, 0x0a, 0x63, 0x61, 0x6e, 0x63, 0x75, - 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x0b, 0x70, 0x72, 0x61, 0x67, 0x75, 0x65, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xda, 0xde, 0x1f, 0x15, + 0x1b, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x5f, 0x6e, 0x65, 0x74, + 0x73, 0x70, 0x6c, 0x69, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x52, 0x12, 0x6d, 0x65, + 0x72, 0x67, 0x65, 0x4e, 0x65, 0x74, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x18, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x64, + 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x65, 0x6e, 0x6f, + 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x18, 0x1a, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x12, 0x56, 0x0a, + 0x0d, 0x73, 0x68, 0x61, 0x6e, 0x67, 0x68, 0x61, 0x69, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1b, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x31, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, + 0xde, 0x1f, 0x14, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x73, 0x68, 0x61, 0x6e, 0x67, 0x68, 0x61, + 0x69, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x6e, 0x67, 0x68, 0x61, + 0x69, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x0b, 0x63, 0x61, 0x6e, 0x63, 0x75, 0x6e, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, - 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x12, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x70, - 0x72, 0x61, 0x67, 0x75, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, 0x0a, 0x70, 0x72, 0x61, - 0x67, 0x75, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x0b, 0x76, 0x65, 0x72, 0x6b, 0x6c, - 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xda, 0xde, + 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x12, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x63, + 0x61, 0x6e, 0x63, 0x75, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, 0x0a, 0x63, 0x61, 0x6e, + 0x63, 0x75, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x0b, 0x70, 0x72, 0x61, 0x67, 0x75, + 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x12, 0x79, 0x61, 0x6d, 0x6c, 0x3a, - 0x22, 0x76, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, 0x0a, 0x76, - 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x6f, 0x73, 0x61, - 0x6b, 0x61, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2e, 0xda, - 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, - 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x11, 0x79, 0x61, 0x6d, 0x6c, - 0x3a, 0x22, 0x6f, 0x73, 0x61, 0x6b, 0x61, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, 0x09, 0x6f, - 0x73, 0x61, 0x6b, 0x61, 0x54, 0x69, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, - 0x08, 0x16, 0x10, 0x17, 0x4a, 0x04, 0x08, 0x17, 0x10, 0x18, 0x22, 0x2f, 0x0a, 0x05, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x50, 0x0a, 0x0f, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x12, - 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, - 0x73, 0x68, 0x12, 0x29, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0x87, 0x03, - 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x0c, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x04, 0x42, 0x0f, 0xea, 0xde, 0x1f, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, - 0x2c, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x13, 0xea, 0xde, 0x1f, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2f, 0x0a, - 0x08, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x42, - 0x14, 0xea, 0xde, 0x1f, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2c, - 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x0d, 0xea, 0xde, 0x1f, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, - 0x68, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x22, 0x0a, 0x05, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0c, 0xea, 0xde, 0x1f, - 0x08, 0x6c, 0x6f, 0x67, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x0f, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x04, 0x42, 0x12, 0xea, 0xde, 0x1f, 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x90, 0x02, 0x0a, 0x08, 0x54, 0x78, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x12, 0x46, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1b, - 0xf2, 0xde, 0x1f, 0x17, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x63, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x52, 0x0f, 0x63, 0x6f, 0x6e, - 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, - 0x62, 0x6c, 0x6f, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6f, - 0x6f, 0x6d, 0x12, 0x57, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, - 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x1b, 0xc8, 0xde, 0x1f, 0x00, 0xf2, 0xde, 0x1f, 0x0e, - 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x74, 0x78, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0xa8, 0xe7, - 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x74, 0x78, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x72, - 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72, 0x65, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, - 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, - 0x55, 0x73, 0x65, 0x64, 0x3a, 0x04, 0x88, 0xa0, 0x1f, 0x00, 0x22, 0x61, 0x0a, 0x0b, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x32, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6b, - 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0f, 0xea, 0xde, 0x1f, 0x0b, 0x73, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, - 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x3a, 0x04, 0x88, 0xa0, 0x1f, 0x00, 0x22, 0xa0, 0x04, - 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x0a, - 0x06, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, - 0x16, 0x0a, 0x06, 0x72, 0x65, 0x65, 0x78, 0x65, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x06, 0x72, 0x65, 0x65, 0x78, 0x65, 0x63, 0x12, 0x35, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x42, 0x10, - 0xea, 0xde, 0x1f, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x63, 0x6b, - 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x3b, - 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x42, 0x12, 0xea, 0xde, 0x1f, 0x0e, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x0e, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, - 0x65, 0x62, 0x75, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x64, 0x65, 0x62, 0x75, - 0x67, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x3b, 0x0a, 0x09, 0x6f, 0x76, 0x65, 0x72, 0x72, - 0x69, 0x64, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, - 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x09, 0x6f, 0x76, 0x65, 0x72, 0x72, - 0x69, 0x64, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, - 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x42, 0x10, 0xea, 0xde, 0x1f, - 0x0c, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x52, 0x0c, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x42, 0x0a, 0x12, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x42, 0x14, 0xea, 0xde, 0x1f, 0x10, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x10, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, - 0x3e, 0x0a, 0x12, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xea, 0xde, 0x1f, - 0x0c, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, - 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x52, 0x0e, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x52, 0x13, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, - 0x22, 0x4e, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, - 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, - 0x22, 0x8b, 0x01, 0x0a, 0x0b, 0x45, 0x76, 0x6d, 0x43, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, - 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, - 0x65, 0x64, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x23, 0x0a, - 0x0d, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x44, 0x65, 0x6e, - 0x6f, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x2a, 0xc0, - 0x01, 0x0a, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3c, 0x0a, - 0x1a, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x45, 0x52, - 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x4c, 0x45, 0x53, 0x53, 0x10, 0x00, 0x1a, 0x1c, 0x8a, - 0x9d, 0x20, 0x18, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x6c, 0x65, 0x73, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x41, - 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x54, 0x52, - 0x49, 0x43, 0x54, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x18, 0x8a, 0x9d, 0x20, 0x14, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x65, - 0x64, 0x12, 0x38, 0x0a, 0x18, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x44, 0x10, 0x02, 0x1a, - 0x1a, 0x8a, 0x9d, 0x20, 0x16, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x50, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x1a, 0x04, 0x88, 0xa3, 0x1e, - 0x00, 0x42, 0xab, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x45, 0x76, 0x6d, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x26, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, - 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, - 0x65, 0x76, 0x6d, 0x2f, 0x76, 0x6d, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x6d, 0x76, 0x31, 0xa2, 0x02, - 0x03, 0x43, 0x45, 0x56, 0xaa, 0x02, 0x10, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x76, - 0x6d, 0x2e, 0x56, 0x6d, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x56, 0x6d, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x43, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x56, 0x6d, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, 0x56, 0x6d, 0x3a, 0x3a, 0x56, 0x31, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x22, 0x70, 0x72, 0x61, 0x67, 0x75, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, 0x0a, 0x70, + 0x72, 0x61, 0x67, 0x75, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x0b, 0x76, 0x65, 0x72, + 0x6b, 0x6c, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, + 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, + 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x12, 0x79, 0x61, 0x6d, + 0x6c, 0x3a, 0x22, 0x76, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, + 0x0a, 0x76, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x6f, + 0x73, 0x61, 0x6b, 0x61, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x2e, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, + 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xf2, 0xde, 0x1f, 0x11, 0x79, 0x61, + 0x6d, 0x6c, 0x3a, 0x22, 0x6f, 0x73, 0x61, 0x6b, 0x61, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, + 0x09, 0x6f, 0x73, 0x61, 0x6b, 0x61, 0x54, 0x69, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, + 0x4a, 0x04, 0x08, 0x16, 0x10, 0x17, 0x4a, 0x04, 0x08, 0x17, 0x10, 0x18, 0x22, 0x2f, 0x0a, 0x05, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x50, 0x0a, + 0x0f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x67, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x68, 0x61, 0x73, 0x68, 0x12, 0x29, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, + 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, + 0x87, 0x03, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, + 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x04, 0x42, 0x0f, 0xea, 0xde, 0x1f, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x12, 0x2c, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x13, 0xea, 0xde, 0x1f, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x48, 0x61, 0x73, 0x68, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, + 0x2f, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x04, 0x42, 0x14, 0xea, 0xde, 0x1f, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x12, 0x2c, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xea, 0xde, 0x1f, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, + 0x61, 0x73, 0x68, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x22, + 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0c, 0xea, + 0xde, 0x1f, 0x08, 0x6c, 0x6f, 0x67, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x05, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x0f, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x04, 0x42, 0x12, 0xea, 0xde, 0x1f, 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x90, 0x02, 0x0a, 0x08, 0x54, 0x78, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x46, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x63, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x1b, 0xf2, 0xde, 0x1f, 0x17, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x52, 0x0f, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, + 0x0a, 0x05, 0x62, 0x6c, 0x6f, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, + 0x6c, 0x6f, 0x6f, 0x6d, 0x12, 0x57, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, + 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x1b, 0xc8, 0xde, 0x1f, 0x00, 0xf2, 0xde, + 0x1f, 0x0e, 0x79, 0x61, 0x6d, 0x6c, 0x3a, 0x22, 0x74, 0x78, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x22, + 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x74, 0x78, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x10, 0x0a, + 0x03, 0x72, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72, 0x65, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x67, + 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, + 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x3a, 0x04, 0x88, 0xa0, 0x1f, 0x00, 0x22, 0x61, 0x0a, 0x0b, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x32, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0f, 0xea, 0xde, 0x1f, + 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x0b, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x3a, 0x04, 0x88, 0xa0, 0x1f, 0x00, 0x22, + 0xa0, 0x04, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x16, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x65, 0x78, 0x65, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x06, 0x72, 0x65, 0x65, 0x78, 0x65, 0x63, 0x12, 0x35, 0x0a, 0x0d, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x42, 0x10, 0xea, 0xde, 0x1f, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, + 0x63, 0x6b, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x63, 0x6b, + 0x12, 0x3b, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x42, 0x12, 0xea, 0xde, 0x1f, 0x0e, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x0e, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x64, 0x65, + 0x62, 0x75, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x3b, 0x0a, 0x09, 0x6f, 0x76, 0x65, + 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x09, 0x6f, 0x76, 0x65, + 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x42, 0x10, 0xea, + 0xde, 0x1f, 0x0c, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x52, + 0x0c, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x42, 0x0a, + 0x12, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x42, 0x14, 0xea, 0xde, 0x1f, 0x10, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, + 0x10, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x44, 0x61, 0x74, + 0x61, 0x12, 0x3e, 0x0a, 0x12, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, + 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xea, + 0xde, 0x1f, 0x0c, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x10, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x52, 0x0e, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x52, 0x13, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, + 0x74, 0x61, 0x22, 0x4e, 0x0a, 0x0a, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, + 0x64, 0x65, 0x22, 0x8b, 0x01, 0x0a, 0x0b, 0x45, 0x76, 0x6d, 0x43, 0x6f, 0x69, 0x6e, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x44, 0x65, 0x6e, 0x6f, 0x6d, 0x12, + 0x23, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x64, 0x65, 0x6e, 0x6f, 0x6d, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x44, + 0x65, 0x6e, 0x6f, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, + 0x2a, 0xc0, 0x01, 0x0a, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x3c, 0x0a, 0x1a, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, + 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x4c, 0x45, 0x53, 0x53, 0x10, 0x00, 0x1a, + 0x1c, 0x8a, 0x9d, 0x20, 0x18, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x50, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x6c, 0x65, 0x73, 0x73, 0x12, 0x34, 0x0a, + 0x16, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x53, + 0x54, 0x52, 0x49, 0x43, 0x54, 0x45, 0x44, 0x10, 0x01, 0x1a, 0x18, 0x8a, 0x9d, 0x20, 0x14, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x18, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x44, 0x10, + 0x02, 0x1a, 0x1a, 0x8a, 0x9d, 0x20, 0x16, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, + 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x1a, 0x04, 0x88, + 0xa3, 0x1e, 0x00, 0x42, 0xab, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x45, 0x76, + 0x6d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x26, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x76, 0x6d, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x6d, 0x76, 0x31, + 0xa2, 0x02, 0x03, 0x43, 0x45, 0x56, 0xaa, 0x02, 0x10, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x45, 0x76, 0x6d, 0x2e, 0x56, 0x6d, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x43, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x56, 0x6d, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x43, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x56, 0x6d, 0x5c, 0x56, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x43, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, 0x56, 0x6d, 0x3a, 0x3a, 0x56, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -11327,37 +12122,39 @@ func file_cosmos_evm_vm_v1_evm_proto_rawDescGZIP() []byte { } var file_cosmos_evm_vm_v1_evm_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_cosmos_evm_vm_v1_evm_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_cosmos_evm_vm_v1_evm_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_cosmos_evm_vm_v1_evm_proto_goTypes = []interface{}{ (AccessType)(0), // 0: cosmos.evm.vm.v1.AccessType (*Params)(nil), // 1: cosmos.evm.vm.v1.Params (*ExtendedDenomOptions)(nil), // 2: cosmos.evm.vm.v1.ExtendedDenomOptions - (*AccessControl)(nil), // 3: cosmos.evm.vm.v1.AccessControl - (*AccessControlType)(nil), // 4: cosmos.evm.vm.v1.AccessControlType - (*ChainConfig)(nil), // 5: cosmos.evm.vm.v1.ChainConfig - (*State)(nil), // 6: cosmos.evm.vm.v1.State - (*TransactionLogs)(nil), // 7: cosmos.evm.vm.v1.TransactionLogs - (*Log)(nil), // 8: cosmos.evm.vm.v1.Log - (*TxResult)(nil), // 9: cosmos.evm.vm.v1.TxResult - (*AccessTuple)(nil), // 10: cosmos.evm.vm.v1.AccessTuple - (*TraceConfig)(nil), // 11: cosmos.evm.vm.v1.TraceConfig - (*Preinstall)(nil), // 12: cosmos.evm.vm.v1.Preinstall - (*EvmCoinInfo)(nil), // 13: cosmos.evm.vm.v1.EvmCoinInfo + (*EVMSchedulerParams)(nil), // 3: cosmos.evm.vm.v1.EVMSchedulerParams + (*AccessControl)(nil), // 4: cosmos.evm.vm.v1.AccessControl + (*AccessControlType)(nil), // 5: cosmos.evm.vm.v1.AccessControlType + (*ChainConfig)(nil), // 6: cosmos.evm.vm.v1.ChainConfig + (*State)(nil), // 7: cosmos.evm.vm.v1.State + (*TransactionLogs)(nil), // 8: cosmos.evm.vm.v1.TransactionLogs + (*Log)(nil), // 9: cosmos.evm.vm.v1.Log + (*TxResult)(nil), // 10: cosmos.evm.vm.v1.TxResult + (*AccessTuple)(nil), // 11: cosmos.evm.vm.v1.AccessTuple + (*TraceConfig)(nil), // 12: cosmos.evm.vm.v1.TraceConfig + (*Preinstall)(nil), // 13: cosmos.evm.vm.v1.Preinstall + (*EvmCoinInfo)(nil), // 14: cosmos.evm.vm.v1.EvmCoinInfo } var file_cosmos_evm_vm_v1_evm_proto_depIdxs = []int32{ - 3, // 0: cosmos.evm.vm.v1.Params.access_control:type_name -> cosmos.evm.vm.v1.AccessControl + 4, // 0: cosmos.evm.vm.v1.Params.access_control:type_name -> cosmos.evm.vm.v1.AccessControl 2, // 1: cosmos.evm.vm.v1.Params.extended_denom_options:type_name -> cosmos.evm.vm.v1.ExtendedDenomOptions - 4, // 2: cosmos.evm.vm.v1.AccessControl.create:type_name -> cosmos.evm.vm.v1.AccessControlType - 4, // 3: cosmos.evm.vm.v1.AccessControl.call:type_name -> cosmos.evm.vm.v1.AccessControlType - 0, // 4: cosmos.evm.vm.v1.AccessControlType.access_type:type_name -> cosmos.evm.vm.v1.AccessType - 8, // 5: cosmos.evm.vm.v1.TransactionLogs.logs:type_name -> cosmos.evm.vm.v1.Log - 7, // 6: cosmos.evm.vm.v1.TxResult.tx_logs:type_name -> cosmos.evm.vm.v1.TransactionLogs - 5, // 7: cosmos.evm.vm.v1.TraceConfig.overrides:type_name -> cosmos.evm.vm.v1.ChainConfig - 8, // [8:8] is the sub-list for method output_type - 8, // [8:8] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 3, // 2: cosmos.evm.vm.v1.Params.scheduler:type_name -> cosmos.evm.vm.v1.EVMSchedulerParams + 5, // 3: cosmos.evm.vm.v1.AccessControl.create:type_name -> cosmos.evm.vm.v1.AccessControlType + 5, // 4: cosmos.evm.vm.v1.AccessControl.call:type_name -> cosmos.evm.vm.v1.AccessControlType + 0, // 5: cosmos.evm.vm.v1.AccessControlType.access_type:type_name -> cosmos.evm.vm.v1.AccessType + 9, // 6: cosmos.evm.vm.v1.TransactionLogs.logs:type_name -> cosmos.evm.vm.v1.Log + 8, // 7: cosmos.evm.vm.v1.TxResult.tx_logs:type_name -> cosmos.evm.vm.v1.TransactionLogs + 6, // 8: cosmos.evm.vm.v1.TraceConfig.overrides:type_name -> cosmos.evm.vm.v1.ChainConfig + 9, // [9:9] is the sub-list for method output_type + 9, // [9:9] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name } func init() { file_cosmos_evm_vm_v1_evm_proto_init() } @@ -11391,7 +12188,7 @@ func file_cosmos_evm_vm_v1_evm_proto_init() { } } file_cosmos_evm_vm_v1_evm_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccessControl); i { + switch v := v.(*EVMSchedulerParams); i { case 0: return &v.state case 1: @@ -11403,7 +12200,7 @@ func file_cosmos_evm_vm_v1_evm_proto_init() { } } file_cosmos_evm_vm_v1_evm_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccessControlType); i { + switch v := v.(*AccessControl); i { case 0: return &v.state case 1: @@ -11415,7 +12212,7 @@ func file_cosmos_evm_vm_v1_evm_proto_init() { } } file_cosmos_evm_vm_v1_evm_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChainConfig); i { + switch v := v.(*AccessControlType); i { case 0: return &v.state case 1: @@ -11427,7 +12224,7 @@ func file_cosmos_evm_vm_v1_evm_proto_init() { } } file_cosmos_evm_vm_v1_evm_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*State); i { + switch v := v.(*ChainConfig); i { case 0: return &v.state case 1: @@ -11439,7 +12236,7 @@ func file_cosmos_evm_vm_v1_evm_proto_init() { } } file_cosmos_evm_vm_v1_evm_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TransactionLogs); i { + switch v := v.(*State); i { case 0: return &v.state case 1: @@ -11451,7 +12248,7 @@ func file_cosmos_evm_vm_v1_evm_proto_init() { } } file_cosmos_evm_vm_v1_evm_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Log); i { + switch v := v.(*TransactionLogs); i { case 0: return &v.state case 1: @@ -11463,7 +12260,7 @@ func file_cosmos_evm_vm_v1_evm_proto_init() { } } file_cosmos_evm_vm_v1_evm_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TxResult); i { + switch v := v.(*Log); i { case 0: return &v.state case 1: @@ -11475,7 +12272,7 @@ func file_cosmos_evm_vm_v1_evm_proto_init() { } } file_cosmos_evm_vm_v1_evm_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccessTuple); i { + switch v := v.(*TxResult); i { case 0: return &v.state case 1: @@ -11487,7 +12284,7 @@ func file_cosmos_evm_vm_v1_evm_proto_init() { } } file_cosmos_evm_vm_v1_evm_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TraceConfig); i { + switch v := v.(*AccessTuple); i { case 0: return &v.state case 1: @@ -11499,7 +12296,7 @@ func file_cosmos_evm_vm_v1_evm_proto_init() { } } file_cosmos_evm_vm_v1_evm_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Preinstall); i { + switch v := v.(*TraceConfig); i { case 0: return &v.state case 1: @@ -11511,6 +12308,18 @@ func file_cosmos_evm_vm_v1_evm_proto_init() { } } file_cosmos_evm_vm_v1_evm_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Preinstall); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_vm_v1_evm_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*EvmCoinInfo); i { case 0: return &v.state @@ -11529,7 +12338,7 @@ func file_cosmos_evm_vm_v1_evm_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cosmos_evm_vm_v1_evm_proto_rawDesc, NumEnums: 1, - NumMessages: 13, + NumMessages: 14, NumExtensions: 0, NumServices: 0, }, diff --git a/contracts/solidity/StakedBondVault.json b/contracts/solidity/StakedBondVault.json new file mode 100644 index 00000000..53e7d012 --- /dev/null +++ b/contracts/solidity/StakedBondVault.json @@ -0,0 +1,1789 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "StakedBondVault", + "sourceName": "solidity/StakedBondVault.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidShortString", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "str", + "type": "string" + } + ], + "name": "StringTooLong", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ops", + "type": "uint256" + } + ], + "name": "Poked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "name": "ValidatorsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "batchId", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "estimatedAssets", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int64", + "name": "maturityTime", + "type": "int64" + } + ], + "name": "WithdrawalBatchProcessed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "batchId", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "settledAssets", + "type": "uint256" + } + ], + "name": "WithdrawalBatchSettled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "batchId", + "type": "uint64" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "WithdrawalClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "batchId", + "type": "uint64" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "WithdrawalRequested", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_VALIDATORS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NATIVE_WERC20", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OPERATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WEIGHT_SCALE", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "asset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "claimRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "assetsOut", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "convertToAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "convertToShares", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentBatchId", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "depositNative", + "outputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "depositsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastPokeOps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liveDelegatedAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "maxWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextRequestId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextSettlementBatchId", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxOps", + "type": "uint256" + } + ], + "name": "poke", + "outputs": [ + { + "internalType": "uint256", + "name": "ops", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "pokeCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pokePaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewMint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "previewRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "previewWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "requestRedeem", + "outputs": [ + { + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "deposits", + "type": "bool" + }, + { + "internalType": "bool", + "name": "withdrawals", + "type": "bool" + }, + { + "internalType": "bool", + "name": "scheduler", + "type": "bool" + } + ], + "name": "setPaused", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[]", + "name": "operatorAddresses", + "type": "string[]" + }, + { + "internalType": "uint16[]", + "name": "weights", + "type": "uint16[]" + } + ], + "name": "setValidators", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "syncDelegations", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "totalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalDelegated", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalLiquidReserved", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalReservedAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalWithdrawalUnbonding", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "validatorCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "validators", + "outputs": [ + { + "internalType": "string", + "name": "operatorAddress", + "type": "string" + }, + { + "internalType": "uint16", + "name": "weight", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "delegated", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "batchId", + "type": "uint64" + } + ], + "name": "withdrawalBatch", + "outputs": [ + { + "internalType": "bool", + "name": "open", + "type": "bool" + }, + { + "internalType": "bool", + "name": "processed", + "type": "bool" + }, + { + "internalType": "bool", + "name": "claimable", + "type": "bool" + }, + { + "internalType": "uint64", + "name": "requestCount", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "claimedCount", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "totalShares_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "estimatedAssets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidAssets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "unbondingAssets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "settledAssets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "claimedAssets", + "type": "uint256" + }, + { + "internalType": "int64", + "name": "maturityTime", + "type": "int64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "withdrawalRequests", + "outputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint64", + "name": "batchId", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawalsPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x6101a060408181523462000644576200520c803803809162000022828662000664565b84398201606083820312620006445782516001600160a01b0381169390849003620006445760208181015190936001600160401b0392909183811162000644578462000070918301620006c7565b93828201518481116200064457620000899201620006c7565b90805194620000988662000648565b60019081875280870197603160f81b89528651868111620005585760038054918583811c9316801562000639575b858410146200062557601f92838111620005dd575b50808584821160011462000578575f916200056c575b505f1982841b1c191690861b1781555b865191888311620005585760049788548781811c911680156200054d575b878210146200053a579081838695949311620004e3575b50869184116001146200047c575f9362000470575b505082861b925f19911b1c19161785555b6200016662000714565b901562000467575b60a05273d4949664cd82660aae99bedc034a0dea8a0bd5176080526200019487620007d4565b95610160968752620001a6896200096f565b9761018098895283815191012099610120998b8b5251902099610140968b88524660e05286519b8c9288878501947f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8652015260608d01524660808d01523060a08d015260a08c5260c08c01928c8410908411176200045457508186528a51902060c05261010099308b5284600a5584601155821562000425575050906016915f8052600990818352855f20815f52835260ff865f20541615620003ef575b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929805f52828452865f20825f52845260ff875f20541615620003b8575b507f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a91825f52808452865f20825f52845260ff875f2054161562000381575b5050506801000000000000000160018060801b03196010541617601055825f5252815f209060ff19825416179055519361472e958662000abe873960805186818161173d01528181611b9b0152818161344301528181613fbb015261463a015260a0518661216e015260c05186613010015260e051866130db01525185612fda0152518461305f01525183613085015251826109230152518161094c0152f35b825f528352855f20815f528352855f208560ff1982541617905533915f80516020620051ec8339815191525f80a45f8080620002e1565b805f52828452865f20825f528452865f208660ff198254161790558133915f80516020620051ec8339815191525f80a45f620002a2565b5f8052818352855f20815f528352855f208560ff1982541617905533815f5f80516020620051ec8339815191528180a462000265565b906961646d696e207a65726f60b01b6101046064938662461bcd60e51b855260c4820152600a60e48201520152fd5b604190634e487b7160e01b5f525260245ffd5b5060126200016e565b015191505f806200014b565b9190879450601f198416928a5f52875f20935f5b89828210620004cc5750508511620004b2575b50505050811b0185556200015c565b01519060f8845f19921b161c191690555f808080620004a3565b8385015187558b9890960195938401930162000490565b9091929350895f52865f208380870160051c82019289881062000530575b918a918897969594930160051c01915b8281106200052157505062000136565b5f81558796508a910162000511565b9250819262000501565b60228a634e487b7160e01b5f525260245ffd5b90607f16906200011f565b634e487b7160e01b5f52604160045260245ffd5b90508a01515f620000f1565b5f8481528781208994509190601f19841690898f5b838310620005c5575050508311620005ad575b5050811b01815562000101565b8c01515f1983861b60f8161c191690555f80620005a0565b84015185558b96909401939283019201898f6200058d565b825f52855f208480840160051c8201928885106200061b575b0160051c019087905b8281106200060f575050620000db565b5f8155018790620005ff565b92508192620005f6565b634e487b7160e01b5f52602260045260245ffd5b92607f1692620000c6565b5f80fd5b604081019081106001600160401b038211176200055857604052565b601f909101601f19168101906001600160401b038211908210176200055857604052565b6001600160401b0381116200055857601f01601f191660200190565b5f5b838110620006b65750505f910152565b8181015183820152602001620006a6565b81601f8201121562000644578051620006e08162000688565b92620006f0604051948562000664565b818452602082840101116200064457620007119160208085019101620006a4565b90565b60405163313ce56760e01b60208201908152600482529190620007378162000648565b5f80938192519073d4949664cd82660aae99bedc034a0dea8a0bd5175afa3d15620007cb573d90620007698262000688565b9162000779604051938462000664565b82523d84602084013e5b80620007be575b62000795575b508190565b602081805181010312620007ba576020015160ff811162000790576001925060ff1690565b8280fd5b506020815110156200078a565b60609062000783565b8051602091908281101562000853575090601f8251116200081157808251920151908083106200080357501790565b825f19910360031b1b161790565b604490620008459260405193849263305a27a960e01b845280600485015282519283918260248701528686019101620006a4565b601f01601f19168101030190fd5b6001600160401b03811162000558576005928354926001938481811c9116801562000964575b838210146200062557601f811162000930575b5081601f8411600114620008ca57509282939183925f94620008be575b50501b915f199060031b1c191617905560ff90565b015192505f80620008a9565b919083601f198116875f52845f20945f905b88838310620009155750505010620008fc575b505050811b01905560ff90565b01515f1960f88460031b161c191690555f8080620008ef565b858701518855909601959485019487935090810190620008dc565b855f5284601f845f209201871c820191601f8601881c015b828110620009585750506200088c565b5f815501859062000948565b90607f169062000879565b8051602090818110156200099c5750601f8251116200081157808251920151908083106200080357501790565b906001600160401b0382116200055857600654926001938481811c9116801562000ab2575b838210146200062557601f811162000a7b575b5081601f841160011462000a1357509282939183925f9462000a07575b50501b915f199060031b1c19161760065560ff90565b015192505f80620009f1565b919083601f19811660065f52845f20945f905b8883831062000a60575050501062000a47575b505050811b0160065560ff90565b01515f1960f88460031b161c191690555f808062000a39565b85870151885590960195948501948793509081019062000a26565b60065f5284601f845f20920160051c820191601f860160051c015b82811062000aa6575050620009d4565b5f815501859062000a96565b90607f1690620009c156fe60806040526004361015610011575f80fd5b60e05f35811c90816301e1d114146124bc57816301ffc9a71461246657816303e5fa881461243d57816306fdde031461239b57816307a2d13a14611afd578163095ea7b3146123755781630a28a477146123335781630a763da11461230d5781630f43a677146122f057816318160ddd146122d357816323b872dd1461229b578163248a9ca31461226e578163291cdb8c146122495781632f2ff15d146121a1578163313ce5671461215a57816332145f901461212f578163331c138c14611ef5578163333fedad14611ed957816333a7391614611ebc57816333bb7f9114611ceb57816335aa2e4414611c765781633644e51514611c5c57816336568abe14611bca57816338d52e0f14611b865781633950935114611b39578163402d267d146103ec5781634221b2c214611b1c578163499bafcc14611b025781634cdad50614611afd578163559904cb14611a35578163588f1343146115615781635ac22fd21461152d5781635c90178314610db757816360da3e8314610d955781636a84a98514610d785781636e553f651461086357816370a0823114610d41578163714897df14610d2757816377397cdd14610d0a5781637aed3cbb14610ced5781637d41c86e14610a685781637ecebe0014610a3057816380d04de814610a1357816384b0196e1461090e57816391d14854146108c5578163937b25811461086857816394bf804d1461086357816395d89b4114610780578163a217fddf14610766578163a457c2d7146106c3578163a9059cbb14610692578163b3d7f6b914610634578163b460af9414610601578163b9bcb70f14610606578163ba08765214610601578163c63d75b6146103ec578163c6e6f5921461033b578163ce96cb77146103ec578163d505accf1461044d57508063d547741f1461040e578063d77bb97c146103f1578063d905777e146103ec578063dd62ed3e1461039f578063e63ab1e914610365578063e9f2838e14610340578063ef8b30f71461033b5763f5b541a6146102fd575f80fd5b34610337575f3660031901126103375760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b5f80fd5b6127e3565b34610337575f36600319011261033757602060ff60125460081c166040519015158152f35b34610337575f3660031901126103375760206040517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b34610337576040366003190112610337576103b861253a565b6103c0612550565b9060018060a01b038091165f52600160205260405f2091165f52602052602060405f2054604051908152f35b6126bd565b34610337575f366003190112610337576020600e54604051908152f35b346103375760403660031901126103375761044b60043561042d612550565b90805f526009602052610446600160405f200154612825565b6129c4565b005b3461033757806003193601126103375761046561253a565b9061046e612550565b604435916084359060643560ff83168303610337578042116105bc5760018060a01b039182871693845f52600760205260405f20918254926001840190556040519360208501937f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98552876040870152868916606087015289608087015260a086015260c085015260c084528301918383106001600160401b038411176105a8576105549361054c93604052519020610525612fd7565b906040519161190160f01b83526002830152602282015260c43591604260a4359220612f54565b919091612e41565b16036105635761044b92612ba0565b60405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606490fd5b634e487b7160e01b5f52604160045260245ffd5b60405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606490fd5b612799565b34610337575f36600319011261033757602060405173d4949664cd82660aae99bedc034a0dea8a0bd5178152f35b346103375760203660031901126103375761064d613420565b6001810180911161067e57600254906001820180921161067e57602091610676916004356132af565b604051908152f35b634e487b7160e01b5f52601160045260245ffd5b34610337576040366003190112610337576106b86106ae61253a565b6024359033612a46565b602060405160018152f35b34610337576040366003190112610337576106dc61253a565b60243590335f52600160205260405f2060018060a01b0382165f5260205260405f205491808310610713576106b892039033612ba0565b60405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608490fd5b34610337575f3660031901126103375760206040515f8152f35b34610337575f366003190112610337576040515f906004546107a181612582565b80835260019180831690811561083b57506001146107e2575b6107de836107ca8187038261269c565b6040519182916020835260208301906124f7565b0390f35b60045f90815260209450917f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b828410610828575050508101909101906107ca816107ba565b805485850187015292850192810161080f565b6107de95506107ca93506020915091849260ff191682840152151560051b82010193506107ba565b612711565b34610337576020366003190112610337576004355f526015602052608060405f2060018060a01b036001600160401b03818354169260026001820154910154926040519485528116602085015260a01c1660408301526060820152f35b34610337576040366003190112610337576108de612550565b6004355f52600960205260405f209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b34610337575f366003190112610337576109477f0000000000000000000000000000000000000000000000000000000000000000613101565b6109707f00000000000000000000000000000000000000000000000000000000000000006131f7565b60405190602090818301938385106001600160401b038611176105a857949392906109c88391856040525f84526109ba604051988998600f60f81b8a5280868b01528901906124f7565b9087820360408901526124f7565b914660608701523060808701525f60a087015285830360c087015251918281520192915f5b8281106109fc57505050500390f35b8351855286955093810193928101926001016109ed565b34610337575f366003190112610337576020600c54604051908152f35b34610337576020366003190112610337576001600160a01b03610a5161253a565b165f526007602052602060405f2054604051908152f35b610a7136612764565b610a7b34156134ee565b610a8361352d565b60ff60125460081c16610cb357610a9b8315156135bf565b6001600160a01b0391808316610ab2811515613583565b838316928315610c815785610af46020977f1dfdc691a597a83af2430bd31addf8d2129d012eab8b35de6d696dc91e64852393873303610c71575b3090612a46565b601154958693610b03856135f9565b601155601054906001600160401b039283831692835f5260168c528460405f2094855460ff811615908115610c63575b50610c25575b506002929150601054169260405193610b518561264b565b8b85528d85019182526040850190815260608501928884528a5f5260158f528060405f2096511660018060a01b0319875416178655600186019251168254916001600160401b0360a01b905160a01b169163ffffffff60e01b16171790555191015560018101610bc2848254612a39565b905580546affffffffffffffff000000610be0848360181c16613607565b60181b166affffffffffffffff0000001991909116179055601054604080516001600160a01b0397909716875260208701939093521693a46001600a55604051908152f35b610c329192939550613607565b1680916001600160401b031916176010555f5260168a52600260405f2092600160ff1985541617845590848d610b39565b60ff915060081c168f610b33565b610c7c823383612c9e565b610aed565b60405162461bcd60e51b815260206004820152600a6024820152696f776e6572207a65726f60b01b6044820152606490fd5b60405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dd85b1cc81c185d5cd95960721b6044820152606490fd5b34610337575f366003190112610337576020600f54604051908152f35b34610337575f366003190112610337576020601454604051908152f35b34610337575f366003190112610337576020604051818152f35b34610337576020366003190112610337576001600160a01b03610d6261253a565b165f525f602052602060405f2054604051908152f35b34610337575f366003190112610337576020601154604051908152f35b34610337575f36600319011261033757602060ff601254166040519015158152f35b6040366003190112610337576004356001600160401b03811161033757610de29036906004016126e1565b906024356001600160401b03811161033757610e029036906004016126e1565b610e0f92919234156134ee565b335f9081527f84e70a45dc3cad9f831e8a7d9f4327701c9df1c790bfeaa7b6cb95e200be673360205260409020547f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9299060ff16156113ae5750808403611377576020841161133c575f91610e816144d3565b93600b545f600b55806112d8575b509291905f935b868510610f5657868661271086148015610f4e575b15610f1b57610ee15760207f6ebd9ef82ef3aa533937a4d42dc350c0739723937c8809f94e4983795d1ccc3c91604051908152a1005b60405162461bcd60e51b815260206004820152601260248201527164656c65676174696f6e732061637469766560701b6044820152606490fd5b60405162461bcd60e51b815260206004820152600b60248201526a626164207765696768747360a81b6044820152606490fd5b508115610eab565b909192610f6485888561385d565b9050156112a15761ffff610f81610f7c87878661389e565b6138ae565b161561126e5760645f610f95878a8761385d565b928391604051948593849263120bba7360e11b845230600485015260406024850152816044850152848401378181018301859052601f01601f191681010301816108005afa801561126357611242575b50610ffb610ff486898661385d565b369161395a565b602081519101205f5b8681106111de5750506110299061ffff611022610f7c88888761389e565b1690612a39565b9361ffff61103882898661385d565b919061105961104b610f7c868a8961389e565b9160405194610ff486612666565b83521660208201525f6040820152600b54600160401b8110156105a8578060016110869201600b55612566565b9190916111cb5780518051906001600160401b0382116105a8576110aa8454612582565b601f8111611190575b50602090601f831160011461112057928260029360409361110c9897965f92611115575b50508160011b915f199060031b1c19161784555b6001840161ffff60208301511661ffff1982541617905501519101556135f9565b93929190610e96565b015190508e806110d7565b90845f5260205f20915f5b601f198516811061117857508360409361110c98979693600193600297601f19811610611160575b505050811b0184556110eb565b01515f1960f88460031b161c191690558e8080611153565b9192602060018192868501518155019401920161112b565b6111bb90855f5260205f206005601f8601811c820192602087106111c1575b601f01901c019061361f565b8b6110b3565b91925082916111af565b634e487b7160e01b5f525f60045260245ffd5b6111ec610ff4828b8861385d565b60208151910120821461120757611202906135f9565b611004565b60405162461bcd60e51b8152602060048201526013602482015272323ab83634b1b0ba32903b30b634b230ba37b960691b6044820152606490fd5b61125d903d805f833e611255818361269c565b8101906138bd565b50610fe5565b6040513d5f823e3d90fd5b60405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc81dd95a59da1d60aa1b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e32b6b83a3c903b30b634b230ba37b960891b6044820152606490fd5b600390808202908282040361067e57600b5f527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9908101905b81811061131f575050610e8f565b8061132a8492613635565b5f60018201555f600282015501611311565b60405162461bcd60e51b8152602060048201526013602482015272746f6f206d616e792076616c696461746f727360681b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b6044820152606490fd5b6113b733612d8a565b604051916113c48361264b565b60428352602083019060603683378351156115195760308253835160019081101561151957607860218601536041905b8082116114d65750506114a557604861147292611481926114a19560405195869376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b60208601526114498151809260206037890191016124d6565b8401917001034b99036b4b9b9b4b733903937b6329607d1b6037840152518093868401906124d6565b0103602881018452018261269c565b60405162461bcd60e51b81526020600482015291829160248301906124f7565b0390fd5b606460405162461bcd60e51b815260206004820152602060248201525f805160206146b98339815191526044820152fd5b9091600f81166010811015611519576f181899199a1a9b1b9c1cb0b131b232b360811b901a6115058488612d79565b5360041c91801561067e575f1901906113f4565b634e487b7160e01b5f52603260045260245ffd5b5f3660031901126103375761154234156134ee565b61154a61352d565b60206115546144d3565b6001600a55604051908152f35b604036600319011261033757611575612550565b61157f34156134ee565b61158761352d565b6004355f52601560205260405f20604051906115a28261264b565b80546001600160a01b0390811680845260018301549182166020850190815260a09290921c6001600160401b031660408501526002909201546060840190815291156119fe576001600160401b036040840151165f52601660205260405f209182549460ff8660101c16156119c9576001600160a01b0381166119c3575081516001600160a01b0316915b516001600160a01b039081169083160361198d576116566001600160401b038660581c16613607565b6001600160401b03808760181c169116145f1461197257506116816005830154600684015490613413565b935b67ffffffffffffffff60581b6116a5605883901c6001600160401b0316613607565b60581b16906001600160401b0360581b1916178255600682016116c9858254612a39565b90556116d784600e54613413565b600e556116e684600f54613413565b600f556004355f908152601560209081526040808320838155600181018490556002018390555163a9059cbb60e01b9181019182526001600160a01b038481166024830152604480830189905282526117d89391927f00000000000000000000000000000000000000000000000000000000000000009091169190819061176e60648661269c565b6040519461177b86612681565b602086527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646020870152519082855af13d1561196a573d916117bc83612d5e565b926117ca604051948561269c565b83523d5f602085013e613695565b8051908115918215611950575b5050156118f8576001600160401b036040840151166040519185835260018060a01b0316917f6443ab78e20802b0a48c253c5a7e05576a8bedd83aec398a8bba1164e7cf6fc3602060043592a4546001600160401b03808260181c169160581c161461185c575b6020826001600a55604051908152f35b60406001600160401b03910151165f52601660205260405f20905f82555f60018301555f600283015560086003925f848201555f60048201555f60058201555f60068201555f6007820155018054905f8155816118bc575b50509061184c565b818402918483040361067e575f5260205f20908101905b818110156118b457806118e68592613635565b5f60018201555f6002820155016118d3565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b611963925060208091830101910161367d565b85806117e5565b606091613695565b61198790516005840154600185015491613391565b93611683565b60405162461bcd60e51b815260206004820152600e60248201526d3bb937b733903932b1b2b4bb32b960911b6044820152606490fd5b9161162d565b60405162461bcd60e51b815260206004820152600d60248201526c6e6f7420636c61696d61626c6560981b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e1d5b9adb9bdddb881c995c5d595cdd608a1b6044820152606490fd5b3461033757602036600319011261033757600435906001600160401b0380831680930361033757610180925f52601660205260405f208054926001820154906002830154906003840154906004850154926005860154946007600688015497015460070b976040519960ff811615158b5260ff8160081c16151560208c015260ff8160101c16151560408c0152818160181c1660608c015260581c1660808a015260a089015260c0880152860152610100850152610120840152610140830152610160820152f35b61251c565b34610337575f366003190112610337576020610676614581565b34610337575f366003190112610337576020601354604051908152f35b34610337576040366003190112610337576106b8611b5561253a565b335f52600160205260405f2060018060a01b0382165f52602052611b7f60243560405f2054612a39565b9033612ba0565b34610337575f366003190112610337576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461033757604036600319011261033757611be3612550565b336001600160a01b03821603611bff5761044b906004356129c4565b60405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608490fd5b34610337575f366003190112610337576020610676612fd7565b3461033757602036600319011261033757600435600b5481101561033757611ca0611cdc91612566565b5060405190611cba82611cb381846125ba565b038361269c565b600261ffff6001830154169101546040519384936060855260608501906124f7565b91602084015260408301520390f35b60208060031936011261033757611d0061253a565b611d0861352d565b60ff60125416611e85576001600160a01b0316801590611d288215613583565b3415611e5257611d3661443c565b5060025480611e095734925b611d4d8415156135bf565b611dc45782611d5b91612a39565b600255805f525f835260405f20828154019055805f5f805160206146d983398151915285604051868152a360405134815282848201527fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d760403392a36001600a55604051908152f35b60405162461bcd60e51b815260048101859052601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606490fd5b611e11613420565b34811115611e4b57611e24903490613413565b600182019081831161067e576001810180911161067e57611e459134613391565b92611d42565b505f611e24565b60405162461bcd60e51b815260048101849052600b60248201526a7a65726f2061737365747360a81b6044820152606490fd5b60405162461bcd60e51b815260048101839052600f60248201526e19195c1bdcda5d1cc81c185d5cd959608a1b6044820152606490fd5b34610337575f366003190112610337576020600d54604051908152f35b34610337575f3660031901126103375760206040516127108152f35b606036600319011261033757600435801515809103610337576024803590811515809203610337576044359081151580920361033757611f3534156134ee565b335f9081527f84574a31e2f767388bfa57bc81ff2590df95d3022c04c363cca3e37ee960863160209081526040909120547f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a9060ff1615611fbd5750505061ff009060ff62ff00006012549260101b1694169062ffffff1916179160081b1617176012555f80f35b611fc633612d8a565b90604051611fd38161264b565b6042815283810191606036843781511561211c5760308353815160019081101561210957607860218401536041905b8082116120a05750506120715760486114a193611472936120559360405195869376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a860152611449815180928c6037890191016124d6565b60405193849362461bcd60e51b855260048501528301906124f7565b606485856040519162461bcd60e51b83528160048401528201525f805160206146b98339815191526044820152fd5b9091600f811660108110156120f6576f181899199a1a9b1b9c1cb0b131b232b360811b901a6120cf8486612d79565b5360041c9180156120e3575f190190612002565b87634e487b7160e01b5f5260116004525ffd5b88634e487b7160e01b5f5260326004525ffd5b86634e487b7160e01b5f5260326004525ffd5b85634e487b7160e01b5f5260326004525ffd5b60203660031901126103375761214534156134ee565b61214d61352d565b602061155460043561372e565b34610337575f3660031901126103375760ff7f00000000000000000000000000000000000000000000000000000000000000001660ff811161067e57602090604051908152f35b34610337576040366003190112610337576004356121bd612550565b815f5260096020526121d5600160405f200154612825565b815f52600960205260405f209060018060a01b031690815f5260205260ff60405f2054161561220057005b815f52600960205260405f20815f5260205260405f20600160ff1982541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d5f80a4005b34610337575f36600319011261033757602060ff60125460101c166040519015158152f35b34610337576020366003190112610337576004355f5260096020526020600160405f200154604051908152f35b34610337576060366003190112610337576106b86122b761253a565b6122bf612550565b604435916122ce833383612c9e565b612a46565b34610337575f366003190112610337576020600254604051908152f35b34610337575f366003190112610337576020600b54604051908152f35b34610337575f3660031901126103375760206001600160401b0360105416604051908152f35b34610337576020366003190112610337576002546001810180911161067e5761235a613420565b906001820180921161067e57602091610676916004356132af565b34610337576040366003190112610337576106b861239161253a565b6024359033612ba0565b34610337575f366003190112610337576040515f906003546123bc81612582565b80835260019180831690811561083b57506001146123e4576107de836107ca8187038261269c565b60035f90815260209450917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b82841061242a575050508101909101906107ca816107ba565b8054858501870152928501928101612411565b34610337575f3660031901126103375760206001600160401b0360105460401c16604051908152f35b346103375760203660031901126103375760043563ffffffff60e01b811680910361033757602090637965db0b60e01b81149081156124ab575b506040519015158152f35b6301ffc9a760e01b149050826124a0565b34610337575f366003190112610337576020610676613420565b5f5b8381106124e75750505f910152565b81810151838201526020016124d8565b90602091612510815180928185528580860191016124d6565b601f01601f1916010190565b34610337576020366003190112610337576020610676600435612d30565b600435906001600160a01b038216820361033757565b602435906001600160a01b038216820361033757565b600b5481101561151957600b5f52600360205f20910201905f90565b90600182811c921680156125b0575b602083101461259c57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691612591565b905f92918054916125ca83612582565b9182825260019384811690815f1461262857506001146125eb575b50505050565b90919394505f52602092835f2092845f945b83861061261457505050500101905f8080806125e5565b8054858701830152940193859082016125fd565b9294505050602093945060ff191683830152151560051b0101905f8080806125e5565b608081019081106001600160401b038211176105a857604052565b606081019081106001600160401b038211176105a857604052565b604081019081106001600160401b038211176105a857604052565b90601f801991011681019081106001600160401b038211176105a857604052565b34610337576020366003190112610337576126d661253a565b5060206040515f8152f35b9181601f84011215610337578235916001600160401b038311610337576020808501948460051b01011161033757565b346103375760403660031901126103375761272a612550565b5060405162461bcd60e51b8152602060048201526011602482015270757365206465706f7369744e617469766560781b6044820152606490fd5b606090600319011261033757600435906001600160a01b03906024358281168103610337579160443590811681036103375790565b34610337576127a736612764565b505060405162461bcd60e51b8152602060048201526011602482015270757365207265717565737452656465656d60781b604482015260649150fd5b34610337576020366003190112610337576002546001810180911161067e5761280a613420565b906001820180921161067e5760209161067691600435613391565b5f9080825260209060098252604092838120338252835260ff84822054161561284e5750505050565b61285733612d8a565b918451906128648261264b565b604282528482019260603685378251156129b057603084538251906001918210156129b05790607860218501536041915b818311612943575050506129145760486114a19386936128f8936128e9985198899376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a860152611449815180928c6037890191016124d6565b0103602881018752018561269c565b5192839262461bcd60e51b8452600484015260248301906124f7565b60648486519062461bcd60e51b825280600483015260248201525f805160206146b98339815191526044820152fd5b909192600f8116601081101561299c576f181899199a1a9b1b9c1cb0b131b232b360811b901a6129738587612d79565b5360041c928015612988575f19019190612895565b634e487b7160e01b82526011600452602482fd5b634e487b7160e01b83526032600452602483fd5b634e487b7160e01b81526032600452602490fd5b905f918083526009602052604083209160018060a01b03169182845260205260ff6040842054166129f457505050565b8083526009602052604083208284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4565b9190820180921161067e57565b6001600160a01b03908116918215612b4d5716918215612afc575f82815280602052604081205491808310612aa857604082825f805160206146d9833981519152958760209652828652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b6001600160a01b03908116918215612c4d5716918215612bfd5760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591835f526001825260405f20855f5282528060405f2055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b9060018060a01b038083165f52600160205260405f209082165f5260205260405f2054925f198403612cd05750505050565b808410612ceb57612ce2930391612ba0565b5f8080806125e5565b60405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606490fd5b612d38613420565b6001810180911161067e57600254906001820180921161067e57612d5b92613391565b90565b6001600160401b0381116105a857601f01601f191660200190565b908151811015611519570160200190565b60405190612d9782612666565b602a82526020820160403682378251156115195760309053815160019081101561151957607860218401536029905b808211612dd65750506114a55790565b9091600f81166010811015612e2d576f181899199a1a9b1b9c1cb0b131b232b360811b901a612e058486612d79565b5360041c918015612e19575f190190612dc6565b60245f634e487b7160e01b81526011600452fd5b60245f634e487b7160e01b81526032600452fd5b6005811015612f405780612e525750565b60018103612e9a5760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b6044820152606490fd5b60028103612ee75760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606490fd5b600314612ef057565b60405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608490fd5b634e487b7160e01b5f52602160045260245ffd5b9291906fa2a8918ca85bafe22016d0b997e4df60600160ff1b038311612fcc5791608094939160ff6020946040519485521684840152604083015260608201525f93849182805260015afa15612fbf5781516001600160a01b03811615612fb9579190565b50600190565b50604051903d90823e3d90fd5b505050505f90600390565b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614806130d8575b15613032577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82527f000000000000000000000000000000000000000000000000000000000000000060408201527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260a0815260c081018181106001600160401b038211176105a85760405251902090565b507f00000000000000000000000000000000000000000000000000000000000000004614613009565b60ff811461313f5760ff811690601f821161312d576040519161312383612681565b8252602082015290565b604051632cd44ac360e21b8152600490fd5b50604051600554815f61315183612582565b8083526001938085169081156131d65750600114613177575b50612d5b9250038261269c565b60055f9081527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db094602093509091905b8183106131be575050612d5b93508201015f61316a565b855487840185015294850194869450918301916131a7565b9050612d5b94506020925060ff191682840152151560051b8201015f61316a565b60ff81146132195760ff811690601f821161312d576040519161312383612681565b50604051600654815f61322b83612582565b8083526001938085169081156131d657506001146132505750612d5b9250038261269c565b60065f9081527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f94602093509091905b818310613297575050612d5b93508201015f61316a565b85548784018501529485019486945091830191613280565b91906132bc828285613391565b9282156132d957096132cb5790565b6001810180911161067e5790565b634e487b7160e01b5f52601260045260245ffd5b905f1981830981830291828083109203918083039214613386576127109082821115613349577fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e91940990828211900360fc1b910360041c170290565b60405162461bcd60e51b81526020600482015260156024820152744d6174683a206d756c446976206f766572666c6f7760581b6044820152606490fd5b505061271091500490565b915f19828409928281029283808610950394808603951461340557848311156133495782910960018219018216809204600280826003021880830282030280830282030280830282030280830282030280830282030280920290030293600183805f03040190848311900302920304170290565b5050809250156132d9570490565b9190820391821161067e57565b600254156134ea576040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611263575f916134b4575b5061349161349a9161348b614581565b90612a39565b600d5490612a39565b600e54808211156134ae57612d5b91613413565b50505f90565b906020823d82116134e2575b816134cd6020938361269c565b810103126134df57505161349161347b565b80fd5b3d91506134c0565b5f90565b156134f557565b60405162461bcd60e51b815260206004820152601060248201526f756e65787065637465642076616c756560801b6044820152606490fd5b6002600a541461353e576002600a55565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b1561358a57565b60405162461bcd60e51b815260206004820152600d60248201526c7265636569766572207a65726f60981b6044820152606490fd5b156135c657565b60405162461bcd60e51b815260206004820152600b60248201526a7a65726f2073686172657360a81b6044820152606490fd5b5f19811461067e5760010190565b9060016001600160401b038093160191821161067e57565b81811061362a575050565b5f815560010161361f565b61363f8154612582565b9081613649575050565b81601f5f931160011461365a575055565b908083918252613679601f60208420940160051c84016001850161361f565b5555565b90816020910312610337575180151581036103375790565b919290156136f757508151156136a9575090565b3b156136b25790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b82519091501561370a5750805190602001fd5b60405162461bcd60e51b8152602060048201529081906114a19060248301906124f7565b905f9160ff60125460101c1661382a5780156138245761374c613fad565b613814575b80831080613806575b6137f6575b808310806137e8575b6137d8575b8210806137ca575b6137ba575b6137856013546135f9565b601355816014556040518281527f4889d7d38c1d1f265318505a98367d07d41591d6b7f9cc000f37ea92b8311daa60203392a2565b906137c4906135f9565b9061377a565b506137d3614295565b613775565b916137e2906135f9565b9161376d565b506137f161443c565b613768565b91613800906135f9565b9161375f565b5061380f613990565b61375a565b9161381e906135f9565b91613751565b505f9150565b60405162461bcd60e51b815260206004820152600b60248201526a1c1bdad9481c185d5cd95960aa1b6044820152606490fd5b91908110156115195760051b81013590601e19813603018212156103375701908135916001600160401b038311610337576020018236038113610337579190565b91908110156115195760051b0190565b3561ffff811681036103375790565b9190916040808285031261033757815193602091828401516001600160401b0394858211610337570190808284031261033757805194818601868110828211176105a8578252825190811161033757820183601f820112156103375780519361393161392886612d5e565b9351938461269c565b84835285858301011161033757849361394f918580850191016124d6565b845201519082015290565b92919261396682612d5e565b91613974604051938461269c565b829481845281830111610337578281602093845f960137010152565b6001600160401b03601054165f52601660205260405f20805460ff811615908115613f9f575b508015613f93575b613f8e576139ca61443c565b506001810154906139da82612d30565b9161010061ffff198354161782558260028301553015613f3f57305f525f60205260405f205490808210613eef57805f923084528360205203604083205580600254036002556040519081525f805160206146d983398151915260203092a3613a4161461f565b82811015613ee557613a5a905b80613ebc575b83613413565b905f9180613b1a575b50613ad86001827f5d78323b7b570071308d257743c74a9a2401f77d37e9de9f908da12c8917a40b606060076001600160401b0396019786199889815416898916179055600484015415613afc575b60105497878916958695015491604051928352602083015260070b6040820152a2613607565b1691829116176010555f52601660205260405f20600160ff19825416179055600190565b835462ff000019166201000017845560038401546005850155613ab2565b600b545f95935015613e8757613b2e6144d3565b50915f925b600b54841080613e7e575b15613e2757613b4c84612566565b509060028201548181105f14613e1f57915b8215613e1357604051630fb6accf60e21b81529060208280613b858785306004850161426b565b03815f6108005af1918215611263575f92613dd5575b50613baa846002830154613413565b6002820155600c613bbc858254613413565b9055600d613bcb858254612a39565b9055600e613bda858254612a39565b9055613bea846004880154612a39565b6004870155613c0e613c1560405192613c0284612666565b604051928380926125ba565b038261269c565b81528360208201528160070b60408201526008860154600160401b8110156105a8576001810180600889015581101561151957600887015f5260205f209082518051906001600160401b0382116105a857613c7560038402850154612582565b90601f91828111613d98575b506020918311600114613d22579282604095936003936002965f92613d17575b50508160011b915f1990851b1c1916178282028401555b60208601516001838302850101550201019101516001600160401b0319825416906001600160401b03161790558760070b8160070b13613d0d575b50613d0791613d0191613413565b936135f9565b92613b33565b9650613d07613cf3565b015190505f80613ca1565b906003840285015f5260205f20915f5b601f1985168110613d805750836003936002969360019360409997601f19811610613d69575b505050811b01828202840155613cb8565b01515f1983871b60f8161c191690555f8080613d58565b91926020600181928685015181550194019201613d32565b613dc6906003860287015f5260205f20600585808801821c83019360208910613dcc575b01901c019061361f565b5f613c81565b93508293613dbc565b9091506020813d602011613e0b575b81613df16020938361269c565b8101031261033757518060070b810361033757905f613b9b565b3d9150613de4565b5093613d0791506135f9565b508091613b5e565b9094919250613e395790613ad8613a63565b60405162461bcd60e51b815260206004820152601d60248201527f696e73756666696369656e742064656c656761746564206173736574730000006044820152606490fd5b50801515613b3e565b60405162461bcd60e51b815260206004820152600d60248201526c6e6f2076616c696461746f727360981b6044820152606490fd5b613ec881600e54612a39565b600e55613ed781600f54612a39565b600f55806003840155613a54565b50613a5a82613a4e565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608490fd5b505f90565b506001810154156139be565b60ff915060081c165f6139b6565b601080546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692916001600160401b03604092831c81169290915b80549083851694848316861015614260575f9786895260209560168752858a2094855460ff808260081c1615918215614254575b50508015614248575b614201575060078501541642106141d55760048085015491828b600f938454938b6140588887612a39565b9260248d51809481936370a0823160e01b835230908301525afa9283156141ca5792614177575b50917f73f330dd18a8f4760be8fa04b392ba243a76dcbe07487724e846182d63dbfafa9b9c9d82846140fa97956141169a99979510614145575b5050506140ee918491600d6140cf828254613413565b90556140e7836140e2600e938454613413565b612a39565b9055612a39565b90556003860154612a39565b60058501908155845462ff000019166201000017909455613607565b815467ffffffffffffffff60401b191690841b67ffffffffffffffff60401b16179055549051908152a2600190565b6140ee94969161415491613413565b9081811115614170576141679250613413565b93915f806140b9565b5050614167565b9091508a81813d83116141c3575b61418f818361269c565b810103126141bf5751907f73f330dd18a8f4760be8fa04b392ba243a76dcbe07487724e846182d63dbfafa61407f565b8d80fd5b503d614185565b8b51903d90823e3d90fd5b50815467ffffffffffffffff60401b1916931b67ffffffffffffffff60401b1692909217909155505050565b92939750955097508492506001600160401b0360401b61422083613607565b67ffffffffffffffff60401b1990921691851b1617855516828114612e195760010192613ff0565b5060048601541561402d565b871c1690505f80614024565b505f96505050505050565b9392916142909060409260018060a01b031686526060602087015260608601906125ba565b930152565b600290815415614437576142a761461f565b908115801561442d575b614426576142bd6144d3565b505f90825b600b548084108061441d575b156144125760019081850180861161067e57036143f25750805b81156143e7576142f784612566565b5060408051906353266bbb60e01b825260209182818061431d89600498308a850161426b565b03815f6108005af19081156143dd575f916143b0575b501561437d5750505061437791614371918761434e87612566565b500161435b838254612a39565b9055600c61436a838254612a39565b9055613413565b926135f9565b916142c2565b5162461bcd60e51b815291820152600f60248201526e19195b1959d85d194819985a5b1959608a1b604482015260649150fd5b6143d09150833d85116143d6575b6143c8818361269c565b81019061367d565b5f614333565b503d6143be565b82513d5f823e3d90fd5b9261437791506135f9565b61ffff61440c9161440286612566565b50015416856132ed565b906142e8565b505092505050600190565b508115156142ce565b9150505f90565b50600b54156142b1565b5f9150565b600b541580156144a2575b6134ea5763ffffffff600b541660405190632efe8a5f60e01b825230600483015260248201526020816044815f6108015af1908115611263575f9161448a575090565b612d5b915060203d81116143d6576143c8818361269c565b506144ab6144d3565b15614447565b6001600160a01b039091168152604060208201819052612d5b929101906125ba565b5f9081805b600b54821015614578576144eb82612566565b5061450d8560409283518093819263120bba7360e11b835230600484016144b1565b03816108005afa91821561456f57509160206145479261454d948891614553575b50018051600261453d87612566565b5001555190612a39565b916135f9565b906144d8565b61456791503d808a833e611255818361269c565b90505f61452e565b513d87823e3d90fd5b92505081600c55565b5f905f80600b545b80831061459557505050565b9091936145a185612566565b506145c38460409283518093819263120bba7360e11b835230600484016144b1565b03816108005afa91821561461657509160206145ed926145f39487916145fa575b50015190612a39565b946135f9565b9190614589565b61460e91503d8089833e611255818361269c565b90505f6145e4565b513d86823e3d90fd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611263575f91614687575b50600f54808211156134ae57612d5b91613413565b906020823d82116146b0575b816146a06020938361269c565b810103126134df5750515f614672565b3d915061469356fe537472696e67733a20686578206c656e67746820696e73756666696369656e74ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212203dea20cc054fb9b8e55a057442460f9c400c356156d57798f5f876718474fdfd64736f6c634300081400332f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "deployedBytecode": "0x60806040526004361015610011575f80fd5b60e05f35811c90816301e1d114146124bc57816301ffc9a71461246657816303e5fa881461243d57816306fdde031461239b57816307a2d13a14611afd578163095ea7b3146123755781630a28a477146123335781630a763da11461230d5781630f43a677146122f057816318160ddd146122d357816323b872dd1461229b578163248a9ca31461226e578163291cdb8c146122495781632f2ff15d146121a1578163313ce5671461215a57816332145f901461212f578163331c138c14611ef5578163333fedad14611ed957816333a7391614611ebc57816333bb7f9114611ceb57816335aa2e4414611c765781633644e51514611c5c57816336568abe14611bca57816338d52e0f14611b865781633950935114611b39578163402d267d146103ec5781634221b2c214611b1c578163499bafcc14611b025781634cdad50614611afd578163559904cb14611a35578163588f1343146115615781635ac22fd21461152d5781635c90178314610db757816360da3e8314610d955781636a84a98514610d785781636e553f651461086357816370a0823114610d41578163714897df14610d2757816377397cdd14610d0a5781637aed3cbb14610ced5781637d41c86e14610a685781637ecebe0014610a3057816380d04de814610a1357816384b0196e1461090e57816391d14854146108c5578163937b25811461086857816394bf804d1461086357816395d89b4114610780578163a217fddf14610766578163a457c2d7146106c3578163a9059cbb14610692578163b3d7f6b914610634578163b460af9414610601578163b9bcb70f14610606578163ba08765214610601578163c63d75b6146103ec578163c6e6f5921461033b578163ce96cb77146103ec578163d505accf1461044d57508063d547741f1461040e578063d77bb97c146103f1578063d905777e146103ec578063dd62ed3e1461039f578063e63ab1e914610365578063e9f2838e14610340578063ef8b30f71461033b5763f5b541a6146102fd575f80fd5b34610337575f3660031901126103375760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b5f80fd5b6127e3565b34610337575f36600319011261033757602060ff60125460081c166040519015158152f35b34610337575f3660031901126103375760206040517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b34610337576040366003190112610337576103b861253a565b6103c0612550565b9060018060a01b038091165f52600160205260405f2091165f52602052602060405f2054604051908152f35b6126bd565b34610337575f366003190112610337576020600e54604051908152f35b346103375760403660031901126103375761044b60043561042d612550565b90805f526009602052610446600160405f200154612825565b6129c4565b005b3461033757806003193601126103375761046561253a565b9061046e612550565b604435916084359060643560ff83168303610337578042116105bc5760018060a01b039182871693845f52600760205260405f20918254926001840190556040519360208501937f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98552876040870152868916606087015289608087015260a086015260c085015260c084528301918383106001600160401b038411176105a8576105549361054c93604052519020610525612fd7565b906040519161190160f01b83526002830152602282015260c43591604260a4359220612f54565b919091612e41565b16036105635761044b92612ba0565b60405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606490fd5b634e487b7160e01b5f52604160045260245ffd5b60405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606490fd5b612799565b34610337575f36600319011261033757602060405173d4949664cd82660aae99bedc034a0dea8a0bd5178152f35b346103375760203660031901126103375761064d613420565b6001810180911161067e57600254906001820180921161067e57602091610676916004356132af565b604051908152f35b634e487b7160e01b5f52601160045260245ffd5b34610337576040366003190112610337576106b86106ae61253a565b6024359033612a46565b602060405160018152f35b34610337576040366003190112610337576106dc61253a565b60243590335f52600160205260405f2060018060a01b0382165f5260205260405f205491808310610713576106b892039033612ba0565b60405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608490fd5b34610337575f3660031901126103375760206040515f8152f35b34610337575f366003190112610337576040515f906004546107a181612582565b80835260019180831690811561083b57506001146107e2575b6107de836107ca8187038261269c565b6040519182916020835260208301906124f7565b0390f35b60045f90815260209450917f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b828410610828575050508101909101906107ca816107ba565b805485850187015292850192810161080f565b6107de95506107ca93506020915091849260ff191682840152151560051b82010193506107ba565b612711565b34610337576020366003190112610337576004355f526015602052608060405f2060018060a01b036001600160401b03818354169260026001820154910154926040519485528116602085015260a01c1660408301526060820152f35b34610337576040366003190112610337576108de612550565b6004355f52600960205260405f209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b34610337575f366003190112610337576109477f0000000000000000000000000000000000000000000000000000000000000000613101565b6109707f00000000000000000000000000000000000000000000000000000000000000006131f7565b60405190602090818301938385106001600160401b038611176105a857949392906109c88391856040525f84526109ba604051988998600f60f81b8a5280868b01528901906124f7565b9087820360408901526124f7565b914660608701523060808701525f60a087015285830360c087015251918281520192915f5b8281106109fc57505050500390f35b8351855286955093810193928101926001016109ed565b34610337575f366003190112610337576020600c54604051908152f35b34610337576020366003190112610337576001600160a01b03610a5161253a565b165f526007602052602060405f2054604051908152f35b610a7136612764565b610a7b34156134ee565b610a8361352d565b60ff60125460081c16610cb357610a9b8315156135bf565b6001600160a01b0391808316610ab2811515613583565b838316928315610c815785610af46020977f1dfdc691a597a83af2430bd31addf8d2129d012eab8b35de6d696dc91e64852393873303610c71575b3090612a46565b601154958693610b03856135f9565b601155601054906001600160401b039283831692835f5260168c528460405f2094855460ff811615908115610c63575b50610c25575b506002929150601054169260405193610b518561264b565b8b85528d85019182526040850190815260608501928884528a5f5260158f528060405f2096511660018060a01b0319875416178655600186019251168254916001600160401b0360a01b905160a01b169163ffffffff60e01b16171790555191015560018101610bc2848254612a39565b905580546affffffffffffffff000000610be0848360181c16613607565b60181b166affffffffffffffff0000001991909116179055601054604080516001600160a01b0397909716875260208701939093521693a46001600a55604051908152f35b610c329192939550613607565b1680916001600160401b031916176010555f5260168a52600260405f2092600160ff1985541617845590848d610b39565b60ff915060081c168f610b33565b610c7c823383612c9e565b610aed565b60405162461bcd60e51b815260206004820152600a6024820152696f776e6572207a65726f60b01b6044820152606490fd5b60405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dd85b1cc81c185d5cd95960721b6044820152606490fd5b34610337575f366003190112610337576020600f54604051908152f35b34610337575f366003190112610337576020601454604051908152f35b34610337575f366003190112610337576020604051818152f35b34610337576020366003190112610337576001600160a01b03610d6261253a565b165f525f602052602060405f2054604051908152f35b34610337575f366003190112610337576020601154604051908152f35b34610337575f36600319011261033757602060ff601254166040519015158152f35b6040366003190112610337576004356001600160401b03811161033757610de29036906004016126e1565b906024356001600160401b03811161033757610e029036906004016126e1565b610e0f92919234156134ee565b335f9081527f84e70a45dc3cad9f831e8a7d9f4327701c9df1c790bfeaa7b6cb95e200be673360205260409020547f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9299060ff16156113ae5750808403611377576020841161133c575f91610e816144d3565b93600b545f600b55806112d8575b509291905f935b868510610f5657868661271086148015610f4e575b15610f1b57610ee15760207f6ebd9ef82ef3aa533937a4d42dc350c0739723937c8809f94e4983795d1ccc3c91604051908152a1005b60405162461bcd60e51b815260206004820152601260248201527164656c65676174696f6e732061637469766560701b6044820152606490fd5b60405162461bcd60e51b815260206004820152600b60248201526a626164207765696768747360a81b6044820152606490fd5b508115610eab565b909192610f6485888561385d565b9050156112a15761ffff610f81610f7c87878661389e565b6138ae565b161561126e5760645f610f95878a8761385d565b928391604051948593849263120bba7360e11b845230600485015260406024850152816044850152848401378181018301859052601f01601f191681010301816108005afa801561126357611242575b50610ffb610ff486898661385d565b369161395a565b602081519101205f5b8681106111de5750506110299061ffff611022610f7c88888761389e565b1690612a39565b9361ffff61103882898661385d565b919061105961104b610f7c868a8961389e565b9160405194610ff486612666565b83521660208201525f6040820152600b54600160401b8110156105a8578060016110869201600b55612566565b9190916111cb5780518051906001600160401b0382116105a8576110aa8454612582565b601f8111611190575b50602090601f831160011461112057928260029360409361110c9897965f92611115575b50508160011b915f199060031b1c19161784555b6001840161ffff60208301511661ffff1982541617905501519101556135f9565b93929190610e96565b015190508e806110d7565b90845f5260205f20915f5b601f198516811061117857508360409361110c98979693600193600297601f19811610611160575b505050811b0184556110eb565b01515f1960f88460031b161c191690558e8080611153565b9192602060018192868501518155019401920161112b565b6111bb90855f5260205f206005601f8601811c820192602087106111c1575b601f01901c019061361f565b8b6110b3565b91925082916111af565b634e487b7160e01b5f525f60045260245ffd5b6111ec610ff4828b8861385d565b60208151910120821461120757611202906135f9565b611004565b60405162461bcd60e51b8152602060048201526013602482015272323ab83634b1b0ba32903b30b634b230ba37b960691b6044820152606490fd5b61125d903d805f833e611255818361269c565b8101906138bd565b50610fe5565b6040513d5f823e3d90fd5b60405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc81dd95a59da1d60aa1b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e32b6b83a3c903b30b634b230ba37b960891b6044820152606490fd5b600390808202908282040361067e57600b5f527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9908101905b81811061131f575050610e8f565b8061132a8492613635565b5f60018201555f600282015501611311565b60405162461bcd60e51b8152602060048201526013602482015272746f6f206d616e792076616c696461746f727360681b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b6044820152606490fd5b6113b733612d8a565b604051916113c48361264b565b60428352602083019060603683378351156115195760308253835160019081101561151957607860218601536041905b8082116114d65750506114a557604861147292611481926114a19560405195869376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b60208601526114498151809260206037890191016124d6565b8401917001034b99036b4b9b9b4b733903937b6329607d1b6037840152518093868401906124d6565b0103602881018452018261269c565b60405162461bcd60e51b81526020600482015291829160248301906124f7565b0390fd5b606460405162461bcd60e51b815260206004820152602060248201525f805160206146b98339815191526044820152fd5b9091600f81166010811015611519576f181899199a1a9b1b9c1cb0b131b232b360811b901a6115058488612d79565b5360041c91801561067e575f1901906113f4565b634e487b7160e01b5f52603260045260245ffd5b5f3660031901126103375761154234156134ee565b61154a61352d565b60206115546144d3565b6001600a55604051908152f35b604036600319011261033757611575612550565b61157f34156134ee565b61158761352d565b6004355f52601560205260405f20604051906115a28261264b565b80546001600160a01b0390811680845260018301549182166020850190815260a09290921c6001600160401b031660408501526002909201546060840190815291156119fe576001600160401b036040840151165f52601660205260405f209182549460ff8660101c16156119c9576001600160a01b0381166119c3575081516001600160a01b0316915b516001600160a01b039081169083160361198d576116566001600160401b038660581c16613607565b6001600160401b03808760181c169116145f1461197257506116816005830154600684015490613413565b935b67ffffffffffffffff60581b6116a5605883901c6001600160401b0316613607565b60581b16906001600160401b0360581b1916178255600682016116c9858254612a39565b90556116d784600e54613413565b600e556116e684600f54613413565b600f556004355f908152601560209081526040808320838155600181018490556002018390555163a9059cbb60e01b9181019182526001600160a01b038481166024830152604480830189905282526117d89391927f00000000000000000000000000000000000000000000000000000000000000009091169190819061176e60648661269c565b6040519461177b86612681565b602086527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646020870152519082855af13d1561196a573d916117bc83612d5e565b926117ca604051948561269c565b83523d5f602085013e613695565b8051908115918215611950575b5050156118f8576001600160401b036040840151166040519185835260018060a01b0316917f6443ab78e20802b0a48c253c5a7e05576a8bedd83aec398a8bba1164e7cf6fc3602060043592a4546001600160401b03808260181c169160581c161461185c575b6020826001600a55604051908152f35b60406001600160401b03910151165f52601660205260405f20905f82555f60018301555f600283015560086003925f848201555f60048201555f60058201555f60068201555f6007820155018054905f8155816118bc575b50509061184c565b818402918483040361067e575f5260205f20908101905b818110156118b457806118e68592613635565b5f60018201555f6002820155016118d3565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b611963925060208091830101910161367d565b85806117e5565b606091613695565b61198790516005840154600185015491613391565b93611683565b60405162461bcd60e51b815260206004820152600e60248201526d3bb937b733903932b1b2b4bb32b960911b6044820152606490fd5b9161162d565b60405162461bcd60e51b815260206004820152600d60248201526c6e6f7420636c61696d61626c6560981b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e1d5b9adb9bdddb881c995c5d595cdd608a1b6044820152606490fd5b3461033757602036600319011261033757600435906001600160401b0380831680930361033757610180925f52601660205260405f208054926001820154906002830154906003840154906004850154926005860154946007600688015497015460070b976040519960ff811615158b5260ff8160081c16151560208c015260ff8160101c16151560408c0152818160181c1660608c015260581c1660808a015260a089015260c0880152860152610100850152610120840152610140830152610160820152f35b61251c565b34610337575f366003190112610337576020610676614581565b34610337575f366003190112610337576020601354604051908152f35b34610337576040366003190112610337576106b8611b5561253a565b335f52600160205260405f2060018060a01b0382165f52602052611b7f60243560405f2054612a39565b9033612ba0565b34610337575f366003190112610337576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461033757604036600319011261033757611be3612550565b336001600160a01b03821603611bff5761044b906004356129c4565b60405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608490fd5b34610337575f366003190112610337576020610676612fd7565b3461033757602036600319011261033757600435600b5481101561033757611ca0611cdc91612566565b5060405190611cba82611cb381846125ba565b038361269c565b600261ffff6001830154169101546040519384936060855260608501906124f7565b91602084015260408301520390f35b60208060031936011261033757611d0061253a565b611d0861352d565b60ff60125416611e85576001600160a01b0316801590611d288215613583565b3415611e5257611d3661443c565b5060025480611e095734925b611d4d8415156135bf565b611dc45782611d5b91612a39565b600255805f525f835260405f20828154019055805f5f805160206146d983398151915285604051868152a360405134815282848201527fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d760403392a36001600a55604051908152f35b60405162461bcd60e51b815260048101859052601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606490fd5b611e11613420565b34811115611e4b57611e24903490613413565b600182019081831161067e576001810180911161067e57611e459134613391565b92611d42565b505f611e24565b60405162461bcd60e51b815260048101849052600b60248201526a7a65726f2061737365747360a81b6044820152606490fd5b60405162461bcd60e51b815260048101839052600f60248201526e19195c1bdcda5d1cc81c185d5cd959608a1b6044820152606490fd5b34610337575f366003190112610337576020600d54604051908152f35b34610337575f3660031901126103375760206040516127108152f35b606036600319011261033757600435801515809103610337576024803590811515809203610337576044359081151580920361033757611f3534156134ee565b335f9081527f84574a31e2f767388bfa57bc81ff2590df95d3022c04c363cca3e37ee960863160209081526040909120547f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a9060ff1615611fbd5750505061ff009060ff62ff00006012549260101b1694169062ffffff1916179160081b1617176012555f80f35b611fc633612d8a565b90604051611fd38161264b565b6042815283810191606036843781511561211c5760308353815160019081101561210957607860218401536041905b8082116120a05750506120715760486114a193611472936120559360405195869376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a860152611449815180928c6037890191016124d6565b60405193849362461bcd60e51b855260048501528301906124f7565b606485856040519162461bcd60e51b83528160048401528201525f805160206146b98339815191526044820152fd5b9091600f811660108110156120f6576f181899199a1a9b1b9c1cb0b131b232b360811b901a6120cf8486612d79565b5360041c9180156120e3575f190190612002565b87634e487b7160e01b5f5260116004525ffd5b88634e487b7160e01b5f5260326004525ffd5b86634e487b7160e01b5f5260326004525ffd5b85634e487b7160e01b5f5260326004525ffd5b60203660031901126103375761214534156134ee565b61214d61352d565b602061155460043561372e565b34610337575f3660031901126103375760ff7f00000000000000000000000000000000000000000000000000000000000000001660ff811161067e57602090604051908152f35b34610337576040366003190112610337576004356121bd612550565b815f5260096020526121d5600160405f200154612825565b815f52600960205260405f209060018060a01b031690815f5260205260ff60405f2054161561220057005b815f52600960205260405f20815f5260205260405f20600160ff1982541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d5f80a4005b34610337575f36600319011261033757602060ff60125460101c166040519015158152f35b34610337576020366003190112610337576004355f5260096020526020600160405f200154604051908152f35b34610337576060366003190112610337576106b86122b761253a565b6122bf612550565b604435916122ce833383612c9e565b612a46565b34610337575f366003190112610337576020600254604051908152f35b34610337575f366003190112610337576020600b54604051908152f35b34610337575f3660031901126103375760206001600160401b0360105416604051908152f35b34610337576020366003190112610337576002546001810180911161067e5761235a613420565b906001820180921161067e57602091610676916004356132af565b34610337576040366003190112610337576106b861239161253a565b6024359033612ba0565b34610337575f366003190112610337576040515f906003546123bc81612582565b80835260019180831690811561083b57506001146123e4576107de836107ca8187038261269c565b60035f90815260209450917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b82841061242a575050508101909101906107ca816107ba565b8054858501870152928501928101612411565b34610337575f3660031901126103375760206001600160401b0360105460401c16604051908152f35b346103375760203660031901126103375760043563ffffffff60e01b811680910361033757602090637965db0b60e01b81149081156124ab575b506040519015158152f35b6301ffc9a760e01b149050826124a0565b34610337575f366003190112610337576020610676613420565b5f5b8381106124e75750505f910152565b81810151838201526020016124d8565b90602091612510815180928185528580860191016124d6565b601f01601f1916010190565b34610337576020366003190112610337576020610676600435612d30565b600435906001600160a01b038216820361033757565b602435906001600160a01b038216820361033757565b600b5481101561151957600b5f52600360205f20910201905f90565b90600182811c921680156125b0575b602083101461259c57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691612591565b905f92918054916125ca83612582565b9182825260019384811690815f1461262857506001146125eb575b50505050565b90919394505f52602092835f2092845f945b83861061261457505050500101905f8080806125e5565b8054858701830152940193859082016125fd565b9294505050602093945060ff191683830152151560051b0101905f8080806125e5565b608081019081106001600160401b038211176105a857604052565b606081019081106001600160401b038211176105a857604052565b604081019081106001600160401b038211176105a857604052565b90601f801991011681019081106001600160401b038211176105a857604052565b34610337576020366003190112610337576126d661253a565b5060206040515f8152f35b9181601f84011215610337578235916001600160401b038311610337576020808501948460051b01011161033757565b346103375760403660031901126103375761272a612550565b5060405162461bcd60e51b8152602060048201526011602482015270757365206465706f7369744e617469766560781b6044820152606490fd5b606090600319011261033757600435906001600160a01b03906024358281168103610337579160443590811681036103375790565b34610337576127a736612764565b505060405162461bcd60e51b8152602060048201526011602482015270757365207265717565737452656465656d60781b604482015260649150fd5b34610337576020366003190112610337576002546001810180911161067e5761280a613420565b906001820180921161067e5760209161067691600435613391565b5f9080825260209060098252604092838120338252835260ff84822054161561284e5750505050565b61285733612d8a565b918451906128648261264b565b604282528482019260603685378251156129b057603084538251906001918210156129b05790607860218501536041915b818311612943575050506129145760486114a19386936128f8936128e9985198899376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a860152611449815180928c6037890191016124d6565b0103602881018752018561269c565b5192839262461bcd60e51b8452600484015260248301906124f7565b60648486519062461bcd60e51b825280600483015260248201525f805160206146b98339815191526044820152fd5b909192600f8116601081101561299c576f181899199a1a9b1b9c1cb0b131b232b360811b901a6129738587612d79565b5360041c928015612988575f19019190612895565b634e487b7160e01b82526011600452602482fd5b634e487b7160e01b83526032600452602483fd5b634e487b7160e01b81526032600452602490fd5b905f918083526009602052604083209160018060a01b03169182845260205260ff6040842054166129f457505050565b8083526009602052604083208284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4565b9190820180921161067e57565b6001600160a01b03908116918215612b4d5716918215612afc575f82815280602052604081205491808310612aa857604082825f805160206146d9833981519152958760209652828652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b6001600160a01b03908116918215612c4d5716918215612bfd5760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591835f526001825260405f20855f5282528060405f2055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b9060018060a01b038083165f52600160205260405f209082165f5260205260405f2054925f198403612cd05750505050565b808410612ceb57612ce2930391612ba0565b5f8080806125e5565b60405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606490fd5b612d38613420565b6001810180911161067e57600254906001820180921161067e57612d5b92613391565b90565b6001600160401b0381116105a857601f01601f191660200190565b908151811015611519570160200190565b60405190612d9782612666565b602a82526020820160403682378251156115195760309053815160019081101561151957607860218401536029905b808211612dd65750506114a55790565b9091600f81166010811015612e2d576f181899199a1a9b1b9c1cb0b131b232b360811b901a612e058486612d79565b5360041c918015612e19575f190190612dc6565b60245f634e487b7160e01b81526011600452fd5b60245f634e487b7160e01b81526032600452fd5b6005811015612f405780612e525750565b60018103612e9a5760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b6044820152606490fd5b60028103612ee75760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606490fd5b600314612ef057565b60405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608490fd5b634e487b7160e01b5f52602160045260245ffd5b9291906fa2a8918ca85bafe22016d0b997e4df60600160ff1b038311612fcc5791608094939160ff6020946040519485521684840152604083015260608201525f93849182805260015afa15612fbf5781516001600160a01b03811615612fb9579190565b50600190565b50604051903d90823e3d90fd5b505050505f90600390565b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614806130d8575b15613032577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82527f000000000000000000000000000000000000000000000000000000000000000060408201527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260a0815260c081018181106001600160401b038211176105a85760405251902090565b507f00000000000000000000000000000000000000000000000000000000000000004614613009565b60ff811461313f5760ff811690601f821161312d576040519161312383612681565b8252602082015290565b604051632cd44ac360e21b8152600490fd5b50604051600554815f61315183612582565b8083526001938085169081156131d65750600114613177575b50612d5b9250038261269c565b60055f9081527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db094602093509091905b8183106131be575050612d5b93508201015f61316a565b855487840185015294850194869450918301916131a7565b9050612d5b94506020925060ff191682840152151560051b8201015f61316a565b60ff81146132195760ff811690601f821161312d576040519161312383612681565b50604051600654815f61322b83612582565b8083526001938085169081156131d657506001146132505750612d5b9250038261269c565b60065f9081527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f94602093509091905b818310613297575050612d5b93508201015f61316a565b85548784018501529485019486945091830191613280565b91906132bc828285613391565b9282156132d957096132cb5790565b6001810180911161067e5790565b634e487b7160e01b5f52601260045260245ffd5b905f1981830981830291828083109203918083039214613386576127109082821115613349577fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e91940990828211900360fc1b910360041c170290565b60405162461bcd60e51b81526020600482015260156024820152744d6174683a206d756c446976206f766572666c6f7760581b6044820152606490fd5b505061271091500490565b915f19828409928281029283808610950394808603951461340557848311156133495782910960018219018216809204600280826003021880830282030280830282030280830282030280830282030280830282030280920290030293600183805f03040190848311900302920304170290565b5050809250156132d9570490565b9190820391821161067e57565b600254156134ea576040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611263575f916134b4575b5061349161349a9161348b614581565b90612a39565b600d5490612a39565b600e54808211156134ae57612d5b91613413565b50505f90565b906020823d82116134e2575b816134cd6020938361269c565b810103126134df57505161349161347b565b80fd5b3d91506134c0565b5f90565b156134f557565b60405162461bcd60e51b815260206004820152601060248201526f756e65787065637465642076616c756560801b6044820152606490fd5b6002600a541461353e576002600a55565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b1561358a57565b60405162461bcd60e51b815260206004820152600d60248201526c7265636569766572207a65726f60981b6044820152606490fd5b156135c657565b60405162461bcd60e51b815260206004820152600b60248201526a7a65726f2073686172657360a81b6044820152606490fd5b5f19811461067e5760010190565b9060016001600160401b038093160191821161067e57565b81811061362a575050565b5f815560010161361f565b61363f8154612582565b9081613649575050565b81601f5f931160011461365a575055565b908083918252613679601f60208420940160051c84016001850161361f565b5555565b90816020910312610337575180151581036103375790565b919290156136f757508151156136a9575090565b3b156136b25790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b82519091501561370a5750805190602001fd5b60405162461bcd60e51b8152602060048201529081906114a19060248301906124f7565b905f9160ff60125460101c1661382a5780156138245761374c613fad565b613814575b80831080613806575b6137f6575b808310806137e8575b6137d8575b8210806137ca575b6137ba575b6137856013546135f9565b601355816014556040518281527f4889d7d38c1d1f265318505a98367d07d41591d6b7f9cc000f37ea92b8311daa60203392a2565b906137c4906135f9565b9061377a565b506137d3614295565b613775565b916137e2906135f9565b9161376d565b506137f161443c565b613768565b91613800906135f9565b9161375f565b5061380f613990565b61375a565b9161381e906135f9565b91613751565b505f9150565b60405162461bcd60e51b815260206004820152600b60248201526a1c1bdad9481c185d5cd95960aa1b6044820152606490fd5b91908110156115195760051b81013590601e19813603018212156103375701908135916001600160401b038311610337576020018236038113610337579190565b91908110156115195760051b0190565b3561ffff811681036103375790565b9190916040808285031261033757815193602091828401516001600160401b0394858211610337570190808284031261033757805194818601868110828211176105a8578252825190811161033757820183601f820112156103375780519361393161392886612d5e565b9351938461269c565b84835285858301011161033757849361394f918580850191016124d6565b845201519082015290565b92919261396682612d5e565b91613974604051938461269c565b829481845281830111610337578281602093845f960137010152565b6001600160401b03601054165f52601660205260405f20805460ff811615908115613f9f575b508015613f93575b613f8e576139ca61443c565b506001810154906139da82612d30565b9161010061ffff198354161782558260028301553015613f3f57305f525f60205260405f205490808210613eef57805f923084528360205203604083205580600254036002556040519081525f805160206146d983398151915260203092a3613a4161461f565b82811015613ee557613a5a905b80613ebc575b83613413565b905f9180613b1a575b50613ad86001827f5d78323b7b570071308d257743c74a9a2401f77d37e9de9f908da12c8917a40b606060076001600160401b0396019786199889815416898916179055600484015415613afc575b60105497878916958695015491604051928352602083015260070b6040820152a2613607565b1691829116176010555f52601660205260405f20600160ff19825416179055600190565b835462ff000019166201000017845560038401546005850155613ab2565b600b545f95935015613e8757613b2e6144d3565b50915f925b600b54841080613e7e575b15613e2757613b4c84612566565b509060028201548181105f14613e1f57915b8215613e1357604051630fb6accf60e21b81529060208280613b858785306004850161426b565b03815f6108005af1918215611263575f92613dd5575b50613baa846002830154613413565b6002820155600c613bbc858254613413565b9055600d613bcb858254612a39565b9055600e613bda858254612a39565b9055613bea846004880154612a39565b6004870155613c0e613c1560405192613c0284612666565b604051928380926125ba565b038261269c565b81528360208201528160070b60408201526008860154600160401b8110156105a8576001810180600889015581101561151957600887015f5260205f209082518051906001600160401b0382116105a857613c7560038402850154612582565b90601f91828111613d98575b506020918311600114613d22579282604095936003936002965f92613d17575b50508160011b915f1990851b1c1916178282028401555b60208601516001838302850101550201019101516001600160401b0319825416906001600160401b03161790558760070b8160070b13613d0d575b50613d0791613d0191613413565b936135f9565b92613b33565b9650613d07613cf3565b015190505f80613ca1565b906003840285015f5260205f20915f5b601f1985168110613d805750836003936002969360019360409997601f19811610613d69575b505050811b01828202840155613cb8565b01515f1983871b60f8161c191690555f8080613d58565b91926020600181928685015181550194019201613d32565b613dc6906003860287015f5260205f20600585808801821c83019360208910613dcc575b01901c019061361f565b5f613c81565b93508293613dbc565b9091506020813d602011613e0b575b81613df16020938361269c565b8101031261033757518060070b810361033757905f613b9b565b3d9150613de4565b5093613d0791506135f9565b508091613b5e565b9094919250613e395790613ad8613a63565b60405162461bcd60e51b815260206004820152601d60248201527f696e73756666696369656e742064656c656761746564206173736574730000006044820152606490fd5b50801515613b3e565b60405162461bcd60e51b815260206004820152600d60248201526c6e6f2076616c696461746f727360981b6044820152606490fd5b613ec881600e54612a39565b600e55613ed781600f54612a39565b600f55806003840155613a54565b50613a5a82613a4e565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608490fd5b505f90565b506001810154156139be565b60ff915060081c165f6139b6565b601080546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692916001600160401b03604092831c81169290915b80549083851694848316861015614260575f9786895260209560168752858a2094855460ff808260081c1615918215614254575b50508015614248575b614201575060078501541642106141d55760048085015491828b600f938454938b6140588887612a39565b9260248d51809481936370a0823160e01b835230908301525afa9283156141ca5792614177575b50917f73f330dd18a8f4760be8fa04b392ba243a76dcbe07487724e846182d63dbfafa9b9c9d82846140fa97956141169a99979510614145575b5050506140ee918491600d6140cf828254613413565b90556140e7836140e2600e938454613413565b612a39565b9055612a39565b90556003860154612a39565b60058501908155845462ff000019166201000017909455613607565b815467ffffffffffffffff60401b191690841b67ffffffffffffffff60401b16179055549051908152a2600190565b6140ee94969161415491613413565b9081811115614170576141679250613413565b93915f806140b9565b5050614167565b9091508a81813d83116141c3575b61418f818361269c565b810103126141bf5751907f73f330dd18a8f4760be8fa04b392ba243a76dcbe07487724e846182d63dbfafa61407f565b8d80fd5b503d614185565b8b51903d90823e3d90fd5b50815467ffffffffffffffff60401b1916931b67ffffffffffffffff60401b1692909217909155505050565b92939750955097508492506001600160401b0360401b61422083613607565b67ffffffffffffffff60401b1990921691851b1617855516828114612e195760010192613ff0565b5060048601541561402d565b871c1690505f80614024565b505f96505050505050565b9392916142909060409260018060a01b031686526060602087015260608601906125ba565b930152565b600290815415614437576142a761461f565b908115801561442d575b614426576142bd6144d3565b505f90825b600b548084108061441d575b156144125760019081850180861161067e57036143f25750805b81156143e7576142f784612566565b5060408051906353266bbb60e01b825260209182818061431d89600498308a850161426b565b03815f6108005af19081156143dd575f916143b0575b501561437d5750505061437791614371918761434e87612566565b500161435b838254612a39565b9055600c61436a838254612a39565b9055613413565b926135f9565b916142c2565b5162461bcd60e51b815291820152600f60248201526e19195b1959d85d194819985a5b1959608a1b604482015260649150fd5b6143d09150833d85116143d6575b6143c8818361269c565b81019061367d565b5f614333565b503d6143be565b82513d5f823e3d90fd5b9261437791506135f9565b61ffff61440c9161440286612566565b50015416856132ed565b906142e8565b505092505050600190565b508115156142ce565b9150505f90565b50600b54156142b1565b5f9150565b600b541580156144a2575b6134ea5763ffffffff600b541660405190632efe8a5f60e01b825230600483015260248201526020816044815f6108015af1908115611263575f9161448a575090565b612d5b915060203d81116143d6576143c8818361269c565b506144ab6144d3565b15614447565b6001600160a01b039091168152604060208201819052612d5b929101906125ba565b5f9081805b600b54821015614578576144eb82612566565b5061450d8560409283518093819263120bba7360e11b835230600484016144b1565b03816108005afa91821561456f57509160206145479261454d948891614553575b50018051600261453d87612566565b5001555190612a39565b916135f9565b906144d8565b61456791503d808a833e611255818361269c565b90505f61452e565b513d87823e3d90fd5b92505081600c55565b5f905f80600b545b80831061459557505050565b9091936145a185612566565b506145c38460409283518093819263120bba7360e11b835230600484016144b1565b03816108005afa91821561461657509160206145ed926145f39487916145fa575b50015190612a39565b946135f9565b9190614589565b61460e91503d8089833e611255818361269c565b90505f6145e4565b513d86823e3d90fd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611263575f91614687575b50600f54808211156134ae57612d5b91613413565b906020823d82116146b0575b816146a06020938361269c565b810103126134df5750515f614672565b3d915061469356fe537472696e67733a20686578206c656e67746820696e73756666696369656e74ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212203dea20cc054fb9b8e55a057442460f9c400c356156d57798f5f876718474fdfd64736f6c63430008140033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": { + "1500": [ + { + "length": 32, + "start": 5949 + }, + { + "length": 32, + "start": 7067 + }, + { + "length": 32, + "start": 13379 + }, + { + "length": 32, + "start": 16315 + }, + { + "length": 32, + "start": 17978 + } + ], + "1502": [ + { + "length": 32, + "start": 8558 + } + ], + "3919": [ + { + "length": 32, + "start": 12304 + } + ], + "3921": [ + { + "length": 32, + "start": 12507 + } + ], + "3923": [ + { + "length": 32, + "start": 12250 + } + ], + "3925": [ + { + "length": 32, + "start": 12383 + } + ], + "3927": [ + { + "length": 32, + "start": 12421 + } + ], + "3930": [ + { + "length": 32, + "start": 2339 + } + ], + "3933": [ + { + "length": 32, + "start": 2380 + } + ] + }, + "inputSourceName": "project/solidity/StakedBondVault.sol", + "buildInfoId": "solc-0_8_20-fd423b4c4179889dc28271432fcc31676a09cfca" +} \ No newline at end of file diff --git a/contracts/solidity/StakedBondVault.sol b/contracts/solidity/StakedBondVault.sol new file mode 100644 index 00000000..f9759457 --- /dev/null +++ b/contracts/solidity/StakedBondVault.sol @@ -0,0 +1,490 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/access/AccessControl.sol"; +import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import "@openzeppelin/contracts/utils/math/Math.sol"; + +import "./precompiles/distribution/DistributionI.sol"; +import "./precompiles/staking/StakingI.sol"; + +contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard { + using Math for uint256; + using SafeERC20 for IERC20; + + bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE"); + bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); + + address public constant NATIVE_WERC20 = 0xD4949664cD82660AaE99bEdc034a0deA8A0bd517; + uint256 public constant MAX_VALIDATORS = 32; + uint16 public constant WEIGHT_SCALE = 10_000; + + struct ValidatorTarget { + string operatorAddress; + uint16 weight; + uint256 delegated; + } + + struct WithdrawalRequest { + address owner; + address receiver; + uint64 batchId; + uint256 shares; + } + + struct UnbondingEntry { + string validatorAddress; + uint256 expectedAssets; + int64 completionTime; + } + + struct WithdrawalBatch { + bool open; + bool processed; + bool claimable; + uint64 requestCount; + uint64 claimedCount; + uint256 totalShares; + uint256 estimatedAssets; + uint256 liquidAssets; + uint256 unbondingAssets; + uint256 settledAssets; + uint256 claimedAssets; + int64 maturityTime; + UnbondingEntry[] unbondingEntries; + } + + ValidatorTarget[] public validators; + uint256 public totalDelegated; + uint256 public totalWithdrawalUnbonding; + uint256 public totalReservedAssets; + uint256 public totalLiquidReserved; + uint64 public currentBatchId; + uint64 public nextSettlementBatchId; + uint256 public nextRequestId = 1; + bool public depositsPaused; + bool public withdrawalsPaused; + bool public pokePaused; + uint256 public pokeCount; + uint256 public lastPokeOps; + + mapping(uint256 => WithdrawalRequest) public withdrawalRequests; + mapping(uint64 => WithdrawalBatch) private withdrawalBatches; + + event ValidatorsUpdated(uint256 count); + event WithdrawalRequested(uint256 indexed requestId, uint64 indexed batchId, address indexed owner, address receiver, uint256 shares); + event WithdrawalBatchProcessed(uint64 indexed batchId, uint256 shares, uint256 estimatedAssets, int64 maturityTime); + event WithdrawalBatchSettled(uint64 indexed batchId, uint256 settledAssets); + event WithdrawalClaimed(uint256 indexed requestId, uint64 indexed batchId, address indexed receiver, uint256 assets); + event Poked(address indexed caller, uint256 ops); + + modifier noNativeValue() { + require(msg.value == 0, "unexpected value"); + _; + } + + constructor(address admin, string memory name_, string memory symbol_) + ERC20(name_, symbol_) + ERC20Permit(name_) + ERC4626(IERC20Metadata(NATIVE_WERC20)) + { + require(admin != address(0), "admin zero"); + _grantRole(DEFAULT_ADMIN_ROLE, admin); + _grantRole(OPERATOR_ROLE, admin); + _grantRole(PAUSER_ROLE, admin); + currentBatchId = 1; + nextSettlementBatchId = 1; + withdrawalBatches[currentBatchId].open = true; + } + + function totalAssets() public view override returns (uint256) { + if (totalSupply() == 0) { + return 0; + } + uint256 gross = IERC20(asset()).balanceOf(address(this)) + _liveDelegatedAssets() + totalWithdrawalUnbonding; + if (gross <= totalReservedAssets) { + return 0; + } + return gross - totalReservedAssets; + } + + function liveDelegatedAssets() external view returns (uint256) { + return _liveDelegatedAssets(); + } + + function syncDelegations() external payable noNativeValue nonReentrant returns (uint256) { + return _syncDelegations(); + } + + function decimals() public view override(ERC20, ERC4626) returns (uint8) { + return ERC4626.decimals(); + } + + function maxDeposit(address) public pure override returns (uint256) { + return 0; + } + + function maxMint(address) public pure override returns (uint256) { + return 0; + } + + function maxWithdraw(address) public pure override returns (uint256) { + return 0; + } + + function maxRedeem(address) public pure override returns (uint256) { + return 0; + } + + function deposit(uint256, address) public pure override returns (uint256) { + revert("use depositNative"); + } + + function mint(uint256, address) public pure override returns (uint256) { + revert("use depositNative"); + } + + function depositNative(address receiver) external payable nonReentrant returns (uint256 shares) { + require(!depositsPaused, "deposits paused"); + require(receiver != address(0), "receiver zero"); + require(msg.value > 0, "zero assets"); + _harvest(); + + uint256 assets = msg.value; + uint256 supply = totalSupply(); + if (supply == 0) { + shares = assets; + } else { + uint256 assetsAfter = totalAssets(); + uint256 assetsBefore = assetsAfter > assets ? assetsAfter - assets : 0; + shares = assets.mulDiv(supply + 1, assetsBefore + 1, Math.Rounding.Down); + } + require(shares > 0, "zero shares"); + _mint(receiver, shares); + emit Deposit(msg.sender, receiver, assets, shares); + } + + function withdraw(uint256, address, address) public pure override returns (uint256) { + revert("use requestRedeem"); + } + + function redeem(uint256, address, address) public pure override returns (uint256) { + revert("use requestRedeem"); + } + + function requestRedeem(uint256 shares, address receiver, address owner) external payable noNativeValue nonReentrant returns (uint256 requestId) { + require(!withdrawalsPaused, "withdrawals paused"); + require(shares > 0, "zero shares"); + require(receiver != address(0), "receiver zero"); + require(owner != address(0), "owner zero"); + if (msg.sender != owner) { + _spendAllowance(owner, msg.sender, shares); + } + + _transfer(owner, address(this), shares); + requestId = nextRequestId++; + WithdrawalBatch storage batch = _openBatch(); + withdrawalRequests[requestId] = WithdrawalRequest({ + owner: owner, + receiver: receiver, + batchId: currentBatchId, + shares: shares + }); + batch.totalShares += shares; + batch.requestCount += 1; + emit WithdrawalRequested(requestId, currentBatchId, owner, receiver, shares); + } + + function claimRedeem(uint256 requestId, address receiver) external payable noNativeValue nonReentrant returns (uint256 assetsOut) { + WithdrawalRequest memory request = withdrawalRequests[requestId]; + require(request.owner != address(0), "unknown request"); + + WithdrawalBatch storage batch = withdrawalBatches[request.batchId]; + require(batch.claimable, "not claimable"); + address payout = receiver == address(0) ? request.receiver : receiver; + require(payout == request.receiver, "wrong receiver"); + + if (batch.claimedCount + 1 == batch.requestCount) { + assetsOut = batch.settledAssets - batch.claimedAssets; + } else { + assetsOut = request.shares.mulDiv(batch.settledAssets, batch.totalShares, Math.Rounding.Down); + } + batch.claimedCount += 1; + batch.claimedAssets += assetsOut; + totalReservedAssets -= assetsOut; + totalLiquidReserved -= assetsOut; + delete withdrawalRequests[requestId]; + IERC20(asset()).safeTransfer(payout, assetsOut); + emit WithdrawalClaimed(requestId, request.batchId, payout, assetsOut); + + if (batch.claimedCount == batch.requestCount) { + delete withdrawalBatches[request.batchId]; + } + } + + function poke(uint256 maxOps) external payable noNativeValue nonReentrant returns (uint256 ops) { + require(!pokePaused, "poke paused"); + if (maxOps == 0) { + return 0; + } + if (_settleMatureBatch()) { + ops++; + } + if (ops < maxOps && _processCurrentBatch()) { + ops++; + } + if (ops < maxOps && _harvest()) { + ops++; + } + if (ops < maxOps && _stakeIdle()) { + ops++; + } + pokeCount++; + lastPokeOps = ops; + emit Poked(msg.sender, ops); + } + + function setPaused(bool deposits, bool withdrawals, bool scheduler) external payable noNativeValue onlyRole(PAUSER_ROLE) { + depositsPaused = deposits; + withdrawalsPaused = withdrawals; + pokePaused = scheduler; + } + + function setValidators(string[] calldata operatorAddresses, uint16[] calldata weights) external payable noNativeValue onlyRole(OPERATOR_ROLE) { + require(operatorAddresses.length == weights.length, "length mismatch"); + require(operatorAddresses.length <= MAX_VALIDATORS, "too many validators"); + + uint256 totalWeight; + uint256 oldDelegated = _syncDelegations(); + delete validators; + for (uint256 i = 0; i < operatorAddresses.length; i++) { + require(bytes(operatorAddresses[i]).length != 0, "empty validator"); + require(weights[i] > 0, "zero weight"); + STAKING_CONTRACT.delegation(address(this), operatorAddresses[i]); + bytes32 operatorHash = keccak256(bytes(operatorAddresses[i])); + for (uint256 j = 0; j < i; j++) { + require(operatorHash != keccak256(bytes(operatorAddresses[j])), "duplicate validator"); + } + totalWeight += weights[i]; + validators.push(ValidatorTarget({ + operatorAddress: operatorAddresses[i], + weight: weights[i], + delegated: 0 + })); + } + require(totalWeight == WEIGHT_SCALE || operatorAddresses.length == 0, "bad weights"); + require(oldDelegated == 0, "delegations active"); + emit ValidatorsUpdated(operatorAddresses.length); + } + + function withdrawalBatch(uint64 batchId) + external + view + returns ( + bool open, + bool processed, + bool claimable, + uint64 requestCount, + uint64 claimedCount, + uint256 totalShares_, + uint256 estimatedAssets, + uint256 liquidAssets, + uint256 unbondingAssets, + uint256 settledAssets, + uint256 claimedAssets, + int64 maturityTime + ) + { + WithdrawalBatch storage batch = withdrawalBatches[batchId]; + return ( + batch.open, + batch.processed, + batch.claimable, + batch.requestCount, + batch.claimedCount, + batch.totalShares, + batch.estimatedAssets, + batch.liquidAssets, + batch.unbondingAssets, + batch.settledAssets, + batch.claimedAssets, + batch.maturityTime + ); + } + + function validatorCount() external view returns (uint256) { + return validators.length; + } + + function _openBatch() internal returns (WithdrawalBatch storage batch) { + batch = withdrawalBatches[currentBatchId]; + if (!batch.open || batch.processed) { + currentBatchId += 1; + batch = withdrawalBatches[currentBatchId]; + batch.open = true; + } + } + + function _processCurrentBatch() internal returns (bool) { + WithdrawalBatch storage batch = withdrawalBatches[currentBatchId]; + if (!batch.open || batch.processed || batch.totalShares == 0) { + return false; + } + + _harvest(); + uint256 assetsOut = convertToAssets(batch.totalShares); + batch.open = false; + batch.processed = true; + batch.estimatedAssets = assetsOut; + _burn(address(this), batch.totalShares); + + uint256 liquid = _min(_freeLiquid(), assetsOut); + if (liquid != 0) { + totalReservedAssets += liquid; + totalLiquidReserved += liquid; + batch.liquidAssets = liquid; + } + + uint256 remaining = assetsOut - liquid; + int64 maturity; + if (remaining != 0) { + maturity = _undelegateForBatch(batch, remaining); + } + batch.maturityTime = maturity; + if (batch.unbondingAssets == 0) { + batch.claimable = true; + batch.settledAssets = batch.liquidAssets; + } + emit WithdrawalBatchProcessed(currentBatchId, batch.totalShares, assetsOut, maturity); + + currentBatchId += 1; + withdrawalBatches[currentBatchId].open = true; + return true; + } + + function _settleMatureBatch() internal returns (bool) { + for (uint64 batchId = nextSettlementBatchId; batchId < currentBatchId; batchId++) { + WithdrawalBatch storage batch = withdrawalBatches[batchId]; + if (!batch.processed || batch.claimable || batch.unbondingAssets == 0) { + nextSettlementBatchId = batchId + 1; + continue; + } + if (block.timestamp < uint256(uint64(batch.maturityTime))) { + nextSettlementBatchId = batchId; + return false; + } + + uint256 expected = batch.unbondingAssets; + uint256 matured = expected; + uint256 requiredLiquid = totalLiquidReserved + expected; + uint256 balance = IERC20(asset()).balanceOf(address(this)); + if (balance < requiredLiquid) { + uint256 shortfall = requiredLiquid - balance; + matured = expected > shortfall ? expected - shortfall : 0; + } + + totalWithdrawalUnbonding -= expected; + totalReservedAssets = totalReservedAssets - expected + matured; + totalLiquidReserved += matured; + batch.settledAssets = batch.liquidAssets + matured; + batch.claimable = true; + nextSettlementBatchId = batchId + 1; + emit WithdrawalBatchSettled(batchId, batch.settledAssets); + return true; + } + return false; + } + + function _undelegateForBatch(WithdrawalBatch storage batch, uint256 assetsNeeded) internal returns (int64 maturity) { + require(validators.length != 0, "no validators"); + _syncDelegations(); + uint256 remaining = assetsNeeded; + for (uint256 i = 0; i < validators.length && remaining != 0; i++) { + ValidatorTarget storage target = validators[i]; + uint256 amount = _min(target.delegated, remaining); + if (amount == 0) { + continue; + } + int64 completion = STAKING_CONTRACT.undelegate(address(this), target.operatorAddress, amount); + target.delegated -= amount; + totalDelegated -= amount; + totalWithdrawalUnbonding += amount; + totalReservedAssets += amount; + batch.unbondingAssets += amount; + batch.unbondingEntries.push(UnbondingEntry({ + validatorAddress: target.operatorAddress, + expectedAssets: amount, + completionTime: completion + })); + if (completion > maturity) { + maturity = completion; + } + remaining -= amount; + } + require(remaining == 0, "insufficient delegated assets"); + } + + function _stakeIdle() internal returns (bool) { + if (totalSupply() == 0) { + return false; + } + uint256 free = _freeLiquid(); + if (free == 0 || validators.length == 0) { + return false; + } + _syncDelegations(); + uint256 remaining = free; + for (uint256 i = 0; i < validators.length && remaining != 0; i++) { + uint256 amount = i + 1 == validators.length + ? remaining + : free.mulDiv(validators[i].weight, WEIGHT_SCALE, Math.Rounding.Down); + if (amount == 0) { + continue; + } + bool success = STAKING_CONTRACT.delegate(address(this), validators[i].operatorAddress, amount); + require(success, "delegate failed"); + validators[i].delegated += amount; + totalDelegated += amount; + remaining -= amount; + } + return true; + } + + function _harvest() internal returns (bool) { + if (validators.length == 0 || _syncDelegations() == 0) { + return false; + } + return DISTRIBUTION_CONTRACT.claimRewards(address(this), uint32(validators.length)); + } + + function _syncDelegations() internal returns (uint256 syncedTotal) { + for (uint256 i = 0; i < validators.length; i++) { + (, Coin memory balance) = STAKING_CONTRACT.delegation(address(this), validators[i].operatorAddress); + validators[i].delegated = balance.amount; + syncedTotal += balance.amount; + } + totalDelegated = syncedTotal; + } + + function _liveDelegatedAssets() internal view returns (uint256 assets_) { + for (uint256 i = 0; i < validators.length; i++) { + (, Coin memory balance) = STAKING_CONTRACT.delegation(address(this), validators[i].operatorAddress); + assets_ += balance.amount; + } + } + + function _freeLiquid() internal view returns (uint256) { + uint256 balance = IERC20(asset()).balanceOf(address(this)); + if (balance <= totalLiquidReserved) { + return 0; + } + return balance - totalLiquidReserved; + } + + function _min(uint256 a, uint256 b) private pure returns (uint256) { + return a < b ? a : b; + } +} diff --git a/contracts/staked_bond_vault.go b/contracts/staked_bond_vault.go new file mode 100644 index 00000000..41d961fe --- /dev/null +++ b/contracts/staked_bond_vault.go @@ -0,0 +1,27 @@ +package contracts + +import ( + _ "embed" + + contractutils "github.com/cosmos/evm/contracts/utils" + evmtypes "github.com/cosmos/evm/x/vm/types" +) + +var ( + // StakedBondVaultJSON are the compiled bytes of the StakedBondVault contract. + // + //go:embed solidity/StakedBondVault.json + StakedBondVaultJSON []byte + + // StakedBondVaultContract is the compiled ERC4626-style staking vault. + StakedBondVaultContract evmtypes.CompiledContract +) + +func init() { + var err error + if StakedBondVaultContract, err = contractutils.ConvertHardhatBytesToCompiledContract( + StakedBondVaultJSON, + ); err != nil { + panic(err) + } +} diff --git a/evmd/app.go b/evmd/app.go index 4e65f60a..2b706887 100644 --- a/evmd/app.go +++ b/evmd/app.go @@ -298,7 +298,11 @@ func NewExampleApp( app.ParamsKeeper.Subspace(poatypes.ModuleName).WithKeyTable(poatypes.ParamKeyTable()) // get authority address - authAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + accountAddressCodec := evmaddress.NewEvmCodec(sdk.GetConfig().GetBech32AccountAddrPrefix()) + authAddr, err := accountAddressCodec.BytesToString(authtypes.NewModuleAddress(govtypes.ModuleName)) + if err != nil { + panic(fmt.Errorf("failed to encode gov authority address: %w", err)) + } // set the BaseApp's parameter store app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper( @@ -313,7 +317,7 @@ func NewExampleApp( app.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, runtime.NewKVStoreService(keys[authtypes.StoreKey]), authtypes.ProtoBaseAccount, evmconfig.GetMaccPerms(), - evmaddress.NewEvmCodec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + accountAddressCodec, sdk.GetConfig().GetBech32AccountAddrPrefix(), authAddr, ) @@ -334,7 +338,7 @@ func NewExampleApp( EnabledSignModes: enabledSignModes, TextualCoinMetadataQueryFn: txmodule.NewBankKeeperCoinMetadataQueryFn(app.BankKeeper), } - txConfig, err := authtx.NewTxConfigWithOptions( + txConfig, err = authtx.NewTxConfigWithOptions( appCodec, txConfigOpts, ) diff --git a/proto/cosmos/evm/vm/v1/evm.proto b/proto/cosmos/evm/vm/v1/evm.proto index ea22da1f..b4a4e470 100644 --- a/proto/cosmos/evm/vm/v1/evm.proto +++ b/proto/cosmos/evm/vm/v1/evm.proto @@ -37,12 +37,29 @@ message Params { repeated string active_static_precompiles = 9; uint64 history_serve_window = 10; ExtendedDenomOptions extended_denom_options = 11; + // scheduler defines an optional bounded EndBlock EVM call used for + // contract-owned maintenance such as vault settlement. + EVMSchedulerParams scheduler = 12 + [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ]; } message ExtendedDenomOptions { string extended_denom = 1; } +message EVMSchedulerParams { + // enabled controls whether EndBlock attempts the configured call. + bool enabled = 1; + // target_contract is the EVM contract called with poke(uint256). + string target_contract = 2; + // gas_cap is the EVM gas limit for the scheduler call. + uint64 gas_cap = 3; + // max_ops is passed as the poke(uint256) argument. + uint32 max_ops = 4; + // cadence_blocks runs the call only when block_height % cadence_blocks == 0. + uint64 cadence_blocks = 5; +} + // AccessControl defines the permission policy of the EVM // for creating and calling contracts message AccessControl { @@ -359,4 +376,4 @@ message EvmCoinInfo { string extended_denom = 2; string display_denom = 3; uint32 decimals = 4; -} \ No newline at end of file +} From 5dcd3200a9b75aa7f6050f3cf70ea0325ae974e8 Mon Sep 17 00:00:00 2001 From: Rahul Ghangas Date: Mon, 1 Jun 2026 12:25:19 +0000 Subject: [PATCH 3/5] test: vault and scheduler --- .../integration/precompiles/gov/test_setup.go | 6 +- .../integration/wallets/test_ledger_suite.go | 21 +- tests/integration/wallets/test_legder.go | 2 +- .../integration/x/erc20/test_ibc_callback.go | 31 +- tests/integration/x/erc20/test_msg_server.go | 2 +- tests/integration/x/erc20/test_proposals.go | 8 +- .../x/feemarket/test_msg_server.go | 5 +- tests/integration/x/ibc/test_msg_server.go | 6 +- .../integration/x/precisebank/test_genesis.go | 5 +- tests/integration/x/vm/keeper_test_suite.go | 7 + tests/integration/x/vm/test_msg_server.go | 7 +- tests/integration/x/vm/test_scheduler.go | 93 ++ .../x/vm/test_staked_bond_vault.go | 1042 +++++++++++++++++ .../integration/x/vm/test_state_transition.go | 3 +- testutil/integration/evm/utils/address.go | 21 + testutil/integration/evm/utils/erc20.go | 5 +- testutil/integration/evm/utils/params.go | 5 +- 17 files changed, 1224 insertions(+), 45 deletions(-) create mode 100644 tests/integration/x/vm/test_scheduler.go create mode 100644 tests/integration/x/vm/test_staked_bond_vault.go create mode 100644 testutil/integration/evm/utils/address.go diff --git a/tests/integration/precompiles/gov/test_setup.go b/tests/integration/precompiles/gov/test_setup.go index d172947e..bb5d982a 100644 --- a/tests/integration/precompiles/gov/test_setup.go +++ b/tests/integration/precompiles/gov/test_setup.go @@ -57,6 +57,10 @@ func (s *PrecompileTestSuite) SetupTest() { if err != nil { panic(err) } + govAddress := sdk.MustBech32ifyAddressBytes( + sdk.GetConfig().GetBech32AccountAddrPrefix(), + authtypes.NewModuleAddress(govtypes.ModuleName), + ) prop := &govv1.Proposal{ Id: 1, Status: govv1.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD, @@ -99,7 +103,7 @@ func (s *PrecompileTestSuite) SetupTest() { bankGen := banktypes.DefaultGenesisState() bankGen.Balances = []banktypes.Balance{{ - Address: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Address: govAddress, Coins: sdk.NewCoins(sdk.NewCoin(testconstants.ExampleAttoDenom, math.NewInt(200))), }} govGen := govv1.DefaultGenesisState() diff --git a/tests/integration/wallets/test_ledger_suite.go b/tests/integration/wallets/test_ledger_suite.go index 0055c651..3ee0f4f2 100644 --- a/tests/integration/wallets/test_ledger_suite.go +++ b/tests/integration/wallets/test_ledger_suite.go @@ -5,6 +5,7 @@ import ( "fmt" "regexp" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/suite" "github.com/cosmos/evm/testutil/constants" @@ -75,6 +76,8 @@ func (suite *LedgerTestSuite) newPubKey(pk string) (res cryptotypes.PubKey) { func (suite *LedgerTestSuite) getMockTxAmino() []byte { whitespaceRegex := regexp.MustCompile(`\s+`) + fromAddress := bech32LedgerAddress("0x1111111111111111111111111111111111111111") + toAddress := bech32LedgerAddress("0x2222222222222222222222222222222222222222") tmp := whitespaceRegex.ReplaceAllString(fmt.Sprintf( `{ "account_number": "0", @@ -88,12 +91,12 @@ func (suite *LedgerTestSuite) getMockTxAmino() []byte { "type":"cosmos-sdk/MsgSend", "value":{ "amount":[{"amount":"150","denom":"atom"}], - "from_address":"og1cml96vmptgw99syqrrz8az79xer2pcgpum8mp7", - "to_address":"og1jcltmuhplrdcwp7stlr4hlhlhgd4htqhgdvy48" + "from_address":"%s", + "to_address":"%s" } }], "sequence":"6" - }`, constants.ExampleChainID.ChainID), + }`, constants.ExampleChainID.ChainID, fromAddress, toAddress), "", ) @@ -105,8 +108,8 @@ func (suite *LedgerTestSuite) getMockTxProtobuf() []byte { memo := "memo" msg := banktypes.NewMsgSend( - sdk.MustAccAddressFromBech32("og1cml96vmptgw99syqrrz8az79xer2pcgpum8mp7"), - sdk.MustAccAddressFromBech32("og1jcltmuhplrdcwp7stlr4hlhlhgd4htqhgdvy48"), + ledgerAccAddress("0x1111111111111111111111111111111111111111"), + ledgerAccAddress("0x2222222222222222222222222222222222222222"), []sdk.Coin{ { Denom: "atom", @@ -164,3 +167,11 @@ func (suite *LedgerTestSuite) getMockTxProtobuf() []byte { return signBytes } + +func ledgerAccAddress(hexAddress string) sdk.AccAddress { + return common.HexToAddress(hexAddress).Bytes() +} + +func bech32LedgerAddress(hexAddress string) string { + return sdk.MustBech32ifyAddressBytes(sdk.GetConfig().GetBech32AccountAddrPrefix(), ledgerAccAddress(hexAddress)) +} diff --git a/tests/integration/wallets/test_legder.go b/tests/integration/wallets/test_legder.go index 8f8a915c..0e53cf7d 100644 --- a/tests/integration/wallets/test_legder.go +++ b/tests/integration/wallets/test_legder.go @@ -205,7 +205,7 @@ func (suite *LedgerTestSuite) TestGetAddressPubKeySECP256K1() { suite.Require().NoError(err) addr := crypto.PubkeyToAddress(privKey.PublicKey) - expAddr, err := sdk.Bech32ifyAddressBytes("cosmos", common.HexToAddress(addr.String()).Bytes()) + expAddr, err := sdk.Bech32ifyAddressBytes(suite.hrp, common.HexToAddress(addr.String()).Bytes()) suite.Require().NoError(err) testCases := []struct { diff --git a/tests/integration/x/erc20/test_ibc_callback.go b/tests/integration/x/erc20/test_ibc_callback.go index 85beefe0..16bdcc4a 100644 --- a/tests/integration/x/erc20/test_ibc_callback.go +++ b/tests/integration/x/erc20/test_ibc_callback.go @@ -11,6 +11,7 @@ import ( "github.com/cosmos/evm/contracts" "github.com/cosmos/evm/crypto/ethsecp256k1" "github.com/cosmos/evm/testutil" + testutils "github.com/cosmos/evm/testutil/integration/evm/utils" "github.com/cosmos/evm/utils" "github.com/cosmos/evm/x/erc20/keeper" "github.com/cosmos/evm/x/erc20/types" @@ -34,17 +35,18 @@ var erc20Denom = "erc20:0xdac17f958d2ee523a2206206994597c13d831ec7" func (s *KeeperTestSuite) TestOnRecvPacketRegistered() { var ctx sdk.Context + bech32Prefix := sdk.GetConfig().GetBech32AccountAddrPrefix() // secp256k1 account secpPk := secp256k1.GenPrivKey() secpAddr := sdk.AccAddress(secpPk.PubKey().Address()) - secpAddrCosmos := sdk.MustBech32ifyAddressBytes(sdk.Bech32MainPrefix, secpAddr) + secpAddrBech32 := sdk.MustBech32ifyAddressBytes(bech32Prefix, secpAddr) // ethsecp256k1 account ethPk, err := ethsecp256k1.GenerateKey() s.Require().Nil(err) ethsecpAddr := sdk.AccAddress(ethPk.PubKey().Address()) ethsecpAddrEvmos := sdk.AccAddress(ethPk.PubKey().Address()).String() - ethsecpAddrCosmos := sdk.MustBech32ifyAddressBytes(sdk.Bech32MainPrefix, ethsecpAddr) + ethsecpAddrBech32 := sdk.MustBech32ifyAddressBytes(bech32Prefix, ethsecpAddr) // Setup Cosmos <=> Cosmos EVM IBC relayer sourceChannel := "channel-292" @@ -91,7 +93,7 @@ func (s *KeeperTestSuite) TestOnRecvPacketRegistered() { { name: "no-op - erc20 module param disabled", malleate: func() { - transfer := transfertypes.NewFungibleTokenPacketData(registeredDenom, "100", ethsecpAddrEvmos, ethsecpAddrCosmos, "") + transfer := transfertypes.NewFungibleTokenPacketData(registeredDenom, "100", ethsecpAddrEvmos, ethsecpAddrBech32, "") bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) packet = channeltypes.NewPacket(bz, 1, transfertypes.PortID, sourceChannel, transfertypes.PortID, cosmosEVMChannel, timeoutHeight, 0) }, @@ -105,7 +107,7 @@ func (s *KeeperTestSuite) TestOnRecvPacketRegistered() { { name: "success - invalid sender (no '1')", malleate: func() { - transfer := transfertypes.NewFungibleTokenPacketData(registeredDenom, "100", "evmos", ethsecpAddrCosmos, "") + transfer := transfertypes.NewFungibleTokenPacketData(registeredDenom, "100", "evmos", ethsecpAddrBech32, "") bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cosmosEVMChannel, timeoutHeight, 0) }, @@ -118,7 +120,7 @@ func (s *KeeperTestSuite) TestOnRecvPacketRegistered() { { name: "success - invalid sender (bad address)", malleate: func() { - transfer := transfertypes.NewFungibleTokenPacketData(registeredDenom, "100", "badba1sv9m0g7ycejwr3s369km58h5qe7xj77hvcxrms", ethsecpAddrCosmos, "") + transfer := transfertypes.NewFungibleTokenPacketData(registeredDenom, "100", "badba1sv9m0g7ycejwr3s369km58h5qe7xj77hvcxrms", ethsecpAddrBech32, "") bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cosmosEVMChannel, timeoutHeight, 0) }, @@ -145,7 +147,7 @@ func (s *KeeperTestSuite) TestOnRecvPacketRegistered() { name: "no-op - receiver is module account", malleate: func() { secpAddr = s.network.App.GetAccountKeeper().GetModuleAccount(ctx, "erc20").GetAddress() - transfer := transfertypes.NewFungibleTokenPacketData(registeredDenom, "100", secpAddrCosmos, secpAddr.String(), "") + transfer := transfertypes.NewFungibleTokenPacketData(registeredDenom, "100", secpAddrBech32, secpAddr.String(), "") bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) packet = channeltypes.NewPacket(bz, 100, transfertypes.PortID, sourceChannel, transfertypes.PortID, cosmosEVMChannel, timeoutHeight, 0) }, @@ -163,7 +165,7 @@ func (s *KeeperTestSuite) TestOnRecvPacketRegistered() { bondDenom, err := s.network.App.GetStakingKeeper().BondDenom(ctx) s.Require().NoError(err) prefixedDenom := transfertypes.NewDenom(bondDenom, hop).Path() - transfer := transfertypes.NewFungibleTokenPacketData(prefixedDenom, "100", secpAddrCosmos, ethsecpAddrEvmos, "") + transfer := transfertypes.NewFungibleTokenPacketData(prefixedDenom, "100", secpAddrBech32, ethsecpAddrEvmos, "") bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) packet = channeltypes.NewPacket(bz, 1, transfertypes.PortID, sourceChannel, transfertypes.PortID, cosmosEVMChannel, timeoutHeight, 0) }, @@ -176,7 +178,7 @@ func (s *KeeperTestSuite) TestOnRecvPacketRegistered() { { name: "no-op - pair is not registered", malleate: func() { - transfer := transfertypes.NewFungibleTokenPacketData(erc20Denom, "100", secpAddrCosmos, ethsecpAddrEvmos, "") + transfer := transfertypes.NewFungibleTokenPacketData(erc20Denom, "100", secpAddrBech32, ethsecpAddrEvmos, "") bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) packet = channeltypes.NewPacket(bz, 1, transfertypes.PortID, sourceChannel, transfertypes.PortID, cosmosEVMChannel, timeoutHeight, 0) }, @@ -189,7 +191,7 @@ func (s *KeeperTestSuite) TestOnRecvPacketRegistered() { { name: "error - pair is not registered but erc20 registered", malleate: func() { - transfer := transfertypes.NewFungibleTokenPacketData(erc20Denom, "100", secpAddrCosmos, ethsecpAddrEvmos, "") + transfer := transfertypes.NewFungibleTokenPacketData(erc20Denom, "100", secpAddrBech32, ethsecpAddrEvmos, "") bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) packet = channeltypes.NewPacket(bz, 1, transfertypes.PortID, sourceChannel, transfertypes.PortID, cosmosEVMChannel, timeoutHeight, 0) collidedAddr, err := utils.GetIBCDenomAddress(transfertypes.NewDenom(erc20Denom, hop).IBCDenom()) @@ -206,7 +208,7 @@ func (s *KeeperTestSuite) TestOnRecvPacketRegistered() { { name: "error - pair is not registered but denom registered", malleate: func() { - transfer := transfertypes.NewFungibleTokenPacketData(erc20Denom, "100", secpAddrCosmos, ethsecpAddrEvmos, "") + transfer := transfertypes.NewFungibleTokenPacketData(erc20Denom, "100", secpAddrBech32, ethsecpAddrEvmos, "") bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) packet = channeltypes.NewPacket(bz, 1, transfertypes.PortID, sourceChannel, transfertypes.PortID, cosmosEVMChannel, timeoutHeight, 0) collidedDenom := transfertypes.NewDenom(erc20Denom, hop).IBCDenom() @@ -222,7 +224,7 @@ func (s *KeeperTestSuite) TestOnRecvPacketRegistered() { { name: "error - pair is not registered but address has code", malleate: func() { - transfer := transfertypes.NewFungibleTokenPacketData(erc20Denom, "100", secpAddrCosmos, ethsecpAddrEvmos, "") + transfer := transfertypes.NewFungibleTokenPacketData(erc20Denom, "100", secpAddrBech32, ethsecpAddrEvmos, "") bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer) packet = channeltypes.NewPacket(bz, 1, transfertypes.PortID, sourceChannel, transfertypes.PortID, cosmosEVMChannel, timeoutHeight, 0) collidedAddr, err := utils.GetIBCDenomAddress(transfertypes.NewDenom(erc20Denom, hop).IBCDenom()) @@ -326,7 +328,7 @@ func (s *KeeperTestSuite) TestOnRecvPacketRegistered() { if tc.disableTokenPair { _, err := s.network.App.GetErc20Keeper().ToggleConversion(ctx, &types.MsgToggleConversion{ - Authority: authtypes.NewModuleAddress("gov").String(), + Authority: testutils.GovAuthority(), Token: pair.Denom, }) s.Require().NoError(err) @@ -359,7 +361,10 @@ func (s *KeeperTestSuite) TestOnRecvPacketRegistered() { func (s *KeeperTestSuite) TestConvertCoinToERC20FromPacket() { var ctx sdk.Context - senderAddr := "cosmos1x2w87cvt5mqjncav4lxy8yfreynn273x34qlwy" + senderAddr := sdk.MustBech32ifyAddressBytes( + sdk.GetConfig().GetBech32AccountAddrPrefix(), + common.HexToAddress("0x329c175fa757b5d5d40187d4eb1e1efc62f12959").Bytes(), + ) baseDenom, err := sdk.GetBaseDenom() s.Require().NoError(err) diff --git a/tests/integration/x/erc20/test_msg_server.go b/tests/integration/x/erc20/test_msg_server.go index 06ed180d..55d4b252 100644 --- a/tests/integration/x/erc20/test_msg_server.go +++ b/tests/integration/x/erc20/test_msg_server.go @@ -693,7 +693,7 @@ func (s *KeeperTestSuite) TestUpdateParams() { { name: "pass - valid Update msg", request: &types.MsgUpdateParams{ - Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Authority: utils.GovAuthority(), Params: types.DefaultParams(), }, expectErr: false, diff --git a/tests/integration/x/erc20/test_proposals.go b/tests/integration/x/erc20/test_proposals.go index 997bd9d8..451b10a7 100644 --- a/tests/integration/x/erc20/test_proposals.go +++ b/tests/integration/x/erc20/test_proposals.go @@ -130,13 +130,13 @@ func (s *KeeperTestSuite) TestRegisterERC20() { func() { s.network.App.GetErc20Keeper().SetPermissionlessRegistration(ctx, false) }, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), + utils.GovAuthority(), true, }, { "ok - governance, permissionless true", func() {}, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), + utils.GovAuthority(), true, }, { @@ -299,7 +299,7 @@ func (s *KeeperTestSuite) TestToggleConverision() { ctx = s.network.GetContext() id = s.network.App.GetErc20Keeper().GetTokenPairID(ctx, contractAddr.String()) pair, _ = s.network.App.GetErc20Keeper().GetTokenPair(ctx, id) - res, err := s.network.App.GetErc20Keeper().ToggleConversion(ctx, &types.MsgToggleConversion{Authority: authtypes.NewModuleAddress("gov").String(), Token: contractAddr.String()}) + res, err := s.network.App.GetErc20Keeper().ToggleConversion(ctx, &types.MsgToggleConversion{Authority: utils.GovAuthority(), Token: contractAddr.String()}) s.Require().NoError(err) s.Require().NotNil(res) pair, _ = s.network.App.GetErc20Keeper().GetTokenPair(ctx, id) @@ -315,7 +315,7 @@ func (s *KeeperTestSuite) TestToggleConverision() { tc.malleate() - _, err = s.network.App.GetErc20Keeper().ToggleConversion(ctx, &types.MsgToggleConversion{Authority: authtypes.NewModuleAddress("gov").String(), Token: contractAddr.String()}) + _, err = s.network.App.GetErc20Keeper().ToggleConversion(ctx, &types.MsgToggleConversion{Authority: utils.GovAuthority(), Token: contractAddr.String()}) // Request the pair using the GetPairToken func to make sure that is updated on the db pair, _ = s.network.App.GetErc20Keeper().GetTokenPair(ctx, id) if tc.expPass { diff --git a/tests/integration/x/feemarket/test_msg_server.go b/tests/integration/x/feemarket/test_msg_server.go index b5b42850..7865af7a 100644 --- a/tests/integration/x/feemarket/test_msg_server.go +++ b/tests/integration/x/feemarket/test_msg_server.go @@ -2,11 +2,10 @@ package feemarket import ( "github.com/cosmos/evm/testutil/integration/evm/network" + testutils "github.com/cosmos/evm/testutil/integration/evm/utils" "github.com/cosmos/evm/x/feemarket/types" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) func (s *KeeperTestSuite) TestUpdateParams() { @@ -28,7 +27,7 @@ func (s *KeeperTestSuite) TestUpdateParams() { { name: "pass - valid Update msg", request: &types.MsgUpdateParams{ - Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Authority: testutils.GovAuthority(), Params: types.DefaultParams(), }, expectErr: false, diff --git a/tests/integration/x/ibc/test_msg_server.go b/tests/integration/x/ibc/test_msg_server.go index f9eb5719..a594166b 100644 --- a/tests/integration/x/ibc/test_msg_server.go +++ b/tests/integration/x/ibc/test_msg_server.go @@ -19,9 +19,7 @@ import ( "github.com/cosmos/cosmos-sdk/runtime" 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" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) func (suite *KeeperTestSuite) TestTransfer() { @@ -34,7 +32,7 @@ func (suite *KeeperTestSuite) TestTransfer() { mockChannelKeeper.On("GetNextSequenceSend", mock.Anything, mock.Anything, mock.Anything).Return(1, true) mockChannelKeeper.On("GetChannel", mock.Anything, mock.Anything, mock.Anything).Return(channeltypes.Channel{Counterparty: channeltypes.NewCounterparty("transfer", "channel-1")}, true) mockICS4Wrapper.On("SendPacket", mock.Anything, mock.Anything, mock.Anything).Return(nil) - authAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + authAddr := utils.GovAuthority() receiver := sdk.AccAddress([]byte("receiver")) chan0 := "channel-0" @@ -376,7 +374,7 @@ func (suite *KeeperTestSuite) TestPrefixTrimming() { mockChannelKeeper.On("GetNextSequenceSend", mock.Anything, mock.Anything, mock.Anything).Return(1, true) mockChannelKeeper.On("GetChannel", mock.Anything, mock.Anything, mock.Anything).Return(channeltypes.Channel{Counterparty: channeltypes.NewCounterparty("transfer", "channel-1")}, true) mockICS4Wrapper.On("SendPacket", mock.Anything, mock.Anything, mock.Anything).Return(nil) - authAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + authAddr := utils.GovAuthority() receiver := sdk.AccAddress([]byte("receiver")) chan0 := "channel-0" diff --git a/tests/integration/x/precisebank/test_genesis.go b/tests/integration/x/precisebank/test_genesis.go index d9abeee0..77c6f554 100644 --- a/tests/integration/x/precisebank/test_genesis.go +++ b/tests/integration/x/precisebank/test_genesis.go @@ -99,7 +99,10 @@ func (s *GenesisTestSuite) TestInitGenesis() { }, sdkmath.ZeroInt(), ), - "failed to validate precisebank genesis state: invalid balances: duplicate address cosmos1qyfkm2y3", + fmt.Sprintf( + "failed to validate precisebank genesis state: invalid balances: duplicate address %s", + sdk.AccAddress{1}.String(), + ), }, { "invalid - module balance insufficient", diff --git a/tests/integration/x/vm/keeper_test_suite.go b/tests/integration/x/vm/keeper_test_suite.go index 5f4aa1c5..555c990e 100644 --- a/tests/integration/x/vm/keeper_test_suite.go +++ b/tests/integration/x/vm/keeper_test_suite.go @@ -18,6 +18,7 @@ import ( 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" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) type KeeperTestSuite struct { @@ -44,6 +45,12 @@ func NewKeeperTestSuite(create network.CreateEvmApp, options ...network.ConfigOp } } +func (s *KeeperTestSuite) govAuthority() string { + authority, err := s.Network.App.GetAccountKeeper().AddressCodec().BytesToString(authtypes.NewModuleAddress(govtypes.ModuleName)) + s.Require().NoError(err) + return authority +} + func (s *KeeperTestSuite) SetupTest() { keys := keyring.New(2) // Set custom balance based on test params diff --git a/tests/integration/x/vm/test_msg_server.go b/tests/integration/x/vm/test_msg_server.go index 8f776f9c..1c4de5f4 100644 --- a/tests/integration/x/vm/test_msg_server.go +++ b/tests/integration/x/vm/test_msg_server.go @@ -12,7 +12,6 @@ import ( sdkmath "cosmossdk.io/math" sdktypes "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -179,7 +178,7 @@ func (s *KeeperTestSuite) TestUpdateParams() { name: "pass - valid Update msg", getMsg: func() *types.MsgUpdateParams { return &types.MsgUpdateParams{ - Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Authority: s.govAuthority(), Params: types.DefaultParams(), } }, @@ -222,7 +221,7 @@ func (s *KeeperTestSuite) TestRegisterPreinstalls() { name: "pass - valid Update msg", getMsg: func() *types.MsgRegisterPreinstalls { return &types.MsgRegisterPreinstalls{ - Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Authority: s.govAuthority(), Preinstalls: []types.Preinstall{{ Name: "Test1", Address: "0xb364E75b1189DcbBF7f0C856456c1ba8e4d6481b", @@ -236,7 +235,7 @@ func (s *KeeperTestSuite) TestRegisterPreinstalls() { name: "fail - double registration", getMsg: func() *types.MsgRegisterPreinstalls { return &types.MsgRegisterPreinstalls{ - Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Authority: s.govAuthority(), Preinstalls: types.DefaultPreinstalls, } }, diff --git a/tests/integration/x/vm/test_scheduler.go b/tests/integration/x/vm/test_scheduler.go new file mode 100644 index 00000000..4e6a36d7 --- /dev/null +++ b/tests/integration/x/vm/test_scheduler.go @@ -0,0 +1,93 @@ +package vm + +import ( + "math/big" + + "github.com/cosmos/evm/contracts" + testcontracts "github.com/cosmos/evm/precompiles/testutil/contracts" + testutiltypes "github.com/cosmos/evm/testutil/types" + erc20types "github.com/cosmos/evm/x/erc20/types" + evmtypes "github.com/cosmos/evm/x/vm/types" +) + +func (s *KeeperTestSuite) TestEVMSchedulerPokesConfiguredVault() { + s.SetupTest() + + admin := s.Keyring.GetAddr(0) + vaultAddr, err := s.Factory.DeployContract( + s.Keyring.GetPrivKey(0), + evmtypes.EvmTxArgs{}, + testutiltypes.ContractDeploymentData{ + Contract: contracts.StakedBondVaultContract, + ConstructorArgs: []interface{}{admin, "Staked Bond", "stBOND"}, + }, + ) + s.Require().NoError(err) + s.Require().NoError(s.Network.NextBlock()) + + params := s.Network.App.GetEVMKeeper().GetParams(s.Network.GetContext()) + params.Scheduler = evmtypes.EVMSchedulerParams{ + Enabled: true, + TargetContract: vaultAddr.Hex(), + GasCap: 1_000_000, + MaxOps: 7, + CadenceBlocks: 1, + } + s.Require().NoError(s.Network.App.GetEVMKeeper().SetParams(s.Network.GetContext(), params)) + s.Network.App.GetEVMKeeper().RunScheduler(s.Network.GetContext()) + + data, err := contracts.StakedBondVaultContract.ABI.Pack("pokeCount") + s.Require().NoError(err) + res, err := s.Network.App.GetEVMKeeper().CallEVMWithData( + s.Network.GetContext(), + erc20types.ModuleAddress, + &vaultAddr, + data, + false, + nil, + ) + s.Require().NoError(err) + out, err := contracts.StakedBondVaultContract.ABI.Unpack("pokeCount", res.Ret) + s.Require().NoError(err) + s.Require().Equal(0, big.NewInt(1).Cmp(out[0].(*big.Int)), "events: %v", s.Network.GetContext().EventManager().Events()) +} + +func (s *KeeperTestSuite) TestEVMSchedulerRevertDoesNotHaltBlock() { + s.SetupTest() + + counter, err := testcontracts.LoadCounterContract() + s.Require().NoError(err) + counterAddr, err := s.Factory.DeployContract( + s.Keyring.GetPrivKey(0), + evmtypes.EvmTxArgs{}, + testutiltypes.ContractDeploymentData{Contract: counter}, + ) + s.Require().NoError(err) + s.Require().NoError(s.Network.NextBlock()) + + params := s.Network.App.GetEVMKeeper().GetParams(s.Network.GetContext()) + params.Scheduler = evmtypes.EVMSchedulerParams{ + Enabled: true, + TargetContract: counterAddr.Hex(), + GasCap: 500_000, + MaxOps: 1, + CadenceBlocks: 1, + } + s.Require().NoError(s.Network.App.GetEVMKeeper().SetParams(s.Network.GetContext(), params)) + s.Network.App.GetEVMKeeper().RunScheduler(s.Network.GetContext()) + + data, err := counter.ABI.Pack("getCounter") + s.Require().NoError(err) + res, err := s.Network.App.GetEVMKeeper().CallEVMWithData( + s.Network.GetContext(), + erc20types.ModuleAddress, + &counterAddr, + data, + false, + nil, + ) + s.Require().NoError(err) + out, err := counter.ABI.Unpack("getCounter", res.Ret) + s.Require().NoError(err) + s.Require().Equal(0, big.NewInt(0).Cmp(out[0].(*big.Int))) +} diff --git a/tests/integration/x/vm/test_staked_bond_vault.go b/tests/integration/x/vm/test_staked_bond_vault.go new file mode 100644 index 00000000..0ac52a49 --- /dev/null +++ b/tests/integration/x/vm/test_staked_bond_vault.go @@ -0,0 +1,1042 @@ +package vm + +import ( + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + + "github.com/cosmos/evm/contracts" + testconstants "github.com/cosmos/evm/testutil/constants" + "github.com/cosmos/evm/testutil/types" + erc20types "github.com/cosmos/evm/x/erc20/types" + evmtypes "github.com/cosmos/evm/x/vm/types" + + sdkmath "cosmossdk.io/math" + + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var zeroAddress = common.Address{} + +func (s *KeeperTestSuite) TestStakedBondVaultLiquidRedeemLifecycle() { + s.SetupTest() + + vault := s.deployStakedBondVault() + owner := s.Keyring.GetAddr(0) + other := s.Keyring.GetAddr(1) + depositAmount := big.NewInt(0).Mul(big.NewInt(5), big.NewInt(1e18)) + + depositRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) + s.Require().NoError(err) + depositOut, err := contracts.StakedBondVaultContract.ABI.Unpack("depositNative", depositRes.Ret) + s.Require().NoError(err) + shares := depositOut[0].(*big.Int) + s.Require().Equal(0, depositAmount.Cmp(shares)) + s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "totalAssets"))) + s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "balanceOf", owner))) + + requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "requestRedeem", shares, owner, owner) + s.Require().NoError(err) + requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) + s.Require().NoError(err) + requestID := requestOut[0].(*big.Int) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) + s.Require().ErrorContains(err, "not claimable") + + s.Require().NoError(s.Network.NextBlock()) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, other) + s.Require().ErrorContains(err, "wrong receiver") + s.Require().NoError(s.Network.NextBlock()) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "claimRedeem", requestID, zeroAddress) + s.Require().NoError(err) + s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) + s.Require().Zero(s.vaultBig(vault, "totalAssets").Sign()) + s.Require().Zero(s.werc20Balance(vault).Sign()) +} + +func (s *KeeperTestSuite) TestStakedBondVaultRejectsUnauthorizedRedeemRequest() { + s.SetupTest() + + vault := s.deployStakedBondVault() + owner := s.Keyring.GetAddr(0) + depositAmount := big.NewInt(1e18) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) + s.Require().NoError(err) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "requestRedeem", depositAmount, s.Keyring.GetAddr(1), owner) + s.Require().ErrorContains(err, "insufficient allowance") +} + +func (s *KeeperTestSuite) TestStakedBondVaultRejectsInvalidAndPausedActions() { + s.SetupTest() + + vault := s.deployStakedBondVault() + owner := s.Keyring.GetAddr(0) + depositAmount := big.NewInt(1e18) + expectVaultError := func(value *big.Int, method string, contains string, args ...interface{}) { + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, value, method, args...) + s.Require().ErrorContains(err, contains) + s.Require().NoError(s.Network.NextBlock()) + } + expectVaultFailure := func(value *big.Int, method string, args ...interface{}) { + res, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, value, method, args...) + if err != nil { + s.Require().NoError(s.Network.NextBlock()) + return + } + s.Require().True(res.Failed(), "%s unexpectedly succeeded", method) + } + + s.Require().Zero(s.vaultBig(vault, "maxDeposit", owner).Sign()) + s.Require().Zero(s.vaultBig(vault, "maxMint", owner).Sign()) + s.Require().Zero(s.vaultBig(vault, "maxWithdraw", owner).Sign()) + s.Require().Zero(s.vaultBig(vault, "maxRedeem", owner).Sign()) + expectVaultError(big.NewInt(0), "depositNative", "zero assets", owner) + expectVaultError(depositAmount, "depositNative", "receiver zero", zeroAddress) + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setPaused", true, false, false) + s.Require().NoError(err) + expectVaultError(depositAmount, "depositNative", "deposits paused", owner) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setPaused", false, false, false) + s.Require().NoError(err) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) + s.Require().NoError(err) + expectVaultFailure(nil, "deposit", big.NewInt(0), owner) + expectVaultFailure(nil, "mint", big.NewInt(0), owner) + expectVaultError(nil, "withdraw", "use requestRedeem", depositAmount, owner, owner) + expectVaultError(nil, "redeem", "use requestRedeem", depositAmount, owner, owner) + expectVaultError(nil, "requestRedeem", "zero shares", big.NewInt(0), owner, owner) + expectVaultError(nil, "requestRedeem", "receiver zero", depositAmount, zeroAddress, owner) + expectVaultError(nil, "requestRedeem", "owner zero", depositAmount, owner, zeroAddress) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setPaused", false, true, false) + s.Require().NoError(err) + expectVaultError(nil, "requestRedeem", "withdrawals paused", depositAmount, owner, owner) + expectVaultError(nil, "claimRedeem", "unknown request", big.NewInt(999), zeroAddress) +} + +func (s *KeeperTestSuite) TestStakedBondVaultRejectsValueBearingNonNativeCalls() { + s.SetupTest() + + vault := s.deployStakedBondVault() + owner := s.Keyring.GetAddr(0) + spender := s.Keyring.GetAddr(1) + depositAmount := big.NewInt(1e18) + dust := big.NewInt(1) + zeroRole := common.Hash{} + expectValueRejected := func(method string, args ...interface{}) { + res, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, dust, method, args...) + if err != nil { + s.Require().NoError(s.Network.NextBlock()) + return + } + s.Require().True(res.Failed(), "%s accepted value-bearing call", method) + } + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) + s.Require().NoError(err) + + expectValueRejected("deposit", big.NewInt(0), owner) + expectValueRejected("mint", big.NewInt(0), owner) + expectValueRejected("requestRedeem", depositAmount, owner, owner) + expectValueRejected("claimRedeem", big.NewInt(999), zeroAddress) + expectValueRejected("poke", big.NewInt(1)) + expectValueRejected("syncDelegations") + expectValueRejected("setPaused", false, false, false) + expectValueRejected("setValidators", []string{}, []uint16{}) + expectValueRejected("approve", spender, big.NewInt(1)) + expectValueRejected("increaseAllowance", spender, big.NewInt(1)) + expectValueRejected("decreaseAllowance", spender, big.NewInt(0)) + expectValueRejected("transfer", spender, big.NewInt(1)) + expectValueRejected("transferFrom", owner, spender, big.NewInt(1)) + expectValueRejected("permit", owner, spender, big.NewInt(0), big.NewInt(0), uint8(27), zeroRole, zeroRole) + expectValueRejected("grantRole", zeroRole, spender) + expectValueRejected("revokeRole", zeroRole, spender) + expectValueRejected("renounceRole", zeroRole, owner) + + s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "balanceOf", owner))) + s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "totalAssets"))) +} + +func (s *KeeperTestSuite) TestStakedBondVaultRejectsRawNativeTransfer() { + s.SetupTest() + + vault := s.deployStakedBondVault() + + res, err := s.executeRawVaultTx(s.Keyring.GetPrivKey(0), vault, big.NewInt(1), nil) + if err != nil { + s.Require().NoError(s.Network.NextBlock()) + return + } + s.Require().True(res.Failed(), "raw native transfer unexpectedly succeeded") +} + +func (s *KeeperTestSuite) TestStakedBondVaultRejectsUnauthorizedAdminActions() { + s.SetupTest() + + vault := s.deployStakedBondVault() + val := s.Network.GetValidators()[0].OperatorAddress + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "setPaused", true, true, true) + s.Require().Error(err) + s.Require().NoError(s.Network.NextBlock()) + s.Require().False(s.vaultBool(vault, "depositsPaused")) + s.Require().False(s.vaultBool(vault, "withdrawalsPaused")) + s.Require().False(s.vaultBool(vault, "pokePaused")) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "setValidators", []string{val}, []uint16{10_000}) + s.Require().Error(err) + s.Require().NoError(s.Network.NextBlock()) + s.Require().Zero(s.vaultBig(vault, "validatorCount").Sign()) +} + +func (s *KeeperTestSuite) TestStakedBondVaultSetPausedTogglesExactFlags() { + s.SetupTest() + + vault := s.deployStakedBondVault() + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setPaused", true, true, true) + s.Require().NoError(err) + s.Require().True(s.vaultBool(vault, "depositsPaused")) + s.Require().True(s.vaultBool(vault, "withdrawalsPaused")) + s.Require().True(s.vaultBool(vault, "pokePaused")) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setPaused", false, false, false) + s.Require().NoError(err) + s.Require().False(s.vaultBool(vault, "depositsPaused")) + s.Require().False(s.vaultBool(vault, "withdrawalsPaused")) + s.Require().False(s.vaultBool(vault, "pokePaused")) +} + +func (s *KeeperTestSuite) TestStakedBondVaultApprovedRedeemClaimPaysFixedReceiver() { + s.SetupTest() + + vault := s.deployStakedBondVault() + owner := s.Keyring.GetAddr(0) + spender := s.Keyring.GetAddr(1) + depositAmount := big.NewInt(1e18) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "approve", spender, depositAmount) + s.Require().NoError(err) + + requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "requestRedeem", depositAmount, spender, owner) + s.Require().NoError(err) + requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) + s.Require().NoError(err) + requestID := requestOut[0].(*big.Int) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, owner) + s.Require().ErrorContains(err, "wrong receiver") + s.Require().NoError(s.Network.NextBlock()) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "claimRedeem", requestID, zeroAddress) + s.Require().NoError(err) + s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) + s.Require().Zero(s.werc20Balance(vault).Sign()) +} + +func (s *KeeperTestSuite) TestStakedBondVaultMultiRequestBatchPaysResidualAndPrunes() { + s.SetupTest() + + vault := s.deployStakedBondVault() + owner := s.Keyring.GetAddr(0) + other := s.Keyring.GetAddr(1) + ownerAmount := big.NewInt(0).Mul(big.NewInt(3), big.NewInt(1e18)) + otherAmount := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, ownerAmount, "depositNative", owner) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, otherAmount, "depositNative", other) + s.Require().NoError(err) + + requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "requestRedeem", ownerAmount, owner, owner) + s.Require().NoError(err) + requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) + s.Require().NoError(err) + ownerRequestID := requestOut[0].(*big.Int) + requestRes, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "requestRedeem", otherAmount, other, other) + s.Require().NoError(err) + requestOut, err = contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) + s.Require().NoError(err) + otherRequestID := requestOut[0].(*big.Int) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "claimRedeem", otherRequestID, zeroAddress) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", ownerRequestID, zeroAddress) + s.Require().NoError(err) + + s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) + s.Require().Zero(s.vaultBig(vault, "totalAssets").Sign()) + s.Require().Zero(s.werc20Balance(vault).Sign()) + res, err := s.callVaultWithData(vault, "withdrawalBatch", false, uint64(1)) + s.Require().NoError(err) + batchOut, err := contracts.StakedBondVaultContract.ABI.Unpack("withdrawalBatch", res.Ret) + s.Require().NoError(err) + s.Require().False(batchOut[1].(bool)) + s.Require().False(batchOut[2].(bool)) +} + +func (s *KeeperTestSuite) TestStakedBondVaultDirectWrappedDonationBeforeFirstDepositDoesNotBlockExit() { + s.SetupTest() + + vault := s.deployStakedBondVault() + owner := s.Keyring.GetAddr(1) + donation := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) + depositAmount := big.NewInt(1e18) + expectedPayout := big.NewInt(0).Add(donation, depositAmount) + + _, err := s.executeWERC20Tx(s.Keyring.GetPrivKey(0), nil, "transfer", vault, donation) + s.Require().NoError(err) + s.Require().Equal(0, donation.Cmp(s.werc20Balance(vault))) + + depositRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, depositAmount, "depositNative", owner) + s.Require().NoError(err) + depositOut, err := contracts.StakedBondVaultContract.ABI.Unpack("depositNative", depositRes.Ret) + s.Require().NoError(err) + shares := depositOut[0].(*big.Int) + s.Require().Equal(0, depositAmount.Cmp(shares)) + s.Require().Equal(0, expectedPayout.Cmp(s.vaultBig(vault, "totalAssets"))) + + requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "requestRedeem", shares, owner, owner) + s.Require().NoError(err) + requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) + s.Require().NoError(err) + requestID := requestOut[0].(*big.Int) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "claimRedeem", requestID, zeroAddress) + s.Require().NoError(err) + + s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) + s.Require().Zero(s.vaultBig(vault, "totalAssets").Sign()) + s.Require().True(s.werc20Balance(vault).Cmp(donation) <= 0) +} + +func (s *KeeperTestSuite) TestStakedBondVaultDoesNotStakeOrphanDonationWithoutShares() { + s.SetupTest() + + vault := s.deployStakedBondVault() + val := s.Network.GetValidators()[0].OperatorAddress + donation := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) + s.Require().NoError(err) + _, err = s.executeWERC20Tx(s.Keyring.GetPrivKey(0), nil, "transfer", vault, donation) + s.Require().NoError(err) + s.Require().Equal(0, donation.Cmp(s.werc20Balance(vault))) + s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) + s.Require().Zero(s.vaultBig(vault, "totalAssets").Sign()) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + s.Require().Zero(s.vaultBig(vault, "totalDelegated").Sign()) + s.Require().Equal(0, donation.Cmp(s.werc20Balance(vault))) +} + +func (s *KeeperTestSuite) TestStakedBondVaultRejectsBadValidatorConfiguration() { + s.SetupTest() + + vault := s.deployStakedBondVault() + val := s.Network.GetValidators()[0].OperatorAddress + + _, err := s.executeVaultTx( + s.Keyring.GetPrivKey(0), + vault, + nil, + "setValidators", + []string{val, val}, + []uint16{5_000, 5_000}, + ) + s.Require().ErrorContains(err, "duplicate validator") + s.Require().NoError(s.Network.NextBlock()) + + _, err = s.executeVaultTx( + s.Keyring.GetPrivKey(0), + vault, + nil, + "setValidators", + []string{val}, + []uint16{9_999}, + ) + s.Require().ErrorContains(err, "bad weights") + s.Require().NoError(s.Network.NextBlock()) + + _, err = s.executeVaultTx( + s.Keyring.GetPrivKey(0), + vault, + nil, + "setValidators", + []string{val}, + []uint16{}, + ) + s.Require().ErrorContains(err, "length mismatch") + s.Require().NoError(s.Network.NextBlock()) + + _, err = s.executeVaultTx( + s.Keyring.GetPrivKey(0), + vault, + nil, + "setValidators", + []string{""}, + []uint16{10_000}, + ) + s.Require().ErrorContains(err, "empty validator") + s.Require().NoError(s.Network.NextBlock()) + + _, err = s.executeVaultTx( + s.Keyring.GetPrivKey(0), + vault, + nil, + "setValidators", + []string{val}, + []uint16{0}, + ) + s.Require().ErrorContains(err, "zero weight") + s.Require().NoError(s.Network.NextBlock()) + + operatorAddresses := make([]string, 33) + weights := make([]uint16, 33) + for i := range operatorAddresses { + operatorAddresses[i] = val + weights[i] = 1 + } + _, err = s.executeVaultTx( + s.Keyring.GetPrivKey(0), + vault, + nil, + "setValidators", + operatorAddresses, + weights, + ) + s.Require().ErrorContains(err, "too many validators") +} + +func (s *KeeperTestSuite) TestStakedBondVaultSetValidatorsStoresExactConfig() { + s.SetupTest() + + vault := s.deployStakedBondVault() + val := s.Network.GetValidators()[0].OperatorAddress + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) + s.Require().NoError(err) + s.Require().Equal(0, big.NewInt(1).Cmp(s.vaultBig(vault, "validatorCount"))) + + res, err := s.callVaultWithData(vault, "validators", false, big.NewInt(0)) + s.Require().NoError(err) + out, err := contracts.StakedBondVaultContract.ABI.Unpack("validators", res.Ret) + s.Require().NoError(err) + s.Require().Equal(val, out[0].(string)) + s.Require().Equal(uint16(10_000), out[1].(uint16)) + s.Require().Zero(out[2].(*big.Int).Sign()) +} + +func (s *KeeperTestSuite) TestStakedBondVaultStakeIdleSplitsAcrossValidatorsWithRemainder() { + s.SetupTest() + + vault := s.deployStakedBondVault() + vals := s.Network.GetValidators() + owner := s.Keyring.GetAddr(0) + depositAmount := big.NewInt(0).Mul(big.NewInt(10_001), big.NewInt(1e18)) + operatorAddresses := []string{ + vals[0].OperatorAddress, + vals[1].OperatorAddress, + vals[2].OperatorAddress, + } + weights := []uint16{3_333, 3_333, 3_334} + expectedFirst := big.NewInt(0).Div(big.NewInt(0).Mul(depositAmount, big.NewInt(3_333)), big.NewInt(10_000)) + expectedSecond := big.NewInt(0).Set(expectedFirst) + expectedThird := big.NewInt(0).Sub(big.NewInt(0).Sub(depositAmount, expectedFirst), expectedSecond) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", operatorAddresses, weights) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + + for i, expected := range []*big.Int{expectedFirst, expectedSecond, expectedThird} { + res, err := s.callVaultWithData(vault, "validators", false, big.NewInt(int64(i))) + s.Require().NoError(err) + out, err := contracts.StakedBondVaultContract.ABI.Unpack("validators", res.Ret) + s.Require().NoError(err) + s.Require().Equal(operatorAddresses[i], out[0].(string)) + s.Require().Equal(weights[i], out[1].(uint16)) + s.Require().Equal(0, expected.Cmp(out[2].(*big.Int))) + } + s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) +} + +func (s *KeeperTestSuite) TestStakedBondVaultStakesAndBlocksValidatorUpdatesWhileDelegated() { + s.SetupTest() + + vault := s.deployStakedBondVault() + val := s.Network.GetValidators()[0].OperatorAddress + depositAmount := big.NewInt(0).Mul(big.NewInt(3), big.NewInt(1e18)) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", s.Keyring.GetAddr(0)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + + delegated := s.vaultBig(vault, "totalDelegated") + s.Require().Positive(delegated.Sign()) + s.Require().Equal(0, delegated.Cmp(s.vaultBig(vault, "liveDelegatedAssets"))) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{}, []uint16{}) + s.Require().ErrorContains(err, "delegations active") +} + +func (s *KeeperTestSuite) TestStakedBondVaultPokeRecordsBoundedWork() { + s.SetupTest() + + vault := s.deployStakedBondVault() + val := s.Network.GetValidators()[0].OperatorAddress + depositAmount := big.NewInt(1e18) + + res, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(0)) + s.Require().NoError(err) + out, err := contracts.StakedBondVaultContract.ABI.Unpack("poke", res.Ret) + s.Require().NoError(err) + s.Require().Zero(out[0].(*big.Int).Sign()) + s.Require().Zero(s.vaultBig(vault, "pokeCount").Sign()) + s.Require().Zero(s.vaultBig(vault, "lastPokeOps").Sign()) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setPaused", false, false, true) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(1)) + s.Require().ErrorContains(err, "poke paused") + s.Require().NoError(s.Network.NextBlock()) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setPaused", false, false, false) + s.Require().NoError(err) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", s.Keyring.GetAddr(0)) + s.Require().NoError(err) + + res, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(1)) + s.Require().NoError(err) + out, err = contracts.StakedBondVaultContract.ABI.Unpack("poke", res.Ret) + s.Require().NoError(err) + s.Require().Equal(0, big.NewInt(1).Cmp(out[0].(*big.Int))) + s.Require().Equal(0, big.NewInt(1).Cmp(s.vaultBig(vault, "pokeCount"))) + s.Require().Equal(0, big.NewInt(1).Cmp(s.vaultBig(vault, "lastPokeOps"))) + s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) +} + +func (s *KeeperTestSuite) TestStakedBondVaultStakedRedeemLifecycle() { + s.SetupTest() + + vault := s.deployStakedBondVault() + val := s.Network.GetValidators()[0].OperatorAddress + owner := s.Keyring.GetAddr(0) + depositAmount := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + + requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "requestRedeem", depositAmount, owner, owner) + s.Require().NoError(err) + requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) + s.Require().NoError(err) + requestID := requestOut[0].(*big.Int) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "totalWithdrawalUnbonding"))) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) + s.Require().ErrorContains(err, "not claimable") + s.Require().NoError(s.Network.NextBlock()) + + maturity := s.vaultBatchMaturity(vault, 1) + wait := time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second + if wait > 0 { + s.Require().NoError(s.Network.NextBlockAfter(wait)) + } + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) + s.Require().ErrorContains(err, "unknown request") + s.Require().NoError(s.Network.NextBlock()) + + s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) + s.Require().Zero(s.vaultBig(vault, "totalAssets").Sign()) + s.Require().Zero(s.vaultBig(vault, "totalWithdrawalUnbonding").Sign()) +} + +func (s *KeeperTestSuite) TestStakedBondVaultMixedLiquidAndStakedRedeemLifecycle() { + s.SetupTest() + + vault := s.deployStakedBondVault() + val := s.Network.GetValidators()[0].OperatorAddress + owner := s.Keyring.GetAddr(0) + stakedAmount := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) + liquidAmount := big.NewInt(1e18) + totalAmount := big.NewInt(0).Add(stakedAmount, liquidAmount) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, stakedAmount, "depositNative", owner) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + s.Require().Equal(0, stakedAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, liquidAmount, "depositNative", owner) + s.Require().NoError(err) + requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "requestRedeem", totalAmount, owner, owner) + s.Require().NoError(err) + requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) + s.Require().NoError(err) + requestID := requestOut[0].(*big.Int) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + s.Require().Equal(0, stakedAmount.Cmp(s.vaultBig(vault, "totalWithdrawalUnbonding"))) + s.Require().Zero(s.vaultBig(vault, "totalDelegated").Sign()) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) + s.Require().ErrorContains(err, "not claimable") + s.Require().NoError(s.Network.NextBlock()) + + maturity := s.vaultBatchMaturity(vault, 1) + wait := time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second + if wait > 0 { + s.Require().NoError(s.Network.NextBlockAfter(wait)) + } + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) + s.Require().NoError(err) + + s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) + s.Require().Zero(s.vaultBig(vault, "totalAssets").Sign()) + s.Require().Zero(s.vaultBig(vault, "totalWithdrawalUnbonding").Sign()) +} + +func (s *KeeperTestSuite) TestStakedBondVaultPendingUnbondingDoesNotSkipSettlementAfterLiquidBatch() { + s.SetupTest() + + vault := s.deployStakedBondVault() + val := s.Network.GetValidators()[0].OperatorAddress + owner := s.Keyring.GetAddr(0) + other := s.Keyring.GetAddr(1) + stakedAmount := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) + liquidAmount := big.NewInt(1e18) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, stakedAmount, "depositNative", owner) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + s.Require().Equal(0, stakedAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + + requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "requestRedeem", stakedAmount, owner, owner) + s.Require().NoError(err) + requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) + s.Require().NoError(err) + stakedRequestID := requestOut[0].(*big.Int) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + s.Require().Equal(0, stakedAmount.Cmp(s.vaultBig(vault, "totalWithdrawalUnbonding"))) + s.Require().Equal(0, big.NewInt(1).Cmp(s.vaultBig(vault, "nextSettlementBatchId"))) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, liquidAmount, "depositNative", other) + s.Require().NoError(err) + requestRes, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "requestRedeem", liquidAmount, other, other) + s.Require().NoError(err) + requestOut, err = contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) + s.Require().NoError(err) + liquidRequestID := requestOut[0].(*big.Int) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + s.Require().Equal(0, big.NewInt(1).Cmp(s.vaultBig(vault, "nextSettlementBatchId"))) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "claimRedeem", liquidRequestID, zeroAddress) + s.Require().NoError(err) + + maturity := s.vaultBatchMaturity(vault, 1) + wait := time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second + if wait > 0 { + s.Require().NoError(s.Network.NextBlockAfter(wait)) + } + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", stakedRequestID, zeroAddress) + s.Require().NoError(err) + s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) + s.Require().Zero(s.vaultBig(vault, "totalWithdrawalUnbonding").Sign()) +} + +func (s *KeeperTestSuite) TestStakedBondVaultDepositDuringPendingUnbondingCanStakeAndExit() { + s.SetupTest() + + vault := s.deployStakedBondVault() + val := s.Network.GetValidators()[0].OperatorAddress + owner := s.Keyring.GetAddr(0) + other := s.Keyring.GetAddr(1) + ownerAmount := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) + otherAmount := big.NewInt(1e18) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, ownerAmount, "depositNative", owner) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + s.Require().Equal(0, ownerAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + + requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "requestRedeem", ownerAmount, owner, owner) + s.Require().NoError(err) + requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) + s.Require().NoError(err) + ownerRequestID := requestOut[0].(*big.Int) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + s.Require().Equal(0, ownerAmount.Cmp(s.vaultBig(vault, "totalWithdrawalUnbonding"))) + s.Require().Zero(s.vaultBig(vault, "totalDelegated").Sign()) + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, otherAmount, "depositNative", other) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + s.Require().Equal(0, otherAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + s.Require().Equal(0, ownerAmount.Cmp(s.vaultBig(vault, "totalWithdrawalUnbonding"))) + + maturity := s.vaultBatchMaturity(vault, 1) + wait := time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second + if wait > 0 { + s.Require().NoError(s.Network.NextBlockAfter(wait)) + } + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", ownerRequestID, zeroAddress) + s.Require().NoError(err) + s.Require().Zero(s.vaultBig(vault, "totalWithdrawalUnbonding").Sign()) + s.Require().Equal(0, otherAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + + otherShares := s.vaultBig(vault, "balanceOf", other) + requestRes, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "requestRedeem", otherShares, other, other) + s.Require().NoError(err) + requestOut, err = contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) + s.Require().NoError(err) + otherRequestID := requestOut[0].(*big.Int) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + + maturity = s.vaultBatchMaturity(vault, 2) + wait = time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second + if wait > 0 { + s.Require().NoError(s.Network.NextBlockAfter(wait)) + } + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "claimRedeem", otherRequestID, zeroAddress) + s.Require().NoError(err) + s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) + s.Require().Zero(s.vaultBig(vault, "totalWithdrawalUnbonding").Sign()) +} + +func (s *KeeperTestSuite) TestStakedBondVaultSlashedStakeCanRedeemRemainingAssets() { + s.SetupTest() + + vault := s.deployStakedBondVault() + validator := s.Network.GetValidators()[0] + owner := s.Keyring.GetAddr(0) + depositAmount := big.NewInt(0).Mul(big.NewInt(3), big.NewInt(1e18)) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{validator.OperatorAddress}, []uint16{10_000}) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + beforeSlash := s.vaultBig(vault, "liveDelegatedAssets") + s.Require().Positive(beforeSlash.Sign()) + + consAddr, err := validator.GetConsAddr() + s.Require().NoError(err) + powerReduction := s.Network.App.GetStakingKeeper().PowerReduction(s.Network.GetContext()) + power := validator.GetConsensusPower(powerReduction) + _, err = s.Network.App.GetStakingKeeper().Slash( + s.Network.GetContext(), + sdk.ConsAddress(consAddr), + s.Network.GetContext().BlockHeight(), + power, + sdkmath.LegacyNewDecWithPrec(5, 1), + ) + s.Require().NoError(err) + afterSlash := s.vaultBig(vault, "liveDelegatedAssets") + s.Require().Positive(afterSlash.Sign()) + s.Require().Negative(afterSlash.Cmp(beforeSlash)) + + requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "requestRedeem", depositAmount, owner, owner) + s.Require().NoError(err) + requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) + s.Require().NoError(err) + requestID := requestOut[0].(*big.Int) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + unbonding := s.vaultBig(vault, "totalWithdrawalUnbonding") + s.Require().Positive(unbonding.Sign()) + s.Require().True(unbonding.Cmp(depositAmount) <= 0) + + maturity := s.vaultBatchMaturity(vault, 1) + wait := time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second + if wait > 0 { + s.Require().NoError(s.Network.NextBlockAfter(wait)) + } + + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) + s.Require().NoError(err) + s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) + s.Require().Zero(s.vaultBig(vault, "totalAssets").Sign()) + s.Require().Zero(s.vaultBig(vault, "totalWithdrawalUnbonding").Sign()) +} + +func (s *KeeperTestSuite) TestStakedBondVaultSlashSyncUpdatesCachedDelegations() { + s.SetupTest() + + vault := s.deployStakedBondVault() + validator := s.Network.GetValidators()[0] + depositAmount := big.NewInt(0).Mul(big.NewInt(3), big.NewInt(1e18)) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{validator.OperatorAddress}, []uint16{10_000}) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", s.Keyring.GetAddr(0)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + s.Require().NoError(err) + + before := s.vaultBig(vault, "liveDelegatedAssets") + s.Require().Positive(before.Sign()) + + consAddr, err := validator.GetConsAddr() + s.Require().NoError(err) + powerReduction := s.Network.App.GetStakingKeeper().PowerReduction(s.Network.GetContext()) + power := validator.GetConsensusPower(powerReduction) + _, err = s.Network.App.GetStakingKeeper().Slash( + s.Network.GetContext(), + sdk.ConsAddress(consAddr), + s.Network.GetContext().BlockHeight(), + power, + sdkmath.LegacyNewDecWithPrec(5, 1), + ) + s.Require().NoError(err) + + after := s.vaultBig(vault, "liveDelegatedAssets") + s.Require().Negative(after.Cmp(before)) + + _, err = s.callVaultWithData(vault, "syncDelegations", true) + s.Require().NoError(err) + s.Require().Equal(0, after.Cmp(s.vaultBig(vault, "totalDelegated"))) +} + +func (s *KeeperTestSuite) deployStakedBondVault() common.Address { + admin := s.Keyring.GetAddr(0) + vault, err := s.Factory.DeployContract( + s.Keyring.GetPrivKey(0), + evmtypes.EvmTxArgs{GasLimit: 8_000_000}, + types.ContractDeploymentData{ + Contract: contracts.StakedBondVaultContract, + ConstructorArgs: []interface{}{admin, "Staked Bond", "stBOND"}, + }, + ) + s.Require().NoError(err) + s.Require().NoError(s.Network.NextBlock()) + return vault +} + +func (s *KeeperTestSuite) executeVaultTx( + priv cryptotypes.PrivKey, + vault common.Address, + value *big.Int, + method string, + args ...interface{}, +) (*evmtypes.MsgEthereumTxResponse, error) { + txArgs := evmtypes.EvmTxArgs{ + To: &vault, + GasLimit: 8_000_000, + Amount: value, + } + res, err := s.Factory.ExecuteContractCall( + priv, + txArgs, + types.CallArgs{ + ContractABI: contracts.StakedBondVaultContract.ABI, + MethodName: method, + Args: args, + }, + ) + if err != nil { + return nil, err + } + ethRes, err := s.Factory.GetEvmTransactionResponseFromTxResult(res) + if err != nil { + return nil, err + } + return ethRes, s.Network.NextBlock() +} + +func (s *KeeperTestSuite) executeRawVaultTx( + priv cryptotypes.PrivKey, + vault common.Address, + value *big.Int, + input []byte, +) (*evmtypes.MsgEthereumTxResponse, error) { + txArgs := evmtypes.EvmTxArgs{ + To: &vault, + GasLimit: 8_000_000, + Amount: value, + Input: input, + } + res, err := s.Factory.ExecuteEthTx(priv, txArgs) + if err != nil { + return nil, err + } + ethRes, err := s.Factory.GetEvmTransactionResponseFromTxResult(res) + if err != nil { + return nil, err + } + return ethRes, s.Network.NextBlock() +} + +func (s *KeeperTestSuite) executeWERC20Tx( + priv cryptotypes.PrivKey, + value *big.Int, + method string, + args ...interface{}, +) (*evmtypes.MsgEthereumTxResponse, error) { + werc20 := common.HexToAddress(testconstants.WEVMOSContractMainnet) + txArgs := evmtypes.EvmTxArgs{ + To: &werc20, + GasLimit: 8_000_000, + Amount: value, + } + res, err := s.Factory.ExecuteContractCall( + priv, + txArgs, + types.CallArgs{ + ContractABI: contracts.WATOMContract.ABI, + MethodName: method, + Args: args, + }, + ) + if err != nil { + return nil, err + } + ethRes, err := s.Factory.GetEvmTransactionResponseFromTxResult(res) + if err != nil { + return nil, err + } + return ethRes, s.Network.NextBlock() +} + +func (s *KeeperTestSuite) vaultBig(vault common.Address, method string, args ...interface{}) *big.Int { + res, err := s.callVaultWithData(vault, method, false, args...) + s.Require().NoError(err) + out, err := contracts.StakedBondVaultContract.ABI.Unpack(method, res.Ret) + s.Require().NoError(err) + switch value := out[0].(type) { + case *big.Int: + return value + case uint64: + return new(big.Int).SetUint64(value) + default: + s.T().Fatalf("unexpected numeric type %T", value) + return nil + } +} + +func (s *KeeperTestSuite) vaultBool(vault common.Address, method string, args ...interface{}) bool { + res, err := s.callVaultWithData(vault, method, false, args...) + s.Require().NoError(err) + out, err := contracts.StakedBondVaultContract.ABI.Unpack(method, res.Ret) + s.Require().NoError(err) + value, ok := out[0].(bool) + s.Require().True(ok, "unexpected bool type %T", out[0]) + return value +} + +func (s *KeeperTestSuite) vaultBatchMaturity(vault common.Address, batchID uint64) int64 { + res, err := s.callVaultWithData(vault, "withdrawalBatch", false, batchID) + s.Require().NoError(err) + out, err := contracts.StakedBondVaultContract.ABI.Unpack("withdrawalBatch", res.Ret) + s.Require().NoError(err) + switch maturity := out[11].(type) { + case int64: + return maturity + case *big.Int: + return maturity.Int64() + default: + s.T().Fatalf("unexpected maturity type %T", out[11]) + return 0 + } +} + +func (s *KeeperTestSuite) callVaultWithData(vault common.Address, method string, commit bool, args ...interface{}) (*evmtypes.MsgEthereumTxResponse, error) { + data, err := contracts.StakedBondVaultContract.ABI.Pack(method, args...) + if err != nil { + return nil, err + } + return s.Network.App.GetEVMKeeper().CallEVMWithData( + s.Network.GetContext(), + erc20types.ModuleAddress, + &vault, + data, + commit, + big.NewInt(8_000_000), + ) +} + +func (s *KeeperTestSuite) werc20Balance(account common.Address) *big.Int { + werc20 := common.HexToAddress(testconstants.WEVMOSContractMainnet) + data, err := contracts.ERC20MinterBurnerDecimalsContract.ABI.Pack("balanceOf", account) + s.Require().NoError(err) + res, err := s.Network.App.GetEVMKeeper().CallEVMWithData( + s.Network.GetContext(), + erc20types.ModuleAddress, + &werc20, + data, + false, + big.NewInt(8_000_000), + ) + s.Require().NoError(err) + out, err := contracts.ERC20MinterBurnerDecimalsContract.ABI.Unpack("balanceOf", res.Ret) + s.Require().NoError(err) + return out[0].(*big.Int) +} diff --git a/tests/integration/x/vm/test_state_transition.go b/tests/integration/x/vm/test_state_transition.go index 738a6596..e548a7bd 100644 --- a/tests/integration/x/vm/test_state_transition.go +++ b/tests/integration/x/vm/test_state_transition.go @@ -35,7 +35,6 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) const TestPostProcessingEventType = "test_post_processing_event" @@ -48,7 +47,7 @@ func (s *KeeperTestSuite) TestContextSetConsensusParams() { consParams := res.Params consParams.Block.MaxGas = maxGas _, err = s.Network.App.GetConsensusParamsKeeper().UpdateParams(s.Network.GetContext(), &consensustypes.MsgUpdateParams{ - Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Authority: s.govAuthority(), Block: consParams.Block, Evidence: consParams.Evidence, Validator: consParams.Validator, diff --git a/testutil/integration/evm/utils/address.go b/testutil/integration/evm/utils/address.go new file mode 100644 index 00000000..c0a17e50 --- /dev/null +++ b/testutil/integration/evm/utils/address.go @@ -0,0 +1,21 @@ +package utils + +import ( + "fmt" + + evmaddress "github.com/cosmos/evm/encoding/address" + + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" +) + +func GovAuthority() string { + authority, err := evmaddress.NewEvmCodec(sdk.GetConfig().GetBech32AccountAddrPrefix()). + BytesToString(authtypes.NewModuleAddress(govtypes.ModuleName)) + if err != nil { + panic(fmt.Errorf("failed to encode gov authority address: %w", err)) + } + + return authority +} diff --git a/testutil/integration/evm/utils/erc20.go b/testutil/integration/evm/utils/erc20.go index 89d34c27..ce34e93b 100644 --- a/testutil/integration/evm/utils/erc20.go +++ b/testutil/integration/evm/utils/erc20.go @@ -12,7 +12,6 @@ import ( errorsmod "cosmossdk.io/errors" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) // ERC20RegistrationData is the necessary data to provide in order to register an ERC20 token. @@ -58,7 +57,7 @@ func RegisterERC20(tf factory.TxFactory, network network.Network, data ERC20Regi } proposal := erc20types.MsgRegisterERC20{ - Signer: authtypes.NewModuleAddress("gov").String(), + Signer: GovAuthority(), Erc20Addresses: data.Addresses, } @@ -96,7 +95,7 @@ func RegisterERC20(tf factory.TxFactory, network network.Network, data ERC20Regi // submitting a governance proposal and having it pass. func ToggleTokenConversion(tf factory.TxFactory, network network.Network, privKey cryptotypes.PrivKey, token string) error { proposal := erc20types.MsgToggleConversion{ - Authority: authtypes.NewModuleAddress("gov").String(), + Authority: GovAuthority(), Token: token, } diff --git a/testutil/integration/evm/utils/params.go b/testutil/integration/evm/utils/params.go index 76f62b38..58c360de 100644 --- a/testutil/integration/evm/utils/params.go +++ b/testutil/integration/evm/utils/params.go @@ -11,7 +11,6 @@ import ( cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1types "github.com/cosmos/cosmos-sdk/x/gov/types/v1" ) @@ -23,8 +22,6 @@ type UpdateParamsInput struct { Params interface{} } -var authority = authtypes.NewModuleAddress(govtypes.ModuleName).String() - // UpdateEvmParams helper function to update the EVM module parameters // It submits an update params proposal, votes for it, and waits till it passes func UpdateEvmParams(input UpdateParamsInput) error { @@ -70,6 +67,8 @@ func updateModuleParams[T interface{}](input UpdateParamsInput, moduleName strin // createProposalMsg creates the module-specific update params message func createProposalMsg(params interface{}, name string) sdk.Msg { + authority := GovAuthority() + switch name { case evmtypes.ModuleName: return &evmtypes.MsgUpdateParams{Authority: authority, Params: params.(evmtypes.Params)} From 4a449832117823339a4f512a5ec4ff2d81c33093 Mon Sep 17 00:00:00 2001 From: Rahul Ghangas Date: Fri, 5 Jun 2026 09:55:24 +0000 Subject: [PATCH 4/5] fix: accounting and validator selection --- contracts/solidity/StakedBondVault.json | 407 ++++++------ contracts/solidity/StakedBondVault.sol | 615 ++++++++++++++---- precompiles/staking/types.go | 19 +- .../x/vm/test_staked_bond_vault.go | 441 ++++++------- 4 files changed, 920 insertions(+), 562 deletions(-) diff --git a/contracts/solidity/StakedBondVault.json b/contracts/solidity/StakedBondVault.json index 53e7d012..50e9dd23 100644 --- a/contracts/solidity/StakedBondVault.json +++ b/contracts/solidity/StakedBondVault.json @@ -24,22 +24,6 @@ "stateMutability": "nonpayable", "type": "constructor" }, - { - "inputs": [], - "name": "InvalidShortString", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "str", - "type": "string" - } - ], - "name": "StringTooLong", - "type": "error" - }, { "anonymous": false, "inputs": [ @@ -98,8 +82,21 @@ }, { "anonymous": false, - "inputs": [], - "name": "EIP712DomainChanged", + "inputs": [ + { + "indexed": true, + "internalType": "uint8", + "name": "step", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "reason", + "type": "bytes" + } + ], + "name": "PokeStepFailed", "type": "event" }, { @@ -221,6 +218,50 @@ "name": "Transfer", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "targetValidatorCount", + "type": "uint8" + } + ], + "name": "ValidatorPolicyUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "srcValidator", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "dstValidator", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int64", + "name": "completionTime", + "type": "int64" + } + ], + "name": "ValidatorRebalanced", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -231,7 +272,7 @@ "type": "uint256" } ], - "name": "ValidatorsUpdated", + "name": "ValidatorSelectionUpdated", "type": "event" }, { @@ -271,6 +312,25 @@ "name": "Withdraw", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "batchId", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "firstMatureBlock", + "type": "uint64" + } + ], + "name": "WithdrawalBatchMatured", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -404,12 +464,25 @@ }, { "inputs": [], - "name": "DOMAIN_SEPARATOR", + "name": "DEFAULT_TARGET_VALIDATOR_COUNT", "outputs": [ { - "internalType": "bytes32", + "internalType": "uint256", "name": "", - "type": "bytes32" + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_UNBONDING_ENTRIES", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" } ], "stateMutability": "view", @@ -428,6 +501,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "MIN_OPERATION_ASSETS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "NATIVE_WERC20", @@ -469,12 +555,25 @@ }, { "inputs": [], - "name": "WEIGHT_SCALE", + "name": "SCORE_SCALE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VALIDATOR_SCAN_PAGE_LIMIT", "outputs": [ { - "internalType": "uint16", + "internalType": "uint256", "name": "", - "type": "uint16" + "type": "uint256" } ], "stateMutability": "view", @@ -728,49 +827,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "eip712Domain", - "outputs": [ - { - "internalType": "bytes1", - "name": "fields", - "type": "bytes1" - }, - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "string", - "name": "version", - "type": "string" - }, - { - "internalType": "uint256", - "name": "chainId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "verifyingContract", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - }, - { - "internalType": "uint256[]", - "name": "extensions", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -1021,68 +1077,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "nonces", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "uint8", - "name": "v", - "type": "uint8" - }, - { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "permit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -1128,6 +1122,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "step", + "type": "uint8" + } + ], + "name": "pokeStep", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -1298,6 +1311,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "selectedValidatorCount", + "outputs": [ + { + "internalType": "uint256", + "name": "count", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -1324,17 +1350,12 @@ { "inputs": [ { - "internalType": "string[]", - "name": "operatorAddresses", - "type": "string[]" - }, - { - "internalType": "uint16[]", - "name": "weights", - "type": "uint16[]" + "internalType": "uint8", + "name": "count", + "type": "uint8" } ], - "name": "setValidators", + "name": "setValidatorPolicy", "outputs": [], "stateMutability": "payable", "type": "function" @@ -1384,6 +1405,19 @@ "stateMutability": "payable", "type": "function" }, + { + "inputs": [], + "name": "targetValidatorCount", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "totalAssets", @@ -1410,6 +1444,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "totalIdleLiquid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "totalLiquidReserved", @@ -1544,14 +1591,19 @@ "type": "string" }, { - "internalType": "uint16", - "name": "weight", - "type": "uint16" + "internalType": "uint256", + "name": "score", + "type": "uint256" }, { "internalType": "uint256", "name": "delegated", "type": "uint256" + }, + { + "internalType": "bool", + "name": "selected", + "type": "bool" } ], "stateMutability": "view", @@ -1655,6 +1707,11 @@ "internalType": "int64", "name": "maturityTime", "type": "int64" + }, + { + "internalType": "uint64", + "name": "firstMatureBlock", + "type": "uint64" } ], "stateMutability": "view", @@ -1708,82 +1765,36 @@ "type": "function" } ], - "bytecode": "0x6101a060408181523462000644576200520c803803809162000022828662000664565b84398201606083820312620006445782516001600160a01b0381169390849003620006445760208181015190936001600160401b0392909183811162000644578462000070918301620006c7565b93828201518481116200064457620000899201620006c7565b90805194620000988662000648565b60019081875280870197603160f81b89528651868111620005585760038054918583811c9316801562000639575b858410146200062557601f92838111620005dd575b50808584821160011462000578575f916200056c575b505f1982841b1c191690861b1781555b865191888311620005585760049788548781811c911680156200054d575b878210146200053a579081838695949311620004e3575b50869184116001146200047c575f9362000470575b505082861b925f19911b1c19161785555b6200016662000714565b901562000467575b60a05273d4949664cd82660aae99bedc034a0dea8a0bd5176080526200019487620007d4565b95610160968752620001a6896200096f565b9761018098895283815191012099610120998b8b5251902099610140968b88524660e05286519b8c9288878501947f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8652015260608d01524660808d01523060a08d015260a08c5260c08c01928c8410908411176200045457508186528a51902060c05261010099308b5284600a5584601155821562000425575050906016915f8052600990818352855f20815f52835260ff865f20541615620003ef575b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929805f52828452865f20825f52845260ff875f20541615620003b8575b507f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a91825f52808452865f20825f52845260ff875f2054161562000381575b5050506801000000000000000160018060801b03196010541617601055825f5252815f209060ff19825416179055519361472e958662000abe873960805186818161173d01528181611b9b0152818161344301528181613fbb015261463a015260a0518661216e015260c05186613010015260e051866130db01525185612fda0152518461305f01525183613085015251826109230152518161094c0152f35b825f528352855f20815f528352855f208560ff1982541617905533915f80516020620051ec8339815191525f80a45f8080620002e1565b805f52828452865f20825f528452865f208660ff198254161790558133915f80516020620051ec8339815191525f80a45f620002a2565b5f8052818352855f20815f528352855f208560ff1982541617905533815f5f80516020620051ec8339815191528180a462000265565b906961646d696e207a65726f60b01b6101046064938662461bcd60e51b855260c4820152600a60e48201520152fd5b604190634e487b7160e01b5f525260245ffd5b5060126200016e565b015191505f806200014b565b9190879450601f198416928a5f52875f20935f5b89828210620004cc5750508511620004b2575b50505050811b0185556200015c565b01519060f8845f19921b161c191690555f808080620004a3565b8385015187558b9890960195938401930162000490565b9091929350895f52865f208380870160051c82019289881062000530575b918a918897969594930160051c01915b8281106200052157505062000136565b5f81558796508a910162000511565b9250819262000501565b60228a634e487b7160e01b5f525260245ffd5b90607f16906200011f565b634e487b7160e01b5f52604160045260245ffd5b90508a01515f620000f1565b5f8481528781208994509190601f19841690898f5b838310620005c5575050508311620005ad575b5050811b01815562000101565b8c01515f1983861b60f8161c191690555f80620005a0565b84015185558b96909401939283019201898f6200058d565b825f52855f208480840160051c8201928885106200061b575b0160051c019087905b8281106200060f575050620000db565b5f8155018790620005ff565b92508192620005f6565b634e487b7160e01b5f52602260045260245ffd5b92607f1692620000c6565b5f80fd5b604081019081106001600160401b038211176200055857604052565b601f909101601f19168101906001600160401b038211908210176200055857604052565b6001600160401b0381116200055857601f01601f191660200190565b5f5b838110620006b65750505f910152565b8181015183820152602001620006a6565b81601f8201121562000644578051620006e08162000688565b92620006f0604051948562000664565b818452602082840101116200064457620007119160208085019101620006a4565b90565b60405163313ce56760e01b60208201908152600482529190620007378162000648565b5f80938192519073d4949664cd82660aae99bedc034a0dea8a0bd5175afa3d15620007cb573d90620007698262000688565b9162000779604051938462000664565b82523d84602084013e5b80620007be575b62000795575b508190565b602081805181010312620007ba576020015160ff811162000790576001925060ff1690565b8280fd5b506020815110156200078a565b60609062000783565b8051602091908281101562000853575090601f8251116200081157808251920151908083106200080357501790565b825f19910360031b1b161790565b604490620008459260405193849263305a27a960e01b845280600485015282519283918260248701528686019101620006a4565b601f01601f19168101030190fd5b6001600160401b03811162000558576005928354926001938481811c9116801562000964575b838210146200062557601f811162000930575b5081601f8411600114620008ca57509282939183925f94620008be575b50501b915f199060031b1c191617905560ff90565b015192505f80620008a9565b919083601f198116875f52845f20945f905b88838310620009155750505010620008fc575b505050811b01905560ff90565b01515f1960f88460031b161c191690555f8080620008ef565b858701518855909601959485019487935090810190620008dc565b855f5284601f845f209201871c820191601f8601881c015b828110620009585750506200088c565b5f815501859062000948565b90607f169062000879565b8051602090818110156200099c5750601f8251116200081157808251920151908083106200080357501790565b906001600160401b0382116200055857600654926001938481811c9116801562000ab2575b838210146200062557601f811162000a7b575b5081601f841160011462000a1357509282939183925f9462000a07575b50501b915f199060031b1c19161760065560ff90565b015192505f80620009f1565b919083601f19811660065f52845f20945f905b8883831062000a60575050501062000a47575b505050811b0160065560ff90565b01515f1960f88460031b161c191690555f808062000a39565b85870151885590960195948501948793509081019062000a26565b60065f5284601f845f20920160051c820191601f860160051c015b82811062000aa6575050620009d4565b5f815501859062000a96565b90607f1690620009c156fe60806040526004361015610011575f80fd5b60e05f35811c90816301e1d114146124bc57816301ffc9a71461246657816303e5fa881461243d57816306fdde031461239b57816307a2d13a14611afd578163095ea7b3146123755781630a28a477146123335781630a763da11461230d5781630f43a677146122f057816318160ddd146122d357816323b872dd1461229b578163248a9ca31461226e578163291cdb8c146122495781632f2ff15d146121a1578163313ce5671461215a57816332145f901461212f578163331c138c14611ef5578163333fedad14611ed957816333a7391614611ebc57816333bb7f9114611ceb57816335aa2e4414611c765781633644e51514611c5c57816336568abe14611bca57816338d52e0f14611b865781633950935114611b39578163402d267d146103ec5781634221b2c214611b1c578163499bafcc14611b025781634cdad50614611afd578163559904cb14611a35578163588f1343146115615781635ac22fd21461152d5781635c90178314610db757816360da3e8314610d955781636a84a98514610d785781636e553f651461086357816370a0823114610d41578163714897df14610d2757816377397cdd14610d0a5781637aed3cbb14610ced5781637d41c86e14610a685781637ecebe0014610a3057816380d04de814610a1357816384b0196e1461090e57816391d14854146108c5578163937b25811461086857816394bf804d1461086357816395d89b4114610780578163a217fddf14610766578163a457c2d7146106c3578163a9059cbb14610692578163b3d7f6b914610634578163b460af9414610601578163b9bcb70f14610606578163ba08765214610601578163c63d75b6146103ec578163c6e6f5921461033b578163ce96cb77146103ec578163d505accf1461044d57508063d547741f1461040e578063d77bb97c146103f1578063d905777e146103ec578063dd62ed3e1461039f578063e63ab1e914610365578063e9f2838e14610340578063ef8b30f71461033b5763f5b541a6146102fd575f80fd5b34610337575f3660031901126103375760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b5f80fd5b6127e3565b34610337575f36600319011261033757602060ff60125460081c166040519015158152f35b34610337575f3660031901126103375760206040517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b34610337576040366003190112610337576103b861253a565b6103c0612550565b9060018060a01b038091165f52600160205260405f2091165f52602052602060405f2054604051908152f35b6126bd565b34610337575f366003190112610337576020600e54604051908152f35b346103375760403660031901126103375761044b60043561042d612550565b90805f526009602052610446600160405f200154612825565b6129c4565b005b3461033757806003193601126103375761046561253a565b9061046e612550565b604435916084359060643560ff83168303610337578042116105bc5760018060a01b039182871693845f52600760205260405f20918254926001840190556040519360208501937f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98552876040870152868916606087015289608087015260a086015260c085015260c084528301918383106001600160401b038411176105a8576105549361054c93604052519020610525612fd7565b906040519161190160f01b83526002830152602282015260c43591604260a4359220612f54565b919091612e41565b16036105635761044b92612ba0565b60405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606490fd5b634e487b7160e01b5f52604160045260245ffd5b60405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606490fd5b612799565b34610337575f36600319011261033757602060405173d4949664cd82660aae99bedc034a0dea8a0bd5178152f35b346103375760203660031901126103375761064d613420565b6001810180911161067e57600254906001820180921161067e57602091610676916004356132af565b604051908152f35b634e487b7160e01b5f52601160045260245ffd5b34610337576040366003190112610337576106b86106ae61253a565b6024359033612a46565b602060405160018152f35b34610337576040366003190112610337576106dc61253a565b60243590335f52600160205260405f2060018060a01b0382165f5260205260405f205491808310610713576106b892039033612ba0565b60405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608490fd5b34610337575f3660031901126103375760206040515f8152f35b34610337575f366003190112610337576040515f906004546107a181612582565b80835260019180831690811561083b57506001146107e2575b6107de836107ca8187038261269c565b6040519182916020835260208301906124f7565b0390f35b60045f90815260209450917f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b828410610828575050508101909101906107ca816107ba565b805485850187015292850192810161080f565b6107de95506107ca93506020915091849260ff191682840152151560051b82010193506107ba565b612711565b34610337576020366003190112610337576004355f526015602052608060405f2060018060a01b036001600160401b03818354169260026001820154910154926040519485528116602085015260a01c1660408301526060820152f35b34610337576040366003190112610337576108de612550565b6004355f52600960205260405f209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b34610337575f366003190112610337576109477f0000000000000000000000000000000000000000000000000000000000000000613101565b6109707f00000000000000000000000000000000000000000000000000000000000000006131f7565b60405190602090818301938385106001600160401b038611176105a857949392906109c88391856040525f84526109ba604051988998600f60f81b8a5280868b01528901906124f7565b9087820360408901526124f7565b914660608701523060808701525f60a087015285830360c087015251918281520192915f5b8281106109fc57505050500390f35b8351855286955093810193928101926001016109ed565b34610337575f366003190112610337576020600c54604051908152f35b34610337576020366003190112610337576001600160a01b03610a5161253a565b165f526007602052602060405f2054604051908152f35b610a7136612764565b610a7b34156134ee565b610a8361352d565b60ff60125460081c16610cb357610a9b8315156135bf565b6001600160a01b0391808316610ab2811515613583565b838316928315610c815785610af46020977f1dfdc691a597a83af2430bd31addf8d2129d012eab8b35de6d696dc91e64852393873303610c71575b3090612a46565b601154958693610b03856135f9565b601155601054906001600160401b039283831692835f5260168c528460405f2094855460ff811615908115610c63575b50610c25575b506002929150601054169260405193610b518561264b565b8b85528d85019182526040850190815260608501928884528a5f5260158f528060405f2096511660018060a01b0319875416178655600186019251168254916001600160401b0360a01b905160a01b169163ffffffff60e01b16171790555191015560018101610bc2848254612a39565b905580546affffffffffffffff000000610be0848360181c16613607565b60181b166affffffffffffffff0000001991909116179055601054604080516001600160a01b0397909716875260208701939093521693a46001600a55604051908152f35b610c329192939550613607565b1680916001600160401b031916176010555f5260168a52600260405f2092600160ff1985541617845590848d610b39565b60ff915060081c168f610b33565b610c7c823383612c9e565b610aed565b60405162461bcd60e51b815260206004820152600a6024820152696f776e6572207a65726f60b01b6044820152606490fd5b60405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dd85b1cc81c185d5cd95960721b6044820152606490fd5b34610337575f366003190112610337576020600f54604051908152f35b34610337575f366003190112610337576020601454604051908152f35b34610337575f366003190112610337576020604051818152f35b34610337576020366003190112610337576001600160a01b03610d6261253a565b165f525f602052602060405f2054604051908152f35b34610337575f366003190112610337576020601154604051908152f35b34610337575f36600319011261033757602060ff601254166040519015158152f35b6040366003190112610337576004356001600160401b03811161033757610de29036906004016126e1565b906024356001600160401b03811161033757610e029036906004016126e1565b610e0f92919234156134ee565b335f9081527f84e70a45dc3cad9f831e8a7d9f4327701c9df1c790bfeaa7b6cb95e200be673360205260409020547f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9299060ff16156113ae5750808403611377576020841161133c575f91610e816144d3565b93600b545f600b55806112d8575b509291905f935b868510610f5657868661271086148015610f4e575b15610f1b57610ee15760207f6ebd9ef82ef3aa533937a4d42dc350c0739723937c8809f94e4983795d1ccc3c91604051908152a1005b60405162461bcd60e51b815260206004820152601260248201527164656c65676174696f6e732061637469766560701b6044820152606490fd5b60405162461bcd60e51b815260206004820152600b60248201526a626164207765696768747360a81b6044820152606490fd5b508115610eab565b909192610f6485888561385d565b9050156112a15761ffff610f81610f7c87878661389e565b6138ae565b161561126e5760645f610f95878a8761385d565b928391604051948593849263120bba7360e11b845230600485015260406024850152816044850152848401378181018301859052601f01601f191681010301816108005afa801561126357611242575b50610ffb610ff486898661385d565b369161395a565b602081519101205f5b8681106111de5750506110299061ffff611022610f7c88888761389e565b1690612a39565b9361ffff61103882898661385d565b919061105961104b610f7c868a8961389e565b9160405194610ff486612666565b83521660208201525f6040820152600b54600160401b8110156105a8578060016110869201600b55612566565b9190916111cb5780518051906001600160401b0382116105a8576110aa8454612582565b601f8111611190575b50602090601f831160011461112057928260029360409361110c9897965f92611115575b50508160011b915f199060031b1c19161784555b6001840161ffff60208301511661ffff1982541617905501519101556135f9565b93929190610e96565b015190508e806110d7565b90845f5260205f20915f5b601f198516811061117857508360409361110c98979693600193600297601f19811610611160575b505050811b0184556110eb565b01515f1960f88460031b161c191690558e8080611153565b9192602060018192868501518155019401920161112b565b6111bb90855f5260205f206005601f8601811c820192602087106111c1575b601f01901c019061361f565b8b6110b3565b91925082916111af565b634e487b7160e01b5f525f60045260245ffd5b6111ec610ff4828b8861385d565b60208151910120821461120757611202906135f9565b611004565b60405162461bcd60e51b8152602060048201526013602482015272323ab83634b1b0ba32903b30b634b230ba37b960691b6044820152606490fd5b61125d903d805f833e611255818361269c565b8101906138bd565b50610fe5565b6040513d5f823e3d90fd5b60405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc81dd95a59da1d60aa1b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e32b6b83a3c903b30b634b230ba37b960891b6044820152606490fd5b600390808202908282040361067e57600b5f527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9908101905b81811061131f575050610e8f565b8061132a8492613635565b5f60018201555f600282015501611311565b60405162461bcd60e51b8152602060048201526013602482015272746f6f206d616e792076616c696461746f727360681b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b6044820152606490fd5b6113b733612d8a565b604051916113c48361264b565b60428352602083019060603683378351156115195760308253835160019081101561151957607860218601536041905b8082116114d65750506114a557604861147292611481926114a19560405195869376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b60208601526114498151809260206037890191016124d6565b8401917001034b99036b4b9b9b4b733903937b6329607d1b6037840152518093868401906124d6565b0103602881018452018261269c565b60405162461bcd60e51b81526020600482015291829160248301906124f7565b0390fd5b606460405162461bcd60e51b815260206004820152602060248201525f805160206146b98339815191526044820152fd5b9091600f81166010811015611519576f181899199a1a9b1b9c1cb0b131b232b360811b901a6115058488612d79565b5360041c91801561067e575f1901906113f4565b634e487b7160e01b5f52603260045260245ffd5b5f3660031901126103375761154234156134ee565b61154a61352d565b60206115546144d3565b6001600a55604051908152f35b604036600319011261033757611575612550565b61157f34156134ee565b61158761352d565b6004355f52601560205260405f20604051906115a28261264b565b80546001600160a01b0390811680845260018301549182166020850190815260a09290921c6001600160401b031660408501526002909201546060840190815291156119fe576001600160401b036040840151165f52601660205260405f209182549460ff8660101c16156119c9576001600160a01b0381166119c3575081516001600160a01b0316915b516001600160a01b039081169083160361198d576116566001600160401b038660581c16613607565b6001600160401b03808760181c169116145f1461197257506116816005830154600684015490613413565b935b67ffffffffffffffff60581b6116a5605883901c6001600160401b0316613607565b60581b16906001600160401b0360581b1916178255600682016116c9858254612a39565b90556116d784600e54613413565b600e556116e684600f54613413565b600f556004355f908152601560209081526040808320838155600181018490556002018390555163a9059cbb60e01b9181019182526001600160a01b038481166024830152604480830189905282526117d89391927f00000000000000000000000000000000000000000000000000000000000000009091169190819061176e60648661269c565b6040519461177b86612681565b602086527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646020870152519082855af13d1561196a573d916117bc83612d5e565b926117ca604051948561269c565b83523d5f602085013e613695565b8051908115918215611950575b5050156118f8576001600160401b036040840151166040519185835260018060a01b0316917f6443ab78e20802b0a48c253c5a7e05576a8bedd83aec398a8bba1164e7cf6fc3602060043592a4546001600160401b03808260181c169160581c161461185c575b6020826001600a55604051908152f35b60406001600160401b03910151165f52601660205260405f20905f82555f60018301555f600283015560086003925f848201555f60048201555f60058201555f60068201555f6007820155018054905f8155816118bc575b50509061184c565b818402918483040361067e575f5260205f20908101905b818110156118b457806118e68592613635565b5f60018201555f6002820155016118d3565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b611963925060208091830101910161367d565b85806117e5565b606091613695565b61198790516005840154600185015491613391565b93611683565b60405162461bcd60e51b815260206004820152600e60248201526d3bb937b733903932b1b2b4bb32b960911b6044820152606490fd5b9161162d565b60405162461bcd60e51b815260206004820152600d60248201526c6e6f7420636c61696d61626c6560981b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e1d5b9adb9bdddb881c995c5d595cdd608a1b6044820152606490fd5b3461033757602036600319011261033757600435906001600160401b0380831680930361033757610180925f52601660205260405f208054926001820154906002830154906003840154906004850154926005860154946007600688015497015460070b976040519960ff811615158b5260ff8160081c16151560208c015260ff8160101c16151560408c0152818160181c1660608c015260581c1660808a015260a089015260c0880152860152610100850152610120840152610140830152610160820152f35b61251c565b34610337575f366003190112610337576020610676614581565b34610337575f366003190112610337576020601354604051908152f35b34610337576040366003190112610337576106b8611b5561253a565b335f52600160205260405f2060018060a01b0382165f52602052611b7f60243560405f2054612a39565b9033612ba0565b34610337575f366003190112610337576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461033757604036600319011261033757611be3612550565b336001600160a01b03821603611bff5761044b906004356129c4565b60405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608490fd5b34610337575f366003190112610337576020610676612fd7565b3461033757602036600319011261033757600435600b5481101561033757611ca0611cdc91612566565b5060405190611cba82611cb381846125ba565b038361269c565b600261ffff6001830154169101546040519384936060855260608501906124f7565b91602084015260408301520390f35b60208060031936011261033757611d0061253a565b611d0861352d565b60ff60125416611e85576001600160a01b0316801590611d288215613583565b3415611e5257611d3661443c565b5060025480611e095734925b611d4d8415156135bf565b611dc45782611d5b91612a39565b600255805f525f835260405f20828154019055805f5f805160206146d983398151915285604051868152a360405134815282848201527fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d760403392a36001600a55604051908152f35b60405162461bcd60e51b815260048101859052601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606490fd5b611e11613420565b34811115611e4b57611e24903490613413565b600182019081831161067e576001810180911161067e57611e459134613391565b92611d42565b505f611e24565b60405162461bcd60e51b815260048101849052600b60248201526a7a65726f2061737365747360a81b6044820152606490fd5b60405162461bcd60e51b815260048101839052600f60248201526e19195c1bdcda5d1cc81c185d5cd959608a1b6044820152606490fd5b34610337575f366003190112610337576020600d54604051908152f35b34610337575f3660031901126103375760206040516127108152f35b606036600319011261033757600435801515809103610337576024803590811515809203610337576044359081151580920361033757611f3534156134ee565b335f9081527f84574a31e2f767388bfa57bc81ff2590df95d3022c04c363cca3e37ee960863160209081526040909120547f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a9060ff1615611fbd5750505061ff009060ff62ff00006012549260101b1694169062ffffff1916179160081b1617176012555f80f35b611fc633612d8a565b90604051611fd38161264b565b6042815283810191606036843781511561211c5760308353815160019081101561210957607860218401536041905b8082116120a05750506120715760486114a193611472936120559360405195869376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a860152611449815180928c6037890191016124d6565b60405193849362461bcd60e51b855260048501528301906124f7565b606485856040519162461bcd60e51b83528160048401528201525f805160206146b98339815191526044820152fd5b9091600f811660108110156120f6576f181899199a1a9b1b9c1cb0b131b232b360811b901a6120cf8486612d79565b5360041c9180156120e3575f190190612002565b87634e487b7160e01b5f5260116004525ffd5b88634e487b7160e01b5f5260326004525ffd5b86634e487b7160e01b5f5260326004525ffd5b85634e487b7160e01b5f5260326004525ffd5b60203660031901126103375761214534156134ee565b61214d61352d565b602061155460043561372e565b34610337575f3660031901126103375760ff7f00000000000000000000000000000000000000000000000000000000000000001660ff811161067e57602090604051908152f35b34610337576040366003190112610337576004356121bd612550565b815f5260096020526121d5600160405f200154612825565b815f52600960205260405f209060018060a01b031690815f5260205260ff60405f2054161561220057005b815f52600960205260405f20815f5260205260405f20600160ff1982541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d5f80a4005b34610337575f36600319011261033757602060ff60125460101c166040519015158152f35b34610337576020366003190112610337576004355f5260096020526020600160405f200154604051908152f35b34610337576060366003190112610337576106b86122b761253a565b6122bf612550565b604435916122ce833383612c9e565b612a46565b34610337575f366003190112610337576020600254604051908152f35b34610337575f366003190112610337576020600b54604051908152f35b34610337575f3660031901126103375760206001600160401b0360105416604051908152f35b34610337576020366003190112610337576002546001810180911161067e5761235a613420565b906001820180921161067e57602091610676916004356132af565b34610337576040366003190112610337576106b861239161253a565b6024359033612ba0565b34610337575f366003190112610337576040515f906003546123bc81612582565b80835260019180831690811561083b57506001146123e4576107de836107ca8187038261269c565b60035f90815260209450917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b82841061242a575050508101909101906107ca816107ba565b8054858501870152928501928101612411565b34610337575f3660031901126103375760206001600160401b0360105460401c16604051908152f35b346103375760203660031901126103375760043563ffffffff60e01b811680910361033757602090637965db0b60e01b81149081156124ab575b506040519015158152f35b6301ffc9a760e01b149050826124a0565b34610337575f366003190112610337576020610676613420565b5f5b8381106124e75750505f910152565b81810151838201526020016124d8565b90602091612510815180928185528580860191016124d6565b601f01601f1916010190565b34610337576020366003190112610337576020610676600435612d30565b600435906001600160a01b038216820361033757565b602435906001600160a01b038216820361033757565b600b5481101561151957600b5f52600360205f20910201905f90565b90600182811c921680156125b0575b602083101461259c57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691612591565b905f92918054916125ca83612582565b9182825260019384811690815f1461262857506001146125eb575b50505050565b90919394505f52602092835f2092845f945b83861061261457505050500101905f8080806125e5565b8054858701830152940193859082016125fd565b9294505050602093945060ff191683830152151560051b0101905f8080806125e5565b608081019081106001600160401b038211176105a857604052565b606081019081106001600160401b038211176105a857604052565b604081019081106001600160401b038211176105a857604052565b90601f801991011681019081106001600160401b038211176105a857604052565b34610337576020366003190112610337576126d661253a565b5060206040515f8152f35b9181601f84011215610337578235916001600160401b038311610337576020808501948460051b01011161033757565b346103375760403660031901126103375761272a612550565b5060405162461bcd60e51b8152602060048201526011602482015270757365206465706f7369744e617469766560781b6044820152606490fd5b606090600319011261033757600435906001600160a01b03906024358281168103610337579160443590811681036103375790565b34610337576127a736612764565b505060405162461bcd60e51b8152602060048201526011602482015270757365207265717565737452656465656d60781b604482015260649150fd5b34610337576020366003190112610337576002546001810180911161067e5761280a613420565b906001820180921161067e5760209161067691600435613391565b5f9080825260209060098252604092838120338252835260ff84822054161561284e5750505050565b61285733612d8a565b918451906128648261264b565b604282528482019260603685378251156129b057603084538251906001918210156129b05790607860218501536041915b818311612943575050506129145760486114a19386936128f8936128e9985198899376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a860152611449815180928c6037890191016124d6565b0103602881018752018561269c565b5192839262461bcd60e51b8452600484015260248301906124f7565b60648486519062461bcd60e51b825280600483015260248201525f805160206146b98339815191526044820152fd5b909192600f8116601081101561299c576f181899199a1a9b1b9c1cb0b131b232b360811b901a6129738587612d79565b5360041c928015612988575f19019190612895565b634e487b7160e01b82526011600452602482fd5b634e487b7160e01b83526032600452602483fd5b634e487b7160e01b81526032600452602490fd5b905f918083526009602052604083209160018060a01b03169182845260205260ff6040842054166129f457505050565b8083526009602052604083208284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4565b9190820180921161067e57565b6001600160a01b03908116918215612b4d5716918215612afc575f82815280602052604081205491808310612aa857604082825f805160206146d9833981519152958760209652828652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b6001600160a01b03908116918215612c4d5716918215612bfd5760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591835f526001825260405f20855f5282528060405f2055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b9060018060a01b038083165f52600160205260405f209082165f5260205260405f2054925f198403612cd05750505050565b808410612ceb57612ce2930391612ba0565b5f8080806125e5565b60405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606490fd5b612d38613420565b6001810180911161067e57600254906001820180921161067e57612d5b92613391565b90565b6001600160401b0381116105a857601f01601f191660200190565b908151811015611519570160200190565b60405190612d9782612666565b602a82526020820160403682378251156115195760309053815160019081101561151957607860218401536029905b808211612dd65750506114a55790565b9091600f81166010811015612e2d576f181899199a1a9b1b9c1cb0b131b232b360811b901a612e058486612d79565b5360041c918015612e19575f190190612dc6565b60245f634e487b7160e01b81526011600452fd5b60245f634e487b7160e01b81526032600452fd5b6005811015612f405780612e525750565b60018103612e9a5760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b6044820152606490fd5b60028103612ee75760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606490fd5b600314612ef057565b60405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608490fd5b634e487b7160e01b5f52602160045260245ffd5b9291906fa2a8918ca85bafe22016d0b997e4df60600160ff1b038311612fcc5791608094939160ff6020946040519485521684840152604083015260608201525f93849182805260015afa15612fbf5781516001600160a01b03811615612fb9579190565b50600190565b50604051903d90823e3d90fd5b505050505f90600390565b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614806130d8575b15613032577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82527f000000000000000000000000000000000000000000000000000000000000000060408201527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260a0815260c081018181106001600160401b038211176105a85760405251902090565b507f00000000000000000000000000000000000000000000000000000000000000004614613009565b60ff811461313f5760ff811690601f821161312d576040519161312383612681565b8252602082015290565b604051632cd44ac360e21b8152600490fd5b50604051600554815f61315183612582565b8083526001938085169081156131d65750600114613177575b50612d5b9250038261269c565b60055f9081527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db094602093509091905b8183106131be575050612d5b93508201015f61316a565b855487840185015294850194869450918301916131a7565b9050612d5b94506020925060ff191682840152151560051b8201015f61316a565b60ff81146132195760ff811690601f821161312d576040519161312383612681565b50604051600654815f61322b83612582565b8083526001938085169081156131d657506001146132505750612d5b9250038261269c565b60065f9081527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f94602093509091905b818310613297575050612d5b93508201015f61316a565b85548784018501529485019486945091830191613280565b91906132bc828285613391565b9282156132d957096132cb5790565b6001810180911161067e5790565b634e487b7160e01b5f52601260045260245ffd5b905f1981830981830291828083109203918083039214613386576127109082821115613349577fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e91940990828211900360fc1b910360041c170290565b60405162461bcd60e51b81526020600482015260156024820152744d6174683a206d756c446976206f766572666c6f7760581b6044820152606490fd5b505061271091500490565b915f19828409928281029283808610950394808603951461340557848311156133495782910960018219018216809204600280826003021880830282030280830282030280830282030280830282030280830282030280920290030293600183805f03040190848311900302920304170290565b5050809250156132d9570490565b9190820391821161067e57565b600254156134ea576040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611263575f916134b4575b5061349161349a9161348b614581565b90612a39565b600d5490612a39565b600e54808211156134ae57612d5b91613413565b50505f90565b906020823d82116134e2575b816134cd6020938361269c565b810103126134df57505161349161347b565b80fd5b3d91506134c0565b5f90565b156134f557565b60405162461bcd60e51b815260206004820152601060248201526f756e65787065637465642076616c756560801b6044820152606490fd5b6002600a541461353e576002600a55565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b1561358a57565b60405162461bcd60e51b815260206004820152600d60248201526c7265636569766572207a65726f60981b6044820152606490fd5b156135c657565b60405162461bcd60e51b815260206004820152600b60248201526a7a65726f2073686172657360a81b6044820152606490fd5b5f19811461067e5760010190565b9060016001600160401b038093160191821161067e57565b81811061362a575050565b5f815560010161361f565b61363f8154612582565b9081613649575050565b81601f5f931160011461365a575055565b908083918252613679601f60208420940160051c84016001850161361f565b5555565b90816020910312610337575180151581036103375790565b919290156136f757508151156136a9575090565b3b156136b25790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b82519091501561370a5750805190602001fd5b60405162461bcd60e51b8152602060048201529081906114a19060248301906124f7565b905f9160ff60125460101c1661382a5780156138245761374c613fad565b613814575b80831080613806575b6137f6575b808310806137e8575b6137d8575b8210806137ca575b6137ba575b6137856013546135f9565b601355816014556040518281527f4889d7d38c1d1f265318505a98367d07d41591d6b7f9cc000f37ea92b8311daa60203392a2565b906137c4906135f9565b9061377a565b506137d3614295565b613775565b916137e2906135f9565b9161376d565b506137f161443c565b613768565b91613800906135f9565b9161375f565b5061380f613990565b61375a565b9161381e906135f9565b91613751565b505f9150565b60405162461bcd60e51b815260206004820152600b60248201526a1c1bdad9481c185d5cd95960aa1b6044820152606490fd5b91908110156115195760051b81013590601e19813603018212156103375701908135916001600160401b038311610337576020018236038113610337579190565b91908110156115195760051b0190565b3561ffff811681036103375790565b9190916040808285031261033757815193602091828401516001600160401b0394858211610337570190808284031261033757805194818601868110828211176105a8578252825190811161033757820183601f820112156103375780519361393161392886612d5e565b9351938461269c565b84835285858301011161033757849361394f918580850191016124d6565b845201519082015290565b92919261396682612d5e565b91613974604051938461269c565b829481845281830111610337578281602093845f960137010152565b6001600160401b03601054165f52601660205260405f20805460ff811615908115613f9f575b508015613f93575b613f8e576139ca61443c565b506001810154906139da82612d30565b9161010061ffff198354161782558260028301553015613f3f57305f525f60205260405f205490808210613eef57805f923084528360205203604083205580600254036002556040519081525f805160206146d983398151915260203092a3613a4161461f565b82811015613ee557613a5a905b80613ebc575b83613413565b905f9180613b1a575b50613ad86001827f5d78323b7b570071308d257743c74a9a2401f77d37e9de9f908da12c8917a40b606060076001600160401b0396019786199889815416898916179055600484015415613afc575b60105497878916958695015491604051928352602083015260070b6040820152a2613607565b1691829116176010555f52601660205260405f20600160ff19825416179055600190565b835462ff000019166201000017845560038401546005850155613ab2565b600b545f95935015613e8757613b2e6144d3565b50915f925b600b54841080613e7e575b15613e2757613b4c84612566565b509060028201548181105f14613e1f57915b8215613e1357604051630fb6accf60e21b81529060208280613b858785306004850161426b565b03815f6108005af1918215611263575f92613dd5575b50613baa846002830154613413565b6002820155600c613bbc858254613413565b9055600d613bcb858254612a39565b9055600e613bda858254612a39565b9055613bea846004880154612a39565b6004870155613c0e613c1560405192613c0284612666565b604051928380926125ba565b038261269c565b81528360208201528160070b60408201526008860154600160401b8110156105a8576001810180600889015581101561151957600887015f5260205f209082518051906001600160401b0382116105a857613c7560038402850154612582565b90601f91828111613d98575b506020918311600114613d22579282604095936003936002965f92613d17575b50508160011b915f1990851b1c1916178282028401555b60208601516001838302850101550201019101516001600160401b0319825416906001600160401b03161790558760070b8160070b13613d0d575b50613d0791613d0191613413565b936135f9565b92613b33565b9650613d07613cf3565b015190505f80613ca1565b906003840285015f5260205f20915f5b601f1985168110613d805750836003936002969360019360409997601f19811610613d69575b505050811b01828202840155613cb8565b01515f1983871b60f8161c191690555f8080613d58565b91926020600181928685015181550194019201613d32565b613dc6906003860287015f5260205f20600585808801821c83019360208910613dcc575b01901c019061361f565b5f613c81565b93508293613dbc565b9091506020813d602011613e0b575b81613df16020938361269c565b8101031261033757518060070b810361033757905f613b9b565b3d9150613de4565b5093613d0791506135f9565b508091613b5e565b9094919250613e395790613ad8613a63565b60405162461bcd60e51b815260206004820152601d60248201527f696e73756666696369656e742064656c656761746564206173736574730000006044820152606490fd5b50801515613b3e565b60405162461bcd60e51b815260206004820152600d60248201526c6e6f2076616c696461746f727360981b6044820152606490fd5b613ec881600e54612a39565b600e55613ed781600f54612a39565b600f55806003840155613a54565b50613a5a82613a4e565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608490fd5b505f90565b506001810154156139be565b60ff915060081c165f6139b6565b601080546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692916001600160401b03604092831c81169290915b80549083851694848316861015614260575f9786895260209560168752858a2094855460ff808260081c1615918215614254575b50508015614248575b614201575060078501541642106141d55760048085015491828b600f938454938b6140588887612a39565b9260248d51809481936370a0823160e01b835230908301525afa9283156141ca5792614177575b50917f73f330dd18a8f4760be8fa04b392ba243a76dcbe07487724e846182d63dbfafa9b9c9d82846140fa97956141169a99979510614145575b5050506140ee918491600d6140cf828254613413565b90556140e7836140e2600e938454613413565b612a39565b9055612a39565b90556003860154612a39565b60058501908155845462ff000019166201000017909455613607565b815467ffffffffffffffff60401b191690841b67ffffffffffffffff60401b16179055549051908152a2600190565b6140ee94969161415491613413565b9081811115614170576141679250613413565b93915f806140b9565b5050614167565b9091508a81813d83116141c3575b61418f818361269c565b810103126141bf5751907f73f330dd18a8f4760be8fa04b392ba243a76dcbe07487724e846182d63dbfafa61407f565b8d80fd5b503d614185565b8b51903d90823e3d90fd5b50815467ffffffffffffffff60401b1916931b67ffffffffffffffff60401b1692909217909155505050565b92939750955097508492506001600160401b0360401b61422083613607565b67ffffffffffffffff60401b1990921691851b1617855516828114612e195760010192613ff0565b5060048601541561402d565b871c1690505f80614024565b505f96505050505050565b9392916142909060409260018060a01b031686526060602087015260608601906125ba565b930152565b600290815415614437576142a761461f565b908115801561442d575b614426576142bd6144d3565b505f90825b600b548084108061441d575b156144125760019081850180861161067e57036143f25750805b81156143e7576142f784612566565b5060408051906353266bbb60e01b825260209182818061431d89600498308a850161426b565b03815f6108005af19081156143dd575f916143b0575b501561437d5750505061437791614371918761434e87612566565b500161435b838254612a39565b9055600c61436a838254612a39565b9055613413565b926135f9565b916142c2565b5162461bcd60e51b815291820152600f60248201526e19195b1959d85d194819985a5b1959608a1b604482015260649150fd5b6143d09150833d85116143d6575b6143c8818361269c565b81019061367d565b5f614333565b503d6143be565b82513d5f823e3d90fd5b9261437791506135f9565b61ffff61440c9161440286612566565b50015416856132ed565b906142e8565b505092505050600190565b508115156142ce565b9150505f90565b50600b54156142b1565b5f9150565b600b541580156144a2575b6134ea5763ffffffff600b541660405190632efe8a5f60e01b825230600483015260248201526020816044815f6108015af1908115611263575f9161448a575090565b612d5b915060203d81116143d6576143c8818361269c565b506144ab6144d3565b15614447565b6001600160a01b039091168152604060208201819052612d5b929101906125ba565b5f9081805b600b54821015614578576144eb82612566565b5061450d8560409283518093819263120bba7360e11b835230600484016144b1565b03816108005afa91821561456f57509160206145479261454d948891614553575b50018051600261453d87612566565b5001555190612a39565b916135f9565b906144d8565b61456791503d808a833e611255818361269c565b90505f61452e565b513d87823e3d90fd5b92505081600c55565b5f905f80600b545b80831061459557505050565b9091936145a185612566565b506145c38460409283518093819263120bba7360e11b835230600484016144b1565b03816108005afa91821561461657509160206145ed926145f39487916145fa575b50015190612a39565b946135f9565b9190614589565b61460e91503d8089833e611255818361269c565b90505f6145e4565b513d86823e3d90fd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611263575f91614687575b50600f54808211156134ae57612d5b91613413565b906020823d82116146b0575b816146a06020938361269c565b810103126134df5750515f614672565b3d915061469356fe537472696e67733a20686578206c656e67746820696e73756666696369656e74ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212203dea20cc054fb9b8e55a057442460f9c400c356156d57798f5f876718474fdfd64736f6c634300081400332f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", - "deployedBytecode": "0x60806040526004361015610011575f80fd5b60e05f35811c90816301e1d114146124bc57816301ffc9a71461246657816303e5fa881461243d57816306fdde031461239b57816307a2d13a14611afd578163095ea7b3146123755781630a28a477146123335781630a763da11461230d5781630f43a677146122f057816318160ddd146122d357816323b872dd1461229b578163248a9ca31461226e578163291cdb8c146122495781632f2ff15d146121a1578163313ce5671461215a57816332145f901461212f578163331c138c14611ef5578163333fedad14611ed957816333a7391614611ebc57816333bb7f9114611ceb57816335aa2e4414611c765781633644e51514611c5c57816336568abe14611bca57816338d52e0f14611b865781633950935114611b39578163402d267d146103ec5781634221b2c214611b1c578163499bafcc14611b025781634cdad50614611afd578163559904cb14611a35578163588f1343146115615781635ac22fd21461152d5781635c90178314610db757816360da3e8314610d955781636a84a98514610d785781636e553f651461086357816370a0823114610d41578163714897df14610d2757816377397cdd14610d0a5781637aed3cbb14610ced5781637d41c86e14610a685781637ecebe0014610a3057816380d04de814610a1357816384b0196e1461090e57816391d14854146108c5578163937b25811461086857816394bf804d1461086357816395d89b4114610780578163a217fddf14610766578163a457c2d7146106c3578163a9059cbb14610692578163b3d7f6b914610634578163b460af9414610601578163b9bcb70f14610606578163ba08765214610601578163c63d75b6146103ec578163c6e6f5921461033b578163ce96cb77146103ec578163d505accf1461044d57508063d547741f1461040e578063d77bb97c146103f1578063d905777e146103ec578063dd62ed3e1461039f578063e63ab1e914610365578063e9f2838e14610340578063ef8b30f71461033b5763f5b541a6146102fd575f80fd5b34610337575f3660031901126103375760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b5f80fd5b6127e3565b34610337575f36600319011261033757602060ff60125460081c166040519015158152f35b34610337575f3660031901126103375760206040517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b34610337576040366003190112610337576103b861253a565b6103c0612550565b9060018060a01b038091165f52600160205260405f2091165f52602052602060405f2054604051908152f35b6126bd565b34610337575f366003190112610337576020600e54604051908152f35b346103375760403660031901126103375761044b60043561042d612550565b90805f526009602052610446600160405f200154612825565b6129c4565b005b3461033757806003193601126103375761046561253a565b9061046e612550565b604435916084359060643560ff83168303610337578042116105bc5760018060a01b039182871693845f52600760205260405f20918254926001840190556040519360208501937f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98552876040870152868916606087015289608087015260a086015260c085015260c084528301918383106001600160401b038411176105a8576105549361054c93604052519020610525612fd7565b906040519161190160f01b83526002830152602282015260c43591604260a4359220612f54565b919091612e41565b16036105635761044b92612ba0565b60405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606490fd5b634e487b7160e01b5f52604160045260245ffd5b60405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606490fd5b612799565b34610337575f36600319011261033757602060405173d4949664cd82660aae99bedc034a0dea8a0bd5178152f35b346103375760203660031901126103375761064d613420565b6001810180911161067e57600254906001820180921161067e57602091610676916004356132af565b604051908152f35b634e487b7160e01b5f52601160045260245ffd5b34610337576040366003190112610337576106b86106ae61253a565b6024359033612a46565b602060405160018152f35b34610337576040366003190112610337576106dc61253a565b60243590335f52600160205260405f2060018060a01b0382165f5260205260405f205491808310610713576106b892039033612ba0565b60405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608490fd5b34610337575f3660031901126103375760206040515f8152f35b34610337575f366003190112610337576040515f906004546107a181612582565b80835260019180831690811561083b57506001146107e2575b6107de836107ca8187038261269c565b6040519182916020835260208301906124f7565b0390f35b60045f90815260209450917f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b828410610828575050508101909101906107ca816107ba565b805485850187015292850192810161080f565b6107de95506107ca93506020915091849260ff191682840152151560051b82010193506107ba565b612711565b34610337576020366003190112610337576004355f526015602052608060405f2060018060a01b036001600160401b03818354169260026001820154910154926040519485528116602085015260a01c1660408301526060820152f35b34610337576040366003190112610337576108de612550565b6004355f52600960205260405f209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b34610337575f366003190112610337576109477f0000000000000000000000000000000000000000000000000000000000000000613101565b6109707f00000000000000000000000000000000000000000000000000000000000000006131f7565b60405190602090818301938385106001600160401b038611176105a857949392906109c88391856040525f84526109ba604051988998600f60f81b8a5280868b01528901906124f7565b9087820360408901526124f7565b914660608701523060808701525f60a087015285830360c087015251918281520192915f5b8281106109fc57505050500390f35b8351855286955093810193928101926001016109ed565b34610337575f366003190112610337576020600c54604051908152f35b34610337576020366003190112610337576001600160a01b03610a5161253a565b165f526007602052602060405f2054604051908152f35b610a7136612764565b610a7b34156134ee565b610a8361352d565b60ff60125460081c16610cb357610a9b8315156135bf565b6001600160a01b0391808316610ab2811515613583565b838316928315610c815785610af46020977f1dfdc691a597a83af2430bd31addf8d2129d012eab8b35de6d696dc91e64852393873303610c71575b3090612a46565b601154958693610b03856135f9565b601155601054906001600160401b039283831692835f5260168c528460405f2094855460ff811615908115610c63575b50610c25575b506002929150601054169260405193610b518561264b565b8b85528d85019182526040850190815260608501928884528a5f5260158f528060405f2096511660018060a01b0319875416178655600186019251168254916001600160401b0360a01b905160a01b169163ffffffff60e01b16171790555191015560018101610bc2848254612a39565b905580546affffffffffffffff000000610be0848360181c16613607565b60181b166affffffffffffffff0000001991909116179055601054604080516001600160a01b0397909716875260208701939093521693a46001600a55604051908152f35b610c329192939550613607565b1680916001600160401b031916176010555f5260168a52600260405f2092600160ff1985541617845590848d610b39565b60ff915060081c168f610b33565b610c7c823383612c9e565b610aed565b60405162461bcd60e51b815260206004820152600a6024820152696f776e6572207a65726f60b01b6044820152606490fd5b60405162461bcd60e51b81526020600482015260126024820152711dda5d1a191c985dd85b1cc81c185d5cd95960721b6044820152606490fd5b34610337575f366003190112610337576020600f54604051908152f35b34610337575f366003190112610337576020601454604051908152f35b34610337575f366003190112610337576020604051818152f35b34610337576020366003190112610337576001600160a01b03610d6261253a565b165f525f602052602060405f2054604051908152f35b34610337575f366003190112610337576020601154604051908152f35b34610337575f36600319011261033757602060ff601254166040519015158152f35b6040366003190112610337576004356001600160401b03811161033757610de29036906004016126e1565b906024356001600160401b03811161033757610e029036906004016126e1565b610e0f92919234156134ee565b335f9081527f84e70a45dc3cad9f831e8a7d9f4327701c9df1c790bfeaa7b6cb95e200be673360205260409020547f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9299060ff16156113ae5750808403611377576020841161133c575f91610e816144d3565b93600b545f600b55806112d8575b509291905f935b868510610f5657868661271086148015610f4e575b15610f1b57610ee15760207f6ebd9ef82ef3aa533937a4d42dc350c0739723937c8809f94e4983795d1ccc3c91604051908152a1005b60405162461bcd60e51b815260206004820152601260248201527164656c65676174696f6e732061637469766560701b6044820152606490fd5b60405162461bcd60e51b815260206004820152600b60248201526a626164207765696768747360a81b6044820152606490fd5b508115610eab565b909192610f6485888561385d565b9050156112a15761ffff610f81610f7c87878661389e565b6138ae565b161561126e5760645f610f95878a8761385d565b928391604051948593849263120bba7360e11b845230600485015260406024850152816044850152848401378181018301859052601f01601f191681010301816108005afa801561126357611242575b50610ffb610ff486898661385d565b369161395a565b602081519101205f5b8681106111de5750506110299061ffff611022610f7c88888761389e565b1690612a39565b9361ffff61103882898661385d565b919061105961104b610f7c868a8961389e565b9160405194610ff486612666565b83521660208201525f6040820152600b54600160401b8110156105a8578060016110869201600b55612566565b9190916111cb5780518051906001600160401b0382116105a8576110aa8454612582565b601f8111611190575b50602090601f831160011461112057928260029360409361110c9897965f92611115575b50508160011b915f199060031b1c19161784555b6001840161ffff60208301511661ffff1982541617905501519101556135f9565b93929190610e96565b015190508e806110d7565b90845f5260205f20915f5b601f198516811061117857508360409361110c98979693600193600297601f19811610611160575b505050811b0184556110eb565b01515f1960f88460031b161c191690558e8080611153565b9192602060018192868501518155019401920161112b565b6111bb90855f5260205f206005601f8601811c820192602087106111c1575b601f01901c019061361f565b8b6110b3565b91925082916111af565b634e487b7160e01b5f525f60045260245ffd5b6111ec610ff4828b8861385d565b60208151910120821461120757611202906135f9565b611004565b60405162461bcd60e51b8152602060048201526013602482015272323ab83634b1b0ba32903b30b634b230ba37b960691b6044820152606490fd5b61125d903d805f833e611255818361269c565b8101906138bd565b50610fe5565b6040513d5f823e3d90fd5b60405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc81dd95a59da1d60aa1b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e32b6b83a3c903b30b634b230ba37b960891b6044820152606490fd5b600390808202908282040361067e57600b5f527f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9908101905b81811061131f575050610e8f565b8061132a8492613635565b5f60018201555f600282015501611311565b60405162461bcd60e51b8152602060048201526013602482015272746f6f206d616e792076616c696461746f727360681b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e0d8cadccee8d040dad2e6dac2e8c6d608b1b6044820152606490fd5b6113b733612d8a565b604051916113c48361264b565b60428352602083019060603683378351156115195760308253835160019081101561151957607860218601536041905b8082116114d65750506114a557604861147292611481926114a19560405195869376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b60208601526114498151809260206037890191016124d6565b8401917001034b99036b4b9b9b4b733903937b6329607d1b6037840152518093868401906124d6565b0103602881018452018261269c565b60405162461bcd60e51b81526020600482015291829160248301906124f7565b0390fd5b606460405162461bcd60e51b815260206004820152602060248201525f805160206146b98339815191526044820152fd5b9091600f81166010811015611519576f181899199a1a9b1b9c1cb0b131b232b360811b901a6115058488612d79565b5360041c91801561067e575f1901906113f4565b634e487b7160e01b5f52603260045260245ffd5b5f3660031901126103375761154234156134ee565b61154a61352d565b60206115546144d3565b6001600a55604051908152f35b604036600319011261033757611575612550565b61157f34156134ee565b61158761352d565b6004355f52601560205260405f20604051906115a28261264b565b80546001600160a01b0390811680845260018301549182166020850190815260a09290921c6001600160401b031660408501526002909201546060840190815291156119fe576001600160401b036040840151165f52601660205260405f209182549460ff8660101c16156119c9576001600160a01b0381166119c3575081516001600160a01b0316915b516001600160a01b039081169083160361198d576116566001600160401b038660581c16613607565b6001600160401b03808760181c169116145f1461197257506116816005830154600684015490613413565b935b67ffffffffffffffff60581b6116a5605883901c6001600160401b0316613607565b60581b16906001600160401b0360581b1916178255600682016116c9858254612a39565b90556116d784600e54613413565b600e556116e684600f54613413565b600f556004355f908152601560209081526040808320838155600181018490556002018390555163a9059cbb60e01b9181019182526001600160a01b038481166024830152604480830189905282526117d89391927f00000000000000000000000000000000000000000000000000000000000000009091169190819061176e60648661269c565b6040519461177b86612681565b602086527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646020870152519082855af13d1561196a573d916117bc83612d5e565b926117ca604051948561269c565b83523d5f602085013e613695565b8051908115918215611950575b5050156118f8576001600160401b036040840151166040519185835260018060a01b0316917f6443ab78e20802b0a48c253c5a7e05576a8bedd83aec398a8bba1164e7cf6fc3602060043592a4546001600160401b03808260181c169160581c161461185c575b6020826001600a55604051908152f35b60406001600160401b03910151165f52601660205260405f20905f82555f60018301555f600283015560086003925f848201555f60048201555f60058201555f60068201555f6007820155018054905f8155816118bc575b50509061184c565b818402918483040361067e575f5260205f20908101905b818110156118b457806118e68592613635565b5f60018201555f6002820155016118d3565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b611963925060208091830101910161367d565b85806117e5565b606091613695565b61198790516005840154600185015491613391565b93611683565b60405162461bcd60e51b815260206004820152600e60248201526d3bb937b733903932b1b2b4bb32b960911b6044820152606490fd5b9161162d565b60405162461bcd60e51b815260206004820152600d60248201526c6e6f7420636c61696d61626c6560981b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e1d5b9adb9bdddb881c995c5d595cdd608a1b6044820152606490fd5b3461033757602036600319011261033757600435906001600160401b0380831680930361033757610180925f52601660205260405f208054926001820154906002830154906003840154906004850154926005860154946007600688015497015460070b976040519960ff811615158b5260ff8160081c16151560208c015260ff8160101c16151560408c0152818160181c1660608c015260581c1660808a015260a089015260c0880152860152610100850152610120840152610140830152610160820152f35b61251c565b34610337575f366003190112610337576020610676614581565b34610337575f366003190112610337576020601354604051908152f35b34610337576040366003190112610337576106b8611b5561253a565b335f52600160205260405f2060018060a01b0382165f52602052611b7f60243560405f2054612a39565b9033612ba0565b34610337575f366003190112610337576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b3461033757604036600319011261033757611be3612550565b336001600160a01b03821603611bff5761044b906004356129c4565b60405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608490fd5b34610337575f366003190112610337576020610676612fd7565b3461033757602036600319011261033757600435600b5481101561033757611ca0611cdc91612566565b5060405190611cba82611cb381846125ba565b038361269c565b600261ffff6001830154169101546040519384936060855260608501906124f7565b91602084015260408301520390f35b60208060031936011261033757611d0061253a565b611d0861352d565b60ff60125416611e85576001600160a01b0316801590611d288215613583565b3415611e5257611d3661443c565b5060025480611e095734925b611d4d8415156135bf565b611dc45782611d5b91612a39565b600255805f525f835260405f20828154019055805f5f805160206146d983398151915285604051868152a360405134815282848201527fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d760403392a36001600a55604051908152f35b60405162461bcd60e51b815260048101859052601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606490fd5b611e11613420565b34811115611e4b57611e24903490613413565b600182019081831161067e576001810180911161067e57611e459134613391565b92611d42565b505f611e24565b60405162461bcd60e51b815260048101849052600b60248201526a7a65726f2061737365747360a81b6044820152606490fd5b60405162461bcd60e51b815260048101839052600f60248201526e19195c1bdcda5d1cc81c185d5cd959608a1b6044820152606490fd5b34610337575f366003190112610337576020600d54604051908152f35b34610337575f3660031901126103375760206040516127108152f35b606036600319011261033757600435801515809103610337576024803590811515809203610337576044359081151580920361033757611f3534156134ee565b335f9081527f84574a31e2f767388bfa57bc81ff2590df95d3022c04c363cca3e37ee960863160209081526040909120547f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a9060ff1615611fbd5750505061ff009060ff62ff00006012549260101b1694169062ffffff1916179160081b1617176012555f80f35b611fc633612d8a565b90604051611fd38161264b565b6042815283810191606036843781511561211c5760308353815160019081101561210957607860218401536041905b8082116120a05750506120715760486114a193611472936120559360405195869376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a860152611449815180928c6037890191016124d6565b60405193849362461bcd60e51b855260048501528301906124f7565b606485856040519162461bcd60e51b83528160048401528201525f805160206146b98339815191526044820152fd5b9091600f811660108110156120f6576f181899199a1a9b1b9c1cb0b131b232b360811b901a6120cf8486612d79565b5360041c9180156120e3575f190190612002565b87634e487b7160e01b5f5260116004525ffd5b88634e487b7160e01b5f5260326004525ffd5b86634e487b7160e01b5f5260326004525ffd5b85634e487b7160e01b5f5260326004525ffd5b60203660031901126103375761214534156134ee565b61214d61352d565b602061155460043561372e565b34610337575f3660031901126103375760ff7f00000000000000000000000000000000000000000000000000000000000000001660ff811161067e57602090604051908152f35b34610337576040366003190112610337576004356121bd612550565b815f5260096020526121d5600160405f200154612825565b815f52600960205260405f209060018060a01b031690815f5260205260ff60405f2054161561220057005b815f52600960205260405f20815f5260205260405f20600160ff1982541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d5f80a4005b34610337575f36600319011261033757602060ff60125460101c166040519015158152f35b34610337576020366003190112610337576004355f5260096020526020600160405f200154604051908152f35b34610337576060366003190112610337576106b86122b761253a565b6122bf612550565b604435916122ce833383612c9e565b612a46565b34610337575f366003190112610337576020600254604051908152f35b34610337575f366003190112610337576020600b54604051908152f35b34610337575f3660031901126103375760206001600160401b0360105416604051908152f35b34610337576020366003190112610337576002546001810180911161067e5761235a613420565b906001820180921161067e57602091610676916004356132af565b34610337576040366003190112610337576106b861239161253a565b6024359033612ba0565b34610337575f366003190112610337576040515f906003546123bc81612582565b80835260019180831690811561083b57506001146123e4576107de836107ca8187038261269c565b60035f90815260209450917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b82841061242a575050508101909101906107ca816107ba565b8054858501870152928501928101612411565b34610337575f3660031901126103375760206001600160401b0360105460401c16604051908152f35b346103375760203660031901126103375760043563ffffffff60e01b811680910361033757602090637965db0b60e01b81149081156124ab575b506040519015158152f35b6301ffc9a760e01b149050826124a0565b34610337575f366003190112610337576020610676613420565b5f5b8381106124e75750505f910152565b81810151838201526020016124d8565b90602091612510815180928185528580860191016124d6565b601f01601f1916010190565b34610337576020366003190112610337576020610676600435612d30565b600435906001600160a01b038216820361033757565b602435906001600160a01b038216820361033757565b600b5481101561151957600b5f52600360205f20910201905f90565b90600182811c921680156125b0575b602083101461259c57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691612591565b905f92918054916125ca83612582565b9182825260019384811690815f1461262857506001146125eb575b50505050565b90919394505f52602092835f2092845f945b83861061261457505050500101905f8080806125e5565b8054858701830152940193859082016125fd565b9294505050602093945060ff191683830152151560051b0101905f8080806125e5565b608081019081106001600160401b038211176105a857604052565b606081019081106001600160401b038211176105a857604052565b604081019081106001600160401b038211176105a857604052565b90601f801991011681019081106001600160401b038211176105a857604052565b34610337576020366003190112610337576126d661253a565b5060206040515f8152f35b9181601f84011215610337578235916001600160401b038311610337576020808501948460051b01011161033757565b346103375760403660031901126103375761272a612550565b5060405162461bcd60e51b8152602060048201526011602482015270757365206465706f7369744e617469766560781b6044820152606490fd5b606090600319011261033757600435906001600160a01b03906024358281168103610337579160443590811681036103375790565b34610337576127a736612764565b505060405162461bcd60e51b8152602060048201526011602482015270757365207265717565737452656465656d60781b604482015260649150fd5b34610337576020366003190112610337576002546001810180911161067e5761280a613420565b906001820180921161067e5760209161067691600435613391565b5f9080825260209060098252604092838120338252835260ff84822054161561284e5750505050565b61285733612d8a565b918451906128648261264b565b604282528482019260603685378251156129b057603084538251906001918210156129b05790607860218501536041915b818311612943575050506129145760486114a19386936128f8936128e9985198899376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a860152611449815180928c6037890191016124d6565b0103602881018752018561269c565b5192839262461bcd60e51b8452600484015260248301906124f7565b60648486519062461bcd60e51b825280600483015260248201525f805160206146b98339815191526044820152fd5b909192600f8116601081101561299c576f181899199a1a9b1b9c1cb0b131b232b360811b901a6129738587612d79565b5360041c928015612988575f19019190612895565b634e487b7160e01b82526011600452602482fd5b634e487b7160e01b83526032600452602483fd5b634e487b7160e01b81526032600452602490fd5b905f918083526009602052604083209160018060a01b03169182845260205260ff6040842054166129f457505050565b8083526009602052604083208284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4565b9190820180921161067e57565b6001600160a01b03908116918215612b4d5716918215612afc575f82815280602052604081205491808310612aa857604082825f805160206146d9833981519152958760209652828652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b6001600160a01b03908116918215612c4d5716918215612bfd5760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591835f526001825260405f20855f5282528060405f2055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b9060018060a01b038083165f52600160205260405f209082165f5260205260405f2054925f198403612cd05750505050565b808410612ceb57612ce2930391612ba0565b5f8080806125e5565b60405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606490fd5b612d38613420565b6001810180911161067e57600254906001820180921161067e57612d5b92613391565b90565b6001600160401b0381116105a857601f01601f191660200190565b908151811015611519570160200190565b60405190612d9782612666565b602a82526020820160403682378251156115195760309053815160019081101561151957607860218401536029905b808211612dd65750506114a55790565b9091600f81166010811015612e2d576f181899199a1a9b1b9c1cb0b131b232b360811b901a612e058486612d79565b5360041c918015612e19575f190190612dc6565b60245f634e487b7160e01b81526011600452fd5b60245f634e487b7160e01b81526032600452fd5b6005811015612f405780612e525750565b60018103612e9a5760405162461bcd60e51b815260206004820152601860248201527745434453413a20696e76616c6964207369676e617475726560401b6044820152606490fd5b60028103612ee75760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606490fd5b600314612ef057565b60405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608490fd5b634e487b7160e01b5f52602160045260245ffd5b9291906fa2a8918ca85bafe22016d0b997e4df60600160ff1b038311612fcc5791608094939160ff6020946040519485521684840152604083015260608201525f93849182805260015afa15612fbf5781516001600160a01b03811615612fb9579190565b50600190565b50604051903d90823e3d90fd5b505050505f90600390565b307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614806130d8575b15613032577f000000000000000000000000000000000000000000000000000000000000000090565b60405160208101907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82527f000000000000000000000000000000000000000000000000000000000000000060408201527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260a0815260c081018181106001600160401b038211176105a85760405251902090565b507f00000000000000000000000000000000000000000000000000000000000000004614613009565b60ff811461313f5760ff811690601f821161312d576040519161312383612681565b8252602082015290565b604051632cd44ac360e21b8152600490fd5b50604051600554815f61315183612582565b8083526001938085169081156131d65750600114613177575b50612d5b9250038261269c565b60055f9081527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db094602093509091905b8183106131be575050612d5b93508201015f61316a565b855487840185015294850194869450918301916131a7565b9050612d5b94506020925060ff191682840152151560051b8201015f61316a565b60ff81146132195760ff811690601f821161312d576040519161312383612681565b50604051600654815f61322b83612582565b8083526001938085169081156131d657506001146132505750612d5b9250038261269c565b60065f9081527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f94602093509091905b818310613297575050612d5b93508201015f61316a565b85548784018501529485019486945091830191613280565b91906132bc828285613391565b9282156132d957096132cb5790565b6001810180911161067e5790565b634e487b7160e01b5f52601260045260245ffd5b905f1981830981830291828083109203918083039214613386576127109082821115613349577fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e91940990828211900360fc1b910360041c170290565b60405162461bcd60e51b81526020600482015260156024820152744d6174683a206d756c446976206f766572666c6f7760581b6044820152606490fd5b505061271091500490565b915f19828409928281029283808610950394808603951461340557848311156133495782910960018219018216809204600280826003021880830282030280830282030280830282030280830282030280830282030280920290030293600183805f03040190848311900302920304170290565b5050809250156132d9570490565b9190820391821161067e57565b600254156134ea576040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611263575f916134b4575b5061349161349a9161348b614581565b90612a39565b600d5490612a39565b600e54808211156134ae57612d5b91613413565b50505f90565b906020823d82116134e2575b816134cd6020938361269c565b810103126134df57505161349161347b565b80fd5b3d91506134c0565b5f90565b156134f557565b60405162461bcd60e51b815260206004820152601060248201526f756e65787065637465642076616c756560801b6044820152606490fd5b6002600a541461353e576002600a55565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b1561358a57565b60405162461bcd60e51b815260206004820152600d60248201526c7265636569766572207a65726f60981b6044820152606490fd5b156135c657565b60405162461bcd60e51b815260206004820152600b60248201526a7a65726f2073686172657360a81b6044820152606490fd5b5f19811461067e5760010190565b9060016001600160401b038093160191821161067e57565b81811061362a575050565b5f815560010161361f565b61363f8154612582565b9081613649575050565b81601f5f931160011461365a575055565b908083918252613679601f60208420940160051c84016001850161361f565b5555565b90816020910312610337575180151581036103375790565b919290156136f757508151156136a9575090565b3b156136b25790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b82519091501561370a5750805190602001fd5b60405162461bcd60e51b8152602060048201529081906114a19060248301906124f7565b905f9160ff60125460101c1661382a5780156138245761374c613fad565b613814575b80831080613806575b6137f6575b808310806137e8575b6137d8575b8210806137ca575b6137ba575b6137856013546135f9565b601355816014556040518281527f4889d7d38c1d1f265318505a98367d07d41591d6b7f9cc000f37ea92b8311daa60203392a2565b906137c4906135f9565b9061377a565b506137d3614295565b613775565b916137e2906135f9565b9161376d565b506137f161443c565b613768565b91613800906135f9565b9161375f565b5061380f613990565b61375a565b9161381e906135f9565b91613751565b505f9150565b60405162461bcd60e51b815260206004820152600b60248201526a1c1bdad9481c185d5cd95960aa1b6044820152606490fd5b91908110156115195760051b81013590601e19813603018212156103375701908135916001600160401b038311610337576020018236038113610337579190565b91908110156115195760051b0190565b3561ffff811681036103375790565b9190916040808285031261033757815193602091828401516001600160401b0394858211610337570190808284031261033757805194818601868110828211176105a8578252825190811161033757820183601f820112156103375780519361393161392886612d5e565b9351938461269c565b84835285858301011161033757849361394f918580850191016124d6565b845201519082015290565b92919261396682612d5e565b91613974604051938461269c565b829481845281830111610337578281602093845f960137010152565b6001600160401b03601054165f52601660205260405f20805460ff811615908115613f9f575b508015613f93575b613f8e576139ca61443c565b506001810154906139da82612d30565b9161010061ffff198354161782558260028301553015613f3f57305f525f60205260405f205490808210613eef57805f923084528360205203604083205580600254036002556040519081525f805160206146d983398151915260203092a3613a4161461f565b82811015613ee557613a5a905b80613ebc575b83613413565b905f9180613b1a575b50613ad86001827f5d78323b7b570071308d257743c74a9a2401f77d37e9de9f908da12c8917a40b606060076001600160401b0396019786199889815416898916179055600484015415613afc575b60105497878916958695015491604051928352602083015260070b6040820152a2613607565b1691829116176010555f52601660205260405f20600160ff19825416179055600190565b835462ff000019166201000017845560038401546005850155613ab2565b600b545f95935015613e8757613b2e6144d3565b50915f925b600b54841080613e7e575b15613e2757613b4c84612566565b509060028201548181105f14613e1f57915b8215613e1357604051630fb6accf60e21b81529060208280613b858785306004850161426b565b03815f6108005af1918215611263575f92613dd5575b50613baa846002830154613413565b6002820155600c613bbc858254613413565b9055600d613bcb858254612a39565b9055600e613bda858254612a39565b9055613bea846004880154612a39565b6004870155613c0e613c1560405192613c0284612666565b604051928380926125ba565b038261269c565b81528360208201528160070b60408201526008860154600160401b8110156105a8576001810180600889015581101561151957600887015f5260205f209082518051906001600160401b0382116105a857613c7560038402850154612582565b90601f91828111613d98575b506020918311600114613d22579282604095936003936002965f92613d17575b50508160011b915f1990851b1c1916178282028401555b60208601516001838302850101550201019101516001600160401b0319825416906001600160401b03161790558760070b8160070b13613d0d575b50613d0791613d0191613413565b936135f9565b92613b33565b9650613d07613cf3565b015190505f80613ca1565b906003840285015f5260205f20915f5b601f1985168110613d805750836003936002969360019360409997601f19811610613d69575b505050811b01828202840155613cb8565b01515f1983871b60f8161c191690555f8080613d58565b91926020600181928685015181550194019201613d32565b613dc6906003860287015f5260205f20600585808801821c83019360208910613dcc575b01901c019061361f565b5f613c81565b93508293613dbc565b9091506020813d602011613e0b575b81613df16020938361269c565b8101031261033757518060070b810361033757905f613b9b565b3d9150613de4565b5093613d0791506135f9565b508091613b5e565b9094919250613e395790613ad8613a63565b60405162461bcd60e51b815260206004820152601d60248201527f696e73756666696369656e742064656c656761746564206173736574730000006044820152606490fd5b50801515613b3e565b60405162461bcd60e51b815260206004820152600d60248201526c6e6f2076616c696461746f727360981b6044820152606490fd5b613ec881600e54612a39565b600e55613ed781600f54612a39565b600f55806003840155613a54565b50613a5a82613a4e565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608490fd5b505f90565b506001810154156139be565b60ff915060081c165f6139b6565b601080546001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001692916001600160401b03604092831c81169290915b80549083851694848316861015614260575f9786895260209560168752858a2094855460ff808260081c1615918215614254575b50508015614248575b614201575060078501541642106141d55760048085015491828b600f938454938b6140588887612a39565b9260248d51809481936370a0823160e01b835230908301525afa9283156141ca5792614177575b50917f73f330dd18a8f4760be8fa04b392ba243a76dcbe07487724e846182d63dbfafa9b9c9d82846140fa97956141169a99979510614145575b5050506140ee918491600d6140cf828254613413565b90556140e7836140e2600e938454613413565b612a39565b9055612a39565b90556003860154612a39565b60058501908155845462ff000019166201000017909455613607565b815467ffffffffffffffff60401b191690841b67ffffffffffffffff60401b16179055549051908152a2600190565b6140ee94969161415491613413565b9081811115614170576141679250613413565b93915f806140b9565b5050614167565b9091508a81813d83116141c3575b61418f818361269c565b810103126141bf5751907f73f330dd18a8f4760be8fa04b392ba243a76dcbe07487724e846182d63dbfafa61407f565b8d80fd5b503d614185565b8b51903d90823e3d90fd5b50815467ffffffffffffffff60401b1916931b67ffffffffffffffff60401b1692909217909155505050565b92939750955097508492506001600160401b0360401b61422083613607565b67ffffffffffffffff60401b1990921691851b1617855516828114612e195760010192613ff0565b5060048601541561402d565b871c1690505f80614024565b505f96505050505050565b9392916142909060409260018060a01b031686526060602087015260608601906125ba565b930152565b600290815415614437576142a761461f565b908115801561442d575b614426576142bd6144d3565b505f90825b600b548084108061441d575b156144125760019081850180861161067e57036143f25750805b81156143e7576142f784612566565b5060408051906353266bbb60e01b825260209182818061431d89600498308a850161426b565b03815f6108005af19081156143dd575f916143b0575b501561437d5750505061437791614371918761434e87612566565b500161435b838254612a39565b9055600c61436a838254612a39565b9055613413565b926135f9565b916142c2565b5162461bcd60e51b815291820152600f60248201526e19195b1959d85d194819985a5b1959608a1b604482015260649150fd5b6143d09150833d85116143d6575b6143c8818361269c565b81019061367d565b5f614333565b503d6143be565b82513d5f823e3d90fd5b9261437791506135f9565b61ffff61440c9161440286612566565b50015416856132ed565b906142e8565b505092505050600190565b508115156142ce565b9150505f90565b50600b54156142b1565b5f9150565b600b541580156144a2575b6134ea5763ffffffff600b541660405190632efe8a5f60e01b825230600483015260248201526020816044815f6108015af1908115611263575f9161448a575090565b612d5b915060203d81116143d6576143c8818361269c565b506144ab6144d3565b15614447565b6001600160a01b039091168152604060208201819052612d5b929101906125ba565b5f9081805b600b54821015614578576144eb82612566565b5061450d8560409283518093819263120bba7360e11b835230600484016144b1565b03816108005afa91821561456f57509160206145479261454d948891614553575b50018051600261453d87612566565b5001555190612a39565b916135f9565b906144d8565b61456791503d808a833e611255818361269c565b90505f61452e565b513d87823e3d90fd5b92505081600c55565b5f905f80600b545b80831061459557505050565b9091936145a185612566565b506145c38460409283518093819263120bba7360e11b835230600484016144b1565b03816108005afa91821561461657509160206145ed926145f39487916145fa575b50015190612a39565b946135f9565b9190614589565b61460e91503d8089833e611255818361269c565b90505f6145e4565b513d86823e3d90fd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611263575f91614687575b50600f54808211156134ae57612d5b91613413565b906020823d82116146b0575b816146a06020938361269c565b810103126134df5750515f614672565b3d915061469356fe537472696e67733a20686578206c656e67746820696e73756666696369656e74ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212203dea20cc054fb9b8e55a057442460f9c400c356156d57798f5f876718474fdfd64736f6c63430008140033", + "bytecode": "0x60c0604090808252346200053c5762006016803803809162000022828562000540565b833981016060828203126200053c5781516001600160a01b038116908190036200053c576020838101516001600160401b0394919291908581116200053c57846200006f91830162000580565b93868201518681116200053c5762000088920162000580565b93835181811162000447576003908154906001968783811c9316801562000531575b878410146200051d578190601f93848111620004ca575b50879084831160011462000467575f926200045b575b50505f1982851b1c191690871b1782555b8651928311620004475760049687548781811c911680156200043c575b8782101462000429579081838695949311620003d2575b50869184116001146200036b575f936200035f575b505082861b925f19911b1c19161784555b6200014c620005e8565b901562000356575b60a05273d4949664cd82660aae99bedc034a0dea8a0bd5176080528260065560ff1993600885600a541617600a558360115581156200032b5750906016915f8052600590818352865f20815f52835260ff875f20541615620002f7575b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929805f52828452875f20825f52845260ff885f20541615620002c2575b507f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a91825f52808452875f20825f52845260ff885f205416156200028d575b5050506801000000000000000160018060801b03196010541617601055825f5252825f20918254161790555161593f9081620006b78239608051818181611006015281816114e201528181614b9201526157d9015260a05181611a9b0152f35b825f528352865f20815f528352865f20858782541617905533915f8051602062005ff68339815191525f80a45f80806200022d565b805f52828452875f20825f528452875f2086888254161790558133915f8051602062005ff68339815191525f80a45f620001ee565b5f8052818352865f20815f528352865f20858782541617905533815f5f8051602062005ff68339815191528180a4620001b1565b855162461bcd60e51b8152908101839052600560248201526420a226a4a760d91b6044820152606490fd5b50601262000154565b015191505f8062000131565b9190879450601f19841692895f52875f20935f5b89828210620003bb5750508511620003a1575b50505050811b01845562000142565b01519060f8845f19921b161c191690555f80808062000392565b8385015187558b989096019593840193016200037f565b9091929350885f52865f208380870160051c8201928988106200041f575b918a918897969594930160051c01915b828110620004105750506200011c565b5f81558796508a910162000400565b92508192620003f0565b602289634e487b7160e01b5f525260245ffd5b90607f169062000105565b634e487b7160e01b5f52604160045260245ffd5b015190505f80620000d7565b90899350601f19831691865f52895f20925f5b8b828210620004b357505084116200049b575b505050811b018255620000e8565b01515f1983871b60f8161c191690555f80806200048d565b8385015186558d979095019493840193016200047a565b909150845f52875f208480850160051c8201928a861062000513575b918b91869594930160051c01915b82811062000504575050620000c1565b5f81558594508b9101620004f4565b92508192620004e6565b634e487b7160e01b5f52602260045260245ffd5b92607f1692620000aa565b5f80fd5b601f909101601f19168101906001600160401b038211908210176200044757604052565b6001600160401b0381116200044757601f01601f191660200190565b919080601f840112156200053c578251906200059c8262000564565b91620005ac604051938462000540565b8083526020918282870101116200053c575f5b818110620005d45750825f9394955001015290565b8581018301518482018401528201620005bf565b6040805163313ce56760e01b6020820190815260048252929181016001600160401b0381118282101762000447576040525f80938192519073d4949664cd82660aae99bedc034a0dea8a0bd5175afa3d15620006ad573d906200064b8262000564565b916200065b604051938462000540565b82523d84602084013e5b80620006a0575b62000677575b508190565b6020818051810103126200069c576020015160ff811162000672576001925060ff1690565b8280fd5b506020815110156200066c565b6060906200066556fe60806040526004361015610011575f80fd5b5f3560e01c806301e1d11414611e1e57806301ffc9a714611dc857806303e5fa8814611d9f57806306fdde0314611cfd57806307a2d13a146113c2578063095ea7b314611cd75780630a28a47714611c955780630a763da114611c6f5780630f43a67714611c5257806318160ddd14611c355780631f9acd7e14611c1a57806323b872dd14611be2578063248a9ca314611bb5578063291cdb8c14611b905780632d9414b514611b765780632f2ff15d14611ace578063313ce56714611a8757806332145f9014611a5c578063331c138c1461181357806333a73916146117f657806333bb7f911461162557806335aa2e44146115a357806336568abe1461151157806338d52e0f146114cd578063391ed03c14611468578063395093511461141b578063402d267d146106dc5780634221b2c2146113fe5780634864b09d146113e1578063499bafcc146113c75780634cdad506146113c25780634f7b9013146113a1578063559904cb146112cd578063588f134314610e2a5780635ac22fd214610df657806360da3e8314610dd45780636a84a98514610db75780636c68e40314610d7b5780636e553f65146109c857806370a0823114610d80578063714897df14610d7b5780637316a19614610d5b57806377397cdd14610d3e5780637aed3cbb14610d215780637d41c86e14610a9057806380d04de814610a7357806391d1485414610a2a578063937b2581146109cd57806394bf804d146109c857806395d89b41146108e5578063a217fddf146108cb578063a41fcdc3146108b0578063a457c2d71461080d578063a9059cbb146107dc578063ac44da52146107ba578063b3d7f6b914610770578063b460af941461073d578063b9bcb70f14610742578063ba0876521461073d578063c63d75b6146106dc578063c6e6f59214610364578063ce96cb77146106dc578063d547741f146106fe578063d77bb97c146106e1578063d905777e146106dc578063dd62ed3e1461068f578063e63ab1e914610655578063e9f2838e14610630578063ecdcce2414610369578063ef8b30f7146103645763f5b541a614610326575f80fd5b34610360575f3660031901126103605760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b5f80fd5b61214a565b602080600319360112610360576004359060ff82168092036103605761038f3415612984565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929805f526005825260405f20335f52825260ff60405f205416156104a2575081151580610498575b1561046c57817fe28c6c3955ed05a471a85214f10fe95cb125572d2aadeb008a7c5992533984969260ff19600a541617600a556104126136a9565b61041d600954611f00565b8061042d575b50604051908152a1005b601f811160011461044457505f6009555b83610423565b5f9060098252610462601f858420920160051c820160018301612adf565b816009555561043e565b6064906040519062461bcd60e51b82526004820152600560248201526410d3d5539560da1b6044820152fd5b50808211156103d7565b906104ac336126f1565b916040516104b981611fc9565b6042815282810191606036843781511561061c5760308353815160019081101561061c57607860218401536041905b8082116105c557505061059557610561936105709260489260405196879376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b88860152610538815180928a603789019101611e38565b8401917001034b99036b4b9b9b4b733903937b6329607d1b603784015251809386840190611e38565b0103602881018552018361202e565b61059160405192839262461bcd60e51b845260048401526024830190611e59565b0390fd5b6064836040519062461bcd60e51b825280600483015260248201525f805160206158aa8339815191526044820152fd5b9091600f8116601081101561061c576f181899199a1a9b1b9c1cb0b131b232b360811b901a6105f484866126e0565b5360041c918015610608575f1901906104e8565b634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b34610360575f36600319011261036057602060ff60125460081c166040519015158152f35b34610360575f3660031901126103605760206040517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b34610360576040366003190112610360576106a8611e9c565b6106b0611eb2565b9060018060a01b038091165f52600160205260405f2091165f52602052602060405f2054604051908152f35b61204f565b34610360575f366003190112610360576020600e54604051908152f35b346103605760403660031901126103605761073b60043561071d611eb2565b90805f526005602052610736600160405f20015461218c565b61232b565b005b61210b565b34610360575f36600319011261036057602060405173d4949664cd82660aae99bedc034a0dea8a0bd5178152f35b3461036057602036600319011261036057610789612964565b60018101809111610608576002549060018201809211610608576020916107b2916004356127e9565b604051908152f35b34610360575f366003190112610360576020604051670de0b6b3a76400008152f35b34610360576040366003190112610360576108026107f8611e9c565b60243590336123ad565b602060405160018152f35b3461036057604036600319011261036057610826611e9c565b60243590335f52600160205260405f2060018060a01b0382165f5260205260405f20549180831061085d5761080292039033612507565b60405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608490fd5b34610360575f36600319011261036057602060405160078152f35b34610360575f3660031901126103605760206040515f8152f35b34610360575f366003190112610360576040515f9060045461090681611f00565b8083526001918083169081156109a05750600114610947575b6109438361092f8187038261202e565b604051918291602083526020830190611e59565b0390f35b60045f90815260209450917f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b82841061098d5750505081019091019061092f8161091f565b8054858501870152928501928101610974565b610943955061092f93506020915091849260ff191682840152151560051b820101935061091f565b61208d565b34610360576020366003190112610360576004355f526015602052608060405f2060018060a01b036001600160401b03818354169260026001820154910154926040519485528116602085015260a01c1660408301526060820152f35b3461036057604036600319011261036057610a43611eb2565b6004355f52600560205260405f209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b34610360575f366003190112610360576020600c54604051908152f35b610a99366120d6565b610aa33415612984565b610aab6129b8565b60ff60125460081c16610cf157610ac3831515612a77565b6001600160a01b0391808316610ada811515612a0e565b838316928315610cc45785610b37817f1dfdc691a597a83af2430bd31addf8d2129d012eab8b35de6d696dc91e64852393610b2866038d7ea4c68000610b2160209c612697565b1015612a45565b873303610cb4575b30906123ad565b601154958693610b4685612aac565b601155601054906001600160401b039283831692835f5260168c528460405f2094855460ff811615908115610ca6575b50610c68575b506002929150601054169260405193610b9485611fc9565b8b85528d85019182526040850190815260608501928884528a5f5260158f528060405f2096511660018060a01b0319875416178655600186019251168254916001600160401b0360a01b905160a01b169163ffffffff60e01b16171790555191015560018101610c058482546123a0565b905580546affffffffffffffff000000610c23848360181c16612aba565b60181b166affffffffffffffff0000001991909116179055601054604080516001600160a01b0397909716875260208701939093521693a46001600655604051908152f35b610c759192939550612aba565b1680916001600160401b031916176010555f5260168a52600260405f2092600160ff1985541617845590848d610b7c565b60ff915060081c168f610b76565b610cbf823383612605565b610b30565b60405162461bcd60e51b815260206004820152600560248201526427aba722a960d91b6044820152606490fd5b60405162461bcd60e51b815260206004820152600860248201526715d7d4105554d15160c21b6044820152606490fd5b34610360575f366003190112610360576020600f54604051908152f35b34610360575f366003190112610360576020601454604051908152f35b34610360575f36600319011261036057602060ff600a5416604051908152f35b612073565b34610360576020366003190112610360576001600160a01b03610da1611e9c565b165f525f602052602060405f2054604051908152f35b34610360575f366003190112610360576020601154604051908152f35b34610360575f36600319011261036057602060ff601254166040519015158152f35b5f36600319011261036057610e0b3415612984565b610e136129b8565b6020610e1d615687565b6001600655604051908152f35b604036600319011261036057610e3e611eb2565b610e483415612984565b610e506129b8565b6004355f52601560205260405f2060405190610e6b82611fc9565b80546001600160a01b039081168084526001830154918216602085015260a09190911c6001600160401b031660408401526002919091015460608301521561129e576001600160401b036040820151165f52601660205260405f2080549260ff8460101c161561126d576001600160a01b038116611268575060208201516001600160a01b03165b60208301516001600160a01b039081169082160361123a57610f206001600160401b038560581c16612aba565b6001600160401b03808660181c169116145f1461121c57610f4a6005830154600684015490612ad2565b935b67ffffffffffffffff60581b610f6e605883901c6001600160401b0316612aba565b60581b16906001600160401b0360581b191617825560068201610f928582546123a0565b9055610fa084600e54612ad2565b600e55610faf84600f54612ad2565b600f556004355f908152601560209081526040808320838155600181018490556002018390555163a9059cbb60e01b9181019182526001600160a01b038481166024830152604480830189905282526110829391927f00000000000000000000000000000000000000000000000000000000000000009091169190819061103760648661202e565b6040519461104486612013565b602086527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646020870152519082855af161107c612b4b565b91612b7a565b80519081159182156111fa575b5050156111a2576001600160401b036040840151166040519185835260018060a01b0316917f6443ab78e20802b0a48c253c5a7e05576a8bedd83aec398a8bba1164e7cf6fc3602060043592a4546001600160401b03808260181c169160581c1614611106575b6020826001600655604051908152f35b60406001600160401b03910151165f52601660205260405f20905f82555f60018301555f600283015560086003925f848201555f60048201555f60058201555f60068201555f6007820155018054905f815581611166575b5050906110f6565b8184029184830403610608575f5260205f20908101905b8181101561115e57806111908592612af5565b5f60018201555f60028201550161117d565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b81925090602091810103126103605760206112159101612b3e565b858061108f565b611234606084015160058401546001850154916128f0565b93610f4c565b60405162461bcd60e51b815260206004820152600660248201526514105653d55560d21b6044820152606490fd5b610ef3565b60405162461bcd60e51b8152602060048201526009602482015268434c41494d41424c4560b81b6044820152606490fd5b60405162461bcd60e51b8152602060048201526007602482015266149154555154d560ca1b6044820152606490fd5b34610360576020366003190112610360576004356001600160401b03808216809203610360576101a0915f52601660205260405f2090815491600181015490600281015460038201546004830154906005840154926007600686015495015495876040519960ff811615158b5260ff8160081c16151560208c015260ff8160101c16151560408c0152818160181c1660608c015260581c1660808a015260a089015260c088015260e08701526101008601526101208501526101408401528060070b61016084015260401c16610180820152f35b34610360575f36600319011261036057602060405166038d7ea4c680008152f35b611e7e565b34610360575f3660031901126103605760206107b2615740565b34610360575f366003190112610360576020600b54604051908152f35b34610360575f366003190112610360576020601354604051908152f35b3461036057604036600319011261036057610802611437611e9c565b335f52600160205260405f2060018060a01b0382165f5260205261146160243560405f20546123a0565b9033612507565b346103605760203660031901126103605760043560ff81168103610360573033036114a257611498602091612cd6565b6040519015158152f35b606460405162461bcd60e51b815260206004820152600460248201526329a2a62360e11b6044820152fd5b34610360575f366003190112610360576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346103605760403660031901126103605761152a611eb2565b336001600160a01b038216036115465761073b9060043561232b565b60405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608490fd5b3461036057602036600319011261036057600435600754811015610360576115cd61160f91611ec8565b50604051906115e7826115e08184611f38565b038361202e565b60018101549060ff600360028301549201541690604051948594608086526080860190611e59565b9260208501526040840152151560608301520390f35b6020806003193601126103605761163a611e9c565b6116426129b8565b60ff601254166117c6576001600160a01b03168015906116628215612a0e565b61167566038d7ea4c68000341015612a45565b61167d614b6d565b50600254611689612964565b81611768575034925b61169d841515612a77565b6116a934600b546123a0565b600b5561172357826116ba916123a0565b600255805f525f835260405f20828154019055805f5f805160206158ea83398151915285604051868152a360405134815282848201527fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d760403392a36001600655604051908152f35b60405162461bcd60e51b815260048101859052601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606490fd5b801561179557600182019081831161060857600181018091116106085761178f91346128f0565b92611692565b60405162461bcd60e51b8152600481018690526009602482015268125394d3d31591539560ba1b6044820152606490fd5b60405162461bcd60e51b81526004810183905260086024820152671117d4105554d15160c21b6044820152606490fd5b34610360575f366003190112610360576020600d54604051908152f35b6060366003190112610360576004358015158091036103605760248035908115158092036103605760443590811515809203610360576118533415612984565b335f9081527f99f2891db7a8db76249871a02b43b68c0bb8f22ef8a3bc1034ae9375ef6b7c3c60209081526040909120547f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a9060ff16156118db5750505061ff009060ff62ff00006012549260101b1694169062ffffff1916179160081b1617176012555f80f35b6118e4336126f1565b906040516118f181611fc9565b60428152838101916060368437815115611a4957603083538151600190811015611a3657607860218401536041905b8082116119cd57505061199e57604861059193611973936119829360405195869376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a860152610538815180928c603789019101611e38565b0103602881018452018261202e565b60405193849362461bcd60e51b85526004850152830190611e59565b606485856040519162461bcd60e51b83528160048401528201525f805160206158aa8339815191526044820152fd5b9091600f81166010811015611a23576f181899199a1a9b1b9c1cb0b131b232b360811b901a6119fc84866126e0565b5360041c918015611a10575f190190611920565b87634e487b7160e01b5f5260116004525ffd5b88634e487b7160e01b5f5260326004525ffd5b86634e487b7160e01b5f5260326004525ffd5b85634e487b7160e01b5f5260326004525ffd5b602036600319011261036057611a723415612984565b611a7a6129b8565b6020610e1d600435612c13565b34610360575f3660031901126103605760ff7f00000000000000000000000000000000000000000000000000000000000000001660ff811161060857602090604051908152f35b3461036057604036600319011261036057600435611aea611eb2565b815f526005602052611b02600160405f20015461218c565b815f52600560205260405f209060018060a01b031690815f5260205260ff60405f20541615611b2d57005b815f52600560205260405f20815f5260205260405f20600160ff1982541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d5f80a4005b34610360575f3660031901126103605760206107b261373d565b34610360575f36600319011261036057602060ff60125460101c166040519015158152f35b34610360576020366003190112610360576004355f5260056020526020600160405f200154604051908152f35b3461036057606036600319011261036057610802611bfe611e9c565b611c06611eb2565b60443591611c15833383612605565b6123ad565b34610360575f36600319011261036057602060405160088152f35b34610360575f366003190112610360576020600254604051908152f35b34610360575f366003190112610360576020600754604051908152f35b34610360575f3660031901126103605760206001600160401b0360105416604051908152f35b34610360576020366003190112610360576002546001810180911161060857611cbc612964565b9060018201809211610608576020916107b2916004356127e9565b3461036057604036600319011261036057610802611cf3611e9c565b6024359033612507565b34610360575f366003190112610360576040515f90600354611d1e81611f00565b8083526001918083169081156109a05750600114611d46576109438361092f8187038261202e565b60035f90815260209450917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b828410611d8c5750505081019091019061092f8161091f565b8054858501870152928501928101611d73565b34610360575f3660031901126103605760206001600160401b0360105460401c16604051908152f35b346103605760203660031901126103605760043563ffffffff60e01b811680910361036057602090637965db0b60e01b8114908115611e0d575b506040519015158152f35b6301ffc9a760e01b14905082611e02565b34610360575f3660031901126103605760206107b2612964565b5f5b838110611e495750505f910152565b8181015183820152602001611e3a565b90602091611e7281518092818552858086019101611e38565b601f01601f1916010190565b346103605760203660031901126103605760206107b2600435612697565b600435906001600160a01b038216820361036057565b602435906001600160a01b038216820361036057565b60075481101561061c5760075f5260205f209060021b01905f90565b60085481101561061c5760085f5260205f209060021b01905f90565b90600182811c92168015611f2e575b6020831014611f1a57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691611f0f565b905f9291805491611f4883611f00565b9182825260019384811690815f14611fa65750600114611f69575b50505050565b90919394505f52602092835f2092845f945b838610611f9257505050500101905f808080611f63565b805485870183015294019385908201611f7b565b9294505050602093945060ff191683830152151560051b0101905f808080611f63565b608081019081106001600160401b03821117611fe457604052565b634e487b7160e01b5f52604160045260245ffd5b60a081019081106001600160401b03821117611fe457604052565b604081019081106001600160401b03821117611fe457604052565b90601f801991011681019081106001600160401b03821117611fe457604052565b3461036057602036600319011261036057612068611e9c565b5060206040515f8152f35b34610360575f366003190112610360576020604051818152f35b34610360576040366003190112610360576120a6611eb2565b5060405162461bcd60e51b815260206004820152600760248201526611115413d4d25560ca1b6044820152606490fd5b606090600319011261036057600435906001600160a01b03906024358281168103610360579160443590811681036103605790565b3461036057612119366120d6565b505060405162461bcd60e51b815260206004820152600660248201526552454445454d60d01b604482015260649150fd5b34610360576020366003190112610360576002546001810180911161060857612171612964565b9060018201809211610608576020916107b2916004356128f0565b5f9080825260209060058252604092838120338252835260ff8482205416156121b55750505050565b6121be336126f1565b918451906121cb82611fc9565b6042825284820192606036853782511561231757603084538251906001918210156123175790607860218501536041915b8183116122aa5750505061227b57604861059193869361225f93612250985198899376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a860152610538815180928c603789019101611e38565b0103602881018752018561202e565b5192839262461bcd60e51b845260048401526024830190611e59565b60648486519062461bcd60e51b825280600483015260248201525f805160206158aa8339815191526044820152fd5b909192600f81166010811015612303576f181899199a1a9b1b9c1cb0b131b232b360811b901a6122da85876126e0565b5360041c9280156122ef575f190191906121fc565b634e487b7160e01b82526011600452602482fd5b634e487b7160e01b83526032600452602483fd5b634e487b7160e01b81526032600452602490fd5b905f918083526005602052604083209160018060a01b03169182845260205260ff60408420541661235b57505050565b8083526005602052604083208284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4565b9190820180921161060857565b6001600160a01b039081169182156124b45716918215612463575f8281528060205260408120549180831061240f57604082825f805160206158ea833981519152958760209652828652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b6001600160a01b039081169182156125b457169182156125645760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591835f526001825260405f20855f5282528060405f2055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b9060018060a01b038083165f52600160205260405f209082165f5260205260405f2054925f1984036126375750505050565b80841061265257612649930391612507565b5f808080611f63565b60405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606490fd5b61269f612964565b60018101809111610608576002549060018201809211610608576126c2926128f0565b90565b6001600160401b038111611fe457601f01601f191660200190565b90815181101561061c570160200190565b60405190606082018281106001600160401b03821117611fe457604052602a825260208201604036823782511561061c5760309053815160019081101561061c57607860218401536029905b80821161277e57505061274d5790565b606460405162461bcd60e51b815260206004820152602060248201525f805160206158aa8339815191526044820152fd5b9091600f811660108110156127d5576f181899199a1a9b1b9c1cb0b131b232b360811b901a6127ad84866126e0565b5360041c9180156127c1575f19019061273d565b60245f634e487b7160e01b81526011600452fd5b60245f634e487b7160e01b81526032600452fd5b91906127f68282856128f0565b92821561281357096128055790565b600181018091116106085790565b634e487b7160e01b5f52601260045260245ffd5b90670de0b6b3a7640000905f1982840992828102928380861095039480860395146128e257848311156128a55782910960018219018216809204600280826003021880830282030280830282030280830282030280830282030280830282030280920290030293600183805f03040190848311900302920304170290565b60405162461bcd60e51b81526020600482015260156024820152744d6174683a206d756c446976206f766572666c6f7760581b6044820152606490fd5b505080925015612813570490565b915f1982840992828102928380861095039480860395146128e257848311156128a55782910960018219018216809204600280826003021880830282030280830282030280830282030280830282030280830282030280920290030293600183805f03040190848311900302920304170290565b60025415612980576126c2600b5461297a615740565b906123a0565b5f90565b1561298b57565b60405162461bcd60e51b815260206004820152600560248201526456414c554560d81b6044820152606490fd5b6002600654146129c9576002600655565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b15612a1557565b60405162461bcd60e51b81526020600482015260086024820152672922a1a2a4ab22a960c11b6044820152606490fd5b15612a4c57565b60405162461bcd60e51b815260206004820152600360248201526226a4a760e91b6044820152606490fd5b15612a7e57565b60405162461bcd60e51b815260206004820152600660248201526553484152455360d01b6044820152606490fd5b5f1981146106085760010190565b9060016001600160401b038093160191821161060857565b9190820391821161060857565b818110612aea575050565b5f8155600101612adf565b612aff8154611f00565b9081612b09575050565b81601f5f9311600114612b1b5750555b565b908083918252612b3a601f60208420940160051c840160018501612adf565b5555565b5190811515820361036057565b3d15612b75573d90612b5c826126c5565b91612b6a604051938461202e565b82523d5f602084013e565b606090565b91929015612bdc5750815115612b8e575090565b3b15612b975790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015612bef5750805190602001fd5b60405162461bcd60e51b815260206004820152908190610591906024830190611e59565b5f9060ff60125460101c16612ca6578015612ca057612c59612c53612c4d612c47612c41612c5f9686613789565b8561384a565b846138d2565b8361395a565b826139e1565b90613a69565b90612c6b601354612aac565b601355816014556040518281527f4889d7d38c1d1f265318505a98367d07d41591d6b7f9cc000f37ea92b8311daa60203392a2565b50505f90565b60405162461bcd60e51b81526020600482015260086024820152671417d4105554d15160c21b6044820152606490fd5b60ff16600181146136a05760028114613697576003811461368e5760048114612d1d5760058114612d1457600614612d0c575f90565b6126c26149ec565b506126c26146f9565b50604051612d2a81611ff8565b604051600954815f612d3b83611f00565b808352926001811690811561366f5750600114613630575b612d5f9250038261202e565b81525f6020820152602060408201525f60608201525f60808201525f60405180809363186b216760e01b82526040600483015260126044830152711093d39117d4d510551554d7d093d391115160721b6064830152608060248301526080612dd4825160a06084860152610124850190611e59565b916001600160401b0360208201511660a48501526001600160401b0360408201511660c48501526060810151151560e48501520151151561010483015203816108005afa918215613625575f91829361324e575b505f5b8251811015612edc57612e3e81846146e5565b5190604082015115801590612eb0575b8015612ea4575b612e9a5760808201519161012081015190670de0b6b3a764000091820180921161060857612e89612e9092612e9595612827565b9051614e0b565b612aac565b612e2b565b612e959150612aac565b50608082015115612e55565b5060608201516004811015612ec85760031415612e4e565b634e487b7160e01b5f52602160045260245ffd5b50909180519283516001600160401b038111611fe457612efd600954611f00565b601f81116131f5575b50602094601f8211600114613191579481929394955f92613186575b50508160011b915f199060031b1c1916176009555b81515115612f56575b511590811591612f4e575090565b905051511590565b9190612f60615687565b505f5b600754811015612f9f57806003612f7c612f9a93611ec8565b5001805460ff191690555f6001612f9283611ec8565b500155612aac565b612f63565b50905f5b60085481101561306a57612fd8612fcc612fd3612fbf84611ee4565b5060405192838092611f38565b038261202e565b615863565b90156130185790816003612fee61301394611ec8565b5001600160ff198254161790556001612f928161300a85611ee4565b50015492611ec8565b612fa3565b50600790815460208110613032575b506130139150612aac565b61303b82611ee4565b50600160401b821015611fe45761305e8261301395600161306495019055611ec8565b90615067565b5f613027565b5090915f915b60078054808510156131425760ff600361308987611ec8565b50015416158061312d575b1561311b575f1990808201908111610608576130b26130bc91611ec8565b5061305e87611ec8565b815480156131075701906130cf82611ec8565b6130f4576003816130e05f93612af5565b826001820155826002820155015555613070565b634e487b7160e01b5f525f60045260245ffd5b634e487b7160e01b5f52603160045260245ffd5b50509161312790612aac565b91613070565b50600261313986611ec8565b50015415613094565b505092915061314f6136a9565b7f17e14f5a0c6831022cc1f0f72d2d717ac74633f5193b19f76e18d9711b6d7cec602061317a61373d565b604051908152a1612f40565b015190505f80612f22565b601f1982169560095f5260205f20915f5b8881106131dd575083600195969798106131c5575b505050811b01600955612f37565b01515f1960f88460031b161c191690555f80806131b7565b919260206001819286850151815501940192016131a2565b60095f5261323e907f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af601f840160051c81019160208510613244575b601f0160051c0190612adf565b5f612f06565b9091508190613231565b919092503d8082843e613261818461202e565b6040838281010312613364578251916001600160401b03831161335d57818401601f84860101121561335d578284015161329a8161466b565b936132a8604051958661202e565b818552602085019084870160208460051b838a0101011161336057602081880101915b60208460051b838a0101018310613368575050505060208401516001600160401b038111613364578401916040838287010312613364576040519461330f86612013565b83516001600160401b03811161336057840192828201601f8501121561335d575060209261335094926133489201908481519101614682565b8552016146d1565b602083015290915f612e28565b80fd5b8380fd5b5080fd5b82516001600160401b038111613621576101608984018201888b0103601f1901126136215760405190816101608101106001600160401b036101608401111761360d576101608201604052602081858c010101516001600160401b038111613609578a60206133e09284888d850194010101016146b7565b8252604081858c010101516001600160401b038111613609578a602061340f9284888d850194010101016146b7565b6020830152613424606082868d010101612b3e565b6040830152608081858c010101516004811015613609576060830152898401810160a081810151608085015260c08201519084015260e001516001600160401b0381116136095760a0858c01830182018a8d0103601f190112613609576040519060208184888f61349487611ff8565b01010101516001600160401b038111613605578184888f6134c68f9560206040978401918787878701010101016146b7565b875201010101516001600160401b038111613605578184888f6134fa8f9560206060978401918787878701010101016146b7565b602088015201010101516001600160401b038111613605578184888f6135318f9560206080978401918787878701010101016146b7565b604088015201010101516001600160401b038111613605578184888f6135688f95602060a0978401918787878701010101016146b7565b60608801520101010151906001600160401b0382116136055761016084602097948f938a8f8b9a976135a6938c9b8c938a01948a01010101016146b7565b608082015260c085015288610100936135c4858484840101016145e2565b60e0870152610120946135dc868585850101016145e2565b9087015261014094858484840101015190870152010101519082015281520193019290506132cb565b8980fd5b8780fd5b634e487b7160e01b87526041600452602487fd5b8580fd5b6040513d5f823e3d90fd5b505060095f52816020805f20925f905b8082106136555750612d5f9350820101612d53565b845482870184015260019094019385935090820190613640565b60209250612d5f94915060ff191682840152151560051b820101612d53565b506126c2614b6d565b506126c2613af1565b506126c261422e565b6008545f80600855816136ba575050565b6001600160fe1b038216820361372957600881527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3600292831b810192905b8381106137065750505050565b80613712600492612af5565b8360018201558383820155836003820155016136f9565b634e487b7160e01b81526011600452602490fd5b5f905f600754905b818110613750575050565b60ff600361375d83611ec8565b50015416613774575b61376f90612aac565b613745565b9261378161376f91612aac565b939050613766565b8110156126c257604051630e47b40f60e21b8152600160048201526020905f90828160248185305af182918161380f575b506137f55750505f805160206158ca8339815191526001916137da612b4b565b906137ef604051928284938452830190611e59565b0390a290565b909150613800575090565b60018201809211613729575090565b9091508381813d8311613843575b613827818361202e565b8101031261383f5761383890612b3e565b905f6137ba565b8280fd5b503d61381d565b8110156126c257604051630e47b40f60e21b8152600260048201526020905f90828160248185305af182918161389b575b506137f55750505f805160206158ca8339815191526002916137da612b4b565b9091508381813d83116138cb575b6138b3818361202e565b8101031261383f576138c490612b3e565b905f61387b565b503d6138a9565b8110156126c257604051630e47b40f60e21b8152600360048201526020905f90828160248185305af1829181613923575b506137f55750505f805160206158ca8339815191526003916137da612b4b565b9091508381813d8311613953575b61393b818361202e565b8101031261383f5761394c90612b3e565b905f613903565b503d613931565b8110156126c257604051630e47b40f60e21b81526004808201526020905f90828160248185305af18291816139aa575b506137f55750505f805160206158ca8339815191526004916137da612b4b565b9091508381813d83116139da575b6139c2818361202e565b8101031261383f576139d390612b3e565b905f61398a565b503d6139b8565b8110156126c257604051630e47b40f60e21b8152600560048201526020905f90828160248185305af1829181613a32575b506137f55750505f805160206158ca8339815191526005916137da612b4b565b9091508381813d8311613a62575b613a4a818361202e565b8101031261383f57613a5b90612b3e565b905f613a12565b503d613a40565b8110156126c257604051630e47b40f60e21b8152600660048201526020905f90828160248185305af1829181613aba575b506137f55750505f805160206158ca8339815191526006916137da612b4b565b9091508381813d8311613aea575b613ad2818361202e565b8101031261383f57613ae390612b3e565b905f613a9a565b503d613ac8565b6001600160401b03601054165f52601660205260405f20805460ff811615908115614220575b508015614214575b61420f57613b2b614b6d565b50600181015490613b3b82612697565b9182156142085761010061ffff1983541617825582600283015530156141b957305f525f60205260405f20549080821061416957805f923084528360205203604083205580600254036002556040519081525f805160206158ea83398151915260203092a3613bc0600b548381105f1461416257805b818061412b575b505083612ad2565b905f9180613c80575b50613c3e6001827f5d78323b7b570071308d257743c74a9a2401f77d37e9de9f908da12c8917a40b606060076001600160401b0396019786199889815416898916179055600484015415613c62575b60105497878916958695015491604051928352602083015260070b6040820152a2612aba565b1691829116176010555f52601660205260405f20600160ff19825416179055600190565b835462ff000019166201000017845560038401546005850155613c18565b9150925f91600754156140f957613c95615687565b50905f5b6007548110806140f0575b156140ae57613cb281611ec8565b5060028101548015801561408b575b614080578481101561407857905b604051630fb6accf60e21b81529060208280613cf0868530600485016145f0565b03815f6108005af15f928161403c575b50613d1657505050613d1190612aac565b613c99565b613d7e81613d2f856002612fcc959a97989a0154612ad2565b6002820155600c613d41878254612ad2565b9055600d613d508782546123a0565b9055600e613d5f8782546123a0565b905560048b01613d708782546123a0565b905560405192838092611f38565b5f6080604051613d8d81611ff8565b606081528260208201528260408201528260608201520152613def5f60405192613db684611ff8565b8084528660208501528160408501528460070b60608501528160808501526040518093819263a03ffee160e01b8352306004840161545d565b03816108005afa5f9181614018575b50613f70575b506008890154600160401b811015611fe457806001613e2c920160088c015560088b0161461a565b6130f45781518051906001600160401b038211611fe457613e5782613e518554611f00565b85614633565b602090601f8311600114613f075760029392915f9183613efc575b50508160011b915f199060031b1c19161781555b602083015160018201550190604081015182546001600160401b03606084015160401b93608082811b91015160801b16938160401b169216906001600160401b0360c01b1617171790558560070b8160070b13613ef2575b50613d1191613eec91612ad2565b92612aac565b9450613d11613ede565b015190505f80613e72565b90835f5260205f20915f5b601f1985168110613f58575091839160019360029695601f19811610613f40575b505050811b018155613e86565b01515f1960f88460031b161c191690555f8080613f33565b91926020600181928685015181550194019201613f12565b9790969195945f5b60408a015180518210156140095790613f9481613fb3936146e5565b518960070b602082015160070b1480613fe5575b613fb8575b50612aac565b613f78565b606081015160208c0152805160070b60408c01526080908101516001600160401b0316908b01525f613fad565b506001600160401b036080820151166001600160401b0360808d0151161115613fa8565b5050949591969097505f613e04565b6140359192503d805f833e61402d818361202e565b8101906152fa565b905f613dfe565b9092506020813d602011614070575b816140586020938361202e565b8101031261036057614069906145e2565b915f613d00565b3d915061404b565b508390613ccf565b5050613d1190612aac565b5060076140a76040516140a281612fcc8188611f38565b6155cb565b1015613cc1565b509391906140bf5790613c3e613bc9565b60405162461bcd60e51b81526020600482015260096024820152681111531151d055115160ba1b6044820152606490fd5b50821515613ca4565b60405162461bcd60e51b815260206004820152600a60248201526956414c494441544f525360b01b6044820152606490fd5b61413491612ad2565b600b5561414381600e546123a0565b600e5561415281600f546123a0565b600f558060038401555f81613bb8565b8390613bb1565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608490fd5b5050505f90565b505f90565b50600181015415613b1f565b60ff915060081c165f613b17565b6001600160401b036010805482604091821c16935b825493808616908086168210156145d7575f93828552602091601683528186209081549860ff9960089a80828d1c16159182156145cb575b505080156145bf575b6145775750600782018181541642106145445780548281861c16156144d9575054831c164311156144a9579497600197860196899691875b89548c1015614354578b6142d96142d3828d61461a565b506154a1565b90614308575b506143029160016142f36142fc938e61461a565b500154906123a0565b9b612aac565b9a6142bc565b9b50908a908a9c614319848461461a565b50600101548110614302946142fc946001936142f393614340575b505093505050916142df565b8461434b848461461a565b5001555f614334565b929598509295995092959760048501918254808210614477575b50501561444857906143f77f73f330dd18a8f4760be8fa04b392ba243a76dcbe07487724e846182d63dbfafa97986144139354906143aa6157be565b9050808210156144425750805b600d6143c4828254612ad2565b90556143dc826143d7600e938454612ad2565b6123a0565b9055600f6143eb8282546123a0565b905560038601546123a0565b60058501908155845462ff000019166201000017909455612aba565b815467ffffffffffffffff60401b191690841b67ffffffffffffffff60401b16179055549051908152a2600190565b906143b7565b50815467ffffffffffffffff60401b1916931b67ffffffffffffffff60401b1692909217909155509192915050565b8161448191612ad2565b908355600d614491828254612ad2565b90556144a0600e918254612ad2565b90555f8061436e565b50855467ffffffffffffffff60401b191697901b67ffffffffffffffff60401b1696909617909355909350915050565b919599509396507f5e49965d9b92858198b2c5bab7c3a3fa70fcaf004a265239d97b798b708646ce9792959991506001600160401b0360401b6001600160401b0360401b19918282438a1b169116178555835492871b16911617905554821c169051908152a2600190565b5050865467ffffffffffffffff60401b19169890911b67ffffffffffffffff60401b169790971790945550909350915050565b9350975050935085929691506001600160401b0360401b61459783612aba565b67ffffffffffffffff60401b1990921691851b16178455168381146127c15760010193614243565b50600483015415614284565b8b1c1690505f8061427b565b505093505050505f90565b51908160070b820361036057565b9392916146159060409260018060a01b03168652606060208701526060860190611f38565b930152565b805482101561061c575f52600360205f20910201905f90565b9190601f811161464257505050565b612b19925f5260205f20906020601f840160051c8301931061324457601f0160051c0190612adf565b6001600160401b038111611fe45760051b60200190565b9092919261468f816126c5565b9161469d604051938461202e565b829482845282820111610360576020612b19930190611e38565b9080601f830112156103605781516126c292602001614682565b51906001600160401b038216820361036057565b805182101561061c5760209160051b010190565b6002806007541061420f5761470c615687565b506007545f80805b83811061499e57508115908115614992575b506142085790614735826150b4565b915f94919490819482938390600c54915b8381106148de5750505050159081156148d5575b5080156148cc575b6148c357808210156148bb5750915b66038d7ea4c6800083106148b35761478b61479291611ec8565b5091611ec8565b50916040516354b826f560e01b815230600482015260806024820152602081806147d46147c26084830188611f38565b82810360031901604484015288611f38565b85606483015203815f6108005af15f9181614878575b506147f85750505050505f90565b61486261485494867f2a3f2dce4ae3c46ff8fd3dbcf9cac1ca39da18b59d0ac57b2047d061ec99c1cb97860161482f868254612ad2565b9055810161483e8582546123a0565b9055604051958695608087526080870190611f38565b908582036020870152611f38565b91604084015260070b60608301520390a1600190565b90916020823d82116148ab575b816148926020938361202e565b8101031261335d57506148a4906145e2565b905f6147ea565b3d9150614885565b505050505f90565b905091614771565b50505050505f90565b50828414614762565b9050155f61475a565b60ff60036148eb83611ec8565b5001541615614989576148fd81611ec8565b5061490e83600180930154866128f0565b908c898161491b86611ec8565b50015484119182614969575b505061493e575b505061493990612aac565b614746565b929650985095509361493961496187998c6149588a611ec8565b50015490612ad2565b96905f61492e565b61498191925061497886611ec8565b50015484612ad2565b11898e614927565b61493990612aac565b9050600c54105f614726565b60ff60036149ab83611ec8565b500154166149c2575b6149bd90612aac565b614714565b90916149e46149d96149bd9260016142f386611ec8565b93866142f385611ec8565b9190506149b4565b600254158015614b5b575b61298057614a03615687565b505f80600754905b818110614b1c575050801561420f57614a34600c5491614a2e600b5480946123a0565b906151f6565b909291156142085780614b175750805b80821015614b0f5750905b8115612ca057614a5e90611ec8565b50906040516353266bbb60e01b815260208180614a80858730600485016145f0565b03815f6108005af15f9181614ad4575b50614a9c575050505f90565b15612ca0576002614acc92614ab383600b54612ad2565b600b5501614ac28282546123a0565b9055600c546123a0565b600c55600190565b90916020823d8211614b07575b81614aee6020938361202e565b8101031261335d5750614b0090612b3e565b905f614a90565b3d9150614ae1565b905090614a4f565b614a44565b60ff6003614b2983611ec8565b50015416614b40575b614b3b90612aac565b614a0b565b91614b53614b3b9160016142f386611ec8565b929050614b32565b5066038d7ea4c68000600b54106149f7565b600754158015614cff575b612980576040516370a0823160e01b8082523060048301527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906020908184602481865afa938415613625575f94614cd0575b5063ffffffff6007541660405190632efe8a5f60e01b8252306004830152602482015282816044815f6108015af15f9181614c99575b50614c185750505050505f90565b156148b357819060246040518095819382523060048301525afa908115613625575f91614c6d575b509050818111614c505750505f90565b614c6591614c5d91612ad2565b600b546123a0565b600b55600190565b82813d8311614c92575b614c81818361202e565b8101031261335d575051805f614c40565b503d614c77565b90918482813d8311614cc9575b614cb0818361202e565b8101031261335d5750614cc290612b3e565b905f614c0a565b503d614ca6565b90938282813d8311614cf8575b614ce7818361202e565b8101031261335d575051925f614bd4565b503d614cdd565b50614d08615687565b15614b78565b909291926130f45782519283516001600160401b038111611fe457614d3781613e518554611f00565b6020601f8211600114614da1579181606092600394612b1997985f92614d96575b50508160011b915f1990861b1c19161784555b60208101516001850155604081015160028501550151151591019060ff801983541691151516179055565b015190505f80614d58565b601f19821695845f52815f20965f5b818110614df3575092612b199697600395936001938360609710614ddc575b505050811b018455614d6b565b01515f1983881b60f8161c191690555f8080614dcf565b83830151895560019098019760209384019301614db0565b908015614f8d575f5b600854811015614e8357614e4483612fcc614e31612fbf85611ee4565b6020815191012090602081519101201490565b614e5657614e5190612aac565b614e14565b909150614e6281611ee4565b50906001809201548311614e7557505050565b614e7e90611ee4565b500155565b509060085460ff600a54168110614f4c5750600854915f831561231757600881527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee454600194855b818110614f125750508211614ee05750505050565b61264993614f0c9260405194614ef586611fc9565b855260208501525f60408501526060840152611ee4565b90614d0e565b8287614f1d83611ee4565b50015410614f34575b614f2f90612aac565b614ecb565b9250905084614f4283611ee4565b5001549082614f26565b9160405191614f5a83611fc9565b825260208201525f604082015260016060820152600160401b821015611fe457614f0c826001612b199401600855611ee4565b5050565b90808214614f8d57614fa38154611f00565b906001600160401b038211611fe4578190614fc882614fc28654611f00565b86614633565b5f90601f8311600114614ffc575f92614ff1575b50508160011b915f199060031b1c1916179055565b015490505f80614fdc565b81526020808220858352818320935090601f1985169083905b82821061504e575050908460019594939210615036575b505050811b019055565b01545f1960f88460031b161c191690555f808061502c565b8495819295850154815560018091019601940190615015565b906130f457818103615077575050565b600360ff818461508a612b199686614f91565b600181015460018601556002810154600286015501541691019060ff801983541691151516179055565b600754915f5b83811061519857505f809381938290600c54915b8381106150de5750505050929190565b60ff60036150eb83611ec8565b500154161561518f576150fd81611ec8565b5061510e83600180930154866128f0565b61511783611ec8565b509160028093015466038d7ea4c68000830190818411610608571180615179575b61514e575b50505061514990612aac565b6150ce565b92995089985091955061514991615170916151688a611ec8565b500154612ad2565b96905f8061513d565b5089615189838561516888611ec8565b11615138565b61514990612aac565b60ff60036151a883969596611ec8565b5001541615806151e0575b6151c8576151c090612aac565b9291926150ba565b9250905060026151d783611ec8565b50015460019291565b5060026151ec82611ec8565b50015415156151b3565b90915f809381938291600754925b83811061525a57505050811561521b575b50929190565b5f5b81811061522a5750615215565b60ff600361523783611ec8565b5001541661524d5761524890612aac565b61521d565b6001955093505f92915050565b60ff600361526783611ec8565b50015416156152f15761527981611ec8565b5061528a84600180930154856128f0565b61529383611ec8565b50916002809301548211806152dc575b6152b9575b5050506152b490612aac565b615204565b9299508998509195506152b4916152d3916149588a611ec8565b96905f806152a8565b50896152eb8461497887611ec8565b116152a3565b6152b490612aac565b90602080838303126103605782516001600160401b039384821161036057019260609283858203126103605760409283519585870187811085821117611fe4578552805184811161036057836153519183016146b7565b875281810151848111610360578361536a9183016146b7565b82880152848101519084821161036057019180601f84011215610360578251936153938561466b565b966153a08751988961202e565b858852838801928460c080980287010195818711610360578501935b8685106153d157505050505050505082015290565b878583031261036057885190888201908282108683111761544957899288928c526153fb886145e2565b81526154088389016145e2565b838201528b8801518c82015285880151868201526080615429818a016146d1565b9082015260a061543a818a016145e2565b908201528152019401936153bc565b60245f634e487b7160e01b81526041600452fd5b6001600160a01b0390911681526040602082018190526126c292910190611e59565b6001600160a01b0390911681526040602082018190526126c292910190611f38565b6040805163a03ffee160e01b81525f939290918483806154c585306004840161547f565b03816108005afa8593816155af575b506154e1575b5050508190565b90919293805b8285015180518210156155a057816154fe916146e5565b5160028501546001600160401b036080918181841c1680159283159485615591575b5050508161557e575b81615567575b50811561555f575b5061554e57506155478391612aac565b90506154e7565b606001516001969095509350505050565b90505f615537565b90506020830151600791871c820b910b145f61552f565b9050825160079082820b910b1490615529565b860151161492505f8080615520565b505093925050505f80806154da565b6155c49194503d8088833e61402d818361202e565b925f6154d4565b5f6155eb916040518093819263a03ffee160e01b8352306004840161545d565b03816108005afa5f918161560c575b5061560457505f90565b604001515190565b61562091923d8091833e61402d818361202e565b905f6155fa565b9190916040818403126103605780519260208201516001600160401b03928382116103605701604081830312610360576040519261566484612013565b81519081116103605760209261567b9183016146b7565b83520151602082015290565b5f905f805b600754811015615738576156bf826156a383611ec8565b506040518093819263120bba7360e11b8352306004840161547f565b03816108005afa839181615712575b506156e9575080826002612f926156e494611ec8565b61568c565b6156e49194602061570c92018051600261570289611ec8565b50015551906123a0565b93612aac565b61572f9192503d8086833e615727818361202e565b810190615627565b9050905f6156ce565b505081600c55565b5f905f80600754915b82811061575557505050565b615762826156a383611ec8565b03816108005afa8391816157a0575b50615786575b5061578190612aac565b615749565b61578191956020615799920151906123a0565b9490615777565b6157b59192503d8086833e615727818361202e565b9050905f615771565b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115613625575f91615832575b50615821600b54600f54906123a0565b80821115612ca0576126c291612ad2565b906020823d821161585b575b8161584b6020938361202e565b8101031261335d5750515f615811565b3d915061583e565b60075491905f5b83811061587b57505090505f905f90565b61588e82612fcc614e31612fbf85611ec8565b6158a05761589b90612aac565b61586a565b9250506001919056fe537472696e67733a20686578206c656e67746820696e73756666696369656e74f1190c18d28d5d68156de3ae0f68fd157173bc96def1c9c2fae201841639d0adddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220800b05ff46a6147d3ec02ecf5b96df769de94c6b17f9db608c34d6c952fb8b5b64736f6c634300081400332f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "deployedBytecode": "0x60806040526004361015610011575f80fd5b5f3560e01c806301e1d11414611e1e57806301ffc9a714611dc857806303e5fa8814611d9f57806306fdde0314611cfd57806307a2d13a146113c2578063095ea7b314611cd75780630a28a47714611c955780630a763da114611c6f5780630f43a67714611c5257806318160ddd14611c355780631f9acd7e14611c1a57806323b872dd14611be2578063248a9ca314611bb5578063291cdb8c14611b905780632d9414b514611b765780632f2ff15d14611ace578063313ce56714611a8757806332145f9014611a5c578063331c138c1461181357806333a73916146117f657806333bb7f911461162557806335aa2e44146115a357806336568abe1461151157806338d52e0f146114cd578063391ed03c14611468578063395093511461141b578063402d267d146106dc5780634221b2c2146113fe5780634864b09d146113e1578063499bafcc146113c75780634cdad506146113c25780634f7b9013146113a1578063559904cb146112cd578063588f134314610e2a5780635ac22fd214610df657806360da3e8314610dd45780636a84a98514610db75780636c68e40314610d7b5780636e553f65146109c857806370a0823114610d80578063714897df14610d7b5780637316a19614610d5b57806377397cdd14610d3e5780637aed3cbb14610d215780637d41c86e14610a9057806380d04de814610a7357806391d1485414610a2a578063937b2581146109cd57806394bf804d146109c857806395d89b41146108e5578063a217fddf146108cb578063a41fcdc3146108b0578063a457c2d71461080d578063a9059cbb146107dc578063ac44da52146107ba578063b3d7f6b914610770578063b460af941461073d578063b9bcb70f14610742578063ba0876521461073d578063c63d75b6146106dc578063c6e6f59214610364578063ce96cb77146106dc578063d547741f146106fe578063d77bb97c146106e1578063d905777e146106dc578063dd62ed3e1461068f578063e63ab1e914610655578063e9f2838e14610630578063ecdcce2414610369578063ef8b30f7146103645763f5b541a614610326575f80fd5b34610360575f3660031901126103605760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b5f80fd5b61214a565b602080600319360112610360576004359060ff82168092036103605761038f3415612984565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929805f526005825260405f20335f52825260ff60405f205416156104a2575081151580610498575b1561046c57817fe28c6c3955ed05a471a85214f10fe95cb125572d2aadeb008a7c5992533984969260ff19600a541617600a556104126136a9565b61041d600954611f00565b8061042d575b50604051908152a1005b601f811160011461044457505f6009555b83610423565b5f9060098252610462601f858420920160051c820160018301612adf565b816009555561043e565b6064906040519062461bcd60e51b82526004820152600560248201526410d3d5539560da1b6044820152fd5b50808211156103d7565b906104ac336126f1565b916040516104b981611fc9565b6042815282810191606036843781511561061c5760308353815160019081101561061c57607860218401536041905b8082116105c557505061059557610561936105709260489260405196879376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b88860152610538815180928a603789019101611e38565b8401917001034b99036b4b9b9b4b733903937b6329607d1b603784015251809386840190611e38565b0103602881018552018361202e565b61059160405192839262461bcd60e51b845260048401526024830190611e59565b0390fd5b6064836040519062461bcd60e51b825280600483015260248201525f805160206158aa8339815191526044820152fd5b9091600f8116601081101561061c576f181899199a1a9b1b9c1cb0b131b232b360811b901a6105f484866126e0565b5360041c918015610608575f1901906104e8565b634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b34610360575f36600319011261036057602060ff60125460081c166040519015158152f35b34610360575f3660031901126103605760206040517f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a8152f35b34610360576040366003190112610360576106a8611e9c565b6106b0611eb2565b9060018060a01b038091165f52600160205260405f2091165f52602052602060405f2054604051908152f35b61204f565b34610360575f366003190112610360576020600e54604051908152f35b346103605760403660031901126103605761073b60043561071d611eb2565b90805f526005602052610736600160405f20015461218c565b61232b565b005b61210b565b34610360575f36600319011261036057602060405173d4949664cd82660aae99bedc034a0dea8a0bd5178152f35b3461036057602036600319011261036057610789612964565b60018101809111610608576002549060018201809211610608576020916107b2916004356127e9565b604051908152f35b34610360575f366003190112610360576020604051670de0b6b3a76400008152f35b34610360576040366003190112610360576108026107f8611e9c565b60243590336123ad565b602060405160018152f35b3461036057604036600319011261036057610826611e9c565b60243590335f52600160205260405f2060018060a01b0382165f5260205260405f20549180831061085d5761080292039033612507565b60405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608490fd5b34610360575f36600319011261036057602060405160078152f35b34610360575f3660031901126103605760206040515f8152f35b34610360575f366003190112610360576040515f9060045461090681611f00565b8083526001918083169081156109a05750600114610947575b6109438361092f8187038261202e565b604051918291602083526020830190611e59565b0390f35b60045f90815260209450917f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b82841061098d5750505081019091019061092f8161091f565b8054858501870152928501928101610974565b610943955061092f93506020915091849260ff191682840152151560051b820101935061091f565b61208d565b34610360576020366003190112610360576004355f526015602052608060405f2060018060a01b036001600160401b03818354169260026001820154910154926040519485528116602085015260a01c1660408301526060820152f35b3461036057604036600319011261036057610a43611eb2565b6004355f52600560205260405f209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b34610360575f366003190112610360576020600c54604051908152f35b610a99366120d6565b610aa33415612984565b610aab6129b8565b60ff60125460081c16610cf157610ac3831515612a77565b6001600160a01b0391808316610ada811515612a0e565b838316928315610cc45785610b37817f1dfdc691a597a83af2430bd31addf8d2129d012eab8b35de6d696dc91e64852393610b2866038d7ea4c68000610b2160209c612697565b1015612a45565b873303610cb4575b30906123ad565b601154958693610b4685612aac565b601155601054906001600160401b039283831692835f5260168c528460405f2094855460ff811615908115610ca6575b50610c68575b506002929150601054169260405193610b9485611fc9565b8b85528d85019182526040850190815260608501928884528a5f5260158f528060405f2096511660018060a01b0319875416178655600186019251168254916001600160401b0360a01b905160a01b169163ffffffff60e01b16171790555191015560018101610c058482546123a0565b905580546affffffffffffffff000000610c23848360181c16612aba565b60181b166affffffffffffffff0000001991909116179055601054604080516001600160a01b0397909716875260208701939093521693a46001600655604051908152f35b610c759192939550612aba565b1680916001600160401b031916176010555f5260168a52600260405f2092600160ff1985541617845590848d610b7c565b60ff915060081c168f610b76565b610cbf823383612605565b610b30565b60405162461bcd60e51b815260206004820152600560248201526427aba722a960d91b6044820152606490fd5b60405162461bcd60e51b815260206004820152600860248201526715d7d4105554d15160c21b6044820152606490fd5b34610360575f366003190112610360576020600f54604051908152f35b34610360575f366003190112610360576020601454604051908152f35b34610360575f36600319011261036057602060ff600a5416604051908152f35b612073565b34610360576020366003190112610360576001600160a01b03610da1611e9c565b165f525f602052602060405f2054604051908152f35b34610360575f366003190112610360576020601154604051908152f35b34610360575f36600319011261036057602060ff601254166040519015158152f35b5f36600319011261036057610e0b3415612984565b610e136129b8565b6020610e1d615687565b6001600655604051908152f35b604036600319011261036057610e3e611eb2565b610e483415612984565b610e506129b8565b6004355f52601560205260405f2060405190610e6b82611fc9565b80546001600160a01b039081168084526001830154918216602085015260a09190911c6001600160401b031660408401526002919091015460608301521561129e576001600160401b036040820151165f52601660205260405f2080549260ff8460101c161561126d576001600160a01b038116611268575060208201516001600160a01b03165b60208301516001600160a01b039081169082160361123a57610f206001600160401b038560581c16612aba565b6001600160401b03808660181c169116145f1461121c57610f4a6005830154600684015490612ad2565b935b67ffffffffffffffff60581b610f6e605883901c6001600160401b0316612aba565b60581b16906001600160401b0360581b191617825560068201610f928582546123a0565b9055610fa084600e54612ad2565b600e55610faf84600f54612ad2565b600f556004355f908152601560209081526040808320838155600181018490556002018390555163a9059cbb60e01b9181019182526001600160a01b038481166024830152604480830189905282526110829391927f00000000000000000000000000000000000000000000000000000000000000009091169190819061103760648661202e565b6040519461104486612013565b602086527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646020870152519082855af161107c612b4b565b91612b7a565b80519081159182156111fa575b5050156111a2576001600160401b036040840151166040519185835260018060a01b0316917f6443ab78e20802b0a48c253c5a7e05576a8bedd83aec398a8bba1164e7cf6fc3602060043592a4546001600160401b03808260181c169160581c1614611106575b6020826001600655604051908152f35b60406001600160401b03910151165f52601660205260405f20905f82555f60018301555f600283015560086003925f848201555f60048201555f60058201555f60068201555f6007820155018054905f815581611166575b5050906110f6565b8184029184830403610608575f5260205f20908101905b8181101561115e57806111908592612af5565b5f60018201555f60028201550161117d565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b81925090602091810103126103605760206112159101612b3e565b858061108f565b611234606084015160058401546001850154916128f0565b93610f4c565b60405162461bcd60e51b815260206004820152600660248201526514105653d55560d21b6044820152606490fd5b610ef3565b60405162461bcd60e51b8152602060048201526009602482015268434c41494d41424c4560b81b6044820152606490fd5b60405162461bcd60e51b8152602060048201526007602482015266149154555154d560ca1b6044820152606490fd5b34610360576020366003190112610360576004356001600160401b03808216809203610360576101a0915f52601660205260405f2090815491600181015490600281015460038201546004830154906005840154926007600686015495015495876040519960ff811615158b5260ff8160081c16151560208c015260ff8160101c16151560408c0152818160181c1660608c015260581c1660808a015260a089015260c088015260e08701526101008601526101208501526101408401528060070b61016084015260401c16610180820152f35b34610360575f36600319011261036057602060405166038d7ea4c680008152f35b611e7e565b34610360575f3660031901126103605760206107b2615740565b34610360575f366003190112610360576020600b54604051908152f35b34610360575f366003190112610360576020601354604051908152f35b3461036057604036600319011261036057610802611437611e9c565b335f52600160205260405f2060018060a01b0382165f5260205261146160243560405f20546123a0565b9033612507565b346103605760203660031901126103605760043560ff81168103610360573033036114a257611498602091612cd6565b6040519015158152f35b606460405162461bcd60e51b815260206004820152600460248201526329a2a62360e11b6044820152fd5b34610360575f366003190112610360576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346103605760403660031901126103605761152a611eb2565b336001600160a01b038216036115465761073b9060043561232b565b60405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608490fd5b3461036057602036600319011261036057600435600754811015610360576115cd61160f91611ec8565b50604051906115e7826115e08184611f38565b038361202e565b60018101549060ff600360028301549201541690604051948594608086526080860190611e59565b9260208501526040840152151560608301520390f35b6020806003193601126103605761163a611e9c565b6116426129b8565b60ff601254166117c6576001600160a01b03168015906116628215612a0e565b61167566038d7ea4c68000341015612a45565b61167d614b6d565b50600254611689612964565b81611768575034925b61169d841515612a77565b6116a934600b546123a0565b600b5561172357826116ba916123a0565b600255805f525f835260405f20828154019055805f5f805160206158ea83398151915285604051868152a360405134815282848201527fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d760403392a36001600655604051908152f35b60405162461bcd60e51b815260048101859052601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606490fd5b801561179557600182019081831161060857600181018091116106085761178f91346128f0565b92611692565b60405162461bcd60e51b8152600481018690526009602482015268125394d3d31591539560ba1b6044820152606490fd5b60405162461bcd60e51b81526004810183905260086024820152671117d4105554d15160c21b6044820152606490fd5b34610360575f366003190112610360576020600d54604051908152f35b6060366003190112610360576004358015158091036103605760248035908115158092036103605760443590811515809203610360576118533415612984565b335f9081527f99f2891db7a8db76249871a02b43b68c0bb8f22ef8a3bc1034ae9375ef6b7c3c60209081526040909120547f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a9060ff16156118db5750505061ff009060ff62ff00006012549260101b1694169062ffffff1916179160081b1617176012555f80f35b6118e4336126f1565b906040516118f181611fc9565b60428152838101916060368437815115611a4957603083538151600190811015611a3657607860218401536041905b8082116119cd57505061199e57604861059193611973936119829360405195869376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a860152610538815180928c603789019101611e38565b0103602881018452018261202e565b60405193849362461bcd60e51b85526004850152830190611e59565b606485856040519162461bcd60e51b83528160048401528201525f805160206158aa8339815191526044820152fd5b9091600f81166010811015611a23576f181899199a1a9b1b9c1cb0b131b232b360811b901a6119fc84866126e0565b5360041c918015611a10575f190190611920565b87634e487b7160e01b5f5260116004525ffd5b88634e487b7160e01b5f5260326004525ffd5b86634e487b7160e01b5f5260326004525ffd5b85634e487b7160e01b5f5260326004525ffd5b602036600319011261036057611a723415612984565b611a7a6129b8565b6020610e1d600435612c13565b34610360575f3660031901126103605760ff7f00000000000000000000000000000000000000000000000000000000000000001660ff811161060857602090604051908152f35b3461036057604036600319011261036057600435611aea611eb2565b815f526005602052611b02600160405f20015461218c565b815f52600560205260405f209060018060a01b031690815f5260205260ff60405f20541615611b2d57005b815f52600560205260405f20815f5260205260405f20600160ff1982541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d5f80a4005b34610360575f3660031901126103605760206107b261373d565b34610360575f36600319011261036057602060ff60125460101c166040519015158152f35b34610360576020366003190112610360576004355f5260056020526020600160405f200154604051908152f35b3461036057606036600319011261036057610802611bfe611e9c565b611c06611eb2565b60443591611c15833383612605565b6123ad565b34610360575f36600319011261036057602060405160088152f35b34610360575f366003190112610360576020600254604051908152f35b34610360575f366003190112610360576020600754604051908152f35b34610360575f3660031901126103605760206001600160401b0360105416604051908152f35b34610360576020366003190112610360576002546001810180911161060857611cbc612964565b9060018201809211610608576020916107b2916004356127e9565b3461036057604036600319011261036057610802611cf3611e9c565b6024359033612507565b34610360575f366003190112610360576040515f90600354611d1e81611f00565b8083526001918083169081156109a05750600114611d46576109438361092f8187038261202e565b60035f90815260209450917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b828410611d8c5750505081019091019061092f8161091f565b8054858501870152928501928101611d73565b34610360575f3660031901126103605760206001600160401b0360105460401c16604051908152f35b346103605760203660031901126103605760043563ffffffff60e01b811680910361036057602090637965db0b60e01b8114908115611e0d575b506040519015158152f35b6301ffc9a760e01b14905082611e02565b34610360575f3660031901126103605760206107b2612964565b5f5b838110611e495750505f910152565b8181015183820152602001611e3a565b90602091611e7281518092818552858086019101611e38565b601f01601f1916010190565b346103605760203660031901126103605760206107b2600435612697565b600435906001600160a01b038216820361036057565b602435906001600160a01b038216820361036057565b60075481101561061c5760075f5260205f209060021b01905f90565b60085481101561061c5760085f5260205f209060021b01905f90565b90600182811c92168015611f2e575b6020831014611f1a57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691611f0f565b905f9291805491611f4883611f00565b9182825260019384811690815f14611fa65750600114611f69575b50505050565b90919394505f52602092835f2092845f945b838610611f9257505050500101905f808080611f63565b805485870183015294019385908201611f7b565b9294505050602093945060ff191683830152151560051b0101905f808080611f63565b608081019081106001600160401b03821117611fe457604052565b634e487b7160e01b5f52604160045260245ffd5b60a081019081106001600160401b03821117611fe457604052565b604081019081106001600160401b03821117611fe457604052565b90601f801991011681019081106001600160401b03821117611fe457604052565b3461036057602036600319011261036057612068611e9c565b5060206040515f8152f35b34610360575f366003190112610360576020604051818152f35b34610360576040366003190112610360576120a6611eb2565b5060405162461bcd60e51b815260206004820152600760248201526611115413d4d25560ca1b6044820152606490fd5b606090600319011261036057600435906001600160a01b03906024358281168103610360579160443590811681036103605790565b3461036057612119366120d6565b505060405162461bcd60e51b815260206004820152600660248201526552454445454d60d01b604482015260649150fd5b34610360576020366003190112610360576002546001810180911161060857612171612964565b9060018201809211610608576020916107b2916004356128f0565b5f9080825260209060058252604092838120338252835260ff8482205416156121b55750505050565b6121be336126f1565b918451906121cb82611fc9565b6042825284820192606036853782511561231757603084538251906001918210156123175790607860218501536041915b8183116122aa5750505061227b57604861059193869361225f93612250985198899376020b1b1b2b9b9a1b7b73a3937b61d1030b1b1b7bab73a1604d1b8a860152610538815180928c603789019101611e38565b0103602881018752018561202e565b5192839262461bcd60e51b845260048401526024830190611e59565b60648486519062461bcd60e51b825280600483015260248201525f805160206158aa8339815191526044820152fd5b909192600f81166010811015612303576f181899199a1a9b1b9c1cb0b131b232b360811b901a6122da85876126e0565b5360041c9280156122ef575f190191906121fc565b634e487b7160e01b82526011600452602482fd5b634e487b7160e01b83526032600452602483fd5b634e487b7160e01b81526032600452602490fd5b905f918083526005602052604083209160018060a01b03169182845260205260ff60408420541661235b57505050565b8083526005602052604083208284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4565b9190820180921161060857565b6001600160a01b039081169182156124b45716918215612463575f8281528060205260408120549180831061240f57604082825f805160206158ea833981519152958760209652828652038282205586815220818154019055604051908152a3565b60405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608490fd5b60405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608490fd5b6001600160a01b039081169182156125b457169182156125645760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591835f526001825260405f20855f5282528060405f2055604051908152a3565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608490fd5b60405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608490fd5b9060018060a01b038083165f52600160205260405f209082165f5260205260405f2054925f1984036126375750505050565b80841061265257612649930391612507565b5f808080611f63565b60405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606490fd5b61269f612964565b60018101809111610608576002549060018201809211610608576126c2926128f0565b90565b6001600160401b038111611fe457601f01601f191660200190565b90815181101561061c570160200190565b60405190606082018281106001600160401b03821117611fe457604052602a825260208201604036823782511561061c5760309053815160019081101561061c57607860218401536029905b80821161277e57505061274d5790565b606460405162461bcd60e51b815260206004820152602060248201525f805160206158aa8339815191526044820152fd5b9091600f811660108110156127d5576f181899199a1a9b1b9c1cb0b131b232b360811b901a6127ad84866126e0565b5360041c9180156127c1575f19019061273d565b60245f634e487b7160e01b81526011600452fd5b60245f634e487b7160e01b81526032600452fd5b91906127f68282856128f0565b92821561281357096128055790565b600181018091116106085790565b634e487b7160e01b5f52601260045260245ffd5b90670de0b6b3a7640000905f1982840992828102928380861095039480860395146128e257848311156128a55782910960018219018216809204600280826003021880830282030280830282030280830282030280830282030280830282030280920290030293600183805f03040190848311900302920304170290565b60405162461bcd60e51b81526020600482015260156024820152744d6174683a206d756c446976206f766572666c6f7760581b6044820152606490fd5b505080925015612813570490565b915f1982840992828102928380861095039480860395146128e257848311156128a55782910960018219018216809204600280826003021880830282030280830282030280830282030280830282030280830282030280920290030293600183805f03040190848311900302920304170290565b60025415612980576126c2600b5461297a615740565b906123a0565b5f90565b1561298b57565b60405162461bcd60e51b815260206004820152600560248201526456414c554560d81b6044820152606490fd5b6002600654146129c9576002600655565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b15612a1557565b60405162461bcd60e51b81526020600482015260086024820152672922a1a2a4ab22a960c11b6044820152606490fd5b15612a4c57565b60405162461bcd60e51b815260206004820152600360248201526226a4a760e91b6044820152606490fd5b15612a7e57565b60405162461bcd60e51b815260206004820152600660248201526553484152455360d01b6044820152606490fd5b5f1981146106085760010190565b9060016001600160401b038093160191821161060857565b9190820391821161060857565b818110612aea575050565b5f8155600101612adf565b612aff8154611f00565b9081612b09575050565b81601f5f9311600114612b1b5750555b565b908083918252612b3a601f60208420940160051c840160018501612adf565b5555565b5190811515820361036057565b3d15612b75573d90612b5c826126c5565b91612b6a604051938461202e565b82523d5f602084013e565b606090565b91929015612bdc5750815115612b8e575090565b3b15612b975790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015612bef5750805190602001fd5b60405162461bcd60e51b815260206004820152908190610591906024830190611e59565b5f9060ff60125460101c16612ca6578015612ca057612c59612c53612c4d612c47612c41612c5f9686613789565b8561384a565b846138d2565b8361395a565b826139e1565b90613a69565b90612c6b601354612aac565b601355816014556040518281527f4889d7d38c1d1f265318505a98367d07d41591d6b7f9cc000f37ea92b8311daa60203392a2565b50505f90565b60405162461bcd60e51b81526020600482015260086024820152671417d4105554d15160c21b6044820152606490fd5b60ff16600181146136a05760028114613697576003811461368e5760048114612d1d5760058114612d1457600614612d0c575f90565b6126c26149ec565b506126c26146f9565b50604051612d2a81611ff8565b604051600954815f612d3b83611f00565b808352926001811690811561366f5750600114613630575b612d5f9250038261202e565b81525f6020820152602060408201525f60608201525f60808201525f60405180809363186b216760e01b82526040600483015260126044830152711093d39117d4d510551554d7d093d391115160721b6064830152608060248301526080612dd4825160a06084860152610124850190611e59565b916001600160401b0360208201511660a48501526001600160401b0360408201511660c48501526060810151151560e48501520151151561010483015203816108005afa918215613625575f91829361324e575b505f5b8251811015612edc57612e3e81846146e5565b5190604082015115801590612eb0575b8015612ea4575b612e9a5760808201519161012081015190670de0b6b3a764000091820180921161060857612e89612e9092612e9595612827565b9051614e0b565b612aac565b612e2b565b612e959150612aac565b50608082015115612e55565b5060608201516004811015612ec85760031415612e4e565b634e487b7160e01b5f52602160045260245ffd5b50909180519283516001600160401b038111611fe457612efd600954611f00565b601f81116131f5575b50602094601f8211600114613191579481929394955f92613186575b50508160011b915f199060031b1c1916176009555b81515115612f56575b511590811591612f4e575090565b905051511590565b9190612f60615687565b505f5b600754811015612f9f57806003612f7c612f9a93611ec8565b5001805460ff191690555f6001612f9283611ec8565b500155612aac565b612f63565b50905f5b60085481101561306a57612fd8612fcc612fd3612fbf84611ee4565b5060405192838092611f38565b038261202e565b615863565b90156130185790816003612fee61301394611ec8565b5001600160ff198254161790556001612f928161300a85611ee4565b50015492611ec8565b612fa3565b50600790815460208110613032575b506130139150612aac565b61303b82611ee4565b50600160401b821015611fe45761305e8261301395600161306495019055611ec8565b90615067565b5f613027565b5090915f915b60078054808510156131425760ff600361308987611ec8565b50015416158061312d575b1561311b575f1990808201908111610608576130b26130bc91611ec8565b5061305e87611ec8565b815480156131075701906130cf82611ec8565b6130f4576003816130e05f93612af5565b826001820155826002820155015555613070565b634e487b7160e01b5f525f60045260245ffd5b634e487b7160e01b5f52603160045260245ffd5b50509161312790612aac565b91613070565b50600261313986611ec8565b50015415613094565b505092915061314f6136a9565b7f17e14f5a0c6831022cc1f0f72d2d717ac74633f5193b19f76e18d9711b6d7cec602061317a61373d565b604051908152a1612f40565b015190505f80612f22565b601f1982169560095f5260205f20915f5b8881106131dd575083600195969798106131c5575b505050811b01600955612f37565b01515f1960f88460031b161c191690555f80806131b7565b919260206001819286850151815501940192016131a2565b60095f5261323e907f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af601f840160051c81019160208510613244575b601f0160051c0190612adf565b5f612f06565b9091508190613231565b919092503d8082843e613261818461202e565b6040838281010312613364578251916001600160401b03831161335d57818401601f84860101121561335d578284015161329a8161466b565b936132a8604051958661202e565b818552602085019084870160208460051b838a0101011161336057602081880101915b60208460051b838a0101018310613368575050505060208401516001600160401b038111613364578401916040838287010312613364576040519461330f86612013565b83516001600160401b03811161336057840192828201601f8501121561335d575060209261335094926133489201908481519101614682565b8552016146d1565b602083015290915f612e28565b80fd5b8380fd5b5080fd5b82516001600160401b038111613621576101608984018201888b0103601f1901126136215760405190816101608101106001600160401b036101608401111761360d576101608201604052602081858c010101516001600160401b038111613609578a60206133e09284888d850194010101016146b7565b8252604081858c010101516001600160401b038111613609578a602061340f9284888d850194010101016146b7565b6020830152613424606082868d010101612b3e565b6040830152608081858c010101516004811015613609576060830152898401810160a081810151608085015260c08201519084015260e001516001600160401b0381116136095760a0858c01830182018a8d0103601f190112613609576040519060208184888f61349487611ff8565b01010101516001600160401b038111613605578184888f6134c68f9560206040978401918787878701010101016146b7565b875201010101516001600160401b038111613605578184888f6134fa8f9560206060978401918787878701010101016146b7565b602088015201010101516001600160401b038111613605578184888f6135318f9560206080978401918787878701010101016146b7565b604088015201010101516001600160401b038111613605578184888f6135688f95602060a0978401918787878701010101016146b7565b60608801520101010151906001600160401b0382116136055761016084602097948f938a8f8b9a976135a6938c9b8c938a01948a01010101016146b7565b608082015260c085015288610100936135c4858484840101016145e2565b60e0870152610120946135dc868585850101016145e2565b9087015261014094858484840101015190870152010101519082015281520193019290506132cb565b8980fd5b8780fd5b634e487b7160e01b87526041600452602487fd5b8580fd5b6040513d5f823e3d90fd5b505060095f52816020805f20925f905b8082106136555750612d5f9350820101612d53565b845482870184015260019094019385935090820190613640565b60209250612d5f94915060ff191682840152151560051b820101612d53565b506126c2614b6d565b506126c2613af1565b506126c261422e565b6008545f80600855816136ba575050565b6001600160fe1b038216820361372957600881527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3600292831b810192905b8381106137065750505050565b80613712600492612af5565b8360018201558383820155836003820155016136f9565b634e487b7160e01b81526011600452602490fd5b5f905f600754905b818110613750575050565b60ff600361375d83611ec8565b50015416613774575b61376f90612aac565b613745565b9261378161376f91612aac565b939050613766565b8110156126c257604051630e47b40f60e21b8152600160048201526020905f90828160248185305af182918161380f575b506137f55750505f805160206158ca8339815191526001916137da612b4b565b906137ef604051928284938452830190611e59565b0390a290565b909150613800575090565b60018201809211613729575090565b9091508381813d8311613843575b613827818361202e565b8101031261383f5761383890612b3e565b905f6137ba565b8280fd5b503d61381d565b8110156126c257604051630e47b40f60e21b8152600260048201526020905f90828160248185305af182918161389b575b506137f55750505f805160206158ca8339815191526002916137da612b4b565b9091508381813d83116138cb575b6138b3818361202e565b8101031261383f576138c490612b3e565b905f61387b565b503d6138a9565b8110156126c257604051630e47b40f60e21b8152600360048201526020905f90828160248185305af1829181613923575b506137f55750505f805160206158ca8339815191526003916137da612b4b565b9091508381813d8311613953575b61393b818361202e565b8101031261383f5761394c90612b3e565b905f613903565b503d613931565b8110156126c257604051630e47b40f60e21b81526004808201526020905f90828160248185305af18291816139aa575b506137f55750505f805160206158ca8339815191526004916137da612b4b565b9091508381813d83116139da575b6139c2818361202e565b8101031261383f576139d390612b3e565b905f61398a565b503d6139b8565b8110156126c257604051630e47b40f60e21b8152600560048201526020905f90828160248185305af1829181613a32575b506137f55750505f805160206158ca8339815191526005916137da612b4b565b9091508381813d8311613a62575b613a4a818361202e565b8101031261383f57613a5b90612b3e565b905f613a12565b503d613a40565b8110156126c257604051630e47b40f60e21b8152600660048201526020905f90828160248185305af1829181613aba575b506137f55750505f805160206158ca8339815191526006916137da612b4b565b9091508381813d8311613aea575b613ad2818361202e565b8101031261383f57613ae390612b3e565b905f613a9a565b503d613ac8565b6001600160401b03601054165f52601660205260405f20805460ff811615908115614220575b508015614214575b61420f57613b2b614b6d565b50600181015490613b3b82612697565b9182156142085761010061ffff1983541617825582600283015530156141b957305f525f60205260405f20549080821061416957805f923084528360205203604083205580600254036002556040519081525f805160206158ea83398151915260203092a3613bc0600b548381105f1461416257805b818061412b575b505083612ad2565b905f9180613c80575b50613c3e6001827f5d78323b7b570071308d257743c74a9a2401f77d37e9de9f908da12c8917a40b606060076001600160401b0396019786199889815416898916179055600484015415613c62575b60105497878916958695015491604051928352602083015260070b6040820152a2612aba565b1691829116176010555f52601660205260405f20600160ff19825416179055600190565b835462ff000019166201000017845560038401546005850155613c18565b9150925f91600754156140f957613c95615687565b50905f5b6007548110806140f0575b156140ae57613cb281611ec8565b5060028101548015801561408b575b614080578481101561407857905b604051630fb6accf60e21b81529060208280613cf0868530600485016145f0565b03815f6108005af15f928161403c575b50613d1657505050613d1190612aac565b613c99565b613d7e81613d2f856002612fcc959a97989a0154612ad2565b6002820155600c613d41878254612ad2565b9055600d613d508782546123a0565b9055600e613d5f8782546123a0565b905560048b01613d708782546123a0565b905560405192838092611f38565b5f6080604051613d8d81611ff8565b606081528260208201528260408201528260608201520152613def5f60405192613db684611ff8565b8084528660208501528160408501528460070b60608501528160808501526040518093819263a03ffee160e01b8352306004840161545d565b03816108005afa5f9181614018575b50613f70575b506008890154600160401b811015611fe457806001613e2c920160088c015560088b0161461a565b6130f45781518051906001600160401b038211611fe457613e5782613e518554611f00565b85614633565b602090601f8311600114613f075760029392915f9183613efc575b50508160011b915f199060031b1c19161781555b602083015160018201550190604081015182546001600160401b03606084015160401b93608082811b91015160801b16938160401b169216906001600160401b0360c01b1617171790558560070b8160070b13613ef2575b50613d1191613eec91612ad2565b92612aac565b9450613d11613ede565b015190505f80613e72565b90835f5260205f20915f5b601f1985168110613f58575091839160019360029695601f19811610613f40575b505050811b018155613e86565b01515f1960f88460031b161c191690555f8080613f33565b91926020600181928685015181550194019201613f12565b9790969195945f5b60408a015180518210156140095790613f9481613fb3936146e5565b518960070b602082015160070b1480613fe5575b613fb8575b50612aac565b613f78565b606081015160208c0152805160070b60408c01526080908101516001600160401b0316908b01525f613fad565b506001600160401b036080820151166001600160401b0360808d0151161115613fa8565b5050949591969097505f613e04565b6140359192503d805f833e61402d818361202e565b8101906152fa565b905f613dfe565b9092506020813d602011614070575b816140586020938361202e565b8101031261036057614069906145e2565b915f613d00565b3d915061404b565b508390613ccf565b5050613d1190612aac565b5060076140a76040516140a281612fcc8188611f38565b6155cb565b1015613cc1565b509391906140bf5790613c3e613bc9565b60405162461bcd60e51b81526020600482015260096024820152681111531151d055115160ba1b6044820152606490fd5b50821515613ca4565b60405162461bcd60e51b815260206004820152600a60248201526956414c494441544f525360b01b6044820152606490fd5b61413491612ad2565b600b5561414381600e546123a0565b600e5561415281600f546123a0565b600f558060038401555f81613bb8565b8390613bb1565b60405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608490fd5b60405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608490fd5b5050505f90565b505f90565b50600181015415613b1f565b60ff915060081c165f613b17565b6001600160401b036010805482604091821c16935b825493808616908086168210156145d7575f93828552602091601683528186209081549860ff9960089a80828d1c16159182156145cb575b505080156145bf575b6145775750600782018181541642106145445780548281861c16156144d9575054831c164311156144a9579497600197860196899691875b89548c1015614354578b6142d96142d3828d61461a565b506154a1565b90614308575b506143029160016142f36142fc938e61461a565b500154906123a0565b9b612aac565b9a6142bc565b9b50908a908a9c614319848461461a565b50600101548110614302946142fc946001936142f393614340575b505093505050916142df565b8461434b848461461a565b5001555f614334565b929598509295995092959760048501918254808210614477575b50501561444857906143f77f73f330dd18a8f4760be8fa04b392ba243a76dcbe07487724e846182d63dbfafa97986144139354906143aa6157be565b9050808210156144425750805b600d6143c4828254612ad2565b90556143dc826143d7600e938454612ad2565b6123a0565b9055600f6143eb8282546123a0565b905560038601546123a0565b60058501908155845462ff000019166201000017909455612aba565b815467ffffffffffffffff60401b191690841b67ffffffffffffffff60401b16179055549051908152a2600190565b906143b7565b50815467ffffffffffffffff60401b1916931b67ffffffffffffffff60401b1692909217909155509192915050565b8161448191612ad2565b908355600d614491828254612ad2565b90556144a0600e918254612ad2565b90555f8061436e565b50855467ffffffffffffffff60401b191697901b67ffffffffffffffff60401b1696909617909355909350915050565b919599509396507f5e49965d9b92858198b2c5bab7c3a3fa70fcaf004a265239d97b798b708646ce9792959991506001600160401b0360401b6001600160401b0360401b19918282438a1b169116178555835492871b16911617905554821c169051908152a2600190565b5050865467ffffffffffffffff60401b19169890911b67ffffffffffffffff60401b169790971790945550909350915050565b9350975050935085929691506001600160401b0360401b61459783612aba565b67ffffffffffffffff60401b1990921691851b16178455168381146127c15760010193614243565b50600483015415614284565b8b1c1690505f8061427b565b505093505050505f90565b51908160070b820361036057565b9392916146159060409260018060a01b03168652606060208701526060860190611f38565b930152565b805482101561061c575f52600360205f20910201905f90565b9190601f811161464257505050565b612b19925f5260205f20906020601f840160051c8301931061324457601f0160051c0190612adf565b6001600160401b038111611fe45760051b60200190565b9092919261468f816126c5565b9161469d604051938461202e565b829482845282820111610360576020612b19930190611e38565b9080601f830112156103605781516126c292602001614682565b51906001600160401b038216820361036057565b805182101561061c5760209160051b010190565b6002806007541061420f5761470c615687565b506007545f80805b83811061499e57508115908115614992575b506142085790614735826150b4565b915f94919490819482938390600c54915b8381106148de5750505050159081156148d5575b5080156148cc575b6148c357808210156148bb5750915b66038d7ea4c6800083106148b35761478b61479291611ec8565b5091611ec8565b50916040516354b826f560e01b815230600482015260806024820152602081806147d46147c26084830188611f38565b82810360031901604484015288611f38565b85606483015203815f6108005af15f9181614878575b506147f85750505050505f90565b61486261485494867f2a3f2dce4ae3c46ff8fd3dbcf9cac1ca39da18b59d0ac57b2047d061ec99c1cb97860161482f868254612ad2565b9055810161483e8582546123a0565b9055604051958695608087526080870190611f38565b908582036020870152611f38565b91604084015260070b60608301520390a1600190565b90916020823d82116148ab575b816148926020938361202e565b8101031261335d57506148a4906145e2565b905f6147ea565b3d9150614885565b505050505f90565b905091614771565b50505050505f90565b50828414614762565b9050155f61475a565b60ff60036148eb83611ec8565b5001541615614989576148fd81611ec8565b5061490e83600180930154866128f0565b908c898161491b86611ec8565b50015484119182614969575b505061493e575b505061493990612aac565b614746565b929650985095509361493961496187998c6149588a611ec8565b50015490612ad2565b96905f61492e565b61498191925061497886611ec8565b50015484612ad2565b11898e614927565b61493990612aac565b9050600c54105f614726565b60ff60036149ab83611ec8565b500154166149c2575b6149bd90612aac565b614714565b90916149e46149d96149bd9260016142f386611ec8565b93866142f385611ec8565b9190506149b4565b600254158015614b5b575b61298057614a03615687565b505f80600754905b818110614b1c575050801561420f57614a34600c5491614a2e600b5480946123a0565b906151f6565b909291156142085780614b175750805b80821015614b0f5750905b8115612ca057614a5e90611ec8565b50906040516353266bbb60e01b815260208180614a80858730600485016145f0565b03815f6108005af15f9181614ad4575b50614a9c575050505f90565b15612ca0576002614acc92614ab383600b54612ad2565b600b5501614ac28282546123a0565b9055600c546123a0565b600c55600190565b90916020823d8211614b07575b81614aee6020938361202e565b8101031261335d5750614b0090612b3e565b905f614a90565b3d9150614ae1565b905090614a4f565b614a44565b60ff6003614b2983611ec8565b50015416614b40575b614b3b90612aac565b614a0b565b91614b53614b3b9160016142f386611ec8565b929050614b32565b5066038d7ea4c68000600b54106149f7565b600754158015614cff575b612980576040516370a0823160e01b8082523060048301527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906020908184602481865afa938415613625575f94614cd0575b5063ffffffff6007541660405190632efe8a5f60e01b8252306004830152602482015282816044815f6108015af15f9181614c99575b50614c185750505050505f90565b156148b357819060246040518095819382523060048301525afa908115613625575f91614c6d575b509050818111614c505750505f90565b614c6591614c5d91612ad2565b600b546123a0565b600b55600190565b82813d8311614c92575b614c81818361202e565b8101031261335d575051805f614c40565b503d614c77565b90918482813d8311614cc9575b614cb0818361202e565b8101031261335d5750614cc290612b3e565b905f614c0a565b503d614ca6565b90938282813d8311614cf8575b614ce7818361202e565b8101031261335d575051925f614bd4565b503d614cdd565b50614d08615687565b15614b78565b909291926130f45782519283516001600160401b038111611fe457614d3781613e518554611f00565b6020601f8211600114614da1579181606092600394612b1997985f92614d96575b50508160011b915f1990861b1c19161784555b60208101516001850155604081015160028501550151151591019060ff801983541691151516179055565b015190505f80614d58565b601f19821695845f52815f20965f5b818110614df3575092612b199697600395936001938360609710614ddc575b505050811b018455614d6b565b01515f1983881b60f8161c191690555f8080614dcf565b83830151895560019098019760209384019301614db0565b908015614f8d575f5b600854811015614e8357614e4483612fcc614e31612fbf85611ee4565b6020815191012090602081519101201490565b614e5657614e5190612aac565b614e14565b909150614e6281611ee4565b50906001809201548311614e7557505050565b614e7e90611ee4565b500155565b509060085460ff600a54168110614f4c5750600854915f831561231757600881527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee454600194855b818110614f125750508211614ee05750505050565b61264993614f0c9260405194614ef586611fc9565b855260208501525f60408501526060840152611ee4565b90614d0e565b8287614f1d83611ee4565b50015410614f34575b614f2f90612aac565b614ecb565b9250905084614f4283611ee4565b5001549082614f26565b9160405191614f5a83611fc9565b825260208201525f604082015260016060820152600160401b821015611fe457614f0c826001612b199401600855611ee4565b5050565b90808214614f8d57614fa38154611f00565b906001600160401b038211611fe4578190614fc882614fc28654611f00565b86614633565b5f90601f8311600114614ffc575f92614ff1575b50508160011b915f199060031b1c1916179055565b015490505f80614fdc565b81526020808220858352818320935090601f1985169083905b82821061504e575050908460019594939210615036575b505050811b019055565b01545f1960f88460031b161c191690555f808061502c565b8495819295850154815560018091019601940190615015565b906130f457818103615077575050565b600360ff818461508a612b199686614f91565b600181015460018601556002810154600286015501541691019060ff801983541691151516179055565b600754915f5b83811061519857505f809381938290600c54915b8381106150de5750505050929190565b60ff60036150eb83611ec8565b500154161561518f576150fd81611ec8565b5061510e83600180930154866128f0565b61511783611ec8565b509160028093015466038d7ea4c68000830190818411610608571180615179575b61514e575b50505061514990612aac565b6150ce565b92995089985091955061514991615170916151688a611ec8565b500154612ad2565b96905f8061513d565b5089615189838561516888611ec8565b11615138565b61514990612aac565b60ff60036151a883969596611ec8565b5001541615806151e0575b6151c8576151c090612aac565b9291926150ba565b9250905060026151d783611ec8565b50015460019291565b5060026151ec82611ec8565b50015415156151b3565b90915f809381938291600754925b83811061525a57505050811561521b575b50929190565b5f5b81811061522a5750615215565b60ff600361523783611ec8565b5001541661524d5761524890612aac565b61521d565b6001955093505f92915050565b60ff600361526783611ec8565b50015416156152f15761527981611ec8565b5061528a84600180930154856128f0565b61529383611ec8565b50916002809301548211806152dc575b6152b9575b5050506152b490612aac565b615204565b9299508998509195506152b4916152d3916149588a611ec8565b96905f806152a8565b50896152eb8461497887611ec8565b116152a3565b6152b490612aac565b90602080838303126103605782516001600160401b039384821161036057019260609283858203126103605760409283519585870187811085821117611fe4578552805184811161036057836153519183016146b7565b875281810151848111610360578361536a9183016146b7565b82880152848101519084821161036057019180601f84011215610360578251936153938561466b565b966153a08751988961202e565b858852838801928460c080980287010195818711610360578501935b8685106153d157505050505050505082015290565b878583031261036057885190888201908282108683111761544957899288928c526153fb886145e2565b81526154088389016145e2565b838201528b8801518c82015285880151868201526080615429818a016146d1565b9082015260a061543a818a016145e2565b908201528152019401936153bc565b60245f634e487b7160e01b81526041600452fd5b6001600160a01b0390911681526040602082018190526126c292910190611e59565b6001600160a01b0390911681526040602082018190526126c292910190611f38565b6040805163a03ffee160e01b81525f939290918483806154c585306004840161547f565b03816108005afa8593816155af575b506154e1575b5050508190565b90919293805b8285015180518210156155a057816154fe916146e5565b5160028501546001600160401b036080918181841c1680159283159485615591575b5050508161557e575b81615567575b50811561555f575b5061554e57506155478391612aac565b90506154e7565b606001516001969095509350505050565b90505f615537565b90506020830151600791871c820b910b145f61552f565b9050825160079082820b910b1490615529565b860151161492505f8080615520565b505093925050505f80806154da565b6155c49194503d8088833e61402d818361202e565b925f6154d4565b5f6155eb916040518093819263a03ffee160e01b8352306004840161545d565b03816108005afa5f918161560c575b5061560457505f90565b604001515190565b61562091923d8091833e61402d818361202e565b905f6155fa565b9190916040818403126103605780519260208201516001600160401b03928382116103605701604081830312610360576040519261566484612013565b81519081116103605760209261567b9183016146b7565b83520151602082015290565b5f905f805b600754811015615738576156bf826156a383611ec8565b506040518093819263120bba7360e11b8352306004840161547f565b03816108005afa839181615712575b506156e9575080826002612f926156e494611ec8565b61568c565b6156e49194602061570c92018051600261570289611ec8565b50015551906123a0565b93612aac565b61572f9192503d8086833e615727818361202e565b810190615627565b9050905f6156ce565b505081600c55565b5f905f80600754915b82811061575557505050565b615762826156a383611ec8565b03816108005afa8391816157a0575b50615786575b5061578190612aac565b615749565b61578191956020615799920151906123a0565b9490615777565b6157b59192503d8086833e615727818361202e565b9050905f615771565b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115613625575f91615832575b50615821600b54600f54906123a0565b80821115612ca0576126c291612ad2565b906020823d821161585b575b8161584b6020938361202e565b8101031261335d5750515f615811565b3d915061583e565b60075491905f5b83811061587b57505090505f905f90565b61588e82612fcc614e31612fbf85611ec8565b6158a05761589b90612aac565b61586a565b9250506001919056fe537472696e67733a20686578206c656e67746820696e73756666696369656e74f1190c18d28d5d68156de3ae0f68fd157173bc96def1c9c2fae201841639d0adddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220800b05ff46a6147d3ec02ecf5b96df769de94c6b17f9db608c34d6c952fb8b5b64736f6c63430008140033", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": { - "1500": [ - { - "length": 32, - "start": 5949 - }, + "1303": [ { "length": 32, - "start": 7067 + "start": 4102 }, { "length": 32, - "start": 13379 + "start": 5346 }, { "length": 32, - "start": 16315 + "start": 19346 }, { "length": 32, - "start": 17978 - } - ], - "1502": [ - { - "length": 32, - "start": 8558 - } - ], - "3919": [ - { - "length": 32, - "start": 12304 - } - ], - "3921": [ - { - "length": 32, - "start": 12507 - } - ], - "3923": [ - { - "length": 32, - "start": 12250 - } - ], - "3925": [ - { - "length": 32, - "start": 12383 - } - ], - "3927": [ - { - "length": 32, - "start": 12421 - } - ], - "3930": [ - { - "length": 32, - "start": 2339 + "start": 22489 } ], - "3933": [ + "1305": [ { "length": 32, - "start": 2380 + "start": 6811 } ] }, "inputSourceName": "project/solidity/StakedBondVault.sol", - "buildInfoId": "solc-0_8_20-fd423b4c4179889dc28271432fcc31676a09cfca" + "buildInfoId": "solc-0_8_20-71039e9761b7c4a1eae03c7cf3a8dfe85787de84" } \ No newline at end of file diff --git a/contracts/solidity/StakedBondVault.sol b/contracts/solidity/StakedBondVault.sol index f9759457..cb4d8c03 100644 --- a/contracts/solidity/StakedBondVault.sol +++ b/contracts/solidity/StakedBondVault.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.20; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; @@ -11,7 +10,7 @@ import "@openzeppelin/contracts/utils/math/Math.sol"; import "./precompiles/distribution/DistributionI.sol"; import "./precompiles/staking/StakingI.sol"; -contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard { +contract StakedBondVault is ERC4626, AccessControl, ReentrancyGuard { using Math for uint256; using SafeERC20 for IERC20; @@ -19,13 +18,25 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); address public constant NATIVE_WERC20 = 0xD4949664cD82660AaE99bEdc034a0deA8A0bd517; + uint256 public constant MIN_OPERATION_ASSETS = 1e15; uint256 public constant MAX_VALIDATORS = 32; - uint16 public constant WEIGHT_SCALE = 10_000; + uint256 public constant DEFAULT_TARGET_VALIDATOR_COUNT = 8; + uint256 public constant VALIDATOR_SCAN_PAGE_LIMIT = 32; + uint256 public constant SCORE_SCALE = 1e18; + uint256 public constant MAX_UNBONDING_ENTRIES = 7; + + uint8 private constant STEP_SETTLE = 1; + uint8 private constant STEP_PROCESS = 2; + uint8 private constant STEP_HARVEST = 3; + uint8 private constant STEP_REFRESH_VALIDATORS = 4; + uint8 private constant STEP_REBALANCE = 5; + uint8 private constant STEP_STAKE = 6; struct ValidatorTarget { string operatorAddress; - uint16 weight; + uint256 score; uint256 delegated; + bool selected; } struct WithdrawalRequest { @@ -38,7 +49,9 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard struct UnbondingEntry { string validatorAddress; uint256 expectedAssets; + int64 creationHeight; int64 completionTime; + uint64 unbondingId; } struct WithdrawalBatch { @@ -54,10 +67,16 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard uint256 settledAssets; uint256 claimedAssets; int64 maturityTime; + uint64 firstMatureBlock; UnbondingEntry[] unbondingEntries; } ValidatorTarget[] public validators; + ValidatorTarget[] private validatorScanCandidates; + bytes private validatorScanNextKey; + + uint8 public targetValidatorCount = uint8(DEFAULT_TARGET_VALIDATOR_COUNT); + uint256 public totalIdleLiquid; uint256 public totalDelegated; uint256 public totalWithdrawalUnbonding; uint256 public totalReservedAssets; @@ -74,24 +93,32 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard mapping(uint256 => WithdrawalRequest) public withdrawalRequests; mapping(uint64 => WithdrawalBatch) private withdrawalBatches; - event ValidatorsUpdated(uint256 count); + event ValidatorPolicyUpdated(uint8 targetValidatorCount); + event ValidatorSelectionUpdated(uint256 count); + event ValidatorRebalanced(string srcValidator, string dstValidator, uint256 amount, int64 completionTime); event WithdrawalRequested(uint256 indexed requestId, uint64 indexed batchId, address indexed owner, address receiver, uint256 shares); event WithdrawalBatchProcessed(uint64 indexed batchId, uint256 shares, uint256 estimatedAssets, int64 maturityTime); + event WithdrawalBatchMatured(uint64 indexed batchId, uint64 firstMatureBlock); event WithdrawalBatchSettled(uint64 indexed batchId, uint256 settledAssets); event WithdrawalClaimed(uint256 indexed requestId, uint64 indexed batchId, address indexed receiver, uint256 assets); + event PokeStepFailed(uint8 indexed step, bytes reason); event Poked(address indexed caller, uint256 ops); modifier noNativeValue() { - require(msg.value == 0, "unexpected value"); + require(msg.value == 0, "VALUE"); + _; + } + + modifier onlySelf() { + require(msg.sender == address(this), "SELF"); _; } constructor(address admin, string memory name_, string memory symbol_) ERC20(name_, symbol_) - ERC20Permit(name_) ERC4626(IERC20Metadata(NATIVE_WERC20)) { - require(admin != address(0), "admin zero"); + require(admin != address(0), "ADMIN"); _grantRole(DEFAULT_ADMIN_ROLE, admin); _grantRole(OPERATOR_ROLE, admin); _grantRole(PAUSER_ROLE, admin); @@ -104,11 +131,7 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard if (totalSupply() == 0) { return 0; } - uint256 gross = IERC20(asset()).balanceOf(address(this)) + _liveDelegatedAssets() + totalWithdrawalUnbonding; - if (gross <= totalReservedAssets) { - return 0; - } - return gross - totalReservedAssets; + return totalIdleLiquid + _liveDelegatedAssets(); } function liveDelegatedAssets() external view returns (uint256) { @@ -119,7 +142,7 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard return _syncDelegations(); } - function decimals() public view override(ERC20, ERC4626) returns (uint8) { + function decimals() public view override(ERC4626) returns (uint8) { return ERC4626.decimals(); } @@ -140,46 +163,48 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard } function deposit(uint256, address) public pure override returns (uint256) { - revert("use depositNative"); + revert("DEPOSIT"); } function mint(uint256, address) public pure override returns (uint256) { - revert("use depositNative"); + revert("DEPOSIT"); } function depositNative(address receiver) external payable nonReentrant returns (uint256 shares) { - require(!depositsPaused, "deposits paused"); - require(receiver != address(0), "receiver zero"); - require(msg.value > 0, "zero assets"); + require(!depositsPaused, "D_PAUSED"); + require(receiver != address(0), "RECEIVER"); + require(msg.value >= MIN_OPERATION_ASSETS, "MIN"); _harvest(); uint256 assets = msg.value; uint256 supply = totalSupply(); + uint256 assetsBefore = totalAssets(); if (supply == 0) { shares = assets; } else { - uint256 assetsAfter = totalAssets(); - uint256 assetsBefore = assetsAfter > assets ? assetsAfter - assets : 0; + require(assetsBefore != 0, "INSOLVENT"); shares = assets.mulDiv(supply + 1, assetsBefore + 1, Math.Rounding.Down); } - require(shares > 0, "zero shares"); + require(shares > 0, "SHARES"); + totalIdleLiquid += assets; _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); } function withdraw(uint256, address, address) public pure override returns (uint256) { - revert("use requestRedeem"); + revert("REDEEM"); } function redeem(uint256, address, address) public pure override returns (uint256) { - revert("use requestRedeem"); + revert("REDEEM"); } function requestRedeem(uint256 shares, address receiver, address owner) external payable noNativeValue nonReentrant returns (uint256 requestId) { - require(!withdrawalsPaused, "withdrawals paused"); - require(shares > 0, "zero shares"); - require(receiver != address(0), "receiver zero"); - require(owner != address(0), "owner zero"); + require(!withdrawalsPaused, "W_PAUSED"); + require(shares > 0, "SHARES"); + require(receiver != address(0), "RECEIVER"); + require(owner != address(0), "OWNER"); + require(convertToAssets(shares) >= MIN_OPERATION_ASSETS, "MIN"); if (msg.sender != owner) { _spendAllowance(owner, msg.sender, shares); } @@ -200,12 +225,12 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard function claimRedeem(uint256 requestId, address receiver) external payable noNativeValue nonReentrant returns (uint256 assetsOut) { WithdrawalRequest memory request = withdrawalRequests[requestId]; - require(request.owner != address(0), "unknown request"); + require(request.owner != address(0), "REQUEST"); WithdrawalBatch storage batch = withdrawalBatches[request.batchId]; - require(batch.claimable, "not claimable"); + require(batch.claimable, "CLAIMABLE"); address payout = receiver == address(0) ? request.receiver : receiver; - require(payout == request.receiver, "wrong receiver"); + require(payout == request.receiver, "PAYOUT"); if (batch.claimedCount + 1 == batch.requestCount) { assetsOut = batch.settledAssets - batch.claimedAssets; @@ -226,25 +251,41 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard } function poke(uint256 maxOps) external payable noNativeValue nonReentrant returns (uint256 ops) { - require(!pokePaused, "poke paused"); + require(!pokePaused, "P_PAUSED"); if (maxOps == 0) { return 0; } - if (_settleMatureBatch()) { - ops++; + ops = _tryPokeStep(STEP_SETTLE, maxOps, ops); + ops = _tryPokeStep(STEP_PROCESS, maxOps, ops); + ops = _tryPokeStep(STEP_HARVEST, maxOps, ops); + ops = _tryPokeStep(STEP_REFRESH_VALIDATORS, maxOps, ops); + ops = _tryPokeStep(STEP_REBALANCE, maxOps, ops); + ops = _tryPokeStep(STEP_STAKE, maxOps, ops); + pokeCount++; + lastPokeOps = ops; + emit Poked(msg.sender, ops); + } + + function pokeStep(uint8 step) external onlySelf returns (bool) { + if (step == STEP_SETTLE) { + return _settleMatureBatch(); } - if (ops < maxOps && _processCurrentBatch()) { - ops++; + if (step == STEP_PROCESS) { + return _processCurrentBatch(); } - if (ops < maxOps && _harvest()) { - ops++; + if (step == STEP_HARVEST) { + return _harvest(); } - if (ops < maxOps && _stakeIdle()) { - ops++; + if (step == STEP_REFRESH_VALIDATORS) { + return _refreshValidatorSelection(); } - pokeCount++; - lastPokeOps = ops; - emit Poked(msg.sender, ops); + if (step == STEP_REBALANCE) { + return _rebalanceValidators(); + } + if (step == STEP_STAKE) { + return _stakeIdle(); + } + return false; } function setPaused(bool deposits, bool withdrawals, bool scheduler) external payable noNativeValue onlyRole(PAUSER_ROLE) { @@ -253,31 +294,12 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard pokePaused = scheduler; } - function setValidators(string[] calldata operatorAddresses, uint16[] calldata weights) external payable noNativeValue onlyRole(OPERATOR_ROLE) { - require(operatorAddresses.length == weights.length, "length mismatch"); - require(operatorAddresses.length <= MAX_VALIDATORS, "too many validators"); - - uint256 totalWeight; - uint256 oldDelegated = _syncDelegations(); - delete validators; - for (uint256 i = 0; i < operatorAddresses.length; i++) { - require(bytes(operatorAddresses[i]).length != 0, "empty validator"); - require(weights[i] > 0, "zero weight"); - STAKING_CONTRACT.delegation(address(this), operatorAddresses[i]); - bytes32 operatorHash = keccak256(bytes(operatorAddresses[i])); - for (uint256 j = 0; j < i; j++) { - require(operatorHash != keccak256(bytes(operatorAddresses[j])), "duplicate validator"); - } - totalWeight += weights[i]; - validators.push(ValidatorTarget({ - operatorAddress: operatorAddresses[i], - weight: weights[i], - delegated: 0 - })); - } - require(totalWeight == WEIGHT_SCALE || operatorAddresses.length == 0, "bad weights"); - require(oldDelegated == 0, "delegations active"); - emit ValidatorsUpdated(operatorAddresses.length); + function setValidatorPolicy(uint8 count) external payable noNativeValue onlyRole(OPERATOR_ROLE) { + require(count > 0 && count <= MAX_VALIDATORS, "COUNT"); + targetValidatorCount = count; + delete validatorScanCandidates; + delete validatorScanNextKey; + emit ValidatorPolicyUpdated(count); } function withdrawalBatch(uint64 batchId) @@ -295,7 +317,8 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard uint256 unbondingAssets, uint256 settledAssets, uint256 claimedAssets, - int64 maturityTime + int64 maturityTime, + uint64 firstMatureBlock ) { WithdrawalBatch storage batch = withdrawalBatches[batchId]; @@ -311,7 +334,8 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard batch.unbondingAssets, batch.settledAssets, batch.claimedAssets, - batch.maturityTime + batch.maturityTime, + batch.firstMatureBlock ); } @@ -319,6 +343,28 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard return validators.length; } + function selectedValidatorCount() external view returns (uint256 count) { + for (uint256 i = 0; i < validators.length; i++) { + if (validators[i].selected) { + count++; + } + } + } + + function _tryPokeStep(uint8 step, uint256 maxOps, uint256 ops) private returns (uint256) { + if (ops >= maxOps) { + return ops; + } + try this.pokeStep(step) returns (bool didWork) { + if (didWork) { + return ops + 1; + } + } catch (bytes memory reason) { + emit PokeStepFailed(step, reason); + } + return ops; + } + function _openBatch() internal returns (WithdrawalBatch storage batch) { batch = withdrawalBatches[currentBatchId]; if (!batch.open || batch.processed) { @@ -336,13 +382,17 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard _harvest(); uint256 assetsOut = convertToAssets(batch.totalShares); + if (assetsOut == 0) { + return false; + } batch.open = false; batch.processed = true; batch.estimatedAssets = assetsOut; _burn(address(this), batch.totalShares); - uint256 liquid = _min(_freeLiquid(), assetsOut); + uint256 liquid = _min(totalIdleLiquid, assetsOut); if (liquid != 0) { + totalIdleLiquid -= liquid; totalReservedAssets += liquid; totalLiquidReserved += liquid; batch.liquidAssets = liquid; @@ -376,16 +426,25 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard nextSettlementBatchId = batchId; return false; } + if (batch.firstMatureBlock == 0) { + batch.firstMatureBlock = uint64(block.number); + nextSettlementBatchId = batchId; + emit WithdrawalBatchMatured(batchId, batch.firstMatureBlock); + return true; + } + if (block.number <= batch.firstMatureBlock) { + nextSettlementBatchId = batchId; + return false; + } - uint256 expected = batch.unbondingAssets; - uint256 matured = expected; - uint256 requiredLiquid = totalLiquidReserved + expected; - uint256 balance = IERC20(asset()).balanceOf(address(this)); - if (balance < requiredLiquid) { - uint256 shortfall = requiredLiquid - balance; - matured = expected > shortfall ? expected - shortfall : 0; + bool complete = _syncBatchUnbonding(batch); + if (!complete) { + nextSettlementBatchId = batchId; + return false; } + uint256 expected = batch.unbondingAssets; + uint256 matured = _min(expected, _unaccountedLiquid()); totalWithdrawalUnbonding -= expected; totalReservedAssets = totalReservedAssets - expected + matured; totalLiquidReserved += matured; @@ -399,89 +458,405 @@ contract StakedBondVault is ERC4626, ERC20Permit, AccessControl, ReentrancyGuard } function _undelegateForBatch(WithdrawalBatch storage batch, uint256 assetsNeeded) internal returns (int64 maturity) { - require(validators.length != 0, "no validators"); + require(validators.length != 0, "VALIDATORS"); _syncDelegations(); uint256 remaining = assetsNeeded; for (uint256 i = 0; i < validators.length && remaining != 0; i++) { ValidatorTarget storage target = validators[i]; + if (target.delegated == 0 || _unbondingEntryCount(target.operatorAddress) >= MAX_UNBONDING_ENTRIES) { + continue; + } uint256 amount = _min(target.delegated, remaining); - if (amount == 0) { + try STAKING_CONTRACT.undelegate(address(this), target.operatorAddress, amount) returns (int64 completion) { + target.delegated -= amount; + totalDelegated -= amount; + totalWithdrawalUnbonding += amount; + totalReservedAssets += amount; + batch.unbondingAssets += amount; + batch.unbondingEntries.push(_latestUnbondingEntry(target.operatorAddress, amount, completion)); + if (completion > maturity) { + maturity = completion; + } + remaining -= amount; + } catch { continue; } - int64 completion = STAKING_CONTRACT.undelegate(address(this), target.operatorAddress, amount); - target.delegated -= amount; - totalDelegated -= amount; - totalWithdrawalUnbonding += amount; - totalReservedAssets += amount; - batch.unbondingAssets += amount; - batch.unbondingEntries.push(UnbondingEntry({ - validatorAddress: target.operatorAddress, - expectedAssets: amount, - completionTime: completion - })); - if (completion > maturity) { - maturity = completion; + } + require(remaining == 0, "DELEGATED"); + } + + function _refreshValidatorSelection() internal returns (bool) { + PageRequest memory request = PageRequest({ + key: validatorScanNextKey, + offset: 0, + limit: uint64(VALIDATOR_SCAN_PAGE_LIMIT), + countTotal: false, + reverse: false + }); + (Validator[] memory pageValidators, PageResponse memory page) = STAKING_CONTRACT.validators("BOND_STATUS_BONDED", request); + for (uint256 i = 0; i < pageValidators.length; i++) { + Validator memory validator = pageValidators[i]; + if (validator.jailed || validator.status != BondStatus.Bonded || validator.tokens == 0) { + continue; } - remaining -= amount; + uint256 score = validator.tokens.mulDiv(SCORE_SCALE, SCORE_SCALE + validator.commission, Math.Rounding.Down); + _insertScanCandidate(validator.operatorAddress, score); } - require(remaining == 0, "insufficient delegated assets"); + validatorScanNextKey = page.nextKey; + if (page.nextKey.length == 0) { + _applyValidatorSelection(); + } + return pageValidators.length != 0 || page.nextKey.length == 0; } - function _stakeIdle() internal returns (bool) { - if (totalSupply() == 0) { + function _rebalanceValidators() internal returns (bool) { + if (validators.length < 2) { + return false; + } + _syncDelegations(); + (uint256 totalScore, uint256 selectedDelegated) = _selectedScoreAndDelegation(); + if (totalScore == 0 || selectedDelegated > totalDelegated) { + return false; + } + + (bool hasSource, uint256 sourceIndex, uint256 sourceSurplus) = _rebalanceSource(totalScore); + (bool hasDest, uint256 destIndex, uint256 destDeficit) = _rebalanceDestination(totalScore); + if (!hasSource || !hasDest || sourceIndex == destIndex) { + return false; + } + uint256 amount = _min(sourceSurplus, destDeficit); + if (amount < MIN_OPERATION_ASSETS) { + return false; + } + + ValidatorTarget storage src = validators[sourceIndex]; + ValidatorTarget storage dst = validators[destIndex]; + try STAKING_CONTRACT.redelegate(address(this), src.operatorAddress, dst.operatorAddress, amount) returns (int64 completion) { + src.delegated -= amount; + dst.delegated += amount; + emit ValidatorRebalanced(src.operatorAddress, dst.operatorAddress, amount, completion); + return true; + } catch { return false; } - uint256 free = _freeLiquid(); - if (free == 0 || validators.length == 0) { + } + + function _stakeIdle() internal returns (bool) { + if (totalSupply() == 0 || totalIdleLiquid < MIN_OPERATION_ASSETS) { return false; } _syncDelegations(); - uint256 remaining = free; - for (uint256 i = 0; i < validators.length && remaining != 0; i++) { - uint256 amount = i + 1 == validators.length - ? remaining - : free.mulDiv(validators[i].weight, WEIGHT_SCALE, Math.Rounding.Down); - if (amount == 0) { - continue; + uint256 totalScore; + for (uint256 i = 0; i < validators.length; i++) { + if (validators[i].selected) { + totalScore += validators[i].score; } - bool success = STAKING_CONTRACT.delegate(address(this), validators[i].operatorAddress, amount); - require(success, "delegate failed"); - validators[i].delegated += amount; + } + if (totalScore == 0) { + return false; + } + + (bool ok, uint256 destIndex, uint256 deficit) = _stakeDestination(totalScore, totalDelegated + totalIdleLiquid); + if (!ok) { + return false; + } + uint256 amount = _min(totalIdleLiquid, deficit == 0 ? totalIdleLiquid : deficit); + if (amount == 0) { + return false; + } + ValidatorTarget storage dst = validators[destIndex]; + try STAKING_CONTRACT.delegate(address(this), dst.operatorAddress, amount) returns (bool success) { + if (!success) { + return false; + } + totalIdleLiquid -= amount; + dst.delegated += amount; totalDelegated += amount; - remaining -= amount; + return true; + } catch { + return false; } - return true; } function _harvest() internal returns (bool) { if (validators.length == 0 || _syncDelegations() == 0) { return false; } - return DISTRIBUTION_CONTRACT.claimRewards(address(this), uint32(validators.length)); + uint256 beforeBalance = IERC20(asset()).balanceOf(address(this)); + try DISTRIBUTION_CONTRACT.claimRewards(address(this), uint32(validators.length)) returns (bool success) { + if (!success) { + return false; + } + uint256 afterBalance = IERC20(asset()).balanceOf(address(this)); + if (afterBalance > beforeBalance) { + totalIdleLiquid += afterBalance - beforeBalance; + return true; + } + } catch { + return false; + } + return false; + } + + function _insertScanCandidate(string memory operatorAddress, uint256 score) internal { + if (score == 0) { + return; + } + for (uint256 i = 0; i < validatorScanCandidates.length; i++) { + if (_sameString(validatorScanCandidates[i].operatorAddress, operatorAddress)) { + if (score > validatorScanCandidates[i].score) { + validatorScanCandidates[i].score = score; + } + return; + } + } + if (validatorScanCandidates.length < targetValidatorCount) { + validatorScanCandidates.push(ValidatorTarget({ + operatorAddress: operatorAddress, + score: score, + delegated: 0, + selected: true + })); + return; + } + uint256 minIndex; + uint256 minScore = validatorScanCandidates[0].score; + for (uint256 i = 1; i < validatorScanCandidates.length; i++) { + if (validatorScanCandidates[i].score < minScore) { + minScore = validatorScanCandidates[i].score; + minIndex = i; + } + } + if (score > minScore) { + validatorScanCandidates[minIndex] = ValidatorTarget({ + operatorAddress: operatorAddress, + score: score, + delegated: 0, + selected: true + }); + } + } + + function _applyValidatorSelection() internal { + _syncDelegations(); + for (uint256 i = 0; i < validators.length; i++) { + validators[i].selected = false; + validators[i].score = 0; + } + for (uint256 i = 0; i < validatorScanCandidates.length; i++) { + (bool found, uint256 index) = _findValidator(validatorScanCandidates[i].operatorAddress); + if (found) { + validators[index].selected = true; + validators[index].score = validatorScanCandidates[i].score; + } else if (validators.length < MAX_VALIDATORS) { + validators.push(validatorScanCandidates[i]); + } + } + _pruneUnusedValidators(); + delete validatorScanCandidates; + emit ValidatorSelectionUpdated(_selectedValidatorCount()); + } + + function _selectedScoreAndDelegation() internal view returns (uint256 totalScore, uint256 selectedDelegated) { + for (uint256 i = 0; i < validators.length; i++) { + if (validators[i].selected) { + totalScore += validators[i].score; + selectedDelegated += validators[i].delegated; + } + } + } + + function _rebalanceSource(uint256 totalScore) internal view returns (bool, uint256, uint256) { + for (uint256 i = 0; i < validators.length; i++) { + if (!validators[i].selected && validators[i].delegated != 0) { + return (true, i, validators[i].delegated); + } + } + bool found; + uint256 index; + uint256 surplus; + for (uint256 i = 0; i < validators.length; i++) { + if (!validators[i].selected) { + continue; + } + uint256 target = totalDelegated.mulDiv(validators[i].score, totalScore, Math.Rounding.Down); + if (validators[i].delegated > target + MIN_OPERATION_ASSETS && validators[i].delegated - target > surplus) { + found = true; + index = i; + surplus = validators[i].delegated - target; + } + } + return (found, index, surplus); + } + + function _rebalanceDestination(uint256 totalScore) internal view returns (bool, uint256, uint256) { + bool found; + uint256 index; + uint256 deficit; + for (uint256 i = 0; i < validators.length; i++) { + if (!validators[i].selected) { + continue; + } + uint256 target = totalDelegated.mulDiv(validators[i].score, totalScore, Math.Rounding.Down); + if (target > validators[i].delegated && target - validators[i].delegated > deficit) { + found = true; + index = i; + deficit = target - validators[i].delegated; + } + } + return (found, index, deficit); + } + + function _stakeDestination(uint256 totalScore, uint256 totalAfterStake) internal view returns (bool, uint256, uint256) { + bool found; + uint256 index; + uint256 deficit; + for (uint256 i = 0; i < validators.length; i++) { + if (!validators[i].selected) { + continue; + } + uint256 target = totalAfterStake.mulDiv(validators[i].score, totalScore, Math.Rounding.Down); + if (target > validators[i].delegated && target - validators[i].delegated > deficit) { + found = true; + index = i; + deficit = target - validators[i].delegated; + } + } + if (!found) { + for (uint256 i = 0; i < validators.length; i++) { + if (validators[i].selected) { + return (true, i, 0); + } + } + } + return (found, index, deficit); + } + + function _latestUnbondingEntry(string memory validatorAddress, uint256 amount, int64 completion) internal view returns (UnbondingEntry memory entry) { + entry = UnbondingEntry({ + validatorAddress: validatorAddress, + expectedAssets: amount, + creationHeight: 0, + completionTime: completion, + unbondingId: 0 + }); + try STAKING_CONTRACT.unbondingDelegation(address(this), validatorAddress) returns (UnbondingDelegationOutput memory output) { + for (uint256 i = 0; i < output.entries.length; i++) { + UnbondingDelegationEntry memory candidate = output.entries[i]; + if (candidate.completionTime == completion && candidate.unbondingId >= entry.unbondingId) { + entry.expectedAssets = candidate.balance; + entry.creationHeight = candidate.creationHeight; + entry.unbondingId = candidate.unbondingId; + } + } + } catch {} + } + + function _syncBatchUnbonding(WithdrawalBatch storage batch) internal returns (bool complete) { + complete = true; + uint256 syncedExpected; + for (uint256 i = 0; i < batch.unbondingEntries.length; i++) { + (bool pending, uint256 currentBalance) = _pendingEntryBalance(batch.unbondingEntries[i]); + if (pending) { + complete = false; + if (currentBalance < batch.unbondingEntries[i].expectedAssets) { + batch.unbondingEntries[i].expectedAssets = currentBalance; + } + } + syncedExpected += batch.unbondingEntries[i].expectedAssets; + } + if (syncedExpected < batch.unbondingAssets) { + uint256 reduction = batch.unbondingAssets - syncedExpected; + batch.unbondingAssets = syncedExpected; + totalWithdrawalUnbonding -= reduction; + totalReservedAssets -= reduction; + } + } + + function _pendingEntryBalance(UnbondingEntry storage entry) internal view returns (bool pending, uint256 balance) { + try STAKING_CONTRACT.unbondingDelegation(address(this), entry.validatorAddress) returns (UnbondingDelegationOutput memory output) { + for (uint256 i = 0; i < output.entries.length; i++) { + UnbondingDelegationEntry memory candidate = output.entries[i]; + bool idMatch = entry.unbondingId != 0 && candidate.unbondingId == entry.unbondingId; + bool heightMatch = entry.unbondingId == 0 + && candidate.creationHeight == entry.creationHeight + && candidate.completionTime == entry.completionTime; + if (idMatch || heightMatch) { + return (true, candidate.balance); + } + } + } catch {} + return (false, 0); + } + + function _unbondingEntryCount(string memory validatorAddress) internal view returns (uint256) { + try STAKING_CONTRACT.unbondingDelegation(address(this), validatorAddress) returns (UnbondingDelegationOutput memory output) { + return output.entries.length; + } catch { + return 0; + } } function _syncDelegations() internal returns (uint256 syncedTotal) { for (uint256 i = 0; i < validators.length; i++) { - (, Coin memory balance) = STAKING_CONTRACT.delegation(address(this), validators[i].operatorAddress); - validators[i].delegated = balance.amount; - syncedTotal += balance.amount; + try STAKING_CONTRACT.delegation(address(this), validators[i].operatorAddress) returns (uint256, Coin memory balance) { + validators[i].delegated = balance.amount; + syncedTotal += balance.amount; + } catch { + validators[i].delegated = 0; + } } totalDelegated = syncedTotal; } function _liveDelegatedAssets() internal view returns (uint256 assets_) { for (uint256 i = 0; i < validators.length; i++) { - (, Coin memory balance) = STAKING_CONTRACT.delegation(address(this), validators[i].operatorAddress); - assets_ += balance.amount; + try STAKING_CONTRACT.delegation(address(this), validators[i].operatorAddress) returns (uint256, Coin memory balance) { + assets_ += balance.amount; + } catch {} } } - function _freeLiquid() internal view returns (uint256) { + function _unaccountedLiquid() internal view returns (uint256) { uint256 balance = IERC20(asset()).balanceOf(address(this)); - if (balance <= totalLiquidReserved) { + uint256 accounted = totalIdleLiquid + totalLiquidReserved; + if (balance <= accounted) { return 0; } - return balance - totalLiquidReserved; + return balance - accounted; + } + + function _findValidator(string memory operatorAddress) internal view returns (bool, uint256) { + for (uint256 i = 0; i < validators.length; i++) { + if (_sameString(validators[i].operatorAddress, operatorAddress)) { + return (true, i); + } + } + return (false, 0); + } + + function _pruneUnusedValidators() internal { + uint256 i; + while (i < validators.length) { + if (!validators[i].selected && validators[i].delegated == 0) { + validators[i] = validators[validators.length - 1]; + validators.pop(); + } else { + i++; + } + } + } + + function _selectedValidatorCount() internal view returns (uint256 count) { + for (uint256 i = 0; i < validators.length; i++) { + if (validators[i].selected) { + count++; + } + } + } + + function _sameString(string memory a, string memory b) private pure returns (bool) { + return keccak256(bytes(a)) == keccak256(bytes(b)); } function _min(uint256 a, uint256 b) private pure returns (uint256) { diff --git a/precompiles/staking/types.go b/precompiles/staking/types.go index 7c8baae5..e671da94 100644 --- a/precompiles/staking/types.go +++ b/precompiles/staking/types.go @@ -304,11 +304,13 @@ func NewMsgRedelegate(args []interface{}, denom string, addrCdc address.Codec) ( if !ok { return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidType, "validatorSrcAddress", "string", args[1]) } + validatorSrcAddress = normalizeValidatorAddressString(validatorSrcAddress) validatorDstAddress, ok := args[2].(string) if !ok { return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidType, "validatorDstAddress", "string", args[2]) } + validatorDstAddress = normalizeValidatorAddressString(validatorDstAddress) amount, ok := args[3].(*big.Int) if !ok { @@ -348,6 +350,7 @@ func NewMsgCancelUnbondingDelegation(args []interface{}, denom string, addrCdc a if !ok { return nil, common.Address{}, fmt.Errorf(cmn.ErrInvalidType, "validatorAddress", "string", args[1]) } + validatorAddress = normalizeValidatorAddressString(validatorAddress) amount, ok := args[2].(*big.Int) if !ok { @@ -392,6 +395,7 @@ func NewDelegationRequest(args []interface{}, addrCdc address.Codec) (*stakingty if !ok { return nil, fmt.Errorf(cmn.ErrInvalidType, "validatorAddress", "string", args[1]) } + validatorAddress = normalizeValidatorAddressString(validatorAddress) delegatorAddrStr, err := addrCdc.BytesToString(delegatorAddr.Bytes()) if err != nil { @@ -458,6 +462,7 @@ func NewRedelegationRequest(args []interface{}) (*RedelegationRequest, error) { if !ok { return nil, fmt.Errorf(cmn.ErrInvalidType, "validatorSrcAddress", "string", args[1]) } + validatorSrcAddress = normalizeValidatorAddressString(validatorSrcAddress) validatorSrcAddr, err := sdk.ValAddressFromBech32(validatorSrcAddress) if err != nil { @@ -468,6 +473,7 @@ func NewRedelegationRequest(args []interface{}) (*RedelegationRequest, error) { if !ok { return nil, fmt.Errorf(cmn.ErrInvalidType, "validatorDstAddress", "string", args[2]) } + validatorDstAddress = normalizeValidatorAddressString(validatorDstAddress) validatorDstAddr, err := sdk.ValAddressFromBech32(validatorDstAddress) if err != nil { @@ -519,8 +525,8 @@ func NewRedelegationsRequest(method *abi.Method, args []interface{}, addrCdc add return &stakingtypes.QueryRedelegationsRequest{ DelegatorAddr: delegatorAddr, // bech32 formatted - SrcValidatorAddr: input.SrcValidatorAddress, - DstValidatorAddr: input.DstValidatorAddress, + SrcValidatorAddr: normalizeValidatorAddressString(input.SrcValidatorAddress), + DstValidatorAddr: normalizeValidatorAddressString(input.DstValidatorAddress), Pagination: &input.PageRequest, }, nil } @@ -835,6 +841,7 @@ func NewUnbondingDelegationRequest(args []interface{}, addrCdc address.Codec) (* if !ok { return nil, fmt.Errorf(cmn.ErrInvalidType, "validatorAddress", "string", args[1]) } + validatorAddress = normalizeValidatorAddressString(validatorAddress) delegatorAddrStr, err := addrCdc.BytesToString(delegatorAddr.Bytes()) if err != nil { @@ -861,6 +868,7 @@ func checkDelegationUndelegationArgs(args []interface{}) (common.Address, string if !ok { return common.Address{}, "", nil, fmt.Errorf(cmn.ErrInvalidType, "validatorAddress", "string", args[1]) } + validatorAddress = normalizeValidatorAddressString(validatorAddress) amount, ok := args[2].(*big.Int) if !ok { @@ -870,6 +878,13 @@ func checkDelegationUndelegationArgs(args []interface{}) (common.Address, string return delegatorAddr, validatorAddress, amount, nil } +func normalizeValidatorAddressString(addr string) string { + if common.IsHexAddress(addr) { + return sdk.ValAddress(common.HexToAddress(addr).Bytes()).String() + } + return addr +} + // FormatConsensusPubkey format ConsensusPubkey into a base64 string func FormatConsensusPubkey(consensusPubkey *codectypes.Any) string { ed25519pk, ok := consensusPubkey.GetCachedValue().(cryptotypes.PubKey) diff --git a/tests/integration/x/vm/test_staked_bond_vault.go b/tests/integration/x/vm/test_staked_bond_vault.go index 0ac52a49..3e6f709a 100644 --- a/tests/integration/x/vm/test_staked_bond_vault.go +++ b/tests/integration/x/vm/test_staked_bond_vault.go @@ -16,6 +16,7 @@ import ( cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) var zeroAddress = common.Address{} @@ -44,15 +45,15 @@ func (s *KeeperTestSuite) TestStakedBondVaultLiquidRedeemLifecycle() { requestID := requestOut[0].(*big.Int) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) - s.Require().ErrorContains(err, "not claimable") + s.Require().ErrorContains(err, "CLAIMABLE") s.Require().NoError(s.Network.NextBlock()) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, other) - s.Require().ErrorContains(err, "wrong receiver") + s.Require().ErrorContains(err, "PAYOUT") s.Require().NoError(s.Network.NextBlock()) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "claimRedeem", requestID, zeroAddress) @@ -100,11 +101,11 @@ func (s *KeeperTestSuite) TestStakedBondVaultRejectsInvalidAndPausedActions() { s.Require().Zero(s.vaultBig(vault, "maxMint", owner).Sign()) s.Require().Zero(s.vaultBig(vault, "maxWithdraw", owner).Sign()) s.Require().Zero(s.vaultBig(vault, "maxRedeem", owner).Sign()) - expectVaultError(big.NewInt(0), "depositNative", "zero assets", owner) - expectVaultError(depositAmount, "depositNative", "receiver zero", zeroAddress) + expectVaultError(big.NewInt(0), "depositNative", "MIN", owner) + expectVaultError(depositAmount, "depositNative", "RECEIVER", zeroAddress) _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setPaused", true, false, false) s.Require().NoError(err) - expectVaultError(depositAmount, "depositNative", "deposits paused", owner) + expectVaultError(depositAmount, "depositNative", "D_PAUSED", owner) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setPaused", false, false, false) s.Require().NoError(err) @@ -112,15 +113,15 @@ func (s *KeeperTestSuite) TestStakedBondVaultRejectsInvalidAndPausedActions() { s.Require().NoError(err) expectVaultFailure(nil, "deposit", big.NewInt(0), owner) expectVaultFailure(nil, "mint", big.NewInt(0), owner) - expectVaultError(nil, "withdraw", "use requestRedeem", depositAmount, owner, owner) - expectVaultError(nil, "redeem", "use requestRedeem", depositAmount, owner, owner) - expectVaultError(nil, "requestRedeem", "zero shares", big.NewInt(0), owner, owner) - expectVaultError(nil, "requestRedeem", "receiver zero", depositAmount, zeroAddress, owner) - expectVaultError(nil, "requestRedeem", "owner zero", depositAmount, owner, zeroAddress) + expectVaultError(nil, "withdraw", "REDEEM", depositAmount, owner, owner) + expectVaultError(nil, "redeem", "REDEEM", depositAmount, owner, owner) + expectVaultError(nil, "requestRedeem", "SHARES", big.NewInt(0), owner, owner) + expectVaultError(nil, "requestRedeem", "RECEIVER", depositAmount, zeroAddress, owner) + expectVaultError(nil, "requestRedeem", "OWNER", depositAmount, owner, zeroAddress) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setPaused", false, true, false) s.Require().NoError(err) - expectVaultError(nil, "requestRedeem", "withdrawals paused", depositAmount, owner, owner) - expectVaultError(nil, "claimRedeem", "unknown request", big.NewInt(999), zeroAddress) + expectVaultError(nil, "requestRedeem", "W_PAUSED", depositAmount, owner, owner) + expectVaultError(nil, "claimRedeem", "REQUEST", big.NewInt(999), zeroAddress) } func (s *KeeperTestSuite) TestStakedBondVaultRejectsValueBearingNonNativeCalls() { @@ -151,13 +152,12 @@ func (s *KeeperTestSuite) TestStakedBondVaultRejectsValueBearingNonNativeCalls() expectValueRejected("poke", big.NewInt(1)) expectValueRejected("syncDelegations") expectValueRejected("setPaused", false, false, false) - expectValueRejected("setValidators", []string{}, []uint16{}) + expectValueRejected("setValidatorPolicy", uint8(1)) expectValueRejected("approve", spender, big.NewInt(1)) expectValueRejected("increaseAllowance", spender, big.NewInt(1)) expectValueRejected("decreaseAllowance", spender, big.NewInt(0)) expectValueRejected("transfer", spender, big.NewInt(1)) expectValueRejected("transferFrom", owner, spender, big.NewInt(1)) - expectValueRejected("permit", owner, spender, big.NewInt(0), big.NewInt(0), uint8(27), zeroRole, zeroRole) expectValueRejected("grantRole", zeroRole, spender) expectValueRejected("revokeRole", zeroRole, spender) expectValueRejected("renounceRole", zeroRole, owner) @@ -183,7 +183,6 @@ func (s *KeeperTestSuite) TestStakedBondVaultRejectsUnauthorizedAdminActions() { s.SetupTest() vault := s.deployStakedBondVault() - val := s.Network.GetValidators()[0].OperatorAddress _, err := s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "setPaused", true, true, true) s.Require().Error(err) @@ -192,10 +191,10 @@ func (s *KeeperTestSuite) TestStakedBondVaultRejectsUnauthorizedAdminActions() { s.Require().False(s.vaultBool(vault, "withdrawalsPaused")) s.Require().False(s.vaultBool(vault, "pokePaused")) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "setValidators", []string{val}, []uint16{10_000}) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "setValidatorPolicy", uint8(1)) s.Require().Error(err) s.Require().NoError(s.Network.NextBlock()) - s.Require().Zero(s.vaultBig(vault, "validatorCount").Sign()) + s.Require().Equal(0, big.NewInt(8).Cmp(s.vaultBig(vault, "targetValidatorCount"))) } func (s *KeeperTestSuite) TestStakedBondVaultSetPausedTogglesExactFlags() { @@ -235,10 +234,10 @@ func (s *KeeperTestSuite) TestStakedBondVaultApprovedRedeemClaimPaysFixedReceive s.Require().NoError(err) requestID := requestOut[0].(*big.Int) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, owner) - s.Require().ErrorContains(err, "wrong receiver") + s.Require().ErrorContains(err, "PAYOUT") s.Require().NoError(s.Network.NextBlock()) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "claimRedeem", requestID, zeroAddress) @@ -272,7 +271,7 @@ func (s *KeeperTestSuite) TestStakedBondVaultMultiRequestBatchPaysResidualAndPru s.Require().NoError(err) otherRequestID := requestOut[0].(*big.Int) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "claimRedeem", otherRequestID, zeroAddress) s.Require().NoError(err) @@ -297,7 +296,6 @@ func (s *KeeperTestSuite) TestStakedBondVaultDirectWrappedDonationBeforeFirstDep owner := s.Keyring.GetAddr(1) donation := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) depositAmount := big.NewInt(1e18) - expectedPayout := big.NewInt(0).Add(donation, depositAmount) _, err := s.executeWERC20Tx(s.Keyring.GetPrivKey(0), nil, "transfer", vault, donation) s.Require().NoError(err) @@ -309,39 +307,36 @@ func (s *KeeperTestSuite) TestStakedBondVaultDirectWrappedDonationBeforeFirstDep s.Require().NoError(err) shares := depositOut[0].(*big.Int) s.Require().Equal(0, depositAmount.Cmp(shares)) - s.Require().Equal(0, expectedPayout.Cmp(s.vaultBig(vault, "totalAssets"))) + s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "totalAssets"))) requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "requestRedeem", shares, owner, owner) s.Require().NoError(err) requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) s.Require().NoError(err) requestID := requestOut[0].(*big.Int) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "claimRedeem", requestID, zeroAddress) s.Require().NoError(err) s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) s.Require().Zero(s.vaultBig(vault, "totalAssets").Sign()) - s.Require().True(s.werc20Balance(vault).Cmp(donation) <= 0) + s.Require().Equal(0, donation.Cmp(s.werc20Balance(vault))) } func (s *KeeperTestSuite) TestStakedBondVaultDoesNotStakeOrphanDonationWithoutShares() { s.SetupTest() vault := s.deployStakedBondVault() - val := s.Network.GetValidators()[0].OperatorAddress donation := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) - _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) - s.Require().NoError(err) - _, err = s.executeWERC20Tx(s.Keyring.GetPrivKey(0), nil, "transfer", vault, donation) + _, err := s.executeWERC20Tx(s.Keyring.GetPrivKey(0), nil, "transfer", vault, donation) s.Require().NoError(err) s.Require().Equal(0, donation.Cmp(s.werc20Balance(vault))) s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) s.Require().Zero(s.vaultBig(vault, "totalAssets").Sign()) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) s.Require().Zero(s.vaultBig(vault, "totalDelegated").Sign()) s.Require().Equal(0, donation.Cmp(s.werc20Balance(vault))) @@ -351,162 +346,107 @@ func (s *KeeperTestSuite) TestStakedBondVaultRejectsBadValidatorConfiguration() s.SetupTest() vault := s.deployStakedBondVault() - val := s.Network.GetValidators()[0].OperatorAddress - _, err := s.executeVaultTx( - s.Keyring.GetPrivKey(0), - vault, - nil, - "setValidators", - []string{val, val}, - []uint16{5_000, 5_000}, - ) - s.Require().ErrorContains(err, "duplicate validator") + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidatorPolicy", uint8(0)) + s.Require().ErrorContains(err, "COUNT") s.Require().NoError(s.Network.NextBlock()) - _, err = s.executeVaultTx( - s.Keyring.GetPrivKey(0), - vault, - nil, - "setValidators", - []string{val}, - []uint16{9_999}, - ) - s.Require().ErrorContains(err, "bad weights") - s.Require().NoError(s.Network.NextBlock()) - - _, err = s.executeVaultTx( - s.Keyring.GetPrivKey(0), - vault, - nil, - "setValidators", - []string{val}, - []uint16{}, - ) - s.Require().ErrorContains(err, "length mismatch") - s.Require().NoError(s.Network.NextBlock()) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidatorPolicy", uint8(33)) + s.Require().ErrorContains(err, "COUNT") +} - _, err = s.executeVaultTx( - s.Keyring.GetPrivKey(0), - vault, - nil, - "setValidators", - []string{""}, - []uint16{10_000}, - ) - s.Require().ErrorContains(err, "empty validator") - s.Require().NoError(s.Network.NextBlock()) +func (s *KeeperTestSuite) TestStakedBondVaultSetValidatorPolicyStoresTargetCount() { + s.SetupTest() - _, err = s.executeVaultTx( - s.Keyring.GetPrivKey(0), - vault, - nil, - "setValidators", - []string{val}, - []uint16{0}, - ) - s.Require().ErrorContains(err, "zero weight") - s.Require().NoError(s.Network.NextBlock()) + vault := s.deployStakedBondVault() - operatorAddresses := make([]string, 33) - weights := make([]uint16, 33) - for i := range operatorAddresses { - operatorAddresses[i] = val - weights[i] = 1 - } - _, err = s.executeVaultTx( - s.Keyring.GetPrivKey(0), - vault, - nil, - "setValidators", - operatorAddresses, - weights, - ) - s.Require().ErrorContains(err, "too many validators") + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidatorPolicy", uint8(1)) + s.Require().NoError(err) + s.Require().Equal(0, big.NewInt(1).Cmp(s.vaultBig(vault, "targetValidatorCount"))) + s.Require().Zero(s.vaultBig(vault, "validatorCount").Sign()) } -func (s *KeeperTestSuite) TestStakedBondVaultSetValidatorsStoresExactConfig() { +func (s *KeeperTestSuite) TestStakedBondVaultPokeAutoSelectsBondedValidators() { s.SetupTest() vault := s.deployStakedBondVault() - val := s.Network.GetValidators()[0].OperatorAddress - - _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) - s.Require().NoError(err) - s.Require().Equal(0, big.NewInt(1).Cmp(s.vaultBig(vault, "validatorCount"))) - res, err := s.callVaultWithData(vault, "validators", false, big.NewInt(0)) + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidatorPolicy", uint8(3)) s.Require().NoError(err) - out, err := contracts.StakedBondVaultContract.ABI.Unpack("validators", res.Ret) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) - s.Require().Equal(val, out[0].(string)) - s.Require().Equal(uint16(10_000), out[1].(uint16)) - s.Require().Zero(out[2].(*big.Int).Sign()) + s.Require().Equal(0, big.NewInt(3).Cmp(s.vaultBig(vault, "selectedValidatorCount"))) + s.Require().Equal(0, big.NewInt(3).Cmp(s.vaultBig(vault, "validatorCount"))) + + for i := int64(0); i < 3; i++ { + res, err := s.callVaultWithData(vault, "validators", false, big.NewInt(i)) + s.Require().NoError(err) + out, err := contracts.StakedBondVaultContract.ABI.Unpack("validators", res.Ret) + s.Require().NoError(err) + s.Require().NotEmpty(out[0].(string)) + s.Require().Positive(out[1].(*big.Int).Sign()) + s.Require().Zero(out[2].(*big.Int).Sign()) + s.Require().True(out[3].(bool)) + } } -func (s *KeeperTestSuite) TestStakedBondVaultStakeIdleSplitsAcrossValidatorsWithRemainder() { +func (s *KeeperTestSuite) TestStakedBondVaultStakeIdleAcrossAutomaticallySelectedValidators() { s.SetupTest() vault := s.deployStakedBondVault() - vals := s.Network.GetValidators() owner := s.Keyring.GetAddr(0) depositAmount := big.NewInt(0).Mul(big.NewInt(10_001), big.NewInt(1e18)) - operatorAddresses := []string{ - vals[0].OperatorAddress, - vals[1].OperatorAddress, - vals[2].OperatorAddress, - } - weights := []uint16{3_333, 3_333, 3_334} - expectedFirst := big.NewInt(0).Div(big.NewInt(0).Mul(depositAmount, big.NewInt(3_333)), big.NewInt(10_000)) - expectedSecond := big.NewInt(0).Set(expectedFirst) - expectedThird := big.NewInt(0).Sub(big.NewInt(0).Sub(depositAmount, expectedFirst), expectedSecond) - _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", operatorAddresses, weights) + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidatorPolicy", uint8(3)) s.Require().NoError(err) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) + s.stakeVaultIdle(vault, depositAmount) - for i, expected := range []*big.Int{expectedFirst, expectedSecond, expectedThird} { + delegatedAcrossSelected := big.NewInt(0) + for i := int64(0); i < 3; i++ { res, err := s.callVaultWithData(vault, "validators", false, big.NewInt(int64(i))) s.Require().NoError(err) out, err := contracts.StakedBondVaultContract.ABI.Unpack("validators", res.Ret) s.Require().NoError(err) - s.Require().Equal(operatorAddresses[i], out[0].(string)) - s.Require().Equal(weights[i], out[1].(uint16)) - s.Require().Equal(0, expected.Cmp(out[2].(*big.Int))) + s.Require().NotEmpty(out[0].(string)) + s.Require().Positive(out[1].(*big.Int).Sign()) + s.Require().Positive(out[2].(*big.Int).Sign()) + s.Require().True(out[3].(bool)) + delegatedAcrossSelected.Add(delegatedAcrossSelected, out[2].(*big.Int)) } - s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + s.requireVaultDelegatedClose(vault, depositAmount) + s.Require().Equal(0, depositAmount.Cmp(delegatedAcrossSelected)) } -func (s *KeeperTestSuite) TestStakedBondVaultStakesAndBlocksValidatorUpdatesWhileDelegated() { +func (s *KeeperTestSuite) TestStakedBondVaultCanUpdateValidatorPolicyWhileDelegated() { s.SetupTest() vault := s.deployStakedBondVault() - val := s.Network.GetValidators()[0].OperatorAddress depositAmount := big.NewInt(0).Mul(big.NewInt(3), big.NewInt(1e18)) - _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidatorPolicy", uint8(3)) s.Require().NoError(err) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", s.Keyring.GetAddr(0)) s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) + s.stakeVaultIdle(vault, depositAmount) delegated := s.vaultBig(vault, "totalDelegated") s.Require().Positive(delegated.Sign()) s.Require().Equal(0, delegated.Cmp(s.vaultBig(vault, "liveDelegatedAssets"))) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{}, []uint16{}) - s.Require().ErrorContains(err, "delegations active") + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidatorPolicy", uint8(1)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) + s.Require().NoError(err) + s.Require().Equal(0, big.NewInt(1).Cmp(s.vaultBig(vault, "selectedValidatorCount"))) + s.Require().Equal(0, delegated.Cmp(s.vaultBig(vault, "totalDelegated"))) } func (s *KeeperTestSuite) TestStakedBondVaultPokeRecordsBoundedWork() { s.SetupTest() vault := s.deployStakedBondVault() - val := s.Network.GetValidators()[0].OperatorAddress depositAmount := big.NewInt(1e18) res, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(0)) @@ -520,13 +460,11 @@ func (s *KeeperTestSuite) TestStakedBondVaultPokeRecordsBoundedWork() { _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setPaused", false, false, true) s.Require().NoError(err) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(1)) - s.Require().ErrorContains(err, "poke paused") + s.Require().ErrorContains(err, "P_PAUSED") s.Require().NoError(s.Network.NextBlock()) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setPaused", false, false, false) s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) - s.Require().NoError(err) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", s.Keyring.GetAddr(0)) s.Require().NoError(err) @@ -537,24 +475,21 @@ func (s *KeeperTestSuite) TestStakedBondVaultPokeRecordsBoundedWork() { s.Require().Equal(0, big.NewInt(1).Cmp(out[0].(*big.Int))) s.Require().Equal(0, big.NewInt(1).Cmp(s.vaultBig(vault, "pokeCount"))) s.Require().Equal(0, big.NewInt(1).Cmp(s.vaultBig(vault, "lastPokeOps"))) - s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + s.Require().Positive(s.vaultBig(vault, "selectedValidatorCount").Sign()) + s.stakeVaultIdle(vault, depositAmount) } func (s *KeeperTestSuite) TestStakedBondVaultStakedRedeemLifecycle() { s.SetupTest() vault := s.deployStakedBondVault() - val := s.Network.GetValidators()[0].OperatorAddress owner := s.Keyring.GetAddr(0) depositAmount := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) - _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) - s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) - s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) s.Require().NoError(err) - s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + s.stakeVaultIdle(vault, depositAmount) + s.requireVaultDelegatedClose(vault, depositAmount) requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "requestRedeem", depositAmount, owner, owner) s.Require().NoError(err) @@ -562,26 +497,19 @@ func (s *KeeperTestSuite) TestStakedBondVaultStakedRedeemLifecycle() { s.Require().NoError(err) requestID := requestOut[0].(*big.Int) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) - s.Require().Equal(0, depositAmount.Cmp(s.vaultBig(vault, "totalWithdrawalUnbonding"))) + s.requireVaultUnbondingClose(vault, depositAmount) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) - s.Require().ErrorContains(err, "not claimable") + s.Require().ErrorContains(err, "CLAIMABLE") s.Require().NoError(s.Network.NextBlock()) - maturity := s.vaultBatchMaturity(vault, 1) - wait := time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second - if wait > 0 { - s.Require().NoError(s.Network.NextBlockAfter(wait)) - } - - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) + s.waitAndSettleVaultBatch(vault, 1) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) s.Require().NoError(err) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) - s.Require().ErrorContains(err, "unknown request") + s.Require().ErrorContains(err, "REQUEST") s.Require().NoError(s.Network.NextBlock()) s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) @@ -593,19 +521,15 @@ func (s *KeeperTestSuite) TestStakedBondVaultMixedLiquidAndStakedRedeemLifecycle s.SetupTest() vault := s.deployStakedBondVault() - val := s.Network.GetValidators()[0].OperatorAddress owner := s.Keyring.GetAddr(0) stakedAmount := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) liquidAmount := big.NewInt(1e18) totalAmount := big.NewInt(0).Add(stakedAmount, liquidAmount) - _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) - s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, stakedAmount, "depositNative", owner) + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, stakedAmount, "depositNative", owner) s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) - s.Require().Equal(0, stakedAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + s.stakeVaultIdle(vault, stakedAmount) + s.requireVaultDelegatedClose(vault, stakedAmount) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, liquidAmount, "depositNative", owner) s.Require().NoError(err) @@ -615,23 +539,16 @@ func (s *KeeperTestSuite) TestStakedBondVaultMixedLiquidAndStakedRedeemLifecycle s.Require().NoError(err) requestID := requestOut[0].(*big.Int) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) - s.Require().Equal(0, stakedAmount.Cmp(s.vaultBig(vault, "totalWithdrawalUnbonding"))) + s.requireVaultUnbondingClose(vault, stakedAmount) s.Require().Zero(s.vaultBig(vault, "totalDelegated").Sign()) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) - s.Require().ErrorContains(err, "not claimable") + s.Require().ErrorContains(err, "CLAIMABLE") s.Require().NoError(s.Network.NextBlock()) - maturity := s.vaultBatchMaturity(vault, 1) - wait := time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second - if wait > 0 { - s.Require().NoError(s.Network.NextBlockAfter(wait)) - } - - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) + s.waitAndSettleVaultBatch(vault, 1) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) s.Require().NoError(err) @@ -644,28 +561,24 @@ func (s *KeeperTestSuite) TestStakedBondVaultPendingUnbondingDoesNotSkipSettleme s.SetupTest() vault := s.deployStakedBondVault() - val := s.Network.GetValidators()[0].OperatorAddress owner := s.Keyring.GetAddr(0) other := s.Keyring.GetAddr(1) stakedAmount := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) liquidAmount := big.NewInt(1e18) - _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) - s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, stakedAmount, "depositNative", owner) + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, stakedAmount, "depositNative", owner) s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) - s.Require().Equal(0, stakedAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + s.stakeVaultIdle(vault, stakedAmount) + s.requireVaultDelegatedClose(vault, stakedAmount) requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "requestRedeem", stakedAmount, owner, owner) s.Require().NoError(err) requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) s.Require().NoError(err) stakedRequestID := requestOut[0].(*big.Int) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) - s.Require().Equal(0, stakedAmount.Cmp(s.vaultBig(vault, "totalWithdrawalUnbonding"))) + s.requireVaultUnbondingClose(vault, stakedAmount) s.Require().Equal(0, big.NewInt(1).Cmp(s.vaultBig(vault, "nextSettlementBatchId"))) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, liquidAmount, "depositNative", other) @@ -675,23 +588,16 @@ func (s *KeeperTestSuite) TestStakedBondVaultPendingUnbondingDoesNotSkipSettleme requestOut, err = contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) s.Require().NoError(err) liquidRequestID := requestOut[0].(*big.Int) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) s.Require().Equal(0, big.NewInt(1).Cmp(s.vaultBig(vault, "nextSettlementBatchId"))) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "claimRedeem", liquidRequestID, zeroAddress) s.Require().NoError(err) - maturity := s.vaultBatchMaturity(vault, 1) - wait := time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second - if wait > 0 { - s.Require().NoError(s.Network.NextBlockAfter(wait)) - } - - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) + s.waitAndSettleVaultBatch(vault, 1) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", stakedRequestID, zeroAddress) s.Require().NoError(err) s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) @@ -702,49 +608,36 @@ func (s *KeeperTestSuite) TestStakedBondVaultDepositDuringPendingUnbondingCanSta s.SetupTest() vault := s.deployStakedBondVault() - val := s.Network.GetValidators()[0].OperatorAddress owner := s.Keyring.GetAddr(0) other := s.Keyring.GetAddr(1) ownerAmount := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e18)) otherAmount := big.NewInt(1e18) - _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{val}, []uint16{10_000}) - s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, ownerAmount, "depositNative", owner) - s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, ownerAmount, "depositNative", owner) s.Require().NoError(err) - s.Require().Equal(0, ownerAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + s.stakeVaultIdle(vault, ownerAmount) + s.requireVaultDelegatedClose(vault, ownerAmount) requestRes, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "requestRedeem", ownerAmount, owner, owner) s.Require().NoError(err) requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) s.Require().NoError(err) ownerRequestID := requestOut[0].(*big.Int) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) - s.Require().Equal(0, ownerAmount.Cmp(s.vaultBig(vault, "totalWithdrawalUnbonding"))) + s.requireVaultUnbondingClose(vault, ownerAmount) s.Require().Zero(s.vaultBig(vault, "totalDelegated").Sign()) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, otherAmount, "depositNative", other) s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) - s.Require().Equal(0, otherAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) - s.Require().Equal(0, ownerAmount.Cmp(s.vaultBig(vault, "totalWithdrawalUnbonding"))) + s.stakeVaultIdle(vault, otherAmount) + s.requireVaultUnbondingClose(vault, ownerAmount) - maturity := s.vaultBatchMaturity(vault, 1) - wait := time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second - if wait > 0 { - s.Require().NoError(s.Network.NextBlockAfter(wait)) - } - - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) + s.waitAndSettleVaultBatch(vault, 1) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", ownerRequestID, zeroAddress) s.Require().NoError(err) s.Require().Zero(s.vaultBig(vault, "totalWithdrawalUnbonding").Sign()) - s.Require().Equal(0, otherAmount.Cmp(s.vaultBig(vault, "totalDelegated"))) + s.requireVaultDelegatedClose(vault, otherAmount) otherShares := s.vaultBig(vault, "balanceOf", other) requestRes, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "requestRedeem", otherShares, other, other) @@ -752,37 +645,54 @@ func (s *KeeperTestSuite) TestStakedBondVaultDepositDuringPendingUnbondingCanSta requestOut, err = contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) s.Require().NoError(err) otherRequestID := requestOut[0].(*big.Int) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) - maturity = s.vaultBatchMaturity(vault, 2) - wait = time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second - if wait > 0 { - s.Require().NoError(s.Network.NextBlockAfter(wait)) - } - - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) + s.waitAndSettleVaultBatch(vault, 2) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(1), vault, nil, "claimRedeem", otherRequestID, zeroAddress) s.Require().NoError(err) s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) s.Require().Zero(s.vaultBig(vault, "totalWithdrawalUnbonding").Sign()) } +func (s *KeeperTestSuite) TestStakedBondVaultSkipsValidatorAtUnbondingEntryCap() { + s.SetupTest() + + vault := s.deployStakedBondVault() + owner := s.Keyring.GetAddr(0) + depositAmount := big.NewInt(0).Mul(big.NewInt(5), big.NewInt(1e18)) + requestShares := big.NewInt(0).Mul(big.NewInt(2), big.NewInt(1e15)) + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidatorPolicy", uint8(2)) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) + s.Require().NoError(err) + s.stakeVaultIdle(vault, depositAmount) + + for i := 0; i < 8; i++ { + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "requestRedeem", requestShares, owner, owner) + s.Require().NoError(err) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) + s.Require().NoError(err) + } + + expectedUnbonding := big.NewInt(0).Mul(requestShares, big.NewInt(8)) + s.requireVaultUnbondingClose(vault, expectedUnbonding) +} + func (s *KeeperTestSuite) TestStakedBondVaultSlashedStakeCanRedeemRemainingAssets() { s.SetupTest() vault := s.deployStakedBondVault() - validator := s.Network.GetValidators()[0] owner := s.Keyring.GetAddr(0) depositAmount := big.NewInt(0).Mul(big.NewInt(3), big.NewInt(1e18)) - _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{validator.OperatorAddress}, []uint16{10_000}) + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidatorPolicy", uint8(1)) s.Require().NoError(err) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", owner) s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) + s.stakeVaultIdle(vault, depositAmount) + validator := s.selectedVaultSDKValidator(vault) beforeSlash := s.vaultBig(vault, "liveDelegatedAssets") s.Require().Positive(beforeSlash.Sign()) @@ -807,20 +717,13 @@ func (s *KeeperTestSuite) TestStakedBondVaultSlashedStakeCanRedeemRemainingAsset requestOut, err := contracts.StakedBondVaultContract.ABI.Unpack("requestRedeem", requestRes.Ret) s.Require().NoError(err) requestID := requestOut[0].(*big.Int) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) s.Require().NoError(err) unbonding := s.vaultBig(vault, "totalWithdrawalUnbonding") s.Require().Positive(unbonding.Sign()) s.Require().True(unbonding.Cmp(depositAmount) <= 0) - maturity := s.vaultBatchMaturity(vault, 1) - wait := time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second - if wait > 0 { - s.Require().NoError(s.Network.NextBlockAfter(wait)) - } - - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) + s.waitAndSettleVaultBatch(vault, 1) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "claimRedeem", requestID, zeroAddress) s.Require().NoError(err) s.Require().Zero(s.vaultBig(vault, "totalSupply").Sign()) @@ -832,15 +735,14 @@ func (s *KeeperTestSuite) TestStakedBondVaultSlashSyncUpdatesCachedDelegations() s.SetupTest() vault := s.deployStakedBondVault() - validator := s.Network.GetValidators()[0] depositAmount := big.NewInt(0).Mul(big.NewInt(3), big.NewInt(1e18)) - _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidators", []string{validator.OperatorAddress}, []uint16{10_000}) + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "setValidatorPolicy", uint8(1)) s.Require().NoError(err) _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, depositAmount, "depositNative", s.Keyring.GetAddr(0)) s.Require().NoError(err) - _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(4)) - s.Require().NoError(err) + s.stakeVaultIdle(vault, depositAmount) + validator := s.selectedVaultSDKValidator(vault) before := s.vaultBig(vault, "liveDelegatedAssets") s.Require().Positive(before.Sign()) @@ -866,6 +768,59 @@ func (s *KeeperTestSuite) TestStakedBondVaultSlashSyncUpdatesCachedDelegations() s.Require().Equal(0, after.Cmp(s.vaultBig(vault, "totalDelegated"))) } +func (s *KeeperTestSuite) stakeVaultIdle(vault common.Address, expectedDelegated *big.Int) { + for i := 0; i < 24 && s.vaultBig(vault, "totalDelegated").Cmp(expectedDelegated) < 0; i++ { + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) + s.Require().NoError(err) + } + s.requireVaultDelegatedClose(vault, expectedDelegated) +} + +func (s *KeeperTestSuite) requireVaultDelegatedClose(vault common.Address, expectedDelegated *big.Int) { + delegated := s.vaultBig(vault, "totalDelegated") + idle := s.vaultBig(vault, "totalIdleLiquid") + s.Require().True(delegated.Cmp(expectedDelegated) <= 0) + dust := big.NewInt(0).Sub(expectedDelegated, delegated) + s.Require().True(dust.Cmp(big.NewInt(1e15)) < 0, "delegation dust %s exceeds minimum operation size", dust.String()) + s.Require().Equal(0, dust.Cmp(idle)) +} + +func (s *KeeperTestSuite) requireVaultUnbondingClose(vault common.Address, expectedUnbonding *big.Int) { + unbonding := s.vaultBig(vault, "totalWithdrawalUnbonding") + s.Require().True(unbonding.Cmp(expectedUnbonding) <= 0) + dust := big.NewInt(0).Sub(expectedUnbonding, unbonding) + s.Require().True(dust.Cmp(big.NewInt(1e15)) < 0, "unbonding dust %s exceeds minimum operation size", dust.String()) +} + +func (s *KeeperTestSuite) waitAndSettleVaultBatch(vault common.Address, batchID uint64) { + maturity := s.vaultBatchMaturity(vault, batchID) + wait := time.Unix(maturity, 0).Sub(s.Network.GetContext().BlockTime()) + time.Second + if wait > 0 { + s.Require().NoError(s.Network.NextBlockAfter(wait)) + } + + _, err := s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) + s.Require().NoError(err) + s.Require().NoError(s.Network.NextBlock()) + _, err = s.executeVaultTx(s.Keyring.GetPrivKey(0), vault, nil, "poke", big.NewInt(6)) + s.Require().NoError(err) +} + +func (s *KeeperTestSuite) selectedVaultSDKValidator(vault common.Address) stakingtypes.Validator { + res, err := s.callVaultWithData(vault, "validators", false, big.NewInt(0)) + s.Require().NoError(err) + out, err := contracts.StakedBondVaultContract.ABI.Unpack("validators", res.Ret) + s.Require().NoError(err) + operatorAddress := sdk.ValAddress(common.HexToAddress(out[0].(string)).Bytes()).String() + for _, validator := range s.Network.GetValidators() { + if validator.OperatorAddress == operatorAddress { + return validator + } + } + s.T().Fatalf("selected validator %s not found", operatorAddress) + return stakingtypes.Validator{} +} + func (s *KeeperTestSuite) deployStakedBondVault() common.Address { admin := s.Keyring.GetAddr(0) vault, err := s.Factory.DeployContract( @@ -976,6 +931,8 @@ func (s *KeeperTestSuite) vaultBig(vault common.Address, method string, args ... return value case uint64: return new(big.Int).SetUint64(value) + case uint8: + return big.NewInt(int64(value)) default: s.T().Fatalf("unexpected numeric type %T", value) return nil From 0851f3e16687f7ce57cb72e57e7689b680182738 Mon Sep 17 00:00:00 2001 From: Rahul Ghangas Date: Fri, 5 Jun 2026 10:17:29 +0000 Subject: [PATCH 5/5] fix: scheduler panic on params shouldn't cause consensus halt --- tests/integration/x/vm/test_scheduler.go | 28 ++++++++++++++++++++++++ x/vm/keeper/scheduler.go | 15 ++++++++----- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/tests/integration/x/vm/test_scheduler.go b/tests/integration/x/vm/test_scheduler.go index 4e6a36d7..61237ce4 100644 --- a/tests/integration/x/vm/test_scheduler.go +++ b/tests/integration/x/vm/test_scheduler.go @@ -2,6 +2,7 @@ package vm import ( "math/big" + "strings" "github.com/cosmos/evm/contracts" testcontracts "github.com/cosmos/evm/precompiles/testutil/contracts" @@ -91,3 +92,30 @@ func (s *KeeperTestSuite) TestEVMSchedulerRevertDoesNotHaltBlock() { s.Require().NoError(err) s.Require().Equal(0, big.NewInt(0).Cmp(out[0].(*big.Int))) } + +func (s *KeeperTestSuite) TestEVMSchedulerCorruptParamsDoNotHaltBlock() { + s.SetupTest() + + ctx := s.Network.GetContext() + store := ctx.KVStore(s.Network.App.GetKey(evmtypes.StoreKey)) + store.Set(evmtypes.KeyPrefixParams, []byte{0xff}) + + s.Require().NotPanics(func() { + s.Network.App.GetEVMKeeper().RunScheduler(ctx) + }) + + attrs := map[string]string{} + for _, event := range ctx.EventManager().Events() { + if event.Type != "evm_scheduler" { + continue + } + for _, attr := range event.Attributes { + attrs[attr.Key] = attr.Value + } + } + + s.Require().Equal("", attrs["target_contract"]) + s.Require().Equal("false", attrs["success"]) + s.Require().Equal("0", attrs["gas_used"]) + s.Require().True(strings.Contains(attrs["error"], "panic"), "events: %v", ctx.EventManager().Events()) +} diff --git a/x/vm/keeper/scheduler.go b/x/vm/keeper/scheduler.go index 7205c5ab..9958dd7b 100644 --- a/x/vm/keeper/scheduler.go +++ b/x/vm/keeper/scheduler.go @@ -36,18 +36,21 @@ func shouldRunScheduler(ctx sdk.Context, params types.EVMSchedulerParams) bool { // RunScheduler performs the configured bounded EndBlock EVM call. It never // returns an error because scheduler failures must not halt consensus. func (k Keeper) RunScheduler(ctx sdk.Context) { - params := k.GetParams(ctx).Scheduler - if !shouldRunScheduler(ctx, params) { - return - } + targetContract := "" defer func() { if r := recover(); r != nil { errText := fmt.Sprintf("panic: %v", r) - k.Logger(ctx).Error("evm scheduler panicked", "target", params.TargetContract, "err", errText) - k.emitSchedulerEvent(ctx, params.TargetContract, false, 0, "", errText) + k.Logger(ctx).Error("evm scheduler panicked", "target", targetContract, "err", errText) + k.emitSchedulerEvent(ctx, targetContract, false, 0, "", errText) } }() + params := k.GetParams(ctx).Scheduler + targetContract = params.TargetContract + if !shouldRunScheduler(ctx, params) { + return + } + moduleAddr := k.accountKeeper.GetModuleAddress(types.ModuleName) if moduleAddr == nil { k.emitSchedulerEvent(ctx, params.TargetContract, false, 0, "", "evm module account not found")