diff --git a/abi-bindings/go/INativeMinter/INativeMinter.go b/abi-bindings/go/INativeMinter/INativeMinter.go new file mode 100644 index 000000000..308b401a0 --- /dev/null +++ b/abi-bindings/go/INativeMinter/INativeMinter.go @@ -0,0 +1,634 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package inativeminter + +import ( + "errors" + "math/big" + "strings" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = interfaces.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// INativeMinterMetaData contains all meta data concerning the INativeMinter contract. +var INativeMinterMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"function\",\"name\":\"mintNativeCoin\",\"inputs\":[{\"name\":\"addr\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"readAllowList\",\"inputs\":[{\"name\":\"addr\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"role\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"setAdmin\",\"inputs\":[{\"name\":\"addr\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setEnabled\",\"inputs\":[{\"name\":\"addr\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setManager\",\"inputs\":[{\"name\":\"addr\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setNone\",\"inputs\":[{\"name\":\"addr\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"NativeCoinMinted\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"recipient\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RoleSet\",\"inputs\":[{\"name\":\"role\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"account\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"sender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"oldRole\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]", +} + +// INativeMinterABI is the input ABI used to generate the binding from. +// Deprecated: Use INativeMinterMetaData.ABI instead. +var INativeMinterABI = INativeMinterMetaData.ABI + +// INativeMinter is an auto generated Go binding around an Ethereum contract. +type INativeMinter struct { + INativeMinterCaller // Read-only binding to the contract + INativeMinterTransactor // Write-only binding to the contract + INativeMinterFilterer // Log filterer for contract events +} + +// INativeMinterCaller is an auto generated read-only Go binding around an Ethereum contract. +type INativeMinterCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// INativeMinterTransactor is an auto generated write-only Go binding around an Ethereum contract. +type INativeMinterTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// INativeMinterFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type INativeMinterFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// INativeMinterSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type INativeMinterSession struct { + Contract *INativeMinter // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// INativeMinterCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type INativeMinterCallerSession struct { + Contract *INativeMinterCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// INativeMinterTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type INativeMinterTransactorSession struct { + Contract *INativeMinterTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// INativeMinterRaw is an auto generated low-level Go binding around an Ethereum contract. +type INativeMinterRaw struct { + Contract *INativeMinter // Generic contract binding to access the raw methods on +} + +// INativeMinterCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type INativeMinterCallerRaw struct { + Contract *INativeMinterCaller // Generic read-only contract binding to access the raw methods on +} + +// INativeMinterTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type INativeMinterTransactorRaw struct { + Contract *INativeMinterTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewINativeMinter creates a new instance of INativeMinter, bound to a specific deployed contract. +func NewINativeMinter(address common.Address, backend bind.ContractBackend) (*INativeMinter, error) { + contract, err := bindINativeMinter(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &INativeMinter{INativeMinterCaller: INativeMinterCaller{contract: contract}, INativeMinterTransactor: INativeMinterTransactor{contract: contract}, INativeMinterFilterer: INativeMinterFilterer{contract: contract}}, nil +} + +// NewINativeMinterCaller creates a new read-only instance of INativeMinter, bound to a specific deployed contract. +func NewINativeMinterCaller(address common.Address, caller bind.ContractCaller) (*INativeMinterCaller, error) { + contract, err := bindINativeMinter(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &INativeMinterCaller{contract: contract}, nil +} + +// NewINativeMinterTransactor creates a new write-only instance of INativeMinter, bound to a specific deployed contract. +func NewINativeMinterTransactor(address common.Address, transactor bind.ContractTransactor) (*INativeMinterTransactor, error) { + contract, err := bindINativeMinter(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &INativeMinterTransactor{contract: contract}, nil +} + +// NewINativeMinterFilterer creates a new log filterer instance of INativeMinter, bound to a specific deployed contract. +func NewINativeMinterFilterer(address common.Address, filterer bind.ContractFilterer) (*INativeMinterFilterer, error) { + contract, err := bindINativeMinter(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &INativeMinterFilterer{contract: contract}, nil +} + +// bindINativeMinter binds a generic wrapper to an already deployed contract. +func bindINativeMinter(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := INativeMinterMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_INativeMinter *INativeMinterRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _INativeMinter.Contract.INativeMinterCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_INativeMinter *INativeMinterRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _INativeMinter.Contract.INativeMinterTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_INativeMinter *INativeMinterRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _INativeMinter.Contract.INativeMinterTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_INativeMinter *INativeMinterCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _INativeMinter.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_INativeMinter *INativeMinterTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _INativeMinter.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_INativeMinter *INativeMinterTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _INativeMinter.Contract.contract.Transact(opts, method, params...) +} + +// ReadAllowList is a free data retrieval call binding the contract method 0xeb54dae1. +// +// Solidity: function readAllowList(address addr) view returns(uint256 role) +func (_INativeMinter *INativeMinterCaller) ReadAllowList(opts *bind.CallOpts, addr common.Address) (*big.Int, error) { + var out []interface{} + err := _INativeMinter.contract.Call(opts, &out, "readAllowList", addr) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// ReadAllowList is a free data retrieval call binding the contract method 0xeb54dae1. +// +// Solidity: function readAllowList(address addr) view returns(uint256 role) +func (_INativeMinter *INativeMinterSession) ReadAllowList(addr common.Address) (*big.Int, error) { + return _INativeMinter.Contract.ReadAllowList(&_INativeMinter.CallOpts, addr) +} + +// ReadAllowList is a free data retrieval call binding the contract method 0xeb54dae1. +// +// Solidity: function readAllowList(address addr) view returns(uint256 role) +func (_INativeMinter *INativeMinterCallerSession) ReadAllowList(addr common.Address) (*big.Int, error) { + return _INativeMinter.Contract.ReadAllowList(&_INativeMinter.CallOpts, addr) +} + +// MintNativeCoin is a paid mutator transaction binding the contract method 0x4f5aaaba. +// +// Solidity: function mintNativeCoin(address addr, uint256 amount) returns() +func (_INativeMinter *INativeMinterTransactor) MintNativeCoin(opts *bind.TransactOpts, addr common.Address, amount *big.Int) (*types.Transaction, error) { + return _INativeMinter.contract.Transact(opts, "mintNativeCoin", addr, amount) +} + +// MintNativeCoin is a paid mutator transaction binding the contract method 0x4f5aaaba. +// +// Solidity: function mintNativeCoin(address addr, uint256 amount) returns() +func (_INativeMinter *INativeMinterSession) MintNativeCoin(addr common.Address, amount *big.Int) (*types.Transaction, error) { + return _INativeMinter.Contract.MintNativeCoin(&_INativeMinter.TransactOpts, addr, amount) +} + +// MintNativeCoin is a paid mutator transaction binding the contract method 0x4f5aaaba. +// +// Solidity: function mintNativeCoin(address addr, uint256 amount) returns() +func (_INativeMinter *INativeMinterTransactorSession) MintNativeCoin(addr common.Address, amount *big.Int) (*types.Transaction, error) { + return _INativeMinter.Contract.MintNativeCoin(&_INativeMinter.TransactOpts, addr, amount) +} + +// SetAdmin is a paid mutator transaction binding the contract method 0x704b6c02. +// +// Solidity: function setAdmin(address addr) returns() +func (_INativeMinter *INativeMinterTransactor) SetAdmin(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _INativeMinter.contract.Transact(opts, "setAdmin", addr) +} + +// SetAdmin is a paid mutator transaction binding the contract method 0x704b6c02. +// +// Solidity: function setAdmin(address addr) returns() +func (_INativeMinter *INativeMinterSession) SetAdmin(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetAdmin(&_INativeMinter.TransactOpts, addr) +} + +// SetAdmin is a paid mutator transaction binding the contract method 0x704b6c02. +// +// Solidity: function setAdmin(address addr) returns() +func (_INativeMinter *INativeMinterTransactorSession) SetAdmin(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetAdmin(&_INativeMinter.TransactOpts, addr) +} + +// SetEnabled is a paid mutator transaction binding the contract method 0x0aaf7043. +// +// Solidity: function setEnabled(address addr) returns() +func (_INativeMinter *INativeMinterTransactor) SetEnabled(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _INativeMinter.contract.Transact(opts, "setEnabled", addr) +} + +// SetEnabled is a paid mutator transaction binding the contract method 0x0aaf7043. +// +// Solidity: function setEnabled(address addr) returns() +func (_INativeMinter *INativeMinterSession) SetEnabled(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetEnabled(&_INativeMinter.TransactOpts, addr) +} + +// SetEnabled is a paid mutator transaction binding the contract method 0x0aaf7043. +// +// Solidity: function setEnabled(address addr) returns() +func (_INativeMinter *INativeMinterTransactorSession) SetEnabled(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetEnabled(&_INativeMinter.TransactOpts, addr) +} + +// SetManager is a paid mutator transaction binding the contract method 0xd0ebdbe7. +// +// Solidity: function setManager(address addr) returns() +func (_INativeMinter *INativeMinterTransactor) SetManager(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _INativeMinter.contract.Transact(opts, "setManager", addr) +} + +// SetManager is a paid mutator transaction binding the contract method 0xd0ebdbe7. +// +// Solidity: function setManager(address addr) returns() +func (_INativeMinter *INativeMinterSession) SetManager(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetManager(&_INativeMinter.TransactOpts, addr) +} + +// SetManager is a paid mutator transaction binding the contract method 0xd0ebdbe7. +// +// Solidity: function setManager(address addr) returns() +func (_INativeMinter *INativeMinterTransactorSession) SetManager(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetManager(&_INativeMinter.TransactOpts, addr) +} + +// SetNone is a paid mutator transaction binding the contract method 0x8c6bfb3b. +// +// Solidity: function setNone(address addr) returns() +func (_INativeMinter *INativeMinterTransactor) SetNone(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) { + return _INativeMinter.contract.Transact(opts, "setNone", addr) +} + +// SetNone is a paid mutator transaction binding the contract method 0x8c6bfb3b. +// +// Solidity: function setNone(address addr) returns() +func (_INativeMinter *INativeMinterSession) SetNone(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetNone(&_INativeMinter.TransactOpts, addr) +} + +// SetNone is a paid mutator transaction binding the contract method 0x8c6bfb3b. +// +// Solidity: function setNone(address addr) returns() +func (_INativeMinter *INativeMinterTransactorSession) SetNone(addr common.Address) (*types.Transaction, error) { + return _INativeMinter.Contract.SetNone(&_INativeMinter.TransactOpts, addr) +} + +// INativeMinterNativeCoinMintedIterator is returned from FilterNativeCoinMinted and is used to iterate over the raw logs and unpacked data for NativeCoinMinted events raised by the INativeMinter contract. +type INativeMinterNativeCoinMintedIterator struct { + Event *INativeMinterNativeCoinMinted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *INativeMinterNativeCoinMintedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(INativeMinterNativeCoinMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(INativeMinterNativeCoinMinted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *INativeMinterNativeCoinMintedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *INativeMinterNativeCoinMintedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// INativeMinterNativeCoinMinted represents a NativeCoinMinted event raised by the INativeMinter contract. +type INativeMinterNativeCoinMinted struct { + Sender common.Address + Recipient common.Address + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterNativeCoinMinted is a free log retrieval operation binding the contract event 0x400cd392f3d56fd10bb1dbd5839fdda8298208ddaa97b368faa053e1850930ee. +// +// Solidity: event NativeCoinMinted(address indexed sender, address indexed recipient, uint256 amount) +func (_INativeMinter *INativeMinterFilterer) FilterNativeCoinMinted(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*INativeMinterNativeCoinMintedIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _INativeMinter.contract.FilterLogs(opts, "NativeCoinMinted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &INativeMinterNativeCoinMintedIterator{contract: _INativeMinter.contract, event: "NativeCoinMinted", logs: logs, sub: sub}, nil +} + +// WatchNativeCoinMinted is a free log subscription operation binding the contract event 0x400cd392f3d56fd10bb1dbd5839fdda8298208ddaa97b368faa053e1850930ee. +// +// Solidity: event NativeCoinMinted(address indexed sender, address indexed recipient, uint256 amount) +func (_INativeMinter *INativeMinterFilterer) WatchNativeCoinMinted(opts *bind.WatchOpts, sink chan<- *INativeMinterNativeCoinMinted, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _INativeMinter.contract.WatchLogs(opts, "NativeCoinMinted", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(INativeMinterNativeCoinMinted) + if err := _INativeMinter.contract.UnpackLog(event, "NativeCoinMinted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseNativeCoinMinted is a log parse operation binding the contract event 0x400cd392f3d56fd10bb1dbd5839fdda8298208ddaa97b368faa053e1850930ee. +// +// Solidity: event NativeCoinMinted(address indexed sender, address indexed recipient, uint256 amount) +func (_INativeMinter *INativeMinterFilterer) ParseNativeCoinMinted(log types.Log) (*INativeMinterNativeCoinMinted, error) { + event := new(INativeMinterNativeCoinMinted) + if err := _INativeMinter.contract.UnpackLog(event, "NativeCoinMinted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// INativeMinterRoleSetIterator is returned from FilterRoleSet and is used to iterate over the raw logs and unpacked data for RoleSet events raised by the INativeMinter contract. +type INativeMinterRoleSetIterator struct { + Event *INativeMinterRoleSet // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *INativeMinterRoleSetIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(INativeMinterRoleSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(INativeMinterRoleSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *INativeMinterRoleSetIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *INativeMinterRoleSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// INativeMinterRoleSet represents a RoleSet event raised by the INativeMinter contract. +type INativeMinterRoleSet struct { + Role *big.Int + Account common.Address + Sender common.Address + OldRole *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRoleSet is a free log retrieval operation binding the contract event 0xcdb7ea01f00a414d78757bdb0f6391664ba3fedf987eed280927c1e7d695be3e. +// +// Solidity: event RoleSet(uint256 indexed role, address indexed account, address indexed sender, uint256 oldRole) +func (_INativeMinter *INativeMinterFilterer) FilterRoleSet(opts *bind.FilterOpts, role []*big.Int, account []common.Address, sender []common.Address) (*INativeMinterRoleSetIterator, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _INativeMinter.contract.FilterLogs(opts, "RoleSet", roleRule, accountRule, senderRule) + if err != nil { + return nil, err + } + return &INativeMinterRoleSetIterator{contract: _INativeMinter.contract, event: "RoleSet", logs: logs, sub: sub}, nil +} + +// WatchRoleSet is a free log subscription operation binding the contract event 0xcdb7ea01f00a414d78757bdb0f6391664ba3fedf987eed280927c1e7d695be3e. +// +// Solidity: event RoleSet(uint256 indexed role, address indexed account, address indexed sender, uint256 oldRole) +func (_INativeMinter *INativeMinterFilterer) WatchRoleSet(opts *bind.WatchOpts, sink chan<- *INativeMinterRoleSet, role []*big.Int, account []common.Address, sender []common.Address) (event.Subscription, error) { + + var roleRule []interface{} + for _, roleItem := range role { + roleRule = append(roleRule, roleItem) + } + var accountRule []interface{} + for _, accountItem := range account { + accountRule = append(accountRule, accountItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _INativeMinter.contract.WatchLogs(opts, "RoleSet", roleRule, accountRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(INativeMinterRoleSet) + if err := _INativeMinter.contract.UnpackLog(event, "RoleSet", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRoleSet is a log parse operation binding the contract event 0xcdb7ea01f00a414d78757bdb0f6391664ba3fedf987eed280927c1e7d695be3e. +// +// Solidity: event RoleSet(uint256 indexed role, address indexed account, address indexed sender, uint256 oldRole) +func (_INativeMinter *INativeMinterFilterer) ParseRoleSet(log types.Log) (*INativeMinterRoleSet, error) { + event := new(INativeMinterRoleSet) + if err := _INativeMinter.contract.UnpackLog(event, "RoleSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/ProxyAdmin/ProxyAdmin.go b/abi-bindings/go/ProxyAdmin/ProxyAdmin.go new file mode 100644 index 000000000..02989d202 --- /dev/null +++ b/abi-bindings/go/ProxyAdmin/ProxyAdmin.go @@ -0,0 +1,481 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package proxyadmin + +import ( + "errors" + "math/big" + "strings" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = interfaces.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ProxyAdminMetaData contains all meta data concerning the ProxyAdmin contract. +var ProxyAdminMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"initialOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"UPGRADE_INTERFACE_VERSION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"upgradeAndCall\",\"inputs\":[{\"name\":\"proxy\",\"type\":\"address\",\"internalType\":\"contractITransparentUpgradeableProxy\"},{\"name\":\"implementation\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"OwnableInvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]}]", + Bin: "0x608060405234801561000f575f80fd5b506040516104d33803806104d383398101604081905261002e916100bb565b806001600160a01b03811661005c57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b6100658161006c565b50506100e8565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f602082840312156100cb575f80fd5b81516001600160a01b03811681146100e1575f80fd5b9392505050565b6103de806100f55f395ff3fe608060405260043610610049575f3560e01c8063715018a61461004d5780638da5cb5b146100635780639623609d1461008e578063ad3cb1cc146100a1578063f2fde38b146100de575b5f80fd5b348015610058575f80fd5b506100616100fd565b005b34801561006e575f80fd5b505f546040516001600160a01b0390911681526020015b60405180910390f35b61006161009c366004610260565b610110565b3480156100ac575f80fd5b506100d1604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516100859190610372565b3480156100e9575f80fd5b506100616100f836600461038b565b61017b565b6101056101bd565b61010e5f6101e9565b565b6101186101bd565b60405163278f794360e11b81526001600160a01b03841690634f1ef28690349061014890869086906004016103a6565b5f604051808303818588803b15801561015f575f80fd5b505af1158015610171573d5f803e3d5ffd5b5050505050505050565b6101836101bd565b6001600160a01b0381166101b157604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6101ba816101e9565b50565b5f546001600160a01b0316331461010e5760405163118cdaa760e01b81523360048201526024016101a8565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146101ba575f80fd5b634e487b7160e01b5f52604160045260245ffd5b5f805f60608486031215610272575f80fd5b833561027d81610238565b9250602084013561028d81610238565b9150604084013567ffffffffffffffff808211156102a9575f80fd5b818601915086601f8301126102bc575f80fd5b8135818111156102ce576102ce61024c565b604051601f8201601f19908116603f011681019083821181831017156102f6576102f661024c565b8160405282815289602084870101111561030e575f80fd5b826020860160208301375f6020848301015280955050505050509250925092565b5f81518084525f5b8181101561035357602081850181015186830182015201610337565b505f602082860101526020601f19601f83011685010191505092915050565b602081525f610384602083018461032f565b9392505050565b5f6020828403121561039b575f80fd5b813561038481610238565b6001600160a01b03831681526040602082018190525f906103c99083018461032f565b94935050505056fea164736f6c6343000819000a", +} + +// ProxyAdminABI is the input ABI used to generate the binding from. +// Deprecated: Use ProxyAdminMetaData.ABI instead. +var ProxyAdminABI = ProxyAdminMetaData.ABI + +// ProxyAdminBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ProxyAdminMetaData.Bin instead. +var ProxyAdminBin = ProxyAdminMetaData.Bin + +// DeployProxyAdmin deploys a new Ethereum contract, binding an instance of ProxyAdmin to it. +func DeployProxyAdmin(auth *bind.TransactOpts, backend bind.ContractBackend, initialOwner common.Address) (common.Address, *types.Transaction, *ProxyAdmin, error) { + parsed, err := ProxyAdminMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ProxyAdminBin), backend, initialOwner) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ProxyAdmin{ProxyAdminCaller: ProxyAdminCaller{contract: contract}, ProxyAdminTransactor: ProxyAdminTransactor{contract: contract}, ProxyAdminFilterer: ProxyAdminFilterer{contract: contract}}, nil +} + +// ProxyAdmin is an auto generated Go binding around an Ethereum contract. +type ProxyAdmin struct { + ProxyAdminCaller // Read-only binding to the contract + ProxyAdminTransactor // Write-only binding to the contract + ProxyAdminFilterer // Log filterer for contract events +} + +// ProxyAdminCaller is an auto generated read-only Go binding around an Ethereum contract. +type ProxyAdminCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ProxyAdminTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ProxyAdminTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ProxyAdminFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ProxyAdminFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ProxyAdminSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ProxyAdminSession struct { + Contract *ProxyAdmin // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ProxyAdminCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ProxyAdminCallerSession struct { + Contract *ProxyAdminCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ProxyAdminTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ProxyAdminTransactorSession struct { + Contract *ProxyAdminTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ProxyAdminRaw is an auto generated low-level Go binding around an Ethereum contract. +type ProxyAdminRaw struct { + Contract *ProxyAdmin // Generic contract binding to access the raw methods on +} + +// ProxyAdminCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ProxyAdminCallerRaw struct { + Contract *ProxyAdminCaller // Generic read-only contract binding to access the raw methods on +} + +// ProxyAdminTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ProxyAdminTransactorRaw struct { + Contract *ProxyAdminTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewProxyAdmin creates a new instance of ProxyAdmin, bound to a specific deployed contract. +func NewProxyAdmin(address common.Address, backend bind.ContractBackend) (*ProxyAdmin, error) { + contract, err := bindProxyAdmin(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ProxyAdmin{ProxyAdminCaller: ProxyAdminCaller{contract: contract}, ProxyAdminTransactor: ProxyAdminTransactor{contract: contract}, ProxyAdminFilterer: ProxyAdminFilterer{contract: contract}}, nil +} + +// NewProxyAdminCaller creates a new read-only instance of ProxyAdmin, bound to a specific deployed contract. +func NewProxyAdminCaller(address common.Address, caller bind.ContractCaller) (*ProxyAdminCaller, error) { + contract, err := bindProxyAdmin(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ProxyAdminCaller{contract: contract}, nil +} + +// NewProxyAdminTransactor creates a new write-only instance of ProxyAdmin, bound to a specific deployed contract. +func NewProxyAdminTransactor(address common.Address, transactor bind.ContractTransactor) (*ProxyAdminTransactor, error) { + contract, err := bindProxyAdmin(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ProxyAdminTransactor{contract: contract}, nil +} + +// NewProxyAdminFilterer creates a new log filterer instance of ProxyAdmin, bound to a specific deployed contract. +func NewProxyAdminFilterer(address common.Address, filterer bind.ContractFilterer) (*ProxyAdminFilterer, error) { + contract, err := bindProxyAdmin(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ProxyAdminFilterer{contract: contract}, nil +} + +// bindProxyAdmin binds a generic wrapper to an already deployed contract. +func bindProxyAdmin(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ProxyAdminMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ProxyAdmin *ProxyAdminRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ProxyAdmin.Contract.ProxyAdminCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ProxyAdmin *ProxyAdminRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ProxyAdmin.Contract.ProxyAdminTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ProxyAdmin *ProxyAdminRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ProxyAdmin.Contract.ProxyAdminTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ProxyAdmin *ProxyAdminCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ProxyAdmin.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ProxyAdmin *ProxyAdminTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ProxyAdmin.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ProxyAdmin *ProxyAdminTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ProxyAdmin.Contract.contract.Transact(opts, method, params...) +} + +// UPGRADEINTERFACEVERSION is a free data retrieval call binding the contract method 0xad3cb1cc. +// +// Solidity: function UPGRADE_INTERFACE_VERSION() view returns(string) +func (_ProxyAdmin *ProxyAdminCaller) UPGRADEINTERFACEVERSION(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _ProxyAdmin.contract.Call(opts, &out, "UPGRADE_INTERFACE_VERSION") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// UPGRADEINTERFACEVERSION is a free data retrieval call binding the contract method 0xad3cb1cc. +// +// Solidity: function UPGRADE_INTERFACE_VERSION() view returns(string) +func (_ProxyAdmin *ProxyAdminSession) UPGRADEINTERFACEVERSION() (string, error) { + return _ProxyAdmin.Contract.UPGRADEINTERFACEVERSION(&_ProxyAdmin.CallOpts) +} + +// UPGRADEINTERFACEVERSION is a free data retrieval call binding the contract method 0xad3cb1cc. +// +// Solidity: function UPGRADE_INTERFACE_VERSION() view returns(string) +func (_ProxyAdmin *ProxyAdminCallerSession) UPGRADEINTERFACEVERSION() (string, error) { + return _ProxyAdmin.Contract.UPGRADEINTERFACEVERSION(&_ProxyAdmin.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ProxyAdmin *ProxyAdminCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ProxyAdmin.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ProxyAdmin *ProxyAdminSession) Owner() (common.Address, error) { + return _ProxyAdmin.Contract.Owner(&_ProxyAdmin.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_ProxyAdmin *ProxyAdminCallerSession) Owner() (common.Address, error) { + return _ProxyAdmin.Contract.Owner(&_ProxyAdmin.CallOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ProxyAdmin *ProxyAdminTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ProxyAdmin.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ProxyAdmin *ProxyAdminSession) RenounceOwnership() (*types.Transaction, error) { + return _ProxyAdmin.Contract.RenounceOwnership(&_ProxyAdmin.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_ProxyAdmin *ProxyAdminTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _ProxyAdmin.Contract.RenounceOwnership(&_ProxyAdmin.TransactOpts) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ProxyAdmin *ProxyAdminTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _ProxyAdmin.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ProxyAdmin *ProxyAdminSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ProxyAdmin.Contract.TransferOwnership(&_ProxyAdmin.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_ProxyAdmin *ProxyAdminTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _ProxyAdmin.Contract.TransferOwnership(&_ProxyAdmin.TransactOpts, newOwner) +} + +// UpgradeAndCall is a paid mutator transaction binding the contract method 0x9623609d. +// +// Solidity: function upgradeAndCall(address proxy, address implementation, bytes data) payable returns() +func (_ProxyAdmin *ProxyAdminTransactor) UpgradeAndCall(opts *bind.TransactOpts, proxy common.Address, implementation common.Address, data []byte) (*types.Transaction, error) { + return _ProxyAdmin.contract.Transact(opts, "upgradeAndCall", proxy, implementation, data) +} + +// UpgradeAndCall is a paid mutator transaction binding the contract method 0x9623609d. +// +// Solidity: function upgradeAndCall(address proxy, address implementation, bytes data) payable returns() +func (_ProxyAdmin *ProxyAdminSession) UpgradeAndCall(proxy common.Address, implementation common.Address, data []byte) (*types.Transaction, error) { + return _ProxyAdmin.Contract.UpgradeAndCall(&_ProxyAdmin.TransactOpts, proxy, implementation, data) +} + +// UpgradeAndCall is a paid mutator transaction binding the contract method 0x9623609d. +// +// Solidity: function upgradeAndCall(address proxy, address implementation, bytes data) payable returns() +func (_ProxyAdmin *ProxyAdminTransactorSession) UpgradeAndCall(proxy common.Address, implementation common.Address, data []byte) (*types.Transaction, error) { + return _ProxyAdmin.Contract.UpgradeAndCall(&_ProxyAdmin.TransactOpts, proxy, implementation, data) +} + +// ProxyAdminOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the ProxyAdmin contract. +type ProxyAdminOwnershipTransferredIterator struct { + Event *ProxyAdminOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ProxyAdminOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ProxyAdminOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ProxyAdminOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ProxyAdminOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ProxyAdminOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ProxyAdminOwnershipTransferred represents a OwnershipTransferred event raised by the ProxyAdmin contract. +type ProxyAdminOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ProxyAdmin *ProxyAdminFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*ProxyAdminOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ProxyAdmin.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &ProxyAdminOwnershipTransferredIterator{contract: _ProxyAdmin.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ProxyAdmin *ProxyAdminFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *ProxyAdminOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _ProxyAdmin.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ProxyAdminOwnershipTransferred) + if err := _ProxyAdmin.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_ProxyAdmin *ProxyAdminFilterer) ParseOwnershipTransferred(log types.Log) (*ProxyAdminOwnershipTransferred, error) { + event := new(ProxyAdminOwnershipTransferred) + if err := _ProxyAdmin.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/TransparentUpgradeableProxy/TransparentUpgradeableProxy.go b/abi-bindings/go/TransparentUpgradeableProxy/TransparentUpgradeableProxy.go new file mode 100644 index 000000000..a054267e5 --- /dev/null +++ b/abi-bindings/go/TransparentUpgradeableProxy/TransparentUpgradeableProxy.go @@ -0,0 +1,503 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package transparentupgradeableproxy + +import ( + "errors" + "math/big" + "strings" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = interfaces.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// TransparentUpgradeableProxyMetaData contains all meta data concerning the TransparentUpgradeableProxy contract. +var TransparentUpgradeableProxyMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_logic\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"initialOwner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"payable\"},{\"type\":\"fallback\",\"stateMutability\":\"payable\"},{\"type\":\"event\",\"name\":\"AdminChanged\",\"inputs\":[{\"name\":\"previousAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"newAdmin\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Upgraded\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967InvalidAdmin\",\"inputs\":[{\"name\":\"admin\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967InvalidImplementation\",\"inputs\":[{\"name\":\"implementation\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC1967NonPayable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ProxyDeniedAdminAccess\",\"inputs\":[]}]", + Bin: "0x60a0604052604051610dbb380380610dbb8339810160408190526100229161038c565b828161002e828261008c565b50508160405161003d9061032e565b6001600160a01b039091168152602001604051809103905ff080158015610066573d5f803e3d5ffd5b506001600160a01b031660805261008461007f60805190565b6100ea565b505050610471565b61009582610157565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a28051156100de576100d982826101d5565b505050565b6100e6610248565b5050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6101295f80516020610d9b833981519152546001600160a01b031690565b604080516001600160a01b03928316815291841660208301520160405180910390a161015481610269565b50565b806001600160a01b03163b5f0361019157604051634c9c8ce360e01b81526001600160a01b03821660048201526024015b60405180910390fd5b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b80546001600160a01b0319166001600160a01b039290921691909117905550565b60605f80846001600160a01b0316846040516101f19190610456565b5f60405180830381855af49150503d805f8114610229576040519150601f19603f3d011682016040523d82523d5f602084013e61022e565b606091505b50909250905061023f8583836102a6565b95945050505050565b34156102675760405163b398979f60e01b815260040160405180910390fd5b565b6001600160a01b03811661029257604051633173bdd160e11b81525f6004820152602401610188565b805f80516020610d9b8339815191526101b4565b6060826102bb576102b682610305565b6102fe565b81511580156102d257506001600160a01b0384163b155b156102fb57604051639996b31560e01b81526001600160a01b0385166004820152602401610188565b50805b9392505050565b8051156103155780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6104d3806108c883390190565b80516001600160a01b0381168114610351575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b5f5b8381101561038457818101518382015260200161036c565b50505f910152565b5f805f6060848603121561039e575f80fd5b6103a78461033b565b92506103b56020850161033b565b60408501519092506001600160401b03808211156103d1575f80fd5b818601915086601f8301126103e4575f80fd5b8151818111156103f6576103f6610356565b604051601f8201601f19908116603f0116810190838211818310171561041e5761041e610356565b81604052828152896020848701011115610436575f80fd5b61044783602083016020880161036a565b80955050505050509250925092565b5f825161046781846020870161036a565b9190910192915050565b6080516104406104885f395f601001526104405ff3fe608060405261000c61000e565b005b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316330361007a575f356001600160e01b03191663278f794360e11b14610070576040516334ad5dbb60e21b815260040160405180910390fd5b610078610082565b565b6100786100b0565b5f806100913660048184610303565b81019061009e919061033e565b915091506100ac82826100c0565b5050565b6100786100bb61011a565b610151565b6100c98261016f565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a28051156101125761010d82826101ea565b505050565b6100ac61025c565b5f61014c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b905090565b365f80375f80365f845af43d5f803e80801561016b573d5ff35b3d5ffd5b806001600160a01b03163b5f036101a957604051634c9c8ce360e01b81526001600160a01b03821660048201526024015b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b60605f80846001600160a01b0316846040516102069190610407565b5f60405180830381855af49150503d805f811461023e576040519150601f19603f3d011682016040523d82523d5f602084013e610243565b606091505b509150915061025385838361027b565b95945050505050565b34156100785760405163b398979f60e01b815260040160405180910390fd5b6060826102905761028b826102da565b6102d3565b81511580156102a757506001600160a01b0384163b155b156102d057604051639996b31560e01b81526001600160a01b03851660048201526024016101a0565b50805b9392505050565b8051156102ea5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b5f8085851115610311575f80fd5b8386111561031d575f80fd5b5050820193919092039150565b634e487b7160e01b5f52604160045260245ffd5b5f806040838503121561034f575f80fd5b82356001600160a01b0381168114610365575f80fd5b9150602083013567ffffffffffffffff80821115610381575f80fd5b818501915085601f830112610394575f80fd5b8135818111156103a6576103a661032a565b604051601f8201601f19908116603f011681019083821181831017156103ce576103ce61032a565b816040528281528860208487010111156103e6575f80fd5b826020860160208301375f6020848301015280955050505050509250929050565b5f82515f5b81811015610426576020818601810151858301520161040c565b505f92019182525091905056fea164736f6c6343000819000a608060405234801561000f575f80fd5b506040516104d33803806104d383398101604081905261002e916100bb565b806001600160a01b03811661005c57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b6100658161006c565b50506100e8565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f602082840312156100cb575f80fd5b81516001600160a01b03811681146100e1575f80fd5b9392505050565b6103de806100f55f395ff3fe608060405260043610610049575f3560e01c8063715018a61461004d5780638da5cb5b146100635780639623609d1461008e578063ad3cb1cc146100a1578063f2fde38b146100de575b5f80fd5b348015610058575f80fd5b506100616100fd565b005b34801561006e575f80fd5b505f546040516001600160a01b0390911681526020015b60405180910390f35b61006161009c366004610260565b610110565b3480156100ac575f80fd5b506100d1604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516100859190610372565b3480156100e9575f80fd5b506100616100f836600461038b565b61017b565b6101056101bd565b61010e5f6101e9565b565b6101186101bd565b60405163278f794360e11b81526001600160a01b03841690634f1ef28690349061014890869086906004016103a6565b5f604051808303818588803b15801561015f575f80fd5b505af1158015610171573d5f803e3d5ffd5b5050505050505050565b6101836101bd565b6001600160a01b0381166101b157604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b6101ba816101e9565b50565b5f546001600160a01b0316331461010e5760405163118cdaa760e01b81523360048201526024016101a8565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146101ba575f80fd5b634e487b7160e01b5f52604160045260245ffd5b5f805f60608486031215610272575f80fd5b833561027d81610238565b9250602084013561028d81610238565b9150604084013567ffffffffffffffff808211156102a9575f80fd5b818601915086601f8301126102bc575f80fd5b8135818111156102ce576102ce61024c565b604051601f8201601f19908116603f011681019083821181831017156102f6576102f661024c565b8160405282815289602084870101111561030e575f80fd5b826020860160208301375f6020848301015280955050505050509250925092565b5f81518084525f5b8181101561035357602081850181015186830182015201610337565b505f602082860101526020601f19601f83011685010191505092915050565b602081525f610384602083018461032f565b9392505050565b5f6020828403121561039b575f80fd5b813561038481610238565b6001600160a01b03831681526040602082018190525f906103c99083018461032f565b94935050505056fea164736f6c6343000819000ab53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", +} + +// TransparentUpgradeableProxyABI is the input ABI used to generate the binding from. +// Deprecated: Use TransparentUpgradeableProxyMetaData.ABI instead. +var TransparentUpgradeableProxyABI = TransparentUpgradeableProxyMetaData.ABI + +// TransparentUpgradeableProxyBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TransparentUpgradeableProxyMetaData.Bin instead. +var TransparentUpgradeableProxyBin = TransparentUpgradeableProxyMetaData.Bin + +// DeployTransparentUpgradeableProxy deploys a new Ethereum contract, binding an instance of TransparentUpgradeableProxy to it. +func DeployTransparentUpgradeableProxy(auth *bind.TransactOpts, backend bind.ContractBackend, _logic common.Address, initialOwner common.Address, _data []byte) (common.Address, *types.Transaction, *TransparentUpgradeableProxy, error) { + parsed, err := TransparentUpgradeableProxyMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TransparentUpgradeableProxyBin), backend, _logic, initialOwner, _data) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &TransparentUpgradeableProxy{TransparentUpgradeableProxyCaller: TransparentUpgradeableProxyCaller{contract: contract}, TransparentUpgradeableProxyTransactor: TransparentUpgradeableProxyTransactor{contract: contract}, TransparentUpgradeableProxyFilterer: TransparentUpgradeableProxyFilterer{contract: contract}}, nil +} + +// TransparentUpgradeableProxy is an auto generated Go binding around an Ethereum contract. +type TransparentUpgradeableProxy struct { + TransparentUpgradeableProxyCaller // Read-only binding to the contract + TransparentUpgradeableProxyTransactor // Write-only binding to the contract + TransparentUpgradeableProxyFilterer // Log filterer for contract events +} + +// TransparentUpgradeableProxyCaller is an auto generated read-only Go binding around an Ethereum contract. +type TransparentUpgradeableProxyCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TransparentUpgradeableProxyTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TransparentUpgradeableProxyTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TransparentUpgradeableProxyFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TransparentUpgradeableProxyFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TransparentUpgradeableProxySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TransparentUpgradeableProxySession struct { + Contract *TransparentUpgradeableProxy // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TransparentUpgradeableProxyCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TransparentUpgradeableProxyCallerSession struct { + Contract *TransparentUpgradeableProxyCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TransparentUpgradeableProxyTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TransparentUpgradeableProxyTransactorSession struct { + Contract *TransparentUpgradeableProxyTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TransparentUpgradeableProxyRaw is an auto generated low-level Go binding around an Ethereum contract. +type TransparentUpgradeableProxyRaw struct { + Contract *TransparentUpgradeableProxy // Generic contract binding to access the raw methods on +} + +// TransparentUpgradeableProxyCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TransparentUpgradeableProxyCallerRaw struct { + Contract *TransparentUpgradeableProxyCaller // Generic read-only contract binding to access the raw methods on +} + +// TransparentUpgradeableProxyTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TransparentUpgradeableProxyTransactorRaw struct { + Contract *TransparentUpgradeableProxyTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewTransparentUpgradeableProxy creates a new instance of TransparentUpgradeableProxy, bound to a specific deployed contract. +func NewTransparentUpgradeableProxy(address common.Address, backend bind.ContractBackend) (*TransparentUpgradeableProxy, error) { + contract, err := bindTransparentUpgradeableProxy(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &TransparentUpgradeableProxy{TransparentUpgradeableProxyCaller: TransparentUpgradeableProxyCaller{contract: contract}, TransparentUpgradeableProxyTransactor: TransparentUpgradeableProxyTransactor{contract: contract}, TransparentUpgradeableProxyFilterer: TransparentUpgradeableProxyFilterer{contract: contract}}, nil +} + +// NewTransparentUpgradeableProxyCaller creates a new read-only instance of TransparentUpgradeableProxy, bound to a specific deployed contract. +func NewTransparentUpgradeableProxyCaller(address common.Address, caller bind.ContractCaller) (*TransparentUpgradeableProxyCaller, error) { + contract, err := bindTransparentUpgradeableProxy(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TransparentUpgradeableProxyCaller{contract: contract}, nil +} + +// NewTransparentUpgradeableProxyTransactor creates a new write-only instance of TransparentUpgradeableProxy, bound to a specific deployed contract. +func NewTransparentUpgradeableProxyTransactor(address common.Address, transactor bind.ContractTransactor) (*TransparentUpgradeableProxyTransactor, error) { + contract, err := bindTransparentUpgradeableProxy(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TransparentUpgradeableProxyTransactor{contract: contract}, nil +} + +// NewTransparentUpgradeableProxyFilterer creates a new log filterer instance of TransparentUpgradeableProxy, bound to a specific deployed contract. +func NewTransparentUpgradeableProxyFilterer(address common.Address, filterer bind.ContractFilterer) (*TransparentUpgradeableProxyFilterer, error) { + contract, err := bindTransparentUpgradeableProxy(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TransparentUpgradeableProxyFilterer{contract: contract}, nil +} + +// bindTransparentUpgradeableProxy binds a generic wrapper to an already deployed contract. +func bindTransparentUpgradeableProxy(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TransparentUpgradeableProxyMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TransparentUpgradeableProxy.Contract.TransparentUpgradeableProxyCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.Contract.TransparentUpgradeableProxyTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.Contract.TransparentUpgradeableProxyTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _TransparentUpgradeableProxy.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.Contract.contract.Transact(opts, method, params...) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyTransactor) Fallback(opts *bind.TransactOpts, calldata []byte) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.contract.RawTransact(opts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxySession) Fallback(calldata []byte) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.Contract.Fallback(&_TransparentUpgradeableProxy.TransactOpts, calldata) +} + +// Fallback is a paid mutator transaction binding the contract fallback function. +// +// Solidity: fallback() payable returns() +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyTransactorSession) Fallback(calldata []byte) (*types.Transaction, error) { + return _TransparentUpgradeableProxy.Contract.Fallback(&_TransparentUpgradeableProxy.TransactOpts, calldata) +} + +// TransparentUpgradeableProxyAdminChangedIterator is returned from FilterAdminChanged and is used to iterate over the raw logs and unpacked data for AdminChanged events raised by the TransparentUpgradeableProxy contract. +type TransparentUpgradeableProxyAdminChangedIterator struct { + Event *TransparentUpgradeableProxyAdminChanged // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TransparentUpgradeableProxyAdminChangedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TransparentUpgradeableProxyAdminChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TransparentUpgradeableProxyAdminChanged) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TransparentUpgradeableProxyAdminChangedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TransparentUpgradeableProxyAdminChangedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TransparentUpgradeableProxyAdminChanged represents a AdminChanged event raised by the TransparentUpgradeableProxy contract. +type TransparentUpgradeableProxyAdminChanged struct { + PreviousAdmin common.Address + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAdminChanged is a free log retrieval operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyFilterer) FilterAdminChanged(opts *bind.FilterOpts) (*TransparentUpgradeableProxyAdminChangedIterator, error) { + + logs, sub, err := _TransparentUpgradeableProxy.contract.FilterLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return &TransparentUpgradeableProxyAdminChangedIterator{contract: _TransparentUpgradeableProxy.contract, event: "AdminChanged", logs: logs, sub: sub}, nil +} + +// WatchAdminChanged is a free log subscription operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyFilterer) WatchAdminChanged(opts *bind.WatchOpts, sink chan<- *TransparentUpgradeableProxyAdminChanged) (event.Subscription, error) { + + logs, sub, err := _TransparentUpgradeableProxy.contract.WatchLogs(opts, "AdminChanged") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TransparentUpgradeableProxyAdminChanged) + if err := _TransparentUpgradeableProxy.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAdminChanged is a log parse operation binding the contract event 0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f. +// +// Solidity: event AdminChanged(address previousAdmin, address newAdmin) +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyFilterer) ParseAdminChanged(log types.Log) (*TransparentUpgradeableProxyAdminChanged, error) { + event := new(TransparentUpgradeableProxyAdminChanged) + if err := _TransparentUpgradeableProxy.contract.UnpackLog(event, "AdminChanged", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TransparentUpgradeableProxyUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the TransparentUpgradeableProxy contract. +type TransparentUpgradeableProxyUpgradedIterator struct { + Event *TransparentUpgradeableProxyUpgraded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TransparentUpgradeableProxyUpgradedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TransparentUpgradeableProxyUpgraded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TransparentUpgradeableProxyUpgraded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TransparentUpgradeableProxyUpgradedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TransparentUpgradeableProxyUpgradedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TransparentUpgradeableProxyUpgraded represents a Upgraded event raised by the TransparentUpgradeableProxy contract. +type TransparentUpgradeableProxyUpgraded struct { + Implementation common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpgraded is a free log retrieval operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyFilterer) FilterUpgraded(opts *bind.FilterOpts, implementation []common.Address) (*TransparentUpgradeableProxyUpgradedIterator, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _TransparentUpgradeableProxy.contract.FilterLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return &TransparentUpgradeableProxyUpgradedIterator{contract: _TransparentUpgradeableProxy.contract, event: "Upgraded", logs: logs, sub: sub}, nil +} + +// WatchUpgraded is a free log subscription operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyFilterer) WatchUpgraded(opts *bind.WatchOpts, sink chan<- *TransparentUpgradeableProxyUpgraded, implementation []common.Address) (event.Subscription, error) { + + var implementationRule []interface{} + for _, implementationItem := range implementation { + implementationRule = append(implementationRule, implementationItem) + } + + logs, sub, err := _TransparentUpgradeableProxy.contract.WatchLogs(opts, "Upgraded", implementationRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TransparentUpgradeableProxyUpgraded) + if err := _TransparentUpgradeableProxy.contract.UnpackLog(event, "Upgraded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUpgraded is a log parse operation binding the contract event 0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b. +// +// Solidity: event Upgraded(address indexed implementation) +func (_TransparentUpgradeableProxy *TransparentUpgradeableProxyFilterer) ParseUpgraded(log types.Log) (*TransparentUpgradeableProxyUpgraded, error) { + event := new(TransparentUpgradeableProxyUpgraded) + if err := _TransparentUpgradeableProxy.contract.UnpackLog(event, "Upgraded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/mocks/ExampleERC20/ExampleERC20.go b/abi-bindings/go/mocks/ExampleERC20/ExampleERC20.go index bc7f00d16..2f6a01a04 100644 --- a/abi-bindings/go/mocks/ExampleERC20/ExampleERC20.go +++ b/abi-bindings/go/mocks/ExampleERC20/ExampleERC20.go @@ -31,8 +31,8 @@ var ( // ExampleERC20MetaData contains all meta data concerning the ExampleERC20 contract. var ExampleERC20MetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"allowance\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"balanceOf\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"burn\",\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"burnFrom\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"decimals\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"mint\",\"inputs\":[{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"name\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"symbol\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalSupply\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transfer\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Approval\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"spender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"ERC20InsufficientAllowance\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"allowance\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"needed\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ERC20InsufficientBalance\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"balance\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"needed\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ERC20InvalidApprover\",\"inputs\":[{\"name\":\"approver\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC20InvalidReceiver\",\"inputs\":[{\"name\":\"receiver\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC20InvalidSender\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC20InvalidSpender\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"}]}]", - Bin: "0x608060405234801561000f575f80fd5b506040518060400160405280600a81526020016926b7b1b5902a37b5b2b760b11b81525060405180604001604052806004815260200163045584d560e41b815250816003908161005f919061028b565b50600461006c828261028b565b50505061008b336b204fce5e3e2502611000000061009060201b60201c565b61036f565b6001600160a01b0382166100be5760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6100c95f83836100cd565b5050565b6001600160a01b0383166100f7578060025f8282546100ec919061034a565b909155506101679050565b6001600160a01b0383165f90815260208190526040902054818110156101495760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016100b5565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216610183576002805482900390556101a1565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516101e691815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061021b57607f821691505b60208210810361023957634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561028657805f5260205f20601f840160051c810160208510156102645750805b601f840160051c820191505b81811015610283575f8155600101610270565b50505b505050565b81516001600160401b038111156102a4576102a46101f3565b6102b8816102b28454610207565b8461023f565b602080601f8311600181146102eb575f84156102d45750858301515b5f19600386901b1c1916600185901b178555610342565b5f85815260208120601f198616915b82811015610319578886015182559484019460019091019084016102fa565b508582101561033657878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b8082018082111561036957634e487b7160e01b5f52601160045260245ffd5b92915050565b6108328061037c5f395ff3fe608060405234801561000f575f80fd5b50600436106100b1575f3560e01c806370a082311161006e57806370a082311461013f57806379cc67901461016757806395d89b411461017a578063a0712d6814610182578063a9059cbb14610195578063dd62ed3e146101a8575f80fd5b806306fdde03146100b5578063095ea7b3146100d357806318160ddd146100f657806323b872dd14610108578063313ce5671461011b57806342966c681461012a575b5f80fd5b6100bd6101e0565b6040516100ca919061069e565b60405180910390f35b6100e66100e1366004610705565b610270565b60405190151581526020016100ca565b6002545b6040519081526020016100ca565b6100e661011636600461072d565b610289565b604051601281526020016100ca565b61013d610138366004610766565b6102ac565b005b6100fa61014d36600461077d565b6001600160a01b03165f9081526020819052604090205490565b61013d610175366004610705565b6102b9565b6100bd6102d2565b61013d610190366004610766565b6102e1565b6100e66101a3366004610705565b610347565b6100fa6101b636600461079d565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6060600380546101ef906107ce565b80601f016020809104026020016040519081016040528092919081815260200182805461021b906107ce565b80156102665780601f1061023d57610100808354040283529160200191610266565b820191905f5260205f20905b81548152906001019060200180831161024957829003601f168201915b5050505050905090565b5f3361027d818585610354565b60019150505b92915050565b5f33610296858285610366565b6102a18585856103e1565b506001949350505050565b6102b6338261043e565b50565b6102c4823383610366565b6102ce828261043e565b5050565b6060600480546101ef906107ce565b662386f26fc1000081111561033d5760405162461bcd60e51b815260206004820152601f60248201527f4578616d706c6545524332303a206d6178206d696e742065786365656465640060448201526064015b60405180910390fd5b6102b63382610472565b5f3361027d8185856103e1565b61036183838360016104a6565b505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981146103db57818110156103cd57604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610334565b6103db84848484035f6104a6565b50505050565b6001600160a01b03831661040a57604051634b637e8f60e11b81525f6004820152602401610334565b6001600160a01b0382166104335760405163ec442f0560e01b81525f6004820152602401610334565b610361838383610578565b6001600160a01b03821661046757604051634b637e8f60e11b81525f6004820152602401610334565b6102ce825f83610578565b6001600160a01b03821661049b5760405163ec442f0560e01b81525f6004820152602401610334565b6102ce5f8383610578565b6001600160a01b0384166104cf5760405163e602df0560e01b81525f6004820152602401610334565b6001600160a01b0383166104f857604051634a1406b160e11b81525f6004820152602401610334565b6001600160a01b038085165f90815260016020908152604080832093871683529290522082905580156103db57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161056a91815260200190565b60405180910390a350505050565b6001600160a01b0383166105a2578060025f8282546105979190610806565b909155506106129050565b6001600160a01b0383165f90815260208190526040902054818110156105f45760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610334565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b03821661062e5760028054829003905561064c565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161069191815260200190565b60405180910390a3505050565b5f602080835283518060208501525f5b818110156106ca578581018301518582016040015282016106ae565b505f604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610700575f80fd5b919050565b5f8060408385031215610716575f80fd5b61071f836106ea565b946020939093013593505050565b5f805f6060848603121561073f575f80fd5b610748846106ea565b9250610756602085016106ea565b9150604084013590509250925092565b5f60208284031215610776575f80fd5b5035919050565b5f6020828403121561078d575f80fd5b610796826106ea565b9392505050565b5f80604083850312156107ae575f80fd5b6107b7836106ea565b91506107c5602084016106ea565b90509250929050565b600181811c908216806107e257607f821691505b60208210810361080057634e487b7160e01b5f52602260045260245ffd5b50919050565b8082018082111561028357634e487b7160e01b5f52601160045260245ffdfea164736f6c6343000819000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"allowance\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"balanceOf\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"burn\",\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"burnFrom\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"decimals\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"mint\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"mint\",\"inputs\":[{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"name\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"symbol\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"totalSupply\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transfer\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Approval\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"spender\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"ERC20InsufficientAllowance\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"allowance\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"needed\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ERC20InsufficientBalance\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"balance\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"needed\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"type\":\"error\",\"name\":\"ERC20InvalidApprover\",\"inputs\":[{\"name\":\"approver\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC20InvalidReceiver\",\"inputs\":[{\"name\":\"receiver\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC20InvalidSender\",\"inputs\":[{\"name\":\"sender\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ERC20InvalidSpender\",\"inputs\":[{\"name\":\"spender\",\"type\":\"address\",\"internalType\":\"address\"}]}]", + Bin: "0x608060405234801561000f575f80fd5b506040518060400160405280600a81526020016926b7b1b5902a37b5b2b760b11b81525060405180604001604052806004815260200163045584d560e41b815250816003908161005f919061028b565b50600461006c828261028b565b50505061008b336b204fce5e3e2502611000000061009060201b60201c565b61036f565b6001600160a01b0382166100be5760405163ec442f0560e01b81525f60048201526024015b60405180910390fd5b6100c95f83836100cd565b5050565b6001600160a01b0383166100f7578060025f8282546100ec919061034a565b909155506101679050565b6001600160a01b0383165f90815260208190526040902054818110156101495760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016100b5565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216610183576002805482900390556101a1565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516101e691815260200190565b60405180910390a3505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061021b57607f821691505b60208210810361023957634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561028657805f5260205f20601f840160051c810160208510156102645750805b601f840160051c820191505b81811015610283575f8155600101610270565b50505b505050565b81516001600160401b038111156102a4576102a46101f3565b6102b8816102b28454610207565b8461023f565b602080601f8311600181146102eb575f84156102d45750858301515b5f19600386901b1c1916600185901b178555610342565b5f85815260208120601f198616915b82811015610319578886015182559484019460019091019084016102fa565b508582101561033657878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b8082018082111561036957634e487b7160e01b5f52601160045260245ffd5b92915050565b6108c28061037c5f395ff3fe608060405234801561000f575f80fd5b50600436106100cb575f3560e01c806342966c681161008857806395d89b411161006357806395d89b41146101a7578063a0712d68146101af578063a9059cbb146101c2578063dd62ed3e146101d5575f80fd5b806342966c681461015957806370a082311461016c57806379cc679014610194575f80fd5b806306fdde03146100cf578063095ea7b3146100ed57806318160ddd1461011057806323b872dd14610122578063313ce5671461013557806340c10f1914610144575b5f80fd5b6100d761020d565b6040516100e4919061072e565b60405180910390f35b6101006100fb366004610795565b61029d565b60405190151581526020016100e4565b6002545b6040519081526020016100e4565b6101006101303660046107bd565b6102b6565b604051601281526020016100e4565b610157610152366004610795565b6102d9565b005b6101576101673660046107f6565b610344565b61011461017a36600461080d565b6001600160a01b03165f9081526020819052604090205490565b6101576101a2366004610795565b610351565b6100d7610366565b6101576101bd3660046107f6565b610375565b6101006101d0366004610795565b6103d7565b6101146101e336600461082d565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b60606003805461021c9061085e565b80601f01602080910402602001604051908101604052809291908181526020018280546102489061085e565b80156102935780601f1061026a57610100808354040283529160200191610293565b820191905f5260205f20905b81548152906001019060200180831161027657829003601f168201915b5050505050905090565b5f336102aa8185856103e4565b60019150505b92915050565b5f336102c38582856103f6565b6102ce858585610471565b506001949350505050565b678ac7230489e800008111156103365760405162461bcd60e51b815260206004820152601f60248201527f4578616d706c6545524332303a206d6178206d696e742065786365656465640060448201526064015b60405180910390fd5b61034082826104ce565b5050565b61034e3382610502565b50565b61035c8233836103f6565b6103408282610502565b60606004805461021c9061085e565b678ac7230489e800008111156103cd5760405162461bcd60e51b815260206004820152601f60248201527f4578616d706c6545524332303a206d6178206d696e7420657863656564656400604482015260640161032d565b61034e33826104ce565b5f336102aa818585610471565b6103f18383836001610536565b505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f19811461046b578181101561045d57604051637dc7a0d960e11b81526001600160a01b0384166004820152602481018290526044810183905260640161032d565b61046b84848484035f610536565b50505050565b6001600160a01b03831661049a57604051634b637e8f60e11b81525f600482015260240161032d565b6001600160a01b0382166104c35760405163ec442f0560e01b81525f600482015260240161032d565b6103f1838383610608565b6001600160a01b0382166104f75760405163ec442f0560e01b81525f600482015260240161032d565b6103405f8383610608565b6001600160a01b03821661052b57604051634b637e8f60e11b81525f600482015260240161032d565b610340825f83610608565b6001600160a01b03841661055f5760405163e602df0560e01b81525f600482015260240161032d565b6001600160a01b03831661058857604051634a1406b160e11b81525f600482015260240161032d565b6001600160a01b038085165f908152600160209081526040808320938716835292905220829055801561046b57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516105fa91815260200190565b60405180910390a350505050565b6001600160a01b038316610632578060025f8282546106279190610896565b909155506106a29050565b6001600160a01b0383165f90815260208190526040902054818110156106845760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161032d565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166106be576002805482900390556106dc565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161072191815260200190565b60405180910390a3505050565b5f602080835283518060208501525f5b8181101561075a5785810183015185820160400152820161073e565b505f604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610790575f80fd5b919050565b5f80604083850312156107a6575f80fd5b6107af8361077a565b946020939093013593505050565b5f805f606084860312156107cf575f80fd5b6107d88461077a565b92506107e66020850161077a565b9150604084013590509250925092565b5f60208284031215610806575f80fd5b5035919050565b5f6020828403121561081d575f80fd5b6108268261077a565b9392505050565b5f806040838503121561083e575f80fd5b6108478361077a565b91506108556020840161077a565b90509250929050565b600181811c9082168061087257607f821691505b60208210810361089057634e487b7160e01b5f52602260045260245ffd5b50919050565b808201808211156102b057634e487b7160e01b5f52601160045260245ffdfea164736f6c6343000819000a", } // ExampleERC20ABI is the input ABI used to generate the binding from. @@ -451,25 +451,46 @@ func (_ExampleERC20 *ExampleERC20TransactorSession) BurnFrom(account common.Addr return _ExampleERC20.Contract.BurnFrom(&_ExampleERC20.TransactOpts, account, value) } -// Mint is a paid mutator transaction binding the contract method 0xa0712d68. +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 amount) returns() +func (_ExampleERC20 *ExampleERC20Transactor) Mint(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20.contract.Transact(opts, "mint", account, amount) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 amount) returns() +func (_ExampleERC20 *ExampleERC20Session) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Mint(&_ExampleERC20.TransactOpts, account, amount) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 amount) returns() +func (_ExampleERC20 *ExampleERC20TransactorSession) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Mint(&_ExampleERC20.TransactOpts, account, amount) +} + +// Mint0 is a paid mutator transaction binding the contract method 0xa0712d68. // // Solidity: function mint(uint256 amount) returns() -func (_ExampleERC20 *ExampleERC20Transactor) Mint(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { - return _ExampleERC20.contract.Transact(opts, "mint", amount) +func (_ExampleERC20 *ExampleERC20Transactor) Mint0(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20.contract.Transact(opts, "mint0", amount) } -// Mint is a paid mutator transaction binding the contract method 0xa0712d68. +// Mint0 is a paid mutator transaction binding the contract method 0xa0712d68. // // Solidity: function mint(uint256 amount) returns() -func (_ExampleERC20 *ExampleERC20Session) Mint(amount *big.Int) (*types.Transaction, error) { - return _ExampleERC20.Contract.Mint(&_ExampleERC20.TransactOpts, amount) +func (_ExampleERC20 *ExampleERC20Session) Mint0(amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Mint0(&_ExampleERC20.TransactOpts, amount) } -// Mint is a paid mutator transaction binding the contract method 0xa0712d68. +// Mint0 is a paid mutator transaction binding the contract method 0xa0712d68. // // Solidity: function mint(uint256 amount) returns() -func (_ExampleERC20 *ExampleERC20TransactorSession) Mint(amount *big.Int) (*types.Transaction, error) { - return _ExampleERC20.Contract.Mint(&_ExampleERC20.TransactOpts, amount) +func (_ExampleERC20 *ExampleERC20TransactorSession) Mint0(amount *big.Int) (*types.Transaction, error) { + return _ExampleERC20.Contract.Mint0(&_ExampleERC20.TransactOpts, amount) } // Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. diff --git a/abi-bindings/go/teleporter/TeleporterMessenger/TeleporterMessenger.go b/abi-bindings/go/teleporter/TeleporterMessenger/TeleporterMessenger.go index ec3a807f9..805c6ddc4 100644 --- a/abi-bindings/go/teleporter/TeleporterMessenger/TeleporterMessenger.go +++ b/abi-bindings/go/teleporter/TeleporterMessenger/TeleporterMessenger.go @@ -65,8 +65,8 @@ type TeleporterMessageReceipt struct { // TeleporterMessengerMetaData contains all meta data concerning the TeleporterMessenger contract. var TeleporterMessengerMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"function\",\"name\":\"WARP_MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIWarpMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addFeeAmount\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"additionalFeeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"blockchainID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateMessageID\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"checkRelayerRewardAmount\",\"inputs\":[{\"name\":\"relayer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"feeAsset\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getFeeInfo\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMessageHash\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getNextMessageID\",\"inputs\":[{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getReceiptAtIndex\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTeleporterMessageReceipt\",\"components\":[{\"name\":\"receivedMessageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getReceiptQueueSize\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRelayerRewardAddress\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initializeBlockchainID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"messageNonce\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"messageReceived\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"receiptQueues\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"first\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"last\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"receiveCrossChainMessage\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"receivedFailedMessageHashes\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"messageHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"redeemRelayerRewards\",\"inputs\":[{\"name\":\"feeAsset\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"retryMessageExecution\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"message\",\"type\":\"tuple\",\"internalType\":\"structTeleporterMessage\",\"components\":[{\"name\":\"messageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"receipts\",\"type\":\"tuple[]\",\"internalType\":\"structTeleporterMessageReceipt[]\",\"components\":[{\"name\":\"receivedMessageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"retrySendCrossChainMessage\",\"inputs\":[{\"name\":\"message\",\"type\":\"tuple\",\"internalType\":\"structTeleporterMessage\",\"components\":[{\"name\":\"messageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"receipts\",\"type\":\"tuple[]\",\"internalType\":\"structTeleporterMessageReceipt[]\",\"components\":[{\"name\":\"receivedMessageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"sendCrossChainMessage\",\"inputs\":[{\"name\":\"messageInput\",\"type\":\"tuple\",\"internalType\":\"structTeleporterMessageInput\",\"components\":[{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"feeInfo\",\"type\":\"tuple\",\"internalType\":\"structTeleporterFeeInfo\",\"components\":[{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"sendSpecifiedReceipts\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"messageIDs\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"},{\"name\":\"feeInfo\",\"type\":\"tuple\",\"internalType\":\"structTeleporterFeeInfo\",\"components\":[{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"sentMessageInfo\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"messageHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"feeInfo\",\"type\":\"tuple\",\"internalType\":\"structTeleporterFeeInfo\",\"components\":[{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AddFeeAmount\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"updatedFeeInfo\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTeleporterFeeInfo\",\"components\":[{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BlockchainIDInitialized\",\"inputs\":[{\"name\":\"blockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MessageExecuted\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MessageExecutionFailed\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"message\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTeleporterMessage\",\"components\":[{\"name\":\"messageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"receipts\",\"type\":\"tuple[]\",\"internalType\":\"structTeleporterMessageReceipt[]\",\"components\":[{\"name\":\"receivedMessageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ReceiptReceived\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"feeInfo\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTeleporterFeeInfo\",\"components\":[{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ReceiveCrossChainMessage\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"deliverer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"rewardRedeemer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"message\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTeleporterMessage\",\"components\":[{\"name\":\"messageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"receipts\",\"type\":\"tuple[]\",\"internalType\":\"structTeleporterMessageReceipt[]\",\"components\":[{\"name\":\"receivedMessageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RelayerRewardsRedeemed\",\"inputs\":[{\"name\":\"redeemer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"asset\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SendCrossChainMessage\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"message\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTeleporterMessage\",\"components\":[{\"name\":\"messageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"receipts\",\"type\":\"tuple[]\",\"internalType\":\"structTeleporterMessageReceipt[]\",\"components\":[{\"name\":\"receivedMessageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"feeInfo\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTeleporterFeeInfo\",\"components\":[{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"SafeERC20FailedOperation\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"}]}]", - Bin: "0x6080604052348015600e575f80fd5b5060015f8190558055612fbd806100245f395ff3fe608060405234801561000f575f80fd5b5060043610610148575f3560e01c8063a8898181116100bf578063df20e8bc11610079578063df20e8bc14610331578063e69d606a14610344578063e6e67bd5146103ab578063ebc3b1ba146103e6578063ecc7042814610409578063fc2d619714610412575f80fd5b8063a8898181146102a9578063a9a85614146102bc578063b771b3bc146102cf578063c473eef8146102dd578063ccb5f80914610315578063d127dc9b14610328575f80fd5b8063399b77da11610110578063399b77da1461021257806362448850146102315780638245a1b014610244578063860a3b0614610257578063892bf412146102765780638ac0fd0414610296575f80fd5b80630af5b4ff1461014c57806322296c3a146101675780632bc8b0bf1461017c5780632ca40f551461018f5780632e27c223146101e7575b5f80fd5b610154610425565b6040519081526020015b60405180910390f35b61017a610175366004612014565b6104f3565b005b61015461018a36600461202f565b6105e6565b6101d961019d36600461202f565b600560209081525f9182526040918290208054835180850190945260018201546001600160a01b03168452600290910154918301919091529082565b60405161015e929190612046565b6101fa6101f536600461202f565b610602565b6040516001600160a01b03909116815260200161015e565b61015461022036600461202f565b5f9081526005602052604090205490565b61015461023f36600461206d565b610689565b61017a6102523660046120ba565b6106e2565b61015461026536600461202f565b60066020525f908152604090205481565b6102896102843660046120eb565b610885565b60405161015e919061210b565b61017a6102a436600461212b565b6108b6565b6101546102b7366004612160565b610aed565b6101546102ca3660046121d0565b610b2f565b6101fa6005600160991b0181565b6101546102eb366004612261565b6001600160a01b039182165f90815260096020908152604080832093909416825291909152205490565b61017a610323366004612298565b610dc1565b61015460025481565b61015461033f36600461202f565b6111e3565b61038c61035236600461202f565b5f90815260056020908152604091829020825180840190935260018101546001600160a01b03168084526002909101549290910182905291565b604080516001600160a01b03909316835260208301919091520161015e565b6103d16103b936600461202f565b60046020525f90815260409020805460019091015482565b6040805192835260208301919091520161015e565b6103f96103f436600461202f565b61122a565b604051901515815260200161015e565b61015460035481565b61017a6104203660046122bc565b61123f565b6002545f90806104ee576005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610472573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061049691906122ff565b9050806104be5760405162461bcd60e51b81526004016104b590612316565b60405180910390fd5b600281905560405181907f1eac640109dc937d2a9f42735a05f794b39a5e3759d681951d671aabbce4b104905f90a25b919050565b335f9081526009602090815260408083206001600160a01b0385168452909152902054806105745760405162461bcd60e51b815260206004820152602860248201527f54656c65706f727465724d657373656e6765723a206e6f2072657761726420746044820152676f2072656465656d60c01b60648201526084016104b5565b335f8181526009602090815260408083206001600160a01b03871680855290835281842093909355518481529192917f3294c84e5b0f29d9803655319087207bc94f4db29f7927846944822773780b88910160405180910390a36105e26001600160a01b0383163383611494565b5050565b5f8181526004602052604081206105fc906114f8565b92915050565b5f8181526007602052604081205461066e5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a206d657373616765206e6f74604482015268081c9958d95a5d995960ba1b60648201526084016104b5565b505f908152600860205260409020546001600160a01b031690565b5f60015f54146106ab5760405162461bcd60e51b81526004016104b59061235d565b60025f556106d86106bb836125b6565b83355f9081526004602052604090206106d39061150a565b611604565b60015f5592915050565b60015f54146107035760405162461bcd60e51b81526004016104b59061235d565b60025f818155905461071b9060408401358435610aed565b5f818152600560209081526040918290208251808401845281548152835180850190945260018201546001600160a01b0316845260029091015483830152908101919091528051919250906107825760405162461bcd60e51b81526004016104b590612655565b5f8360405160200161079491906128de565b60408051601f19818403018152919052825181516020830120919250146107cd5760405162461bcd60e51b81526004016104b5906128f0565b8360400135837f2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8868560200151604051610808929190612939565b60405180910390a360405163ee5b48eb60e01b81526005600160991b019063ee5b48eb9061083a9084906004016129ba565b6020604051808303815f875af1158015610856573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061087a91906122ff565b505060015f55505050565b604080518082019091525f80825260208201525f8381526004602052604090206108af9083611837565b9392505050565b60015f54146108d75760405162461bcd60e51b81526004016104b59061235d565b60025f5560018054146108fc5760405162461bcd60e51b81526004016104b5906129cc565b6002600155806109665760405162461bcd60e51b815260206004820152602f60248201527f54656c65706f727465724d657373656e6765723a207a65726f2061646469746960448201526e1bdb985b0819995948185b5bdd5b9d608a1b60648201526084016104b5565b6001600160a01b03821661098c5760405162461bcd60e51b81526004016104b590612a11565b5f838152600560205260409020546109b65760405162461bcd60e51b81526004016104b590612655565b5f838152600560205260409020600101546001600160a01b03838116911614610a475760405162461bcd60e51b815260206004820152603760248201527f54656c65706f727465724d657373656e6765723a20696e76616c69642066656560448201527f20617373657420636f6e7472616374206164647265737300000000000000000060648201526084016104b5565b5f610a5283836118f8565b5f85815260056020526040812060020180549293508392909190610a77908490612a79565b90915550505f8481526005602052604090819020905185917fc1bfd1f1208927dfbd414041dcb5256e6c9ad90dd61aec3249facbd34ff7b3e191610ad8916001019081546001600160a01b0316815260019190910154602082015260400190565b60405180910390a2505060018080555f555050565b6040805130602082015290810184905260608101839052608081018290525f9060a0016040516020818303038152906040528051906020012090509392505050565b5f60015f5414610b515760405162461bcd60e51b81526004016104b59061235d565b60025f818155905490866001600160401b03811115610b7257610b726123a0565b604051908082528060200260200182016040528015610bb657816020015b604080518082019091525f8082526020820152815260200190600190039081610b905790505b509050865f5b81811015610d2e575f8a8a83818110610bd757610bd7612a8c565b9050602002013590505f60075f8381526020019081526020015f20549050805f03610c535760405162461bcd60e51b815260206004820152602660248201527f54656c65706f727465724d657373656e6765723a2072656365697074206e6f7460448201526508199bdd5b9960d21b60648201526084016104b5565b610c5e8d8783610aed565b8214610cd25760405162461bcd60e51b815260206004820152603a60248201527f54656c65706f727465724d657373656e6765723a206d6573736167652049442060448201527f6e6f742066726f6d20736f7572636520626c6f636b636861696e00000000000060648201526084016104b5565b5f828152600860209081526040918290205482518084019093528383526001600160a01b03169082018190528651909190879086908110610d1557610d15612a8c565b6020026020010181905250505050806001019050610bbc565b506040805160c0810182528b81525f6020820152610daf918101610d57368b90038b018b612aa0565b81526020015f81526020018888808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052509385525050604080519283526020808401909152909201525083611604565b60015f559a9950505050505050505050565b6001805414610de25760405162461bcd60e51b81526004016104b5906129cc565b60026001556040516306f8253560e41b815263ffffffff831660048201525f9081906005600160991b0190636f825350906024015f60405180830381865afa158015610e30573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e579190810190612b07565b9150915080610eba5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a20696e76616c69642077617260448201526870206d65737361676560b81b60648201526084016104b5565b60208201516001600160a01b03163014610f315760405162461bcd60e51b815260206004820152603260248201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206f726960448201527167696e2073656e646572206164647265737360701b60648201526084016104b5565b5f8260400151806020019051810190610f4a9190612c83565b90505f610f55610425565b905080826040015114610fc45760405162461bcd60e51b815260206004820152603160248201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206465736044820152701d1a5b985d1a5bdb8818da185a5b881251607a1b60648201526084016104b5565b835182515f91610fd5918490610aed565b5f81815260076020526040902054909150156110495760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f727465724d657373656e6765723a206d65737361676520616c7260448201526c1958591e481c9958d95a5d9959609a1b60648201526084016104b5565b611057338460a00151611a5a565b6110b55760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a20756e617574686f72697a6560448201526832103932b630bcb2b960b91b60648201526084016104b5565b6110c281845f0151611ac6565b6001600160a01b038616156110f8575f81815260086020526040902080546001600160a01b0319166001600160a01b0388161790555b60c0830151515f5b8181101561113b5761113384885f01518760c00151848151811061112657611126612a8c565b6020026020010151611b36565b600101611100565b50604080518082018252855181526001600160a01b03891660208083019190915288515f90815260049091529190912061117491611c5a565b336001600160a01b0316865f0151837f292ee90bbaf70b5d4936025e09d56ba08f3e421156b6a568cf3c2840d9343e348a886040516111b4929190612e89565b60405180910390a460e084015151156111d5576111d582875f015186611cb4565b505060018055505050505050565b6002545f90806112055760405162461bcd60e51b81526004016104b590612316565b5f60035460016112159190612a79565b9050611222828583610aed565b949350505050565b5f8181526007602052604081205415156105fc565b60018054146112605760405162461bcd60e51b81526004016104b5906129cc565b60026001819055545f906112779084908435610aed565b5f81815260066020526040902054909150806112a55760405162461bcd60e51b81526004016104b590612655565b80836040516020016112b791906128de565b60405160208183030381529060405280519060200120146112ea5760405162461bcd60e51b81526004016104b5906128f0565b5f6112fb6080850160608601612014565b6001600160a01b03163b1161136f5760405162461bcd60e51b815260206004820152603460248201527f54656c65706f727465724d657373656e6765723a2064657374696e6174696f6e604482015273206164647265737320686173206e6f20636f646560601b60648201526084016104b5565b604051849083907f34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c905f90a35f82815260066020908152604080832083905586916113be918701908701612014565b6113cb60e0870187612eac565b6040516024016113de9493929190612eee565b60408051601f198184030181529190526020810180516001600160e01b031663643477d560e11b17905290505f61142561141e6080870160608801612014565b5a84611de3565b9050806114885760405162461bcd60e51b815260206004820152602b60248201527f54656c65706f727465724d657373656e6765723a20726574727920657865637560448201526a1d1a5bdb8819985a5b195960aa1b60648201526084016104b5565b50506001805550505050565b6040516001600160a01b038381166024830152604482018390526114f391859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611dfa565b505050565b805460018201545f916105fc91612f18565b60605f611520600561151b856114f8565b611e6c565b9050805f0361156c57604080515f8082526020820190925290611564565b604080518082019091525f808252602082015281526020019060019003908161153e5790505b509392505050565b5f816001600160401b03811115611585576115856123a0565b6040519080825280602002602001820160405280156115c957816020015b604080518082019091525f80825260208201528152602001906001900390816115a35790505b5090505f5b82811015611564576115df85611e7b565b8282815181106115f1576115f1612a8c565b60209081029190910101526001016115ce565b5f8061160e610425565b90505f60035f815461161f90612f2b565b91905081905590505f61163683875f015184610aed565b90505f604051806101000160405280848152602001336001600160a01b03168152602001885f0151815260200188602001516001600160a01b0316815260200188606001518152602001886080015181526020018781526020018860a0015181525090505f816040516020016116ac9190612f43565b60405160208183030381529060405290505f808960400151602001511115611713576040890151516001600160a01b03166116f95760405162461bcd60e51b81526004016104b590612a11565b6040890151805160209091015161171091906118f8565b90505b6040805180820182528a820151516001600160a01b03908116825260208083018590528351808501855286518783012081528082018481525f8a815260058452869020915182555180516001830180546001600160a01b03191691909516179093559101516002909101558a51915190919086907f2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8906117b69088908690612f55565b60405180910390a360405163ee5b48eb60e01b81526005600160991b019063ee5b48eb906117e89086906004016129ba565b6020604051808303815f875af1158015611804573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061182891906122ff565b50939998505050505050505050565b604080518082019091525f8082526020820152611853836114f8565b82106118ab5760405162461bcd60e51b815260206004820152602160248201527f5265636569707451756575653a20696e646578206f7574206f6620626f756e646044820152607360f81b60648201526084016104b5565b826002015f83855f01546118bf9190612a79565b815260208082019290925260409081015f20815180830190925280548252600101546001600160a01b0316918101919091529392505050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038516906370a0823190602401602060405180830381865afa15801561193e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061196291906122ff565b90506119796001600160a01b038516333086611f45565b6040516370a0823160e01b81523060048201525f906001600160a01b038616906370a0823190602401602060405180830381865afa1580156119bd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119e191906122ff565b9050818111611a475760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b60648201526084016104b5565b611a518282612f18565b95945050505050565b5f81515f03611a6b575060016105fc565b81515f5b81811015611abc57846001600160a01b0316848281518110611a9357611a93612a8c565b60200260200101516001600160a01b031603611ab4576001925050506105fc565b600101611a6f565b505f949350505050565b805f03611b255760405162461bcd60e51b815260206004820152602760248201527f54656c65706f727465724d657373656e6765723a207a65726f206d657373616760448201526665206e6f6e636560c81b60648201526084016104b5565b5f9182526007602052604090912055565b5f611b458484845f0151610aed565b5f818152600560209081526040918290208251808401845281548152835180850190945260018201546001600160a01b031684526002909101548383015290810191909152805191925090611b9b575050505050565b5f8281526005602090815260408083208381556001810180546001600160a01b03191690556002018390558382018051830151878401516001600160a01b0390811686526009855283862092515116855292528220805491929091611c01908490612a79565b9250508190555082602001516001600160a01b031684837fd13a7935f29af029349bed0a2097455b91fd06190a30478c575db3f31e00bf578460200151604051611c4b9190612f67565b60405180910390a45050505050565b600182018054829160028501915f9182611c7383612f2b565b9091555081526020808201929092526040015f2082518155910151600190910180546001600160a01b0319166001600160a01b039092169190911790555050565b80608001515a1015611d165760405162461bcd60e51b815260206004820152602560248201527f54656c65706f727465724d657373656e6765723a20696e73756666696369656e604482015264742067617360d81b60648201526084016104b5565b80606001516001600160a01b03163b5f03611d36576114f3838383611f7e565b602081015160e08201516040515f92611d53928692602401612f87565b60408051601f198184030181529190526020810180516001600160e01b031663643477d560e11b179052606083015160808401519192505f91611d97919084611de3565b905080611db057611da9858585611f7e565b5050505050565b604051849086907f34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c905f90a35050505050565b5f805f808451602086015f8989f195945050505050565b5f8060205f8451602086015f885af180611e19576040513d5f823e3d81fd5b50505f513d91508115611e30578060011415611e3d565b6001600160a01b0384163b155b15611e6657604051635274afe760e01b81526001600160a01b03851660048201526024016104b5565b50505050565b5f8282188284100282186108af565b604080518082019091525f808252602082015281546001830154819003611ee45760405162461bcd60e51b815260206004820152601960248201527f5265636569707451756575653a20656d7074792071756575650000000000000060448201526064016104b5565b5f8181526002840160208181526040808420815180830190925280548252600180820180546001600160a01b03811685870152888852959094529490556001600160a01b0319909216905590611f3b908390612a79565b9093555090919050565b6040516001600160a01b038481166024830152838116604483015260648201839052611e669186918216906323b872dd906084016114c1565b80604051602001611f8f9190612f43565b60408051601f1981840301815282825280516020918201205f878152600690925291902055829084907f4619adc1017b82e02eaefac01a43d50d6d8de4460774bc370c3ff0210d40c98590611fe5908590612f43565b60405180910390a3505050565b6001600160a01b0381168114612006575f80fd5b50565b80356104ee81611ff2565b5f60208284031215612024575f80fd5b81356108af81611ff2565b5f6020828403121561203f575f80fd5b5035919050565b828152606081016108af602083018480516001600160a01b03168252602090810151910152565b5f6020828403121561207d575f80fd5b81356001600160401b03811115612092575f80fd5b820160e081850312156108af575f80fd5b5f61010082840312156120b4575f80fd5b50919050565b5f602082840312156120ca575f80fd5b81356001600160401b038111156120df575f80fd5b611222848285016120a3565b5f80604083850312156120fc575f80fd5b50508035926020909101359150565b815181526020808301516001600160a01b031690820152604081016105fc565b5f805f6060848603121561213d575f80fd5b83359250602084013561214f81611ff2565b929592945050506040919091013590565b5f805f60608486031215612172575f80fd5b505081359360208301359350604090920135919050565b5f8083601f840112612199575f80fd5b5081356001600160401b038111156121af575f80fd5b6020830191508360208260051b85010111156121c9575f80fd5b9250929050565b5f805f805f8086880360a08112156121e6575f80fd5b8735965060208801356001600160401b0380821115612203575f80fd5b61220f8b838c01612189565b90985096508691506040603f1984011215612228575f80fd5b60408a01955060808a0135925080831115612241575f80fd5b505061224f89828a01612189565b979a9699509497509295939492505050565b5f8060408385031215612272575f80fd5b823561227d81611ff2565b9150602083013561228d81611ff2565b809150509250929050565b5f80604083850312156122a9575f80fd5b823563ffffffff8116811461227d575f80fd5b5f80604083850312156122cd575f80fd5b8235915060208301356001600160401b038111156122e9575f80fd5b6122f5858286016120a3565b9150509250929050565b5f6020828403121561230f575f80fd5b5051919050565b60208082526027908201527f54656c65706f727465724d657373656e6765723a207a65726f20626c6f636b636040820152661a185a5b88125160ca1b606082015260800190565b60208082526023908201527f5265656e7472616e63794775617264733a2073656e646572207265656e7472616040820152626e637960e81b606082015260800190565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156123d6576123d66123a0565b60405290565b60405160c081016001600160401b03811182821017156123d6576123d66123a0565b604051606081016001600160401b03811182821017156123d6576123d66123a0565b60405161010081016001600160401b03811182821017156123d6576123d66123a0565b604051601f8201601f191681016001600160401b038111828210171561246b5761246b6123a0565b604052919050565b5f60408284031215612483575f80fd5b61248b6123b4565b9050813561249881611ff2565b808252506020820135602082015292915050565b5f6001600160401b038211156124c4576124c46123a0565b5060051b60200190565b5f82601f8301126124dd575f80fd5b813560206124f26124ed836124ac565b612443565b8083825260208201915060208460051b870101935086841115612513575f80fd5b602086015b8481101561253857803561252b81611ff2565b8352918301918301612518565b509695505050505050565b5f6001600160401b0382111561255b5761255b6123a0565b50601f01601f191660200190565b5f82601f830112612578575f80fd5b81356125866124ed82612543565b81815284602083860101111561259a575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60e082360312156125c6575f80fd5b6125ce6123dc565b823581526125de60208401612009565b60208201526125f03660408501612473565b60408201526080830135606082015260a08301356001600160401b0380821115612618575f80fd5b612624368387016124ce565b608084015260c085013591508082111561263c575f80fd5b5061264936828601612569565b60a08301525092915050565b60208082526026908201527f54656c65706f727465724d657373656e6765723a206d657373616765206e6f7460408201526508199bdd5b9960d21b606082015260800190565b5f808335601e198436030181126126b0575f80fd5b83016020810192503590506001600160401b038111156126ce575f80fd5b8060051b36038213156121c9575f80fd5b8183525f60208085019450825f5b8581101561271b57813561270081611ff2565b6001600160a01b0316875295820195908201906001016126ed565b509495945050505050565b5f808335601e1984360301811261273b575f80fd5b83016020810192503590506001600160401b03811115612759575f80fd5b8060061b36038213156121c9575f80fd5b8183525f60208085019450825f5b8581101561271b57813587528282013561279181611ff2565b6001600160a01b0316878401526040968701969190910190600101612778565b5f808335601e198436030181126127c6575f80fd5b83016020810192503590506001600160401b038111156127e4575f80fd5b8036038213156121c9575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f61010082358452602083013561283081611ff2565b6001600160a01b031660208501526040838101359085015261285460608401612009565b6001600160a01b031660608501526080838101359085015261287960a084018461269b565b8260a087015261288c83870182846126df565b9250505061289d60c0840184612726565b85830360c08701526128b083828461276a565b925050506128c160e08401846127b1565b85830360e08701526128d48382846127f2565b9695505050505050565b602081525f6108af602083018461281a565b60208082526029908201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206d65736040820152680e6c2ceca40d0c2e6d60bb1b606082015260800190565b606081525f61294b606083018561281a565b90506108af602083018480516001600160a01b03168252602090810151910152565b5f5b8381101561298757818101518382015260200161296f565b50505f910152565b5f81518084526129a681602086016020860161296d565b601f01601f19169290920160200192915050565b602081525f6108af602083018461298f565b60208082526025908201527f5265656e7472616e63794775617264733a207265636569766572207265656e7460408201526472616e637960d81b606082015260800190565b60208082526034908201527f54656c65706f727465724d657373656e6765723a207a65726f2066656520617360408201527373657420636f6e7472616374206164647265737360601b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b808201808211156105fc576105fc612a65565b634e487b7160e01b5f52603260045260245ffd5b5f60408284031215612ab0575f80fd5b6108af8383612473565b80516104ee81611ff2565b5f82601f830112612ad4575f80fd5b8151612ae26124ed82612543565b818152846020838601011115612af6575f80fd5b61122282602083016020870161296d565b5f8060408385031215612b18575f80fd5b82516001600160401b0380821115612b2e575f80fd5b9084019060608287031215612b41575f80fd5b612b496123fe565b825181526020830151612b5b81611ff2565b6020820152604083015182811115612b71575f80fd5b612b7d88828601612ac5565b6040830152508094505050506020830151801515811461228d575f80fd5b5f82601f830112612baa575f80fd5b81516020612bba6124ed836124ac565b8083825260208201915060208460051b870101935086841115612bdb575f80fd5b602086015b84811015612538578051612bf381611ff2565b8352918301918301612be0565b5f82601f830112612c0f575f80fd5b81516020612c1f6124ed836124ac565b82815260069290921b84018101918181019086841115612c3d575f80fd5b8286015b848110156125385760408189031215612c58575f80fd5b612c606123b4565b8151815284820151612c7181611ff2565b81860152835291830191604001612c41565b5f60208284031215612c93575f80fd5b81516001600160401b0380821115612ca9575f80fd5b908301906101008286031215612cbd575f80fd5b612cc5612420565b82518152612cd560208401612aba565b602082015260408301516040820152612cf060608401612aba565b60608201526080830151608082015260a083015182811115612d10575f80fd5b612d1c87828601612b9b565b60a08301525060c083015182811115612d33575f80fd5b612d3f87828601612c00565b60c08301525060e083015182811115612d56575f80fd5b612d6287828601612ac5565b60e08301525095945050505050565b5f815180845260208085019450602084015f5b8381101561271b5781516001600160a01b031687529582019590820190600101612d84565b5f815180845260208085019450602084015f5b8381101561271b57612de2878351805182526020908101516001600160a01b0316910152565b6040969096019590820190600101612dbc565b5f6101008251845260018060a01b036020840151166020850152604083015160408501526060830151612e3360608601826001600160a01b03169052565b506080830151608085015260a08301518160a0860152612e5582860182612d71565b91505060c083015184820360c0860152612e6f8282612da9565b91505060e083015184820360e0860152611a51828261298f565b6001600160a01b03831681526040602082018190525f9061122290830184612df5565b5f808335601e19843603018112612ec1575f80fd5b8301803591506001600160401b03821115612eda575f80fd5b6020019150368190038213156121c9575f80fd5b8481526001600160a01b03841660208201526060604082018190525f906128d490830184866127f2565b818103818111156105fc576105fc612a65565b5f60018201612f3c57612f3c612a65565b5060010190565b602081525f6108af6020830184612df5565b606081525f61294b6060830185612df5565b81516001600160a01b0316815260208083015190820152604081016105fc565b8381526001600160a01b03831660208201526060604082018190525f90611a519083018461298f56fea164736f6c6343000819000a", + ABI: "[{\"type\":\"function\",\"name\":\"WARP_MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIWarpMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addFeeAmount\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"additionalFeeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"blockchainID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateMessageID\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"nonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"checkRelayerRewardAmount\",\"inputs\":[{\"name\":\"relayer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"feeAsset\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getFeeInfo\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMessageHash\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getNextMessageID\",\"inputs\":[{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getReceiptAtIndex\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"index\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTeleporterMessageReceipt\",\"components\":[{\"name\":\"receivedMessageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getReceiptQueueSize\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getRelayerRewardAddress\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initializeBlockchainID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"messageNonce\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"messageReceived\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"receiptQueues\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"first\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"last\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"receiveCrossChainMessage\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"receivedFailedMessageHashes\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"messageHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"redeemRelayerRewards\",\"inputs\":[{\"name\":\"feeAsset\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"retryMessageExecution\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"message\",\"type\":\"tuple\",\"internalType\":\"structTeleporterMessage\",\"components\":[{\"name\":\"messageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"receipts\",\"type\":\"tuple[]\",\"internalType\":\"structTeleporterMessageReceipt[]\",\"components\":[{\"name\":\"receivedMessageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"retrySendCrossChainMessage\",\"inputs\":[{\"name\":\"message\",\"type\":\"tuple\",\"internalType\":\"structTeleporterMessage\",\"components\":[{\"name\":\"messageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"receipts\",\"type\":\"tuple[]\",\"internalType\":\"structTeleporterMessageReceipt[]\",\"components\":[{\"name\":\"receivedMessageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"sendCrossChainMessage\",\"inputs\":[{\"name\":\"messageInput\",\"type\":\"tuple\",\"internalType\":\"structTeleporterMessageInput\",\"components\":[{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"feeInfo\",\"type\":\"tuple\",\"internalType\":\"structTeleporterFeeInfo\",\"components\":[{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"sendSpecifiedReceipts\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"messageIDs\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"},{\"name\":\"feeInfo\",\"type\":\"tuple\",\"internalType\":\"structTeleporterFeeInfo\",\"components\":[{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"sentMessageInfo\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"messageHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"feeInfo\",\"type\":\"tuple\",\"internalType\":\"structTeleporterFeeInfo\",\"components\":[{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AddFeeAmount\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"updatedFeeInfo\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTeleporterFeeInfo\",\"components\":[{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BlockchainIDInitialized\",\"inputs\":[{\"name\":\"blockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MessageExecuted\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MessageExecutionFailed\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"message\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTeleporterMessage\",\"components\":[{\"name\":\"messageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"receipts\",\"type\":\"tuple[]\",\"internalType\":\"structTeleporterMessageReceipt[]\",\"components\":[{\"name\":\"receivedMessageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ReceiptReceived\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"feeInfo\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTeleporterFeeInfo\",\"components\":[{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ReceiveCrossChainMessage\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"deliverer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"rewardRedeemer\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"message\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTeleporterMessage\",\"components\":[{\"name\":\"messageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"receipts\",\"type\":\"tuple[]\",\"internalType\":\"structTeleporterMessageReceipt[]\",\"components\":[{\"name\":\"receivedMessageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RelayerRewardsRedeemed\",\"inputs\":[{\"name\":\"redeemer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"asset\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SendCrossChainMessage\",\"inputs\":[{\"name\":\"messageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"message\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTeleporterMessage\",\"components\":[{\"name\":\"messageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"allowedRelayerAddresses\",\"type\":\"address[]\",\"internalType\":\"address[]\"},{\"name\":\"receipts\",\"type\":\"tuple[]\",\"internalType\":\"structTeleporterMessageReceipt[]\",\"components\":[{\"name\":\"receivedMessageNonce\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"relayerRewardAddress\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"feeInfo\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structTeleporterFeeInfo\",\"components\":[{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AddressInsufficientBalance\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SafeERC20FailedOperation\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"}]}]", + Bin: "0x6080604052348015600e575f80fd5b5060015f81905580556130e9806100245f395ff3fe608060405234801561000f575f80fd5b5060043610610148575f3560e01c8063a8898181116100bf578063df20e8bc11610079578063df20e8bc14610331578063e69d606a14610344578063e6e67bd5146103ab578063ebc3b1ba146103e6578063ecc7042814610409578063fc2d619714610412575f80fd5b8063a8898181146102a9578063a9a85614146102bc578063b771b3bc146102cf578063c473eef8146102dd578063ccb5f80914610315578063d127dc9b14610328575f80fd5b8063399b77da11610110578063399b77da1461021257806362448850146102315780638245a1b014610244578063860a3b0614610257578063892bf412146102765780638ac0fd0414610296575f80fd5b80630af5b4ff1461014c57806322296c3a146101675780632bc8b0bf1461017c5780632ca40f551461018f5780632e27c223146101e7575b5f80fd5b610154610425565b6040519081526020015b60405180910390f35b61017a610175366004612111565b6104f3565b005b61015461018a36600461212c565b6105e6565b6101d961019d36600461212c565b600560209081525f9182526040918290208054835180850190945260018201546001600160a01b03168452600290910154918301919091529082565b60405161015e929190612143565b6101fa6101f536600461212c565b610602565b6040516001600160a01b03909116815260200161015e565b61015461022036600461212c565b5f9081526005602052604090205490565b61015461023f36600461216a565b610689565b61017a6102523660046121b7565b6106e2565b61015461026536600461212c565b60066020525f908152604090205481565b6102896102843660046121e8565b610885565b60405161015e9190612208565b61017a6102a4366004612228565b6108b6565b6101546102b736600461225d565b610aed565b6101546102ca3660046122cd565b610b2f565b6101fa6005600160991b0181565b6101546102eb36600461235e565b6001600160a01b039182165f90815260096020908152604080832093909416825291909152205490565b61017a610323366004612395565b610dc1565b61015460025481565b61015461033f36600461212c565b6111e3565b61038c61035236600461212c565b5f90815260056020908152604091829020825180840190935260018101546001600160a01b03168084526002909101549290910182905291565b604080516001600160a01b03909316835260208301919091520161015e565b6103d16103b936600461212c565b60046020525f90815260409020805460019091015482565b6040805192835260208301919091520161015e565b6103f96103f436600461212c565b61122a565b604051901515815260200161015e565b61015460035481565b61017a6104203660046123b9565b61123f565b6002545f90806104ee576005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610472573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061049691906123fc565b9050806104be5760405162461bcd60e51b81526004016104b590612413565b60405180910390fd5b600281905560405181907f1eac640109dc937d2a9f42735a05f794b39a5e3759d681951d671aabbce4b104905f90a25b919050565b335f9081526009602090815260408083206001600160a01b0385168452909152902054806105745760405162461bcd60e51b815260206004820152602860248201527f54656c65706f727465724d657373656e6765723a206e6f2072657761726420746044820152676f2072656465656d60c01b60648201526084016104b5565b335f8181526009602090815260408083206001600160a01b03871680855290835281842093909355518481529192917f3294c84e5b0f29d9803655319087207bc94f4db29f7927846944822773780b88910160405180910390a36105e26001600160a01b0383163383611494565b5050565b5f8181526004602052604081206105fc906114f8565b92915050565b5f8181526007602052604081205461066e5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a206d657373616765206e6f74604482015268081c9958d95a5d995960ba1b60648201526084016104b5565b505f908152600860205260409020546001600160a01b031690565b5f60015f54146106ab5760405162461bcd60e51b81526004016104b59061245a565b60025f556106d86106bb83612691565b83355f9081526004602052604090206106d39061150a565b611604565b60015f5592915050565b60015f54146107035760405162461bcd60e51b81526004016104b59061245a565b60025f818155905461071b9060408401358435610aed565b5f818152600560209081526040918290208251808401845281548152835180850190945260018201546001600160a01b0316845260029091015483830152908101919091528051919250906107825760405162461bcd60e51b81526004016104b590612730565b5f8360405160200161079491906129af565b60408051601f19818403018152919052825181516020830120919250146107cd5760405162461bcd60e51b81526004016104b5906129c1565b8360400135837f2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8868560200151604051610808929190612a0a565b60405180910390a360405163ee5b48eb60e01b81526005600160991b019063ee5b48eb9061083a908490600401612a8b565b6020604051808303815f875af1158015610856573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061087a91906123fc565b505060015f55505050565b604080518082019091525f80825260208201525f8381526004602052604090206108af9083611837565b9392505050565b60015f54146108d75760405162461bcd60e51b81526004016104b59061245a565b60025f5560018054146108fc5760405162461bcd60e51b81526004016104b590612a9d565b6002600155806109665760405162461bcd60e51b815260206004820152602f60248201527f54656c65706f727465724d657373656e6765723a207a65726f2061646469746960448201526e1bdb985b0819995948185b5bdd5b9d608a1b60648201526084016104b5565b6001600160a01b03821661098c5760405162461bcd60e51b81526004016104b590612ae2565b5f838152600560205260409020546109b65760405162461bcd60e51b81526004016104b590612730565b5f838152600560205260409020600101546001600160a01b03838116911614610a475760405162461bcd60e51b815260206004820152603760248201527f54656c65706f727465724d657373656e6765723a20696e76616c69642066656560448201527f20617373657420636f6e7472616374206164647265737300000000000000000060648201526084016104b5565b5f610a5283836118f8565b5f85815260056020526040812060020180549293508392909190610a77908490612b4a565b90915550505f8481526005602052604090819020905185917fc1bfd1f1208927dfbd414041dcb5256e6c9ad90dd61aec3249facbd34ff7b3e191610ad8916001019081546001600160a01b0316815260019190910154602082015260400190565b60405180910390a2505060018080555f555050565b6040805130602082015290810184905260608101839052608081018290525f9060a0016040516020818303038152906040528051906020012090509392505050565b5f60015f5414610b515760405162461bcd60e51b81526004016104b59061245a565b60025f818155905490866001600160401b03811115610b7257610b7261249d565b604051908082528060200260200182016040528015610bb657816020015b604080518082019091525f8082526020820152815260200190600190039081610b905790505b509050865f5b81811015610d2e575f8a8a83818110610bd757610bd7612b5d565b9050602002013590505f60075f8381526020019081526020015f20549050805f03610c535760405162461bcd60e51b815260206004820152602660248201527f54656c65706f727465724d657373656e6765723a2072656365697074206e6f7460448201526508199bdd5b9960d21b60648201526084016104b5565b610c5e8d8783610aed565b8214610cd25760405162461bcd60e51b815260206004820152603a60248201527f54656c65706f727465724d657373656e6765723a206d6573736167652049442060448201527f6e6f742066726f6d20736f7572636520626c6f636b636861696e00000000000060648201526084016104b5565b5f828152600860209081526040918290205482518084019093528383526001600160a01b03169082018190528651909190879086908110610d1557610d15612b5d565b6020026020010181905250505050806001019050610bbc565b506040805160c0810182528b81525f6020820152610daf918101610d57368b90038b018b612b71565b81526020015f81526020018888808060200260200160405190810160405280939291908181526020018383602002808284375f9201829052509385525050604080519283526020808401909152909201525083611604565b60015f559a9950505050505050505050565b6001805414610de25760405162461bcd60e51b81526004016104b590612a9d565b60026001556040516306f8253560e41b815263ffffffff831660048201525f9081906005600160991b0190636f825350906024015f60405180830381865afa158015610e30573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e579190810190612be7565b9150915080610eba5760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a20696e76616c69642077617260448201526870206d65737361676560b81b60648201526084016104b5565b60208201516001600160a01b03163014610f315760405162461bcd60e51b815260206004820152603260248201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206f726960448201527167696e2073656e646572206164647265737360701b60648201526084016104b5565b5f8260400151806020019051810190610f4a9190612d7b565b90505f610f55610425565b905080826040015114610fc45760405162461bcd60e51b815260206004820152603160248201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206465736044820152701d1a5b985d1a5bdb8818da185a5b881251607a1b60648201526084016104b5565b835182515f91610fd5918490610aed565b5f81815260076020526040902054909150156110495760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f727465724d657373656e6765723a206d65737361676520616c7260448201526c1958591e481c9958d95a5d9959609a1b60648201526084016104b5565b611057338460a00151611a5a565b6110b55760405162461bcd60e51b815260206004820152602960248201527f54656c65706f727465724d657373656e6765723a20756e617574686f72697a6560448201526832103932b630bcb2b960b91b60648201526084016104b5565b6110c281845f0151611ac6565b6001600160a01b038616156110f8575f81815260086020526040902080546001600160a01b0319166001600160a01b0388161790555b60c0830151515f5b8181101561113b5761113384885f01518760c00151848151811061112657611126612b5d565b6020026020010151611b36565b600101611100565b50604080518082018252855181526001600160a01b03891660208083019190915288515f90815260049091529190912061117491611c5a565b336001600160a01b0316865f0151837f292ee90bbaf70b5d4936025e09d56ba08f3e421156b6a568cf3c2840d9343e348a886040516111b4929190612f81565b60405180910390a460e084015151156111d5576111d582875f015186611cb4565b505060018055505050505050565b6002545f90806112055760405162461bcd60e51b81526004016104b590612413565b5f60035460016112159190612b4a565b9050611222828583610aed565b949350505050565b5f8181526007602052604081205415156105fc565b60018054146112605760405162461bcd60e51b81526004016104b590612a9d565b60026001819055545f906112779084908435610aed565b5f81815260066020526040902054909150806112a55760405162461bcd60e51b81526004016104b590612730565b80836040516020016112b791906129af565b60405160208183030381529060405280519060200120146112ea5760405162461bcd60e51b81526004016104b5906129c1565b5f6112fb6080850160608601612111565b6001600160a01b03163b1161136f5760405162461bcd60e51b815260206004820152603460248201527f54656c65706f727465724d657373656e6765723a2064657374696e6174696f6e604482015273206164647265737320686173206e6f20636f646560601b60648201526084016104b5565b604051849083907f34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c905f90a35f82815260066020908152604080832083905586916113be918701908701612111565b6113cb60e0870187612fa4565b6040516024016113de9493929190612fe6565b60408051601f198184030181529190526020810180516001600160e01b031663643477d560e11b17905290505f61142561141e6080870160608801612111565b5a84611de3565b9050806114885760405162461bcd60e51b815260206004820152602b60248201527f54656c65706f727465724d657373656e6765723a20726574727920657865637560448201526a1d1a5bdb8819985a5b195960aa1b60648201526084016104b5565b50506001805550505050565b6040516001600160a01b038381166024830152604482018390526114f391859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611dfa565b505050565b805460018201545f916105fc91613010565b60605f611520600561151b856114f8565b611e5b565b9050805f0361156c57604080515f8082526020820190925290611564565b604080518082019091525f808252602082015281526020019060019003908161153e5790505b509392505050565b5f816001600160401b038111156115855761158561249d565b6040519080825280602002602001820160405280156115c957816020015b604080518082019091525f80825260208201528152602001906001900390816115a35790505b5090505f5b82811015611564576115df85611e70565b8282815181106115f1576115f1612b5d565b60209081029190910101526001016115ce565b5f8061160e610425565b90505f60035f815461161f90613023565b91905081905590505f61163683875f015184610aed565b90505f604051806101000160405280848152602001336001600160a01b03168152602001885f0151815260200188602001516001600160a01b0316815260200188606001518152602001886080015181526020018781526020018860a0015181525090505f816040516020016116ac919061303b565b60405160208183030381529060405290505f808960400151602001511115611713576040890151516001600160a01b03166116f95760405162461bcd60e51b81526004016104b590612ae2565b6040890151805160209091015161171091906118f8565b90505b6040805180820182528a820151516001600160a01b03908116825260208083018590528351808501855286518783012081528082018481525f8a815260058452869020915182555180516001830180546001600160a01b03191691909516179093559101516002909101558a51915190919086907f2a211ad4a59ab9d003852404f9c57c690704ee755f3c79d2c2812ad32da99df8906117b6908890869061304d565b60405180910390a360405163ee5b48eb60e01b81526005600160991b019063ee5b48eb906117e8908690600401612a8b565b6020604051808303815f875af1158015611804573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061182891906123fc565b50939998505050505050505050565b604080518082019091525f8082526020820152611853836114f8565b82106118ab5760405162461bcd60e51b815260206004820152602160248201527f5265636569707451756575653a20696e646578206f7574206f6620626f756e646044820152607360f81b60648201526084016104b5565b826002015f83855f01546118bf9190612b4a565b815260208082019290925260409081015f20815180830190925280548252600101546001600160a01b0316918101919091529392505050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038516906370a0823190602401602060405180830381865afa15801561193e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061196291906123fc565b90506119796001600160a01b038516333086611f3a565b6040516370a0823160e01b81523060048201525f906001600160a01b038616906370a0823190602401602060405180830381865afa1580156119bd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119e191906123fc565b9050818111611a475760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b60648201526084016104b5565b611a518282613010565b95945050505050565b5f81515f03611a6b575060016105fc565b81515f5b81811015611abc57846001600160a01b0316848281518110611a9357611a93612b5d565b60200260200101516001600160a01b031603611ab4576001925050506105fc565b600101611a6f565b505f949350505050565b805f03611b255760405162461bcd60e51b815260206004820152602760248201527f54656c65706f727465724d657373656e6765723a207a65726f206d657373616760448201526665206e6f6e636560c81b60648201526084016104b5565b5f9182526007602052604090912055565b5f611b458484845f0151610aed565b5f818152600560209081526040918290208251808401845281548152835180850190945260018201546001600160a01b031684526002909101548383015290810191909152805191925090611b9b575050505050565b5f8281526005602090815260408083208381556001810180546001600160a01b03191690556002018390558382018051830151878401516001600160a01b0390811686526009855283862092515116855292528220805491929091611c01908490612b4a565b9250508190555082602001516001600160a01b031684837fd13a7935f29af029349bed0a2097455b91fd06190a30478c575db3f31e00bf578460200151604051611c4b919061305f565b60405180910390a45050505050565b600182018054829160028501915f9182611c7383613023565b9091555081526020808201929092526040015f2082518155910151600190910180546001600160a01b0319166001600160a01b039092169190911790555050565b80608001515a1015611d165760405162461bcd60e51b815260206004820152602560248201527f54656c65706f727465724d657373656e6765723a20696e73756666696369656e604482015264742067617360d81b60648201526084016104b5565b80606001516001600160a01b03163b5f03611d36576114f3838383611f79565b602081015160e08201516040515f92611d5392869260240161307f565b60408051601f198184030181529190526020810180516001600160e01b031663643477d560e11b179052606083015160808401519192505f91611d97919084611de3565b905080611db057611da9858585611f79565b5050505050565b604051849086907f34795cc6b122b9a0ae684946319f1e14a577b4e8f9b3dda9ac94c21a54d3188c905f90a35050505050565b5f805f808451602086015f8989f195945050505050565b5f611e0e6001600160a01b03841683611fed565b905080515f14158015611e32575080806020019051810190611e3091906130a8565b155b156114f357604051635274afe760e01b81526001600160a01b03841660048201526024016104b5565b5f818310611e6957816108af565b5090919050565b604080518082019091525f808252602082015281546001830154819003611ed95760405162461bcd60e51b815260206004820152601960248201527f5265636569707451756575653a20656d7074792071756575650000000000000060448201526064016104b5565b5f8181526002840160208181526040808420815180830190925280548252600180820180546001600160a01b03811685870152888852959094529490556001600160a01b0319909216905590611f30908390612b4a565b9093555090919050565b6040516001600160a01b038481166024830152838116604483015260648201839052611f739186918216906323b872dd906084016114c1565b50505050565b80604051602001611f8a919061303b565b60408051601f1981840301815282825280516020918201205f878152600690925291902055829084907f4619adc1017b82e02eaefac01a43d50d6d8de4460774bc370c3ff0210d40c98590611fe090859061303b565b60405180910390a3505050565b60606108af83835f845f80856001600160a01b0316848660405161201191906130c1565b5f6040518083038185875af1925050503d805f811461204b576040519150601f19603f3d011682016040523d82523d5f602084013e612050565b606091505b509150915061206086838361206a565b9695505050505050565b60608261207f5761207a826120c6565b6108af565b815115801561209657506001600160a01b0384163b155b156120bf57604051639996b31560e01b81526001600160a01b03851660048201526024016104b5565b50806108af565b8051156120d65780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b50565b6001600160a01b03811681146120ef575f80fd5b80356104ee816120f2565b5f60208284031215612121575f80fd5b81356108af816120f2565b5f6020828403121561213c575f80fd5b5035919050565b828152606081016108af602083018480516001600160a01b03168252602090810151910152565b5f6020828403121561217a575f80fd5b81356001600160401b0381111561218f575f80fd5b820160e081850312156108af575f80fd5b5f61010082840312156121b1575f80fd5b50919050565b5f602082840312156121c7575f80fd5b81356001600160401b038111156121dc575f80fd5b611222848285016121a0565b5f80604083850312156121f9575f80fd5b50508035926020909101359150565b815181526020808301516001600160a01b031690820152604081016105fc565b5f805f6060848603121561223a575f80fd5b83359250602084013561224c816120f2565b929592945050506040919091013590565b5f805f6060848603121561226f575f80fd5b505081359360208301359350604090920135919050565b5f8083601f840112612296575f80fd5b5081356001600160401b038111156122ac575f80fd5b6020830191508360208260051b85010111156122c6575f80fd5b9250929050565b5f805f805f8086880360a08112156122e3575f80fd5b8735965060208801356001600160401b0380821115612300575f80fd5b61230c8b838c01612286565b90985096508691506040603f1984011215612325575f80fd5b60408a01955060808a013592508083111561233e575f80fd5b505061234c89828a01612286565b979a9699509497509295939492505050565b5f806040838503121561236f575f80fd5b823561237a816120f2565b9150602083013561238a816120f2565b809150509250929050565b5f80604083850312156123a6575f80fd5b823563ffffffff8116811461237a575f80fd5b5f80604083850312156123ca575f80fd5b8235915060208301356001600160401b038111156123e6575f80fd5b6123f2858286016121a0565b9150509250929050565b5f6020828403121561240c575f80fd5b5051919050565b60208082526027908201527f54656c65706f727465724d657373656e6765723a207a65726f20626c6f636b636040820152661a185a5b88125160ca1b606082015260800190565b60208082526023908201527f5265656e7472616e63794775617264733a2073656e646572207265656e7472616040820152626e637960e81b606082015260800190565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156124d3576124d361249d565b60405290565b60405160c081016001600160401b03811182821017156124d3576124d361249d565b60405161010081016001600160401b03811182821017156124d3576124d361249d565b604051601f8201601f191681016001600160401b03811182821017156125465761254661249d565b604052919050565b5f6040828403121561255e575f80fd5b6125666124b1565b90508135612573816120f2565b808252506020820135602082015292915050565b5f6001600160401b0382111561259f5761259f61249d565b5060051b60200190565b5f82601f8301126125b8575f80fd5b813560206125cd6125c883612587565b61251e565b8083825260208201915060208460051b8701019350868411156125ee575f80fd5b602086015b84811015612613578035612606816120f2565b83529183019183016125f3565b509695505050505050565b5f6001600160401b038211156126365761263661249d565b50601f01601f191660200190565b5f82601f830112612653575f80fd5b81356126616125c88261261e565b818152846020838601011115612675575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60e082360312156126a1575f80fd5b6126a96124d9565b823581526126b960208401612106565b60208201526126cb366040850161254e565b60408201526080830135606082015260a08301356001600160401b03808211156126f3575f80fd5b6126ff368387016125a9565b608084015260c0850135915080821115612717575f80fd5b5061272436828601612644565b60a08301525092915050565b60208082526026908201527f54656c65706f727465724d657373656e6765723a206d657373616765206e6f7460408201526508199bdd5b9960d21b606082015260800190565b5f808335601e1984360301811261278b575f80fd5b83016020810192503590506001600160401b038111156127a9575f80fd5b8060051b36038213156122c6575f80fd5b8183525f60208085019450825f5b858110156127f65781356127db816120f2565b6001600160a01b0316875295820195908201906001016127c8565b509495945050505050565b5f808335601e19843603018112612816575f80fd5b83016020810192503590506001600160401b03811115612834575f80fd5b8060061b36038213156122c6575f80fd5b8183525f60208085019450825f5b858110156127f657813587528282013561286c816120f2565b6001600160a01b0316878401526040968701969190910190600101612853565b5f808335601e198436030181126128a1575f80fd5b83016020810192503590506001600160401b038111156128bf575f80fd5b8036038213156122c6575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f61010082358452602083013561290b816120f2565b6001600160a01b031660208501526040838101359085015261292f60608401612106565b6001600160a01b031660608501526080838101359085015261295460a0840184612776565b8260a087015261296783870182846127ba565b9250505061297860c0840184612801565b85830360c087015261298b838284612845565b9250505061299c60e084018461288c565b85830360e08701526120608382846128cd565b602081525f6108af60208301846128f5565b60208082526029908201527f54656c65706f727465724d657373656e6765723a20696e76616c6964206d65736040820152680e6c2ceca40d0c2e6d60bb1b606082015260800190565b606081525f612a1c60608301856128f5565b90506108af602083018480516001600160a01b03168252602090810151910152565b5f5b83811015612a58578181015183820152602001612a40565b50505f910152565b5f8151808452612a77816020860160208601612a3e565b601f01601f19169290920160200192915050565b602081525f6108af6020830184612a60565b60208082526025908201527f5265656e7472616e63794775617264733a207265636569766572207265656e7460408201526472616e637960d81b606082015260800190565b60208082526034908201527f54656c65706f727465724d657373656e6765723a207a65726f2066656520617360408201527373657420636f6e7472616374206164647265737360601b606082015260800190565b634e487b7160e01b5f52601160045260245ffd5b808201808211156105fc576105fc612b36565b634e487b7160e01b5f52603260045260245ffd5b5f60408284031215612b81575f80fd5b6108af838361254e565b80516104ee816120f2565b5f82601f830112612ba5575f80fd5b8151612bb36125c88261261e565b818152846020838601011115612bc7575f80fd5b611222826020830160208701612a3e565b805180151581146104ee575f80fd5b5f8060408385031215612bf8575f80fd5b82516001600160401b0380821115612c0e575f80fd5b9084019060608287031215612c21575f80fd5b604051606081018181108382111715612c3c57612c3c61249d565b604052825181526020830151612c51816120f2565b6020820152604083015182811115612c67575f80fd5b612c7388828601612b96565b6040830152509350612c8a91505060208401612bd8565b90509250929050565b5f82601f830112612ca2575f80fd5b81516020612cb26125c883612587565b8083825260208201915060208460051b870101935086841115612cd3575f80fd5b602086015b84811015612613578051612ceb816120f2565b8352918301918301612cd8565b5f82601f830112612d07575f80fd5b81516020612d176125c883612587565b82815260069290921b84018101918181019086841115612d35575f80fd5b8286015b848110156126135760408189031215612d50575f80fd5b612d586124b1565b8151815284820151612d69816120f2565b81860152835291830191604001612d39565b5f60208284031215612d8b575f80fd5b81516001600160401b0380821115612da1575f80fd5b908301906101008286031215612db5575f80fd5b612dbd6124fb565b82518152612dcd60208401612b8b565b602082015260408301516040820152612de860608401612b8b565b60608201526080830151608082015260a083015182811115612e08575f80fd5b612e1487828601612c93565b60a08301525060c083015182811115612e2b575f80fd5b612e3787828601612cf8565b60c08301525060e083015182811115612e4e575f80fd5b612e5a87828601612b96565b60e08301525095945050505050565b5f815180845260208085019450602084015f5b838110156127f65781516001600160a01b031687529582019590820190600101612e7c565b5f815180845260208085019450602084015f5b838110156127f657612eda878351805182526020908101516001600160a01b0316910152565b6040969096019590820190600101612eb4565b5f6101008251845260018060a01b036020840151166020850152604083015160408501526060830151612f2b60608601826001600160a01b03169052565b506080830151608085015260a08301518160a0860152612f4d82860182612e69565b91505060c083015184820360c0860152612f678282612ea1565b91505060e083015184820360e0860152611a518282612a60565b6001600160a01b03831681526040602082018190525f9061122290830184612eed565b5f808335601e19843603018112612fb9575f80fd5b8301803591506001600160401b03821115612fd2575f80fd5b6020019150368190038213156122c6575f80fd5b8481526001600160a01b03841660208201526060604082018190525f9061206090830184866128cd565b818103818111156105fc576105fc612b36565b5f6001820161303457613034612b36565b5060010190565b602081525f6108af6020830184612eed565b606081525f612a1c6060830185612eed565b81516001600160a01b0316815260208083015190820152604081016105fc565b8381526001600160a01b03831660208201526060604082018190525f90611a5190830184612a60565b5f602082840312156130b8575f80fd5b6108af82612bd8565b5f82516130d2818460208701612a3e565b919091019291505056fea164736f6c6343000819000a", } // TeleporterMessengerABI is the input ABI used to generate the binding from. diff --git a/abi-bindings/go/teleporter/tests/TestMessenger/TestMessenger.go b/abi-bindings/go/teleporter/tests/TestMessenger/TestMessenger.go index 79d3255a3..71e916360 100644 --- a/abi-bindings/go/teleporter/tests/TestMessenger/TestMessenger.go +++ b/abi-bindings/go/teleporter/tests/TestMessenger/TestMessenger.go @@ -31,8 +31,8 @@ var ( // TestMessengerMetaData contains all meta data concerning the TestMessenger contract. var TestMessengerMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"teleporterRegistryAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"teleporterManager\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"minTeleporterVersion\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getCurrentMessage\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMinTeleporterVersion\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isTeleporterAddressPaused\",\"inputs\":[{\"name\":\"teleporterAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauseTeleporterAddress\",\"inputs\":[{\"name\":\"teleporterAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"receiveTeleporterMessage\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"sendMessage\",\"inputs\":[{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"feeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"message\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpauseTeleporterAddress\",\"inputs\":[{\"name\":\"teleporterAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateMinTeleporterVersion\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinTeleporterVersionUpdated\",\"inputs\":[{\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ReceiveMessage\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"message\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SendMessage\",\"inputs\":[{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"feeAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"message\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TeleporterAddressPaused\",\"inputs\":[{\"name\":\"teleporterAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TeleporterAddressUnpaused\",\"inputs\":[{\"name\":\"teleporterAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OwnableInvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SafeERC20FailedOperation\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"}]}]", - Bin: "0x608060405234801561000f575f80fd5b50604051611e44380380611e4483398101604081905261002e9161062e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff1615906001600160401b03165f811580156100775750825b90505f826001600160401b031660011480156100925750303b155b9050811580156100a0575080155b156100be5760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b031916600117855583156100ec57845460ff60401b1916680100000000000000001785555b6100f4610152565b6100ff888888610164565b831561014557845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505061067e565b61015a610184565b6101626101d2565b565b61016c610184565b6101768382610200565b61017f82610226565b505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff1661016257604051631afcd79f60e31b815260040160405180910390fd5b6101da610184565b60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b610208610184565b610210610152565b61021861023a565b6102228282610242565b5050565b61022e610184565b610237816103d1565b50565b610162610184565b61024a610184565b6001600160a01b0382166102cb5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f72746572207265676973747279206164647265737300000000000000000060648201526084015b60405180910390fd5b5f7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0090505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610330573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103549190610667565b116103a95760405162461bcd60e51b815260206004820152603260248201525f80516020611e24833981519152604482015271656c65706f7274657220726567697374727960701b60648201526084016102c2565b81546001600160a01b0319166001600160a01b0382161782556103cb8361040b565b50505050565b6103d9610184565b6001600160a01b03811661040257604051631e4fbdf760e01b81525f60048201526024016102c2565b610237816105a3565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0080546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa158015610472573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104969190610667565b6002830154909150818411156104f55760405162461bcd60e51b815260206004820152603160248201525f80516020611e2483398151915260448201527032b632b837b93a32b9103b32b939b4b7b760791b60648201526084016102c2565b80841161056a5760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e0060648201526084016102c2565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b80516001600160a01b0381168114610629575f80fd5b919050565b5f805f60608486031215610640575f80fd5b61064984610613565b925061065760208501610613565b9150604084015190509250925092565b5f60208284031215610677575f80fd5b5051919050565b6117998061068b5f395ff3fe608060405234801561000f575f80fd5b50600436106100b1575f3560e01c8063973142971161006e5780639731429714610159578063b33fead41461017c578063c868efaa1461019d578063d2cc7a70146101b0578063f2fde38b146101d7578063f63d09d7146101ea575f80fd5b80632b0d8f18146100b55780634511243e146100ca5780635eb99514146100dd578063715018a6146100f05780638da5cb5b146100f8578063909a6ac014610137575b5f80fd5b6100c86100c33660046111bc565b6101fd565b005b6100c86100d83660046111bc565b6102ff565b6100c86100eb3660046111d7565b6103ee565b6100c8610402565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546040516001600160a01b0390911681526020015b60405180910390f35b61014b5f8051602061176d83398151915281565b60405190815260200161012e565b61016c6101673660046111bc565b610415565b604051901515815260200161012e565b61018f61018a3660046111d7565b610435565b60405161012e92919061123b565b6100c86101ab3660046112ab565b610507565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d025461014b565b6100c86101e53660046111bc565b6106e5565b61014b6101f8366004611303565b61071f565b5f8051602061176d83398151915261021361087b565b6001600160a01b0382166102425760405162461bcd60e51b815260040161023990611383565b60405180910390fd5b61024c8183610883565b156102af5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b6064820152608401610239565b6001600160a01b0382165f81815260018381016020526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a25050565b5f8051602061176d83398151915261031561087b565b6001600160a01b03821661033b5760405162461bcd60e51b815260040161023990611383565b6103458183610883565b6103a35760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472794170703a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b6064820152608401610239565b6001600160a01b0382165f818152600183016020526040808220805460ff19169055517f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c39190a25050565b6103f661087b565b6103ff816108a7565b50565b61040a610a3f565b6104135f610a9a565b565b5f5f8051602061176d83398151915261042e8184610883565b9392505050565b5f81815260208181526040808320815180830190925280546001600160a01b031682526001810180546060948694939290840191610472906113d1565b80601f016020809104026020016040519081016040528092919081815260200182805461049e906113d1565b80156104e95780601f106104c0576101008083540402835291602001916104e9565b820191905f5260205f20905b8154815290600101906020018083116104cc57829003601f168201915b5050505050815250509050805f015181602001519250925050915091565b61050f610b0a565b5f5f8051602061176d83398151915260028101548154919250906001600160a01b0316634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561057a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061059e9190611409565b10156106055760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b6064820152608401610239565b61060f8133610883565b156106755760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b6064820152608401610239565b6106b5858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250610b5492505050565b506106df60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b50505050565b6106ed610a3f565b6001600160a01b03811661071657604051631e4fbdf760e01b81525f6004820152602401610239565b6103ff81610a9a565b5f610728610b0a565b5f851561073c576107398787610c09565b90505b876001600160a01b0316897fa06eff1edd0c66b8dc96d086dda7ba263edf88d7417e6cb15073b5e7bff8a8ca898489898960405161077e959493929190611448565b60405180910390a36108446040518060c001604052808b81526020018a6001600160a01b0316815260200160405180604001604052808b6001600160a01b031681526020018581525081526020018781526020015f67ffffffffffffffff8111156107eb576107eb611475565b604051908082528060200260200182016040528015610814578160200160208202803683370190505b508152602001868660405160200161082d929190611489565b604051602081830303815290604052815250610d6b565b91505061087060017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b979650505050505050565b610413610a3f565b6001600160a01b0381165f90815260018301602052604090205460ff165b92915050565b5f8051602061176d83398151915280546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa1580156108fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061091f9190611409565b6002830154909150818411156109915760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b6064820152608401610239565b808411610a065760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e006064820152608401610239565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b33610a717f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146104135760405163118cdaa760e01b8152336004820152602401610239565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00805460011901610b4e57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f81806020019051810190610b69919061149c565b6040805180820182526001600160a01b03868116825260208083018581525f8a815291829052939020825181546001600160a01b03191692169190911781559151929350916001820190610bbd9082611585565b50905050826001600160a01b0316847f1f5c800b5f2b573929a7948f82a199c2a212851b53a6c5bd703ece23999d24aa83604051610bfb9190611645565b60405180910390a350505050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038516906370a0823190602401602060405180830381865afa158015610c4f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c739190611409565b9050610c8a6001600160a01b038516333086610e86565b6040516370a0823160e01b81523060048201525f906001600160a01b038616906370a0823190602401602060405180830381865afa158015610cce573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cf29190611409565b9050818111610d585760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b6064820152608401610239565b610d62828261166b565b95945050505050565b5f80610d75610eed565b60408401516020015190915015610e1a576040830151516001600160a01b0316610df75760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a207a65726f206665652060448201526c746f6b656e206164647265737360981b6064820152608401610239565b604083015160208101519051610e1a916001600160a01b03909116908390610fdd565b604051630624488560e41b81526001600160a01b03821690636244885090610e469086906004016116c1565b6020604051808303815f875af1158015610e62573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061042e9190611409565b6040516001600160a01b0384811660248301528381166044830152606482018390526106df9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611064565b5f8051602061176d83398151915280546040805163d820e64f60e01b815290515f939284926001600160a01b039091169163d820e64f916004808201926020929091908290030181865afa158015610f47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f6b919061173e565b9050610f778282610883565b156108a15760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b6064820152608401610239565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa15801561102a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061104e9190611409565b90506106df848461105f8585611759565b6110d0565b5f8060205f8451602086015f885af180611083576040513d5f823e3d81fd5b50505f513d9150811561109a5780600114156110a7565b6001600160a01b0384163b155b156106df57604051635274afe760e01b81526001600160a01b0385166004820152602401610239565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052611121848261115f565b6106df576040516001600160a01b0384811660248301525f604483015261115591869182169063095ea7b390606401610ebb565b6106df8482611064565b5f805f8060205f8651602088015f8a5af192503d91505f51905082801561119e57508115611190578060011461119e565b5f866001600160a01b03163b115b9695505050505050565b6001600160a01b03811681146103ff575f80fd5b5f602082840312156111cc575f80fd5b813561042e816111a8565b5f602082840312156111e7575f80fd5b5035919050565b5f5b838110156112085781810151838201526020016111f0565b50505f910152565b5f81518084526112278160208601602086016111ee565b601f01601f19169290920160200192915050565b6001600160a01b03831681526040602082018190525f9061125e90830184611210565b949350505050565b5f8083601f840112611276575f80fd5b50813567ffffffffffffffff81111561128d575f80fd5b6020830191508360208285010111156112a4575f80fd5b9250929050565b5f805f80606085870312156112be575f80fd5b8435935060208501356112d0816111a8565b9250604085013567ffffffffffffffff8111156112eb575f80fd5b6112f787828801611266565b95989497509550505050565b5f805f805f805f60c0888a031215611319575f80fd5b87359650602088013561132b816111a8565b9550604088013561133b816111a8565b9450606088013593506080880135925060a088013567ffffffffffffffff811115611364575f80fd5b6113708a828b01611266565b989b979a50959850939692959293505050565b6020808252602e908201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b600181811c908216806113e557607f821691505b60208210810361140357634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215611419575f80fd5b5051919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60018060a01b0386168152846020820152836040820152608060608201525f610870608083018486611420565b634e487b7160e01b5f52604160045260245ffd5b602081525f61125e602083018486611420565b5f602082840312156114ac575f80fd5b815167ffffffffffffffff808211156114c3575f80fd5b818401915084601f8301126114d6575f80fd5b8151818111156114e8576114e8611475565b604051601f8201601f19908116603f0116810190838211818310171561151057611510611475565b81604052828152876020848701011115611528575f80fd5b6108708360208301602088016111ee565b601f82111561158057805f5260205f20601f840160051c8101602085101561155e5750805b601f840160051c820191505b8181101561157d575f815560010161156a565b50505b505050565b815167ffffffffffffffff81111561159f5761159f611475565b6115b3816115ad84546113d1565b84611539565b602080601f8311600181146115e6575f84156115cf5750858301515b5f19600386901b1c1916600185901b17855561163d565b5f85815260208120601f198616915b82811015611614578886015182559484019460019091019084016115f5565b508582101561163157878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b602081525f61042e6020830184611210565b634e487b7160e01b5f52601160045260245ffd5b818103818111156108a1576108a1611657565b5f815180845260208085019450602084015f5b838110156116b65781516001600160a01b031687529582019590820190600101611691565b509495945050505050565b60208152815160208201525f602083015160018060a01b03808216604085015260408501519150808251166060850152506020810151608084015250606083015160a0830152608083015160e060c084015261172161010084018261167e565b905060a0840151601f198483030160e0850152610d628282611210565b5f6020828403121561174e575f80fd5b815161042e816111a8565b808201808211156108a1576108a161165756fede77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00a164736f6c6343000819000a54656c65706f7274657252656769737472794170703a20696e76616c69642054", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"teleporterRegistryAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"teleporterManager\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"minTeleporterVersion\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"TELEPORTER_REGISTRY_APP_STORAGE_LOCATION\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getCurrentMessage\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getMinTeleporterVersion\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isTeleporterAddressPaused\",\"inputs\":[{\"name\":\"teleporterAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"pauseTeleporterAddress\",\"inputs\":[{\"name\":\"teleporterAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"receiveTeleporterMessage\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"message\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"sendMessage\",\"inputs\":[{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"feeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"message\",\"type\":\"string\",\"internalType\":\"string\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"unpauseTeleporterAddress\",\"inputs\":[{\"name\":\"teleporterAddress\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateMinTeleporterVersion\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"MinTeleporterVersionUpdated\",\"inputs\":[{\"name\":\"oldMinTeleporterVersion\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"newMinTeleporterVersion\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ReceiveMessage\",\"inputs\":[{\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"originSenderAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"message\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SendMessage\",\"inputs\":[{\"name\":\"destinationBlockchainID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"destinationAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"feeTokenAddress\",\"type\":\"address\",\"indexed\":false,\"internalType\":\"address\"},{\"name\":\"feeAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"requiredGasLimit\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"message\",\"type\":\"string\",\"indexed\":false,\"internalType\":\"string\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TeleporterAddressPaused\",\"inputs\":[{\"name\":\"teleporterAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"TeleporterAddressUnpaused\",\"inputs\":[{\"name\":\"teleporterAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AddressInsufficientBalance\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OwnableInvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SafeERC20FailedOperation\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"}]}]", + Bin: "0x608060405234801561000f575f80fd5b50604051611ff6380380611ff683398101604081905261002e9161062e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff1615906001600160401b03165f811580156100775750825b90505f826001600160401b031660011480156100925750303b155b9050811580156100a0575080155b156100be5760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b031916600117855583156100ec57845460ff60401b1916680100000000000000001785555b6100f4610152565b6100ff888888610164565b831561014557845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505061067e565b61015a610184565b6101626101d2565b565b61016c610184565b6101768382610200565b61017f82610226565b505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff1661016257604051631afcd79f60e31b815260040160405180910390fd5b6101da610184565b60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b610208610184565b610210610152565b61021861023a565b6102228282610242565b5050565b61022e610184565b610237816103d1565b50565b610162610184565b61024a610184565b6001600160a01b0382166102cb5760405162461bcd60e51b815260206004820152603760248201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560448201527f706f72746572207265676973747279206164647265737300000000000000000060648201526084015b60405180910390fd5b5f7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0090505f8390505f816001600160a01b031663c07f47d46040518163ffffffff1660e01b8152600401602060405180830381865afa158015610330573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103549190610667565b116103a95760405162461bcd60e51b815260206004820152603260248201525f80516020611fd6833981519152604482015271656c65706f7274657220726567697374727960701b60648201526084016102c2565b81546001600160a01b0319166001600160a01b0382161782556103cb8361040b565b50505050565b6103d9610184565b6001600160a01b03811661040257604051631e4fbdf760e01b81525f60048201526024016102c2565b610237816105a3565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d0080546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa158015610472573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104969190610667565b6002830154909150818411156104f55760405162461bcd60e51b815260206004820152603160248201525f80516020611fd683398151915260448201527032b632b837b93a32b9103b32b939b4b7b760791b60648201526084016102c2565b80841161056a5760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e0060648201526084016102c2565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b80516001600160a01b0381168114610629575f80fd5b919050565b5f805f60608486031215610640575f80fd5b61064984610613565b925061065760208501610613565b9150604084015190509250925092565b5f60208284031215610677575f80fd5b5051919050565b61194b8061068b5f395ff3fe608060405234801561000f575f80fd5b50600436106100b1575f3560e01c8063973142971161006e5780639731429714610159578063b33fead41461017c578063c868efaa1461019d578063d2cc7a70146101b0578063f2fde38b146101d7578063f63d09d7146101ea575f80fd5b80632b0d8f18146100b55780634511243e146100ca5780635eb99514146100dd578063715018a6146100f05780638da5cb5b146100f8578063909a6ac014610137575b5f80fd5b6100c86100c3366004611335565b6101fd565b005b6100c86100d8366004611335565b6102ff565b6100c86100eb366004611350565b6103ee565b6100c8610402565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546040516001600160a01b0390911681526020015b60405180910390f35b61014b5f8051602061191f83398151915281565b60405190815260200161012e565b61016c610167366004611335565b610415565b604051901515815260200161012e565b61018f61018a366004611350565b610435565b60405161012e9291906113b4565b6100c86101ab366004611424565b610507565b7fde77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d025461014b565b6100c86101e5366004611335565b6106e5565b61014b6101f836600461147c565b61071f565b5f8051602061191f83398151915261021361087b565b6001600160a01b0382166102425760405162461bcd60e51b8152600401610239906114fc565b60405180910390fd5b61024c8183610883565b156102af5760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a2061646472657373206160448201526c1b1c9958591e481c185d5cd959609a1b6064820152608401610239565b6001600160a01b0382165f81815260018381016020526040808320805460ff1916909217909155517f933f93e57a222e6330362af8b376d0a8725b6901e9a2fb86d00f169702b28a4c9190a25050565b5f8051602061191f83398151915261031561087b565b6001600160a01b03821661033b5760405162461bcd60e51b8152600401610239906114fc565b6103458183610883565b6103a35760405162461bcd60e51b815260206004820152602960248201527f54656c65706f7274657252656769737472794170703a2061646472657373206e6044820152681bdd081c185d5cd95960ba1b6064820152608401610239565b6001600160a01b0382165f818152600183016020526040808220805460ff19169055517f844e2f3154214672229235858fd029d1dfd543901c6d05931f0bc2480a2d72c39190a25050565b6103f661087b565b6103ff816108a7565b50565b61040a610a3f565b6104135f610a9a565b565b5f5f8051602061191f83398151915261042e8184610883565b9392505050565b5f81815260208181526040808320815180830190925280546001600160a01b0316825260018101805460609486949392908401916104729061154a565b80601f016020809104026020016040519081016040528092919081815260200182805461049e9061154a565b80156104e95780601f106104c0576101008083540402835291602001916104e9565b820191905f5260205f20905b8154815290600101906020018083116104cc57829003601f168201915b5050505050815250509050805f015181602001519250925050915091565b61050f610b0a565b5f5f8051602061191f83398151915260028101548154919250906001600160a01b0316634c1f08ce336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561057a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061059e9190611582565b10156106055760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201526f32b632b837b93a32b91039b2b73232b960811b6064820152608401610239565b61060f8133610883565b156106755760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881859191c995cdcc81c185d5cd95960821b6064820152608401610239565b6106b5858585858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250610b5492505050565b506106df60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b50505050565b6106ed610a3f565b6001600160a01b03811661071657604051631e4fbdf760e01b81525f6004820152602401610239565b6103ff81610a9a565b5f610728610b0a565b5f851561073c576107398787610c09565b90505b876001600160a01b0316897fa06eff1edd0c66b8dc96d086dda7ba263edf88d7417e6cb15073b5e7bff8a8ca898489898960405161077e9594939291906115c1565b60405180910390a36108446040518060c001604052808b81526020018a6001600160a01b0316815260200160405180604001604052808b6001600160a01b031681526020018581525081526020018781526020015f67ffffffffffffffff8111156107eb576107eb6115ee565b604051908082528060200260200182016040528015610814578160200160208202803683370190505b508152602001868660405160200161082d929190611602565b604051602081830303815290604052815250610d6b565b91505061087060017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b979650505050505050565b610413610a3f565b6001600160a01b0381165f90815260018301602052604090205460ff165b92915050565b5f8051602061191f83398151915280546040805163301fd1f560e21b815290515f926001600160a01b03169163c07f47d49160048083019260209291908290030181865afa1580156108fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061091f9190611582565b6002830154909150818411156109915760405162461bcd60e51b815260206004820152603160248201527f54656c65706f7274657252656769737472794170703a20696e76616c6964205460448201527032b632b837b93a32b9103b32b939b4b7b760791b6064820152608401610239565b808411610a065760405162461bcd60e51b815260206004820152603f60248201527f54656c65706f7274657252656769737472794170703a206e6f7420677265617460448201527f6572207468616e2063757272656e74206d696e696d756d2076657273696f6e006064820152608401610239565b60028301849055604051849082907fa9a7ef57e41f05b4c15480842f5f0c27edfcbb553fed281f7c4068452cc1c02d905f90a350505050565b33610a717f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146104135760405163118cdaa760e01b8152336004820152602401610239565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00805460011901610b4e57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f81806020019051810190610b699190611615565b6040805180820182526001600160a01b03868116825260208083018581525f8a815291829052939020825181546001600160a01b03191692169190911781559151929350916001820190610bbd90826116fd565b50905050826001600160a01b0316847f1f5c800b5f2b573929a7948f82a199c2a212851b53a6c5bd703ece23999d24aa83604051610bfb91906117bd565b60405180910390a350505050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038516906370a0823190602401602060405180830381865afa158015610c4f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c739190611582565b9050610c8a6001600160a01b038516333086610e86565b6040516370a0823160e01b81523060048201525f906001600160a01b038616906370a0823190602401602060405180830381865afa158015610cce573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cf29190611582565b9050818111610d585760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b6064820152608401610239565b610d6282826117e3565b95945050505050565b5f80610d75610eed565b60408401516020015190915015610e1a576040830151516001600160a01b0316610df75760405162461bcd60e51b815260206004820152602d60248201527f54656c65706f7274657252656769737472794170703a207a65726f206665652060448201526c746f6b656e206164647265737360981b6064820152608401610239565b604083015160208101519051610e1a916001600160a01b03909116908390610fdd565b604051630624488560e41b81526001600160a01b03821690636244885090610e46908690600401611839565b6020604051808303815f875af1158015610e62573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061042e9190611582565b6040516001600160a01b0384811660248301528381166044830152606482018390526106df9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050611064565b5f8051602061191f83398151915280546040805163d820e64f60e01b815290515f939284926001600160a01b039091169163d820e64f916004808201926020929091908290030181865afa158015610f47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f6b91906118b6565b9050610f778282610883565b156108a15760405162461bcd60e51b815260206004820152603060248201527f54656c65706f7274657252656769737472794170703a2054656c65706f72746560448201526f1c881cd95b991a5b99c81c185d5cd95960821b6064820152608401610239565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301525f919085169063dd62ed3e90604401602060405180830381865afa15801561102a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061104e9190611582565b90506106df848461105f85856118d1565b6110ca565b5f6110786001600160a01b03841683611159565b905080515f1415801561109c57508080602001905181019061109a91906118e4565b155b156110c557604051635274afe760e01b81526001600160a01b0384166004820152602401610239565b505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261111b8482611166565b6106df576040516001600160a01b0384811660248301525f604483015261114f91869182169063095ea7b390606401610ebb565b6106df8482611064565b606061042e83835f611203565b5f805f846001600160a01b0316846040516111819190611903565b5f604051808303815f865af19150503d805f81146111ba576040519150601f19603f3d011682016040523d82523d5f602084013e6111bf565b606091505b50915091508180156111e95750805115806111e95750808060200190518101906111e991906118e4565b8015610d625750505050506001600160a01b03163b151590565b6060814710156112285760405163cd78605960e01b8152306004820152602401610239565b5f80856001600160a01b031684866040516112439190611903565b5f6040518083038185875af1925050503d805f811461127d576040519150601f19603f3d011682016040523d82523d5f602084013e611282565b606091505b509150915061129286838361129c565b9695505050505050565b6060826112b1576112ac826112f8565b61042e565b81511580156112c857506001600160a01b0384163b155b156112f157604051639996b31560e01b81526001600160a01b0385166004820152602401610239565b508061042e565b8051156113085780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6001600160a01b03811681146103ff575f80fd5b5f60208284031215611345575f80fd5b813561042e81611321565b5f60208284031215611360575f80fd5b5035919050565b5f5b83811015611381578181015183820152602001611369565b50505f910152565b5f81518084526113a0816020860160208601611367565b601f01601f19169290920160200192915050565b6001600160a01b03831681526040602082018190525f906113d790830184611389565b949350505050565b5f8083601f8401126113ef575f80fd5b50813567ffffffffffffffff811115611406575f80fd5b60208301915083602082850101111561141d575f80fd5b9250929050565b5f805f8060608587031215611437575f80fd5b84359350602085013561144981611321565b9250604085013567ffffffffffffffff811115611464575f80fd5b611470878288016113df565b95989497509550505050565b5f805f805f805f60c0888a031215611492575f80fd5b8735965060208801356114a481611321565b955060408801356114b481611321565b9450606088013593506080880135925060a088013567ffffffffffffffff8111156114dd575f80fd5b6114e98a828b016113df565b989b979a50959850939692959293505050565b6020808252602e908201527f54656c65706f7274657252656769737472794170703a207a65726f2054656c6560408201526d706f72746572206164647265737360901b606082015260800190565b600181811c9082168061155e57607f821691505b60208210810361157c57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215611592575f80fd5b5051919050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60018060a01b0386168152846020820152836040820152608060608201525f610870608083018486611599565b634e487b7160e01b5f52604160045260245ffd5b602081525f6113d7602083018486611599565b5f60208284031215611625575f80fd5b815167ffffffffffffffff8082111561163c575f80fd5b818401915084601f83011261164f575f80fd5b815181811115611661576116616115ee565b604051601f8201601f19908116603f01168101908382118183101715611689576116896115ee565b816040528281528760208487010111156116a1575f80fd5b610870836020830160208801611367565b601f8211156110c557805f5260205f20601f840160051c810160208510156116d75750805b601f840160051c820191505b818110156116f6575f81556001016116e3565b5050505050565b815167ffffffffffffffff811115611717576117176115ee565b61172b81611725845461154a565b846116b2565b602080601f83116001811461175e575f84156117475750858301515b5f19600386901b1c1916600185901b1785556117b5565b5f85815260208120601f198616915b8281101561178c5788860151825594840194600190910190840161176d565b50858210156117a957878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b602081525f61042e6020830184611389565b634e487b7160e01b5f52601160045260245ffd5b818103818111156108a1576108a16117cf565b5f815180845260208085019450602084015f5b8381101561182e5781516001600160a01b031687529582019590820190600101611809565b509495945050505050565b60208152815160208201525f602083015160018060a01b03808216604085015260408501519150808251166060850152506020810151608084015250606083015160a0830152608083015160e060c08401526118996101008401826117f6565b905060a0840151601f198483030160e0850152610d628282611389565b5f602082840312156118c6575f80fd5b815161042e81611321565b808201808211156108a1576108a16117cf565b5f602082840312156118f4575f80fd5b8151801515811461042e575f80fd5b5f8251611914818460208701611367565b919091019291505056fede77a4dc7391f6f8f2d9567915d687d3aee79e7a1fc7300392f2727e9a0f1d00a164736f6c6343000819000a54656c65706f7274657252656769737472794170703a20696e76616c69642054", } // TestMessengerABI is the input ABI used to generate the binding from. diff --git a/abi-bindings/go/validator-manager/ERC20TokenStakingManager/ERC20TokenStakingManager.go b/abi-bindings/go/validator-manager/ERC20TokenStakingManager/ERC20TokenStakingManager.go new file mode 100644 index 000000000..6f9461ea6 --- /dev/null +++ b/abi-bindings/go/validator-manager/ERC20TokenStakingManager/ERC20TokenStakingManager.go @@ -0,0 +1,2671 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package erc20tokenstakingmanager + +import ( + "errors" + "math/big" + "strings" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = interfaces.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// InitialValidator is an auto generated low-level Go binding around an user-defined struct. +type InitialValidator struct { + NodeID [32]byte + Weight uint64 + BlsPublicKey []byte +} + +// PoSValidatorManagerSettings is an auto generated low-level Go binding around an user-defined struct. +type PoSValidatorManagerSettings struct { + BaseSettings ValidatorManagerSettings + MinimumStakeAmount *big.Int + MaximumStakeAmount *big.Int + MinimumStakeDuration uint64 + MinimumDelegationFeeBips uint16 + MaximumStakeMultiplier uint8 + RewardCalculator common.Address +} + +// SubnetConversionData is an auto generated low-level Go binding around an user-defined struct. +type SubnetConversionData struct { + ConvertSubnetTxID [32]byte + ValidatorManagerBlockchainID [32]byte + ValidatorManagerAddress common.Address + InitialValidators []InitialValidator +} + +// Validator is an auto generated low-level Go binding around an user-defined struct. +type Validator struct { + Status uint8 + NodeID [32]byte + StartingWeight uint64 + MessageNonce uint64 + Weight uint64 + StartedAt uint64 + EndedAt uint64 +} + +// ValidatorManagerSettings is an auto generated low-level Go binding around an user-defined struct. +type ValidatorManagerSettings struct { + SubnetID [32]byte + ChurnPeriodSeconds uint64 + MaximumChurnPercentage uint8 +} + +// ValidatorRegistrationInput is an auto generated low-level Go binding around an user-defined struct. +type ValidatorRegistrationInput struct { + NodeID [32]byte + RegistrationExpiry uint64 + BlsPublicKey []byte +} + +// ERC20TokenStakingManagerMetaData contains all meta data concerning the ERC20TokenStakingManager contract. +var ERC20TokenStakingManagerMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"init\",\"type\":\"uint8\",\"internalType\":\"enumICMInitializable\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"ADDRESS_LENGTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"BLS_PUBLIC_KEY_LENGTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAXIMUM_CHURN_PERCENTAGE_LIMIT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAXIMUM_DELEGATION_FEE_BIPS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAXIMUM_REGISTRATION_EXPIRY_LENGTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAXIMUM_STAKE_MULTIPLIER_LIMIT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"P_CHAIN_BLOCKCHAIN_ID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"WARP_MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIWarpMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimDelegationFees\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"completeDelegatorRegistration\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"delegationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"completeEndDelegation\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"delegationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"completeEndValidation\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"completeValidatorRegistration\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"endDelegationCompletedValidator\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getValidator\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structValidator\",\"components\":[{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumValidatorStatus\"},{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"startingWeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"messageNonce\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"weight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"startedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"endedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getWeight\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"settings\",\"type\":\"tuple\",\"internalType\":\"structPoSValidatorManagerSettings\",\"components\":[{\"name\":\"baseSettings\",\"type\":\"tuple\",\"internalType\":\"structValidatorManagerSettings\",\"components\":[{\"name\":\"subnetID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"churnPeriodSeconds\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"maximumChurnPercentage\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"minimumStakeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"maximumStakeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"minimumStakeDuration\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"minimumDelegationFeeBips\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"maximumStakeMultiplier\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"rewardCalculator\",\"type\":\"address\",\"internalType\":\"contractIRewardCalculator\"}]},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20Mintable\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeDelegatorRegistration\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"delegationAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeEndDelegation\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"includeUptimeProof\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeEndValidation\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"includeUptimeProof\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeValidatorRegistration\",\"inputs\":[{\"name\":\"registrationInput\",\"type\":\"tuple\",\"internalType\":\"structValidatorRegistrationInput\",\"components\":[{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registrationExpiry\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"delegationFeeBips\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"minStakeDuration\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stakeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeValidatorSet\",\"inputs\":[{\"name\":\"subnetConversionData\",\"type\":\"tuple\",\"internalType\":\"structSubnetConversionData\",\"components\":[{\"name\":\"convertSubnetTxID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"validatorManagerBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"validatorManagerAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"initialValidators\",\"type\":\"tuple[]\",\"internalType\":\"structInitialValidator[]\",\"components\":[{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"registeredValidators\",\"inputs\":[{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resendEndValidatorMessage\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resendRegisterValidatorMessage\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resendUpdateDelegation\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"valueToWeight\",\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"weightToValue\",\"inputs\":[{\"name\":\"weight\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"pure\"},{\"type\":\"event\",\"name\":\"DelegationEnded\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"rewards\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"fees\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DelegatorAdded\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"delegatorAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"nonce\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"validatorWeight\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"delegatorWeight\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"setWeightMessageID\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DelegatorRegistered\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nonce\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"startTime\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DelegatorRemovalInitialized\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"endTime\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"InitialValidatorCreated\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nodeID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodCreated\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nodeID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"registerValidationMessageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"registrationExpiry\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodEnded\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"status\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumValidatorStatus\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodRegistered\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorRemovalInitialized\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"setWeightMessageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"endTime\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorWeightUpdate\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nonce\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"validatorWeight\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"setWeightMessageID\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressEmptyCode\",\"inputs\":[{\"name\":\"target\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"AddressInsufficientBalance\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAddress\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidBlockchainID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidCodecID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidDelegationFee\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidDelegationID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidDelegatorStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidExpiry\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitializationStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInput\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidMessageLength\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidMessageType\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidNonce\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidStakeAmount\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidStakeDuration\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidStakeMultiplier\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSubnetConversionID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidValidationID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidValidatorStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidWarpMessage\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxChurnRateExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxWeightExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NodeAlreadyRegistered\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SafeERC20FailedOperation\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"UnexpectedRegistrationStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ValidatorNotPoS\",\"inputs\":[]}]", + Bin: "0x608060405234801561000f575f80fd5b5060405161568e38038061568e83398101604081905261002e91610107565b60018160018111156100425761004261012c565b0361004f5761004f610055565b50610140565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100a55760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101045780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60208284031215610117575f80fd5b815160028110610125575f80fd5b9392505050565b634e487b7160e01b5f52602160045260245ffd5b6155418061014d5f395ff3fe608060405234801561000f575f80fd5b50600436106101bb575f3560e01c806393e24598116100f3578063bee0a03f11610093578063df93d8de1161006e578063df93d8de146103cc578063e7d14c1c146103d6578063eb0acb8914610414578063f09969ae14610427575f80fd5b8063bee0a03f14610391578063c974d1b6146103a4578063d5f20ff6146103ac575f80fd5b80639e1bc4ef116100ce5780639e1bc4ef14610332578063a3a65e4814610345578063b771b3bc14610358578063ba3a4b971461037e575f80fd5b806393e24598146102f957806398f3e2b41461030c5780639dde029a1461031f575f80fd5b806360305d621161015e57806366435abf1161013957806366435abf146102c4578063732214f8146102d757806376f78621146102de5780638280a25a146102f1575f80fd5b806360305d621461027357806361e2f4901461029057806362065856146102a3575f80fd5b80632e2194d8116101995780632e2194d81461020657806335455ded14610231578063467ef06f1461024d5780635297fae614610260575f80fd5b80630118acc4146101bf5780630322ed98146101d4578063151d30d1146101e7575b5f80fd5b6101d26101cd366004614a7e565b61043a565b005b6101d26101e2366004614ab9565b6107e1565b6101ef600a81565b60405160ff90911681526020015b60405180910390f35b610219610214366004614ab9565b610953565b6040516001600160401b0390911681526020016101fd565b61023a61271081565b60405161ffff90911681526020016101fd565b6101d261025b366004614ad0565b610969565b6101d261026e366004614ae9565b610a0a565b61027b601481565b60405163ffffffff90911681526020016101fd565b6101d261029e366004614b11565b610de2565b6102b66102b1366004614b75565b611266565b6040519081526020016101fd565b6102196102d2366004614ab9565b61127f565b6102b65f81565b6101d26102ec366004614a7e565b611293565b6101ef603081565b6101d2610307366004614ab9565b61145e565b6101d261031a366004614ae9565b611519565b6101d261032d366004614ab9565b6116b9565b6102b6610340366004614b8e565b611930565b6101d2610353366004614ad0565b61195c565b6103666005600160991b0181565b6040516001600160a01b0390911681526020016101fd565b6101d261038c366004614ab9565b611ace565b6101d261039f366004614ab9565b611caa565b6101ef601481565b6103bf6103ba366004614ab9565b611dd4565b6040516101fd9190614bc2565b6102196202a30081565b6102b66103e4366004614ab9565b5f9081527fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb08602052604090205490565b6102b6610422366004614c82565b611e9c565b6101d2610435366004614cfb565b611ed1565b5f8381525f805160206154758339815191526020526040808220815160e0810190925280545f805160206154b583398151915293929190829060ff16600381111561048757610487614bae565b600381111561049857610498614bae565b8152815461010090046001600160a01b0316602082015260018201546040808301919091526002909201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c0909101528101519091505f61050e82611dd4565b905060028351600381111561052557610525614bae565b146105435760405163f95c7fe160e01b815260040160405180910390fd5b60208301516001600160a01b031633146105705760405163e6c4247b60e01b815260040160405180910390fd5b600383819052505f8060028351600581111561058e5761058e614bae565b036105df5787156105a6576105a38488611fb0565b91505b5f856060015184608001516105bb9190614d4d565b90506105c78582612134565b506001600160401b031660c087015250429050610611565b50505f82815260088501602052604090205460608201516001600160401b0390811660c0808701919091528301519116905b600386015460608601516001600160a01b039091169063778c06b59061063690611266565b8560a00151886080015185875f806040518863ffffffff1660e01b81526004016106669796959493929190614d6d565b602060405180830381865afa158015610681573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106a59190614dab565b5f8a8152600688016020908152604080832093909355600589019052208551815487929190829060ff191660018360038111156106e4576106e4614bae565b0217905550602082015181546001600160a01b0390911661010002610100600160a81b03199091161781556040808301516001830155606083015160029092018054608085015160a086015160c0909601516001600160401b03908116600160c01b026001600160c01b03978216600160801b02979097166001600160801b03928216600160401b026001600160801b031990941691909616179190911716929092179290921790555184908a907f5cd7ff518ea5cf079cc34b155d074410ae8c095910ebea921240641508658c69906107ce9085906001600160401b0391909116815260200190565b60405180910390a3505050505050505050565b5f8181525f805160206155158339815191526020526040808220815160e0810190925280545f805160206154d583398151915293929190829060ff16600581111561082e5761082e614bae565b600581111561083f5761083f614bae565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a08301526003928301541660c090910152909150815160058111156108ae576108ae614bae565b146108cc5760405163a36c527f60e01b815260040160405180910390fd5b6005600160991b016001600160a01b031663ee5b48eb6108f18584606001515f61228b565b6040518263ffffffff1660e01b815260040161090d9190614de4565b6020604051808303815f875af1158015610929573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061094d9190614dab565b50505050565b5f61096364e8d4a5100083614e16565b92915050565b5f805160206154b58339815191525f80610982846122e2565b9150915061098f82612580565b6109995750505050565b5f82815260048085016020526040909120546001600160a01b031690825160058111156109c8576109c8614bae565b036109ed575f838152600785016020526040812080549190556109eb82826125bb565b505b610a03816109fe8460400151611266565b612631565b5050505050565b5f8181525f805160206154758339815191526020526040808220815160e0810190925280545f805160206154b583398151915293929190829060ff166003811115610a5757610a57614bae565b6003811115610a6857610a68614bae565b8152815461010090046001600160a01b0316602082015260018201546040808301919091526002909201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c0909101528101519091505f90610adf90611dd4565b905060015f85815260058501602052604090205460ff166003811115610b0757610b07614bae565b14610b255760405163f95c7fe160e01b815260040160405180910390fd5b600381516005811115610b3a57610b3a614bae565b03610c8357600380835260c0828101516001600160401b039081166080860152606084015116908401525f8581526005850160205260409020835181548593839160ff1916906001908490811115610b9457610b94614bae565b02179055506020828101518254610100600160a81b0319166101006001600160a01b03909216919091021782556040808401516001840155606084015160029093018054608086015160a087015160c0978801516001600160401b039788166001600160801b031990941693909317600160401b92881692909202919091176001600160801b0316600160801b918716919091026001600160c01b031617600160c01b91861691909102179055858101519385015190519216825286917f5cd7ff518ea5cf079cc34b155d074410ae8c095910ebea921240641508658c69910160405180910390a35050505050565b600481516005811115610c9857610c98614bae565b03610ca657610a0384612654565b5f610cb086612831565b90505f80610cc18360400151612931565b509150915081856040015114610cea57604051636990657d60e01b815260040160405180910390fd5b806001600160401b031684606001516001600160401b03161080610d3257505f8781526005870160205260409020600201546001600160401b03808316600160801b90920416115b15610d5057604051633ab3447f60e11b815260040160405180910390fd5b5f878152600587016020908152604091829020805460ff1916600290811782550180546001600160401b0342818116600160401b026fffffffffffffffff00000000000000001990931692909217909255925192835283169184918a917f245fc69b36e168426e0306fc8d8300661b9af297c7958820dbf804f9f63e7064910160405180910390a45050505050505050565b7fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb09545f805160206154d58339815191529060ff1615610e3457604051637fab81e560e01b815260040160405180910390fd5b6005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e77573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e9b9190614dab565b836020013514610ebe5760405163d040949d60e01b815260040160405180910390fd5b30610ecf6060850160408601614e35565b6001600160a01b031614610ef65760405163e6c4247b60e01b815260040160405180910390fd5b5f610f046060850185614e50565b905090505f805b828163ffffffff1610156111b0575f610f276060880188614e50565b8363ffffffff16818110610f3d57610f3d614e95565b9050602002810190610f4f9190614ea9565b610f5890614f59565b80515f8181526008880160205260409020549192509015610f8c57604051630eb0d31360e11b815260040160405180910390fd5b5f6002895f013585604051602001610fbb92919091825260e01b6001600160e01b031916602082015260240190565b60408051601f1981840301815290829052610fd591614ff0565b602060405180830381855afa158015610ff0573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906110139190614dab565b5f8381526008890160209081526040808320849055805160e0810182526002815287518184015287830180516001600160401b039081168385015260608301869052905181166080830152421660a082015260c0810184905284845260078c01909252909120815181549394509192909190829060ff1916600183600581111561109f5761109f614bae565b0217905550602082810151600183015560408301516002830180546060860151608087015160a08801516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c0909301516003909201805467ffffffffffffffff191692841692909217909155840151611152911686615001565b83516020808601516040516001600160401b039091168152929750909183917fb815f891730222788b3f8d66249b3a287ce680c3df13866fd9a4f37743ae1014910160405180910390a3505050806111a990615014565b9050610f0b565b50600483018190555f6111c285612831565b90505f6111d28260400151612b6f565b90505f6111de88612ce4565b9050816002826040516111f19190614ff0565b602060405180830381855afa15801561120c573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061122f9190614dab565b1461124d57604051631e0e8fbd60e21b815260040160405180910390fd5b5050506009909201805460ff1916600117905550505050565b5f6109636001600160401b03831664e8d4a51000615036565b5f61128982611dd4565b6080015192915050565b5f805160206154b58339815191525f6112ab8561317d565b90506112b685612580565b6112c1575050505050565b5f8581526004830160205260409020546001600160a01b031633146112f95760405163e6c4247b60e01b815260040160405180910390fd5b5f85815260048301602052604090205460a082015161132891600160b01b90046001600160401b03169061504d565b6001600160401b03168160c001516001600160401b0316101561135e576040516302336bad60e51b815260040160405180910390fd5b8315610a03575f61136f8685611fb0565b5f87815260088501602052604090819020805467ffffffffffffffff19166001600160401b0384161790556003850154908401519192506001600160a01b03169063778c06b5906113bf90611266565b60a085015160c08601516040516001600160e01b031960e086901b1681526113f3939291829188905f908190600401614d6d565b602060405180830381865afa15801561140e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114329190614dab565b5f87815260078501602052604081208054909190611451908490615001565b9091555050505050505050565b5f805160206154b58339815191525f61147683611dd4565b905060048151600581111561148d5761148d614bae565b146114ab5760405163a36c527f60e01b815260040160405180910390fd5b5f8381526004830160205260409020546001600160a01b031633146114e35760405163e6c4247b60e01b815260040160405180910390fd5b5f8381526007830160209081526040808320805490849055600486019092529091205461094d906001600160a01b0316826125bb565b6115216133ba565b5f8181525f805160206154758339815191526020526040808220815160e0810190925280545f805160206154b583398151915293929190829060ff16600381111561156e5761156e614bae565b600381111561157f5761157f614bae565b8152815461010090046001600160a01b03166020820152600182015460408201526002909101546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c09091015290505f6115ed85612831565b90505f806115fe8360400151612931565b50915091508184604001511461162757604051636990657d60e01b815260040160405180910390fd5b806001600160401b03168460c001516001600160401b0316111561165e57604051633ab3447f60e11b815260040160405180910390fd5b60038451600381111561167357611673614bae565b146116915760405163f95c7fe160e01b815260040160405180910390fd5b61169a86612654565b50505050506116b560015f805160206154f583398151915255565b5050565b6116c16133ba565b5f8181525f805160206154758339815191526020526040808220815160e0810190925280545f805160206154b583398151915293929190829060ff16600381111561170e5761170e614bae565b600381111561171f5761171f614bae565b8152815461010090046001600160a01b0316602082015260018201546040808301919091526002909201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c0909101528101519091505f61179582611dd4565b90505f835160038111156117ab576117ab614bae565b036117c957604051631d0b665760e21b815260040160405180910390fd5b6004815160058111156117de576117de614bae565b146117fc5760405163a36c527f60e01b815260040160405180910390fd5b60018351600381111561181157611811614bae565b036118285761181f85612654565b50505050611917565b60028351600381111561183d5761183d614bae565b0361190957600384015460608401516001600160a01b039091169063778c06b59061186790611266565b60a0840151608087015160c08601515f88815260088b0160205260408082205490516001600160e01b031960e089901b1681526118b996959493926001600160401b0390921691908190600401614d6d565b602060405180830381865afa1580156118d4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118f89190614dab565b5f8681526006860160205260409020555b61191285612654565b505050505b61192d60015f805160206154f583398151915255565b50565b5f6119396133ba565b611944833384613404565b905061096360015f805160206154f583398151915255565b5f805160206154d58339815191525f61197483612831565b90505f8061198583604001516136cb565b91509150806119a757604051633dbcaef760e01b815260040160405180910390fd5b5f828152600685016020526040902080546119c19061506d565b90505f036119e257604051636990657d60e01b815260040160405180910390fd5b60015f83815260078601602052604090205460ff166005811115611a0857611a08614bae565b14611a265760405163a36c527f60e01b815260040160405180910390fd5b5f8281526006850160205260408120611a3e916149ce565b5f828152600785016020908152604091829020805460ff1916600290811782550180546001600160401b0342818116600160c01b026001600160c01b0390931692909217928390558451600160801b9093041682529181019190915283917ff8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568910160405180910390a25050505050565b5f8181525f805160206154758339815191526020526040808220815160e0810190925280545f805160206154b583398151915293929190829060ff166003811115611b1b57611b1b614bae565b6003811115611b2c57611b2c614bae565b8152815461010090046001600160a01b0316602082015260018083015460408301526002909201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c09091015290915081516003811115611ba557611ba5614bae565b14158015611bc65750600381516003811115611bc357611bc3614bae565b14155b15611be45760405163f95c7fe160e01b815260040160405180910390fd5b5f611bf28260400151611dd4565b905080606001516001600160401b03165f03611c2157604051631d0b665760e21b815260040160405180910390fd5b6005600160991b016001600160a01b031663ee5b48eb611c4e84604001518460600151856080015161228b565b6040518263ffffffff1660e01b8152600401611c6a9190614de4565b6020604051808303815f875af1158015611c86573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a039190614dab565b5f8181527fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb066020526040902080545f805160206154d58339815191529190611cf19061506d565b90505f03611d1257604051636990657d60e01b815260040160405180910390fd5b60015f83815260078301602052604090205460ff166005811115611d3857611d38614bae565b14611d565760405163a36c527f60e01b815260040160405180910390fd5b5f82815260068201602052604090819020905163ee5b48eb60e01b81526005600160991b019163ee5b48eb91611d8f91906004016150a5565b6020604051808303815f875af1158015611dab573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dcf9190614dab565b505050565b611ddc614a05565b5f8281525f80516020615515833981519152602052604090819020815160e0810190925280545f805160206154d5833981519152929190829060ff166005811115611e2957611e29614bae565b6005811115611e3a57611e3a614bae565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a083015260039092015490911660c0909101529392505050565b5f611ea56133ba565b611eb18585858561386f565b9050611ec960015f805160206154f583398151915255565b949350505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805460029190600160401b900460ff1680611f1a575080546001600160401b03808416911610155b15611f385760405163f92ee8a960e01b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155611f638484613a0d565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a150505050565b6040516306f8253560e41b815263ffffffff821660048201525f90819081906005600160991b0190636f825350906024015f60405180830381865afa158015611ffb573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612022919081019061513a565b915091508061204457604051636b2f19e960e01b815260040160405180910390fd5b6005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015612087573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120ab9190614dab565b8251146120cb5760405163d040949d60e01b815260040160405180910390fd5b60208201516001600160a01b0316156120f75760405163e6c4247b60e01b815260040160405180910390fd5b5f806121068460400151613a27565b9150915081871461212a57604051636990657d60e01b815260040160405180910390fd5b9695505050505050565b5f8281525f80516020615515833981519152602052604081206002015481905f805160206154d583398151915290600160801b90046001600160401b031661217c8582613c02565b5f61218687613dcb565b5f8881526007850160205260408120600201805467ffffffffffffffff60801b1916600160801b6001600160401b038b16021790559091506005600160991b0163ee5b48eb6121d68a858b61228b565b6040518263ffffffff1660e01b81526004016121f29190614de4565b6020604051808303815f875af115801561220e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906122329190614dab565b604080516001600160401b038a811682526020820184905282519394508516928b927f07de5ff35a674a8005e661f3333c907ca6333462808762d19dc7b3abb1a8c1df928290030190a3909450925050505b9250929050565b6040515f6020820152600160e11b6022820152602681018490526001600160c01b031960c084811b8216604684015283901b16604e82015260609060560160405160208183030381529060405290505b9392505050565b5f6122eb614a05565b5f805160206154d58339815191525f61230385612831565b90505f8061231483604001516136cb565b91509150801561233757604051633dbcaef760e01b815260040160405180910390fd5b5f828152600785016020526040808220815160e081019092528054829060ff16600581111561236857612368614bae565b600581111561237957612379614bae565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a08301526003928301541660c090910152909150815160058111156123e8576123e8614bae565b14158015612409575060018151600581111561240657612406614bae565b14155b156124275760405163a36c527f60e01b815260040160405180910390fd5b60038151600581111561243c5761243c614bae565b0361244a576004815261244f565b600581525b6020808201515f908152600887018252604080822082905585825260078801909252208151815483929190829060ff1916600183600581111561249457612494614bae565b02179055506020820151600182015560408201516002820180546060850151608086015160a08701516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c0909201516003909101805467ffffffffffffffff1916919092161790558051600581111561254857612548614bae565b60405184907f1c08e59656f1a18dc2da76826cdc52805c43e897a17c50faefb8ab3c1526cc16905f90a3919791965090945050505050565b5f9081527f4317713f7ecbdddd4bc99e95d903adedaa883b2e7c2551610bd13e2c7e473d0460205260409020546001600160a01b0316151590565b5f5f8051602061549583398151915280546040516340c10f1960e01b81526001600160a01b038681166004830152602482018690529293509116906340c10f19906044015f604051808303815f87803b158015612616575f80fd5b505af1158015612628573d5f803e3d5ffd5b50505050505050565b5f80516020615495833981519152546116b5906001600160a01b03168383613e40565b5f8181525f805160206154758339815191526020526040808220815160e0810190925280545f805160206154b583398151915293929190829060ff1660038111156126a1576126a1614bae565b60038111156126b2576126b2614bae565b8152815461010090046001600160a01b03166020808301919091526001808401546040808501919091526002948501546001600160401b038082166060870152600160401b820481166080870152600160801b8204811660a0870152600160c01b9091041660c090940193909352848301515f89815260058901845284812080546001600160a81b031916815592830181905591909401819055600687018252828120805490829055848252600488019092529182205493945091926127109061278790600160a01b900461ffff1684615036565b6127919190614e16565b905080856007015f8581526020019081526020015f205f8282546127b59190615001565b909155505f90506127c6828461520c565b90506127d68560200151826125bb565b6127eb85602001516109fe8760600151611266565b6040805182815260208101849052859189917f8ececf510070c320d9a55323ffabe350e294ae505fc0c509dc5736da6f5cc993910160405180910390a350505050505050565b60408051606080820183525f8083526020830152918101919091526040516306f8253560e41b815263ffffffff831660048201525f9081906005600160991b0190636f825350906024015f60405180830381865afa158015612895573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526128bc919081019061513a565b91509150806128de57604051636b2f19e960e01b815260040160405180910390fd5b8151156128fe5760405163d040949d60e01b815260040160405180910390fd5b60208201516001600160a01b03161561292a5760405163e6c4247b60e01b815260040160405180910390fd5b5092915050565b5f805f835160361461295657604051638d0242c960e01b815260040160405180910390fd5b5f805b60028110156129a55761296d81600161520c565b612978906008615036565b61ffff1686828151811061298e5761298e614e95565b016020015160f81c901b9190911790600101612959565b5061ffff8116156129c95760405163059510e360e31b815260040160405180910390fd5b5f805b6004811015612a24576129e081600361520c565b6129eb906008615036565b63ffffffff16876129fd836002615001565b81518110612a0d57612a0d614e95565b016020015160f81c901b91909117906001016129cc565b5063ffffffff8116600414612a4c57604051635b60892f60e01b815260040160405180910390fd5b5f805b6020811015612aa157612a6381601f61520c565b612a6e906008615036565b88612a7a836006615001565b81518110612a8a57612a8a614e95565b016020015160f81c901b9190911790600101612a4f565b505f805b6008811015612b0057612ab981600761520c565b612ac4906008615036565b6001600160401b031689612ad9836026615001565b81518110612ae957612ae9614e95565b016020015160f81c901b9190911790600101612aa5565b505f805b6008811015612b5f57612b1881600761520c565b612b23906008615036565b6001600160401b03168a612b3883602e615001565b81518110612b4857612b48614e95565b016020015160f81c901b9190911790600101612b04565b5091989097509095509350505050565b5f8151602614612b9257604051638d0242c960e01b815260040160405180910390fd5b5f805b6002811015612be157612ba981600161520c565b612bb4906008615036565b61ffff16848281518110612bca57612bca614e95565b016020015160f81c901b9190911790600101612b95565b5061ffff811615612c055760405163059510e360e31b815260040160405180910390fd5b5f805b6004811015612c6057612c1c81600361520c565b612c27906008615036565b63ffffffff1685612c39836002615001565b81518110612c4957612c49614e95565b016020015160f81c901b9190911790600101612c08565b5063ffffffff811615612c8657604051635b60892f60e01b815260040160405180910390fd5b5f805b6020811015612cdb57612c9d81601f61520c565b612ca8906008615036565b86612cb4836006615001565b81518110612cc457612cc4614e95565b016020015160f81c901b9190911790600101612c89565b50949350505050565b60605f612cf383830184614e50565b612cff91506058615036565b612d0a90605c615001565b6001600160401b03811115612d2157612d21614ec7565b6040519080825280601f01601f191660200182016040528015612d4b576020820181803683370190505b5090505f5b6020811015612da05783358160208110612d6c57612d6c614e95565b1a60f81b828281518110612d8257612d82614e95565b60200101906001600160f81b03191690815f1a905350600101612d50565b505f5b6020811015612e005783602001358160208110612dc257612dc2614e95565b1a60f81b82612dd2836020615001565b81518110612de257612de2614e95565b60200101906001600160f81b03191690815f1a905350600101612da3565b505f5b6004811015612e6357612e1781600361520c565b612e22906008615036565b6014901c60f81b82612e35836040615001565b81518110612e4557612e45614e95565b60200101906001600160f81b03191690815f1a905350600101612e03565b505f612e756060850160408601614e35565b60601b90505f5b6014811015612ed557818160148110612e9757612e97614e95565b1a60f81b83612ea7836044615001565b81518110612eb757612eb7614e95565b60200101906001600160f81b03191690815f1a905350600101612e7c565b505f612ee46060860186614e50565b905090505f5b6004811015612f4f57612efe81600361520c565b612f09906008615036565b63ffffffff8316901c60f81b84612f21836058615001565b81518110612f3157612f31614e95565b60200101906001600160f81b03191690815f1a905350600101612eea565b505f5b612f5f6060870187614e50565b9050811015613173575f612f74826058615036565b612f7f90605c615001565b90505f5b602081101561300a57612f996060890189614e50565b84818110612fa957612fa9614e95565b9050602002810190612fbb9190614ea9565b358160208110612fcd57612fcd614e95565b1a60f81b86612fdc8385615001565b81518110612fec57612fec614e95565b60200101906001600160f81b03191690815f1a905350600101612f83565b505f5b60088110156130bf5761302181600761520c565b61302c906008615036565b61303960608a018a614e50565b8581811061304957613049614e95565b905060200281019061305b9190614ea9565b61306c906040810190602001614b75565b6001600160401b0316901c60f81b8682613087856020615001565b6130919190615001565b815181106130a1576130a1614e95565b60200101906001600160f81b03191690815f1a90535060010161300d565b505f5b6030811015613169576130d86060890189614e50565b848181106130e8576130e8614e95565b90506020028101906130fa9190614ea9565b61310890604081019061521f565b8281811061311857613118614e95565b9050013560f81c60f81b86828460286131319190615001565b61313b9190615001565b8151811061314b5761314b614e95565b60200101906001600160f81b03191690815f1a9053506001016130c2565b5050600101612f52565b5091949350505050565b613185614a05565b5f8281525f805160206155158339815191526020526040808220815160e0810190925280545f805160206154d583398151915293929190829060ff1660058111156131d2576131d2614bae565b60058111156131e3576131e3614bae565b8152600182015460208201526002808301546001600160401b038082166040850152600160401b820481166060850152600160801b820481166080850152600160c01b909104811660a084015260039093015490921660c0909101529091508151600581111561325557613255614bae565b146132735760405163a36c527f60e01b815260040160405180910390fd5b60038152426001600160401b031660c08201525f84815260078301602052604090208151815483929190829060ff191660018360058111156132b7576132b7614bae565b02179055506020820151600182015560408201516002820180546060850151608086015160a08701516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c0909201516003909101805467ffffffffffffffff1916919092161790555f6133638582612134565b6080840151604080516001600160401b03909216825242602083015291935083925087917f13d58394cf269d48bcf927959a29a5ffee7c9924dafff8927ecdf3c48ffa7c67910160405180910390a3509392505050565b5f805160206154f58339815191528054600119016133eb57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b60015f805160206154f583398151915255565b5f5f805160206154b58339815191528161342061021485613e9f565b90505f61342c87611dd4565b905061343787612580565b61345457604051636ca57bcf60e01b815260040160405180910390fd5b60028151600581111561346957613469614bae565b146134875760405163a36c527f60e01b815260040160405180910390fd5b5f828260800151613498919061504d565b905083600201600a9054906101000a90046001600160401b031682604001516134c19190615261565b6001600160401b0316816001600160401b031611156134f357604051630c192e7760e41b815260040160405180910390fd5b5f806134ff8a84612134565b915091505f8a8360405160200161352d92919091825260c01b6001600160c01b031916602082015260280190565b60408051601f19818403018152828252805160209091012060e08301909152915080600181526001600160a01b038c1660208083019190915260408083018f90526001600160401b03808b1660608501525f6080850181905290881660a085015260c090930183905284835260058b01909152902081518154829060ff191660018360038111156135c0576135c0614bae565b02179055506020828101518254610100600160a81b0319166101006001600160a01b039283160217835560408085015160018501556060808601516002909501805460808089015160a08a015160c0909a01516001600160401b03998a166001600160801b031990941693909317600160401b918a1691909102176001600160801b0316600160801b998916999099026001600160c01b031698909817600160c01b91881691909102179055815189861681528a861694810194909452938b1690830152918101859052908c16918d9184917fb0024b263bc3a0b728a6edea50a69efa841189f8d32ee8af9d1c2b1a1a223426910160405180910390a49a9950505050505050505050565b5f8082516027146136ef57604051638d0242c960e01b815260040160405180910390fd5b5f805b600281101561373e5761370681600161520c565b613711906008615036565b61ffff1685828151811061372757613727614e95565b016020015160f81c901b91909117906001016136f2565b5061ffff8116156137625760405163059510e360e31b815260040160405180910390fd5b5f805b60048110156137bd5761377981600361520c565b613784906008615036565b63ffffffff1686613796836002615001565b815181106137a6576137a6614e95565b016020015160f81c901b9190911790600101613765565b5063ffffffff81166003146137e557604051635b60892f60e01b815260040160405180910390fd5b5f805b602081101561383a576137fc81601f61520c565b613807906008615036565b87613813836006615001565b8151811061382357613823614e95565b016020015160f81c901b91909117906001016137e8565b505f8660268151811061384f5761384f614e95565b016020015191976001600160f81b03199092161515965090945050505050565b7f4317713f7ecbdddd4bc99e95d903adedaa883b2e7c2551610bd13e2c7e473d02545f905f805160206154b583398151915290600160401b900461ffff90811690861610806138c3575061271061ffff8616115b156138e15760405163c98d73a760e01b815260040160405180910390fd5b60028101546001600160401b039081169085161015613913576040516302336bad60e51b815260040160405180910390fd5b80548310806139255750806001015483115b1561394357604051630103be3b60e21b815260040160405180910390fd5b5f61394d84613e9f565b90505f61395982610953565b90505f6139668983613ec2565b9050604051806060016040528061397a3390565b6001600160a01b03908116825261ffff808c166020808501919091526001600160401b03808d166040958601525f8781526004909a0182529884902085518154928701519690950151909916600160b01b0267ffffffffffffffff60b01b1995909216600160a01b026001600160b01b031990911693909216929092171791909116179093555090915050949350505050565b613a156142ac565b613a1e826142f7565b6116b581614365565b5f808251602e14613a4b57604051638d0242c960e01b815260040160405180910390fd5b5f805b6002811015613a9a57613a6281600161520c565b613a6d906008615036565b61ffff16858281518110613a8357613a83614e95565b016020015160f81c901b9190911790600101613a4e565b5061ffff811615613abe5760405163059510e360e31b815260040160405180910390fd5b5f805b6004811015613b1957613ad581600361520c565b613ae0906008615036565b63ffffffff1686613af2836002615001565b81518110613b0257613b02614e95565b016020015160f81c901b9190911790600101613ac1565b5063ffffffff8116600514613b4157604051635b60892f60e01b815260040160405180910390fd5b5f805b6020811015613b9657613b5881601f61520c565b613b63906008615036565b87613b6f836006615001565b81518110613b7f57613b7f614e95565b016020015160f81c901b9190911790600101613b44565b505f805b6008811015613bf557613bae81600761520c565b613bb9906008615036565b6001600160401b031688613bce836026615001565b81518110613bde57613bde614e95565b016020015160f81c901b9190911790600101613b9a565b5090969095509350505050565b5f805160206154d58339815191525f6001600160401b038084169085161115613c3657613c2f8385614d4d565b9050613c43565b613c408484614d4d565b90505b6040805160808101825260028401548082526003850154602083015260048501549282019290925260058401546001600160401b0316606082015242911580613ca5575060018401548151613ca1916001600160401b031690615001565b8210155b15613ccb576001600160401b038316606082015281815260408101516020820152613cea565b8281606001818151613cdd919061504d565b6001600160401b03169052505b6060810151613cfa906064615261565b602082015160018601546001600160401b039290921691613d259190600160401b900460ff16615036565b1015613d445760405163254d226960e01b815260040160405180910390fd5b856001600160401b031681604001818151613d5f9190615001565b9052506040810180516001600160401b0387169190613d7f90839061520c565b905250805160028501556020810151600385015560408101516004850155606001516005909301805467ffffffffffffffff19166001600160401b039094169390931790925550505050565b5f8181525f805160206155158339815191526020526040812060020180545f805160206154d58339815191529190600890613e1590600160401b90046001600160401b031661528c565b91906101000a8154816001600160401b0302191690836001600160401b031602179055915050919050565b6040516001600160a01b03838116602483015260448201839052611dcf91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506143c2565b5f610963825f80516020615495833981519152546001600160a01b031690614428565b7fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb09545f9060ff16613f0657604051637fab81e560e01b815260040160405180910390fd5b5f805160206154d583398151915242613f256040860160208701614b75565b6001600160401b0316111580613f5f5750613f436202a30042615001565b613f536040860160208701614b75565b6001600160401b031610155b15613f7c5760405162d36c8560e81b815260040160405180910390fd5b6030613f8b604086018661521f565b9050141580613f9957508335155b15613fb75760405163b4fa3fb360e01b815260040160405180910390fd5b83355f90815260088201602052604090205415613fe757604051630eb0d31360e11b815260040160405180910390fd5b613ff1835f613c02565b5f8061408a6040518060a00160405280855f01548152602001885f01358152602001876001600160401b031681526020018860200160208101906140359190614b75565b6001600160401b0316815260200161405060408a018a61521f565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250505091525061458a565b5f828152600686016020526040902091935091506140a882826152eb565b5085355f9081526008840160205260408082208490555163ee5b48eb60e01b81526005600160991b019063ee5b48eb906140e6908590600401614de4565b6020604051808303815f875af1158015614102573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906141269190614dab565b6040805160e08101909152909150806001815288356020808301919091526001600160401b03891660408084018290525f60608501819052608085019290925260a0840182905260c0909301819052868152600788019091522081518154829060ff1916600183600581111561419e5761419e614bae565b021790555060208281015160018301556040808401516002840180546060870151608088015160a08901516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c0909401516003909301805467ffffffffffffffff19169390941692909217909255829189359186917f79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e918b9161427e918e01908e01614b75565b604080516001600160401b0393841681529290911660208301520160405180910390a4509095945050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff166142f557604051631afcd79f60e31b815260040160405180910390fd5b565b6142ff6142ac565b6143088161464d565b614310614666565b61192d6060820135608083013561432d60c0850160a08601614b75565b61433d60e0860160c087016153aa565b61434e610100870160e088016153c3565b61436061012088016101008901614e35565b614676565b61436d6142ac565b5f805160206154958339815191526001600160a01b0382166143a25760405163e6c4247b60e01b815260040160405180910390fd5b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f6143d66001600160a01b03841683614797565b905080515f141580156143fa5750808060200190518101906143f891906153e3565b155b15611dcf57604051635274afe760e01b81526001600160a01b03841660048201526024015b60405180910390fd5b6040516370a0823160e01b81523060048201525f9081906001600160a01b038516906370a0823190602401602060405180830381865afa15801561446e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906144929190614dab565b90506144a96001600160a01b0385163330866147a4565b6040516370a0823160e01b81523060048201525f906001600160a01b038616906370a0823190602401602060405180830381865afa1580156144ed573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906145119190614dab565b90508181116145775760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b606482015260840161441f565b614581828261520c565b95945050505050565b5f60608260800151516030146145b357604051638d0242c960e01b815260040160405180910390fd5b5f806001855f015186602001518760400151886080015189606001516040516020016145e597969594939291906153fe565b60405160208183030381529060405290506002816040516146069190614ff0565b602060405180830381855afa158015614621573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906146449190614dab565b94909350915050565b6146556142ac565b61465d6147dd565b61192d816147e5565b61466e6142ac565b6142f56148b7565b61467e6142ac565b5f805160206154b583398151915261ffff841615806146a2575061271061ffff8516115b156146c05760405163c98d73a760e01b815260040160405180910390fd5b858711156146e157604051630103be3b60e21b815260040160405180910390fd5b60ff831615806146f45750600a60ff8416115b15614712576040516373c01c8d60e01b815260040160405180910390fd5b95865560018601949094556002850180546001600160401b039490941669ffffffffffffffffffff1990941693909317600160401b61ffff93909316929092029190911767ffffffffffffffff60501b191660ff91909116600160501b02179055600390910180546001600160a01b0319166001600160a01b03909216919091179055565b60606122db83835f6148bf565b6040516001600160a01b03848116602483015283811660448301526064820183905261094d9186918216906323b872dd90608401613e6d565b6142f56142ac565b6147ed6142ac565b80355f805160206154d5833981519152908155601461481260608401604085016153c3565b60ff161180614831575061482c60608301604084016153c3565b60ff16155b1561484f5760405163b4fa3fb360e01b815260040160405180910390fd5b61485f60608301604084016153c3565b60018201805460ff92909216600160401b0260ff60401b199092169190911790556148906040830160208401614b75565b600191909101805467ffffffffffffffff19166001600160401b0390921691909117905550565b6133f16142ac565b6060814710156148e45760405163cd78605960e01b815230600482015260240161441f565b5f80856001600160a01b031684866040516148ff9190614ff0565b5f6040518083038185875af1925050503d805f8114614939576040519150601f19603f3d011682016040523d82523d5f602084013e61493e565b606091505b509150915061212a86838360608261495e57614959826149a5565b6122db565b815115801561497557506001600160a01b0384163b155b1561499e57604051639996b31560e01b81526001600160a01b038516600482015260240161441f565b50806122db565b8051156149b55780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b5080546149da9061506d565b5f825580601f106149e9575050565b601f0160209004905f5260205f209081019061192d9190614a41565b6040805160e08101909152805f81525f6020820181905260408201819052606082018190526080820181905260a0820181905260c09091015290565b5b80821115614a55575f8155600101614a42565b5090565b801515811461192d575f80fd5b803563ffffffff81168114614a79575f80fd5b919050565b5f805f60608486031215614a90575f80fd5b833592506020840135614aa281614a59565b9150614ab060408501614a66565b90509250925092565b5f60208284031215614ac9575f80fd5b5035919050565b5f60208284031215614ae0575f80fd5b6122db82614a66565b5f8060408385031215614afa575f80fd5b614b0383614a66565b946020939093013593505050565b5f8060408385031215614b22575f80fd5b82356001600160401b03811115614b37575f80fd5b830160808186031215614b48575f80fd5b9150614b5660208401614a66565b90509250929050565b80356001600160401b0381168114614a79575f80fd5b5f60208284031215614b85575f80fd5b6122db82614b5f565b5f8060408385031215614b9f575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52602160045260245ffd5b815160e082019060068110614be557634e487b7160e01b5f52602160045260245ffd5b80835250602083015160208301526001600160401b0360408401511660408301526060830151614c2060608401826001600160401b03169052565b506080830151614c3b60808401826001600160401b03169052565b5060a0830151614c5660a08401826001600160401b03169052565b5060c083015161292a60c08401826001600160401b03169052565b803561ffff81168114614a79575f80fd5b5f805f8060808587031215614c95575f80fd5b84356001600160401b03811115614caa575f80fd5b850160608188031215614cbb575f80fd5b9350614cc960208601614c71565b9250614cd760408601614b5f565b9396929550929360600135925050565b6001600160a01b038116811461192d575f80fd5b5f80828403610140811215614d0e575f80fd5b61012080821215614d1d575f80fd5b8493508301359050614d2e81614ce7565b809150509250929050565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b0382811682821603908082111561292a5761292a614d39565b9687526001600160401b03958616602088015293851660408701529184166060860152909216608084015260a083019190915260c082015260e00190565b5f60208284031215614dbb575f80fd5b5051919050565b5f5b83811015614ddc578181015183820152602001614dc4565b50505f910152565b602081525f8251806020840152614e02816040850160208701614dc2565b601f01601f19169190910160400192915050565b5f82614e3057634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215614e45575f80fd5b81356122db81614ce7565b5f808335601e19843603018112614e65575f80fd5b8301803591506001600160401b03821115614e7e575f80fd5b6020019150600581901b3603821315612284575f80fd5b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112614ebd575f80fd5b9190910192915050565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b0381118282101715614efd57614efd614ec7565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614f2b57614f2b614ec7565b604052919050565b5f6001600160401b03821115614f4b57614f4b614ec7565b50601f01601f191660200190565b5f60608236031215614f69575f80fd5b614f71614edb565b823581526020614f82818501614b5f565b8183015260408401356001600160401b03811115614f9e575f80fd5b840136601f820112614fae575f80fd5b8035614fc1614fbc82614f33565b614f03565b8181523684838501011115614fd4575f80fd5b81848401858301375f9181019093015250604082015292915050565b5f8251614ebd818460208701614dc2565b8082018082111561096357610963614d39565b5f63ffffffff80831681810361502c5761502c614d39565b6001019392505050565b808202811582820484141761096357610963614d39565b6001600160401b0381811683821601908082111561292a5761292a614d39565b600181811c9082168061508157607f821691505b60208210810361509f57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208083525f84546150b78161506d565b806020870152604060018084165f81146150d857600181146150f457615121565b60ff19851660408a0152604084151560051b8a01019550615121565b895f5260205f205f5b858110156151185781548b82018601529083019088016150fd565b8a016040019650505b509398975050505050505050565b8051614a7981614a59565b5f806040838503121561514b575f80fd5b82516001600160401b0380821115615161575f80fd5b9084019060608287031215615174575f80fd5b61517c614edb565b8251815260208084015161518f81614ce7565b828201526040840151838111156151a4575f80fd5b80850194505087601f8501126151b8575f80fd5b835192506151c8614fbc84614f33565b83815288828587010111156151db575f80fd5b6151ea84838301848801614dc2565b806040840152508195506151ff81880161512f565b9450505050509250929050565b8181038181111561096357610963614d39565b5f808335601e19843603018112615234575f80fd5b8301803591506001600160401b0382111561524d575f80fd5b602001915036819003821315612284575f80fd5b6001600160401b0381811683821602808216919082811461528457615284614d39565b505092915050565b5f6001600160401b0380831681810361502c5761502c614d39565b601f821115611dcf57805f5260205f20601f840160051c810160208510156152cc5750805b601f840160051c820191505b81811015610a03575f81556001016152d8565b81516001600160401b0381111561530457615304614ec7565b61531881615312845461506d565b846152a7565b602080601f83116001811461534b575f84156153345750858301515b5f19600386901b1c1916600185901b1785556153a2565b5f85815260208120601f198616915b828110156153795788860151825594840194600190910190840161535a565b508582101561539657878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b5f602082840312156153ba575f80fd5b6122db82614c71565b5f602082840312156153d3575f80fd5b813560ff811681146122db575f80fd5b5f602082840312156153f3575f80fd5b81516122db81614a59565b61ffff60f01b8860f01b16815263ffffffff60e01b8760e01b1660028201528560068201528460268201525f6001600160401b0360c01b808660c01b166046840152845161545381604e860160208901614dc2565b60c09490941b1691909201604e81019190915260560197965050505050505056fe4317713f7ecbdddd4bc99e95d903adedaa883b2e7c2551610bd13e2c7e473d056e5bdfcce15e53c3406ea67bfce37dcd26f5152d5492824e43fd5e3c8ac5ab004317713f7ecbdddd4bc99e95d903adedaa883b2e7c2551610bd13e2c7e473d00e92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00e92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb07a164736f6c6343000819000a", +} + +// ERC20TokenStakingManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use ERC20TokenStakingManagerMetaData.ABI instead. +var ERC20TokenStakingManagerABI = ERC20TokenStakingManagerMetaData.ABI + +// ERC20TokenStakingManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ERC20TokenStakingManagerMetaData.Bin instead. +var ERC20TokenStakingManagerBin = ERC20TokenStakingManagerMetaData.Bin + +// DeployERC20TokenStakingManager deploys a new Ethereum contract, binding an instance of ERC20TokenStakingManager to it. +func DeployERC20TokenStakingManager(auth *bind.TransactOpts, backend bind.ContractBackend, init uint8) (common.Address, *types.Transaction, *ERC20TokenStakingManager, error) { + parsed, err := ERC20TokenStakingManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ERC20TokenStakingManagerBin), backend, init) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ERC20TokenStakingManager{ERC20TokenStakingManagerCaller: ERC20TokenStakingManagerCaller{contract: contract}, ERC20TokenStakingManagerTransactor: ERC20TokenStakingManagerTransactor{contract: contract}, ERC20TokenStakingManagerFilterer: ERC20TokenStakingManagerFilterer{contract: contract}}, nil +} + +// ERC20TokenStakingManager is an auto generated Go binding around an Ethereum contract. +type ERC20TokenStakingManager struct { + ERC20TokenStakingManagerCaller // Read-only binding to the contract + ERC20TokenStakingManagerTransactor // Write-only binding to the contract + ERC20TokenStakingManagerFilterer // Log filterer for contract events +} + +// ERC20TokenStakingManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type ERC20TokenStakingManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenStakingManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ERC20TokenStakingManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenStakingManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ERC20TokenStakingManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenStakingManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ERC20TokenStakingManagerSession struct { + Contract *ERC20TokenStakingManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenStakingManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ERC20TokenStakingManagerCallerSession struct { + Contract *ERC20TokenStakingManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ERC20TokenStakingManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ERC20TokenStakingManagerTransactorSession struct { + Contract *ERC20TokenStakingManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenStakingManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type ERC20TokenStakingManagerRaw struct { + Contract *ERC20TokenStakingManager // Generic contract binding to access the raw methods on +} + +// ERC20TokenStakingManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ERC20TokenStakingManagerCallerRaw struct { + Contract *ERC20TokenStakingManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// ERC20TokenStakingManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ERC20TokenStakingManagerTransactorRaw struct { + Contract *ERC20TokenStakingManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewERC20TokenStakingManager creates a new instance of ERC20TokenStakingManager, bound to a specific deployed contract. +func NewERC20TokenStakingManager(address common.Address, backend bind.ContractBackend) (*ERC20TokenStakingManager, error) { + contract, err := bindERC20TokenStakingManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManager{ERC20TokenStakingManagerCaller: ERC20TokenStakingManagerCaller{contract: contract}, ERC20TokenStakingManagerTransactor: ERC20TokenStakingManagerTransactor{contract: contract}, ERC20TokenStakingManagerFilterer: ERC20TokenStakingManagerFilterer{contract: contract}}, nil +} + +// NewERC20TokenStakingManagerCaller creates a new read-only instance of ERC20TokenStakingManager, bound to a specific deployed contract. +func NewERC20TokenStakingManagerCaller(address common.Address, caller bind.ContractCaller) (*ERC20TokenStakingManagerCaller, error) { + contract, err := bindERC20TokenStakingManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerCaller{contract: contract}, nil +} + +// NewERC20TokenStakingManagerTransactor creates a new write-only instance of ERC20TokenStakingManager, bound to a specific deployed contract. +func NewERC20TokenStakingManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*ERC20TokenStakingManagerTransactor, error) { + contract, err := bindERC20TokenStakingManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerTransactor{contract: contract}, nil +} + +// NewERC20TokenStakingManagerFilterer creates a new log filterer instance of ERC20TokenStakingManager, bound to a specific deployed contract. +func NewERC20TokenStakingManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*ERC20TokenStakingManagerFilterer, error) { + contract, err := bindERC20TokenStakingManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerFilterer{contract: contract}, nil +} + +// bindERC20TokenStakingManager binds a generic wrapper to an already deployed contract. +func bindERC20TokenStakingManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ERC20TokenStakingManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenStakingManager.Contract.ERC20TokenStakingManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ERC20TokenStakingManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ERC20TokenStakingManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenStakingManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.contract.Transact(opts, method, params...) +} + +// ADDRESSLENGTH is a free data retrieval call binding the contract method 0x60305d62. +// +// Solidity: function ADDRESS_LENGTH() view returns(uint32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) ADDRESSLENGTH(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "ADDRESS_LENGTH") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// ADDRESSLENGTH is a free data retrieval call binding the contract method 0x60305d62. +// +// Solidity: function ADDRESS_LENGTH() view returns(uint32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ADDRESSLENGTH() (uint32, error) { + return _ERC20TokenStakingManager.Contract.ADDRESSLENGTH(&_ERC20TokenStakingManager.CallOpts) +} + +// ADDRESSLENGTH is a free data retrieval call binding the contract method 0x60305d62. +// +// Solidity: function ADDRESS_LENGTH() view returns(uint32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) ADDRESSLENGTH() (uint32, error) { + return _ERC20TokenStakingManager.Contract.ADDRESSLENGTH(&_ERC20TokenStakingManager.CallOpts) +} + +// BLSPUBLICKEYLENGTH is a free data retrieval call binding the contract method 0x8280a25a. +// +// Solidity: function BLS_PUBLIC_KEY_LENGTH() view returns(uint8) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) BLSPUBLICKEYLENGTH(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "BLS_PUBLIC_KEY_LENGTH") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// BLSPUBLICKEYLENGTH is a free data retrieval call binding the contract method 0x8280a25a. +// +// Solidity: function BLS_PUBLIC_KEY_LENGTH() view returns(uint8) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) BLSPUBLICKEYLENGTH() (uint8, error) { + return _ERC20TokenStakingManager.Contract.BLSPUBLICKEYLENGTH(&_ERC20TokenStakingManager.CallOpts) +} + +// BLSPUBLICKEYLENGTH is a free data retrieval call binding the contract method 0x8280a25a. +// +// Solidity: function BLS_PUBLIC_KEY_LENGTH() view returns(uint8) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) BLSPUBLICKEYLENGTH() (uint8, error) { + return _ERC20TokenStakingManager.Contract.BLSPUBLICKEYLENGTH(&_ERC20TokenStakingManager.CallOpts) +} + +// MAXIMUMCHURNPERCENTAGELIMIT is a free data retrieval call binding the contract method 0xc974d1b6. +// +// Solidity: function MAXIMUM_CHURN_PERCENTAGE_LIMIT() view returns(uint8) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) MAXIMUMCHURNPERCENTAGELIMIT(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "MAXIMUM_CHURN_PERCENTAGE_LIMIT") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// MAXIMUMCHURNPERCENTAGELIMIT is a free data retrieval call binding the contract method 0xc974d1b6. +// +// Solidity: function MAXIMUM_CHURN_PERCENTAGE_LIMIT() view returns(uint8) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) MAXIMUMCHURNPERCENTAGELIMIT() (uint8, error) { + return _ERC20TokenStakingManager.Contract.MAXIMUMCHURNPERCENTAGELIMIT(&_ERC20TokenStakingManager.CallOpts) +} + +// MAXIMUMCHURNPERCENTAGELIMIT is a free data retrieval call binding the contract method 0xc974d1b6. +// +// Solidity: function MAXIMUM_CHURN_PERCENTAGE_LIMIT() view returns(uint8) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) MAXIMUMCHURNPERCENTAGELIMIT() (uint8, error) { + return _ERC20TokenStakingManager.Contract.MAXIMUMCHURNPERCENTAGELIMIT(&_ERC20TokenStakingManager.CallOpts) +} + +// MAXIMUMDELEGATIONFEEBIPS is a free data retrieval call binding the contract method 0x35455ded. +// +// Solidity: function MAXIMUM_DELEGATION_FEE_BIPS() view returns(uint16) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) MAXIMUMDELEGATIONFEEBIPS(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "MAXIMUM_DELEGATION_FEE_BIPS") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +// MAXIMUMDELEGATIONFEEBIPS is a free data retrieval call binding the contract method 0x35455ded. +// +// Solidity: function MAXIMUM_DELEGATION_FEE_BIPS() view returns(uint16) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) MAXIMUMDELEGATIONFEEBIPS() (uint16, error) { + return _ERC20TokenStakingManager.Contract.MAXIMUMDELEGATIONFEEBIPS(&_ERC20TokenStakingManager.CallOpts) +} + +// MAXIMUMDELEGATIONFEEBIPS is a free data retrieval call binding the contract method 0x35455ded. +// +// Solidity: function MAXIMUM_DELEGATION_FEE_BIPS() view returns(uint16) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) MAXIMUMDELEGATIONFEEBIPS() (uint16, error) { + return _ERC20TokenStakingManager.Contract.MAXIMUMDELEGATIONFEEBIPS(&_ERC20TokenStakingManager.CallOpts) +} + +// MAXIMUMREGISTRATIONEXPIRYLENGTH is a free data retrieval call binding the contract method 0xdf93d8de. +// +// Solidity: function MAXIMUM_REGISTRATION_EXPIRY_LENGTH() view returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) MAXIMUMREGISTRATIONEXPIRYLENGTH(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "MAXIMUM_REGISTRATION_EXPIRY_LENGTH") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// MAXIMUMREGISTRATIONEXPIRYLENGTH is a free data retrieval call binding the contract method 0xdf93d8de. +// +// Solidity: function MAXIMUM_REGISTRATION_EXPIRY_LENGTH() view returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) MAXIMUMREGISTRATIONEXPIRYLENGTH() (uint64, error) { + return _ERC20TokenStakingManager.Contract.MAXIMUMREGISTRATIONEXPIRYLENGTH(&_ERC20TokenStakingManager.CallOpts) +} + +// MAXIMUMREGISTRATIONEXPIRYLENGTH is a free data retrieval call binding the contract method 0xdf93d8de. +// +// Solidity: function MAXIMUM_REGISTRATION_EXPIRY_LENGTH() view returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) MAXIMUMREGISTRATIONEXPIRYLENGTH() (uint64, error) { + return _ERC20TokenStakingManager.Contract.MAXIMUMREGISTRATIONEXPIRYLENGTH(&_ERC20TokenStakingManager.CallOpts) +} + +// MAXIMUMSTAKEMULTIPLIERLIMIT is a free data retrieval call binding the contract method 0x151d30d1. +// +// Solidity: function MAXIMUM_STAKE_MULTIPLIER_LIMIT() view returns(uint8) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) MAXIMUMSTAKEMULTIPLIERLIMIT(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "MAXIMUM_STAKE_MULTIPLIER_LIMIT") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// MAXIMUMSTAKEMULTIPLIERLIMIT is a free data retrieval call binding the contract method 0x151d30d1. +// +// Solidity: function MAXIMUM_STAKE_MULTIPLIER_LIMIT() view returns(uint8) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) MAXIMUMSTAKEMULTIPLIERLIMIT() (uint8, error) { + return _ERC20TokenStakingManager.Contract.MAXIMUMSTAKEMULTIPLIERLIMIT(&_ERC20TokenStakingManager.CallOpts) +} + +// MAXIMUMSTAKEMULTIPLIERLIMIT is a free data retrieval call binding the contract method 0x151d30d1. +// +// Solidity: function MAXIMUM_STAKE_MULTIPLIER_LIMIT() view returns(uint8) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) MAXIMUMSTAKEMULTIPLIERLIMIT() (uint8, error) { + return _ERC20TokenStakingManager.Contract.MAXIMUMSTAKEMULTIPLIERLIMIT(&_ERC20TokenStakingManager.CallOpts) +} + +// PCHAINBLOCKCHAINID is a free data retrieval call binding the contract method 0x732214f8. +// +// Solidity: function P_CHAIN_BLOCKCHAIN_ID() view returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) PCHAINBLOCKCHAINID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "P_CHAIN_BLOCKCHAIN_ID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// PCHAINBLOCKCHAINID is a free data retrieval call binding the contract method 0x732214f8. +// +// Solidity: function P_CHAIN_BLOCKCHAIN_ID() view returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) PCHAINBLOCKCHAINID() ([32]byte, error) { + return _ERC20TokenStakingManager.Contract.PCHAINBLOCKCHAINID(&_ERC20TokenStakingManager.CallOpts) +} + +// PCHAINBLOCKCHAINID is a free data retrieval call binding the contract method 0x732214f8. +// +// Solidity: function P_CHAIN_BLOCKCHAIN_ID() view returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) PCHAINBLOCKCHAINID() ([32]byte, error) { + return _ERC20TokenStakingManager.Contract.PCHAINBLOCKCHAINID(&_ERC20TokenStakingManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) WARPMESSENGER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "WARP_MESSENGER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) WARPMESSENGER() (common.Address, error) { + return _ERC20TokenStakingManager.Contract.WARPMESSENGER(&_ERC20TokenStakingManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) WARPMESSENGER() (common.Address, error) { + return _ERC20TokenStakingManager.Contract.WARPMESSENGER(&_ERC20TokenStakingManager.CallOpts) +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes32,uint64,uint64,uint64,uint64,uint64)) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) GetValidator(opts *bind.CallOpts, validationID [32]byte) (Validator, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "getValidator", validationID) + + if err != nil { + return *new(Validator), err + } + + out0 := *abi.ConvertType(out[0], new(Validator)).(*Validator) + + return out0, err + +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes32,uint64,uint64,uint64,uint64,uint64)) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) GetValidator(validationID [32]byte) (Validator, error) { + return _ERC20TokenStakingManager.Contract.GetValidator(&_ERC20TokenStakingManager.CallOpts, validationID) +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes32,uint64,uint64,uint64,uint64,uint64)) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) GetValidator(validationID [32]byte) (Validator, error) { + return _ERC20TokenStakingManager.Contract.GetValidator(&_ERC20TokenStakingManager.CallOpts, validationID) +} + +// GetWeight is a free data retrieval call binding the contract method 0x66435abf. +// +// Solidity: function getWeight(bytes32 validationID) view returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) GetWeight(opts *bind.CallOpts, validationID [32]byte) (uint64, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "getWeight", validationID) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// GetWeight is a free data retrieval call binding the contract method 0x66435abf. +// +// Solidity: function getWeight(bytes32 validationID) view returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) GetWeight(validationID [32]byte) (uint64, error) { + return _ERC20TokenStakingManager.Contract.GetWeight(&_ERC20TokenStakingManager.CallOpts, validationID) +} + +// GetWeight is a free data retrieval call binding the contract method 0x66435abf. +// +// Solidity: function getWeight(bytes32 validationID) view returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) GetWeight(validationID [32]byte) (uint64, error) { + return _ERC20TokenStakingManager.Contract.GetWeight(&_ERC20TokenStakingManager.CallOpts, validationID) +} + +// RegisteredValidators is a free data retrieval call binding the contract method 0xe7d14c1c. +// +// Solidity: function registeredValidators(bytes32 nodeID) view returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) RegisteredValidators(opts *bind.CallOpts, nodeID [32]byte) ([32]byte, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "registeredValidators", nodeID) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// RegisteredValidators is a free data retrieval call binding the contract method 0xe7d14c1c. +// +// Solidity: function registeredValidators(bytes32 nodeID) view returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) RegisteredValidators(nodeID [32]byte) ([32]byte, error) { + return _ERC20TokenStakingManager.Contract.RegisteredValidators(&_ERC20TokenStakingManager.CallOpts, nodeID) +} + +// RegisteredValidators is a free data retrieval call binding the contract method 0xe7d14c1c. +// +// Solidity: function registeredValidators(bytes32 nodeID) view returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) RegisteredValidators(nodeID [32]byte) ([32]byte, error) { + return _ERC20TokenStakingManager.Contract.RegisteredValidators(&_ERC20TokenStakingManager.CallOpts, nodeID) +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) pure returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) ValueToWeight(opts *bind.CallOpts, value *big.Int) (uint64, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "valueToWeight", value) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) pure returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ValueToWeight(value *big.Int) (uint64, error) { + return _ERC20TokenStakingManager.Contract.ValueToWeight(&_ERC20TokenStakingManager.CallOpts, value) +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) pure returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) ValueToWeight(value *big.Int) (uint64, error) { + return _ERC20TokenStakingManager.Contract.ValueToWeight(&_ERC20TokenStakingManager.CallOpts, value) +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) pure returns(uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) WeightToValue(opts *bind.CallOpts, weight uint64) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "weightToValue", weight) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) pure returns(uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) WeightToValue(weight uint64) (*big.Int, error) { + return _ERC20TokenStakingManager.Contract.WeightToValue(&_ERC20TokenStakingManager.CallOpts, weight) +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) pure returns(uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) WeightToValue(weight uint64) (*big.Int, error) { + return _ERC20TokenStakingManager.Contract.WeightToValue(&_ERC20TokenStakingManager.CallOpts, weight) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) ClaimDelegationFees(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "claimDelegationFees", validationID) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ClaimDelegationFees(validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ClaimDelegationFees(&_ERC20TokenStakingManager.TransactOpts, validationID) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) ClaimDelegationFees(validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ClaimDelegationFees(&_ERC20TokenStakingManager.TransactOpts, validationID) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x5297fae6. +// +// Solidity: function completeDelegatorRegistration(uint32 messageIndex, bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) CompleteDelegatorRegistration(opts *bind.TransactOpts, messageIndex uint32, delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "completeDelegatorRegistration", messageIndex, delegationID) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x5297fae6. +// +// Solidity: function completeDelegatorRegistration(uint32 messageIndex, bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) CompleteDelegatorRegistration(messageIndex uint32, delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteDelegatorRegistration(&_ERC20TokenStakingManager.TransactOpts, messageIndex, delegationID) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x5297fae6. +// +// Solidity: function completeDelegatorRegistration(uint32 messageIndex, bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) CompleteDelegatorRegistration(messageIndex uint32, delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteDelegatorRegistration(&_ERC20TokenStakingManager.TransactOpts, messageIndex, delegationID) +} + +// CompleteEndDelegation is a paid mutator transaction binding the contract method 0x98f3e2b4. +// +// Solidity: function completeEndDelegation(uint32 messageIndex, bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) CompleteEndDelegation(opts *bind.TransactOpts, messageIndex uint32, delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "completeEndDelegation", messageIndex, delegationID) +} + +// CompleteEndDelegation is a paid mutator transaction binding the contract method 0x98f3e2b4. +// +// Solidity: function completeEndDelegation(uint32 messageIndex, bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) CompleteEndDelegation(messageIndex uint32, delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteEndDelegation(&_ERC20TokenStakingManager.TransactOpts, messageIndex, delegationID) +} + +// CompleteEndDelegation is a paid mutator transaction binding the contract method 0x98f3e2b4. +// +// Solidity: function completeEndDelegation(uint32 messageIndex, bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) CompleteEndDelegation(messageIndex uint32, delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteEndDelegation(&_ERC20TokenStakingManager.TransactOpts, messageIndex, delegationID) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0x467ef06f. +// +// Solidity: function completeEndValidation(uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) CompleteEndValidation(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "completeEndValidation", messageIndex) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0x467ef06f. +// +// Solidity: function completeEndValidation(uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) CompleteEndValidation(messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteEndValidation(&_ERC20TokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0x467ef06f. +// +// Solidity: function completeEndValidation(uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) CompleteEndValidation(messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteEndValidation(&_ERC20TokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) CompleteValidatorRegistration(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "completeValidatorRegistration", messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteValidatorRegistration(&_ERC20TokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteValidatorRegistration(&_ERC20TokenStakingManager.TransactOpts, messageIndex) +} + +// EndDelegationCompletedValidator is a paid mutator transaction binding the contract method 0x9dde029a. +// +// Solidity: function endDelegationCompletedValidator(bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) EndDelegationCompletedValidator(opts *bind.TransactOpts, delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "endDelegationCompletedValidator", delegationID) +} + +// EndDelegationCompletedValidator is a paid mutator transaction binding the contract method 0x9dde029a. +// +// Solidity: function endDelegationCompletedValidator(bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) EndDelegationCompletedValidator(delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.EndDelegationCompletedValidator(&_ERC20TokenStakingManager.TransactOpts, delegationID) +} + +// EndDelegationCompletedValidator is a paid mutator transaction binding the contract method 0x9dde029a. +// +// Solidity: function endDelegationCompletedValidator(bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) EndDelegationCompletedValidator(delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.EndDelegationCompletedValidator(&_ERC20TokenStakingManager.TransactOpts, delegationID) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf09969ae. +// +// Solidity: function initialize(((bytes32,uint64,uint8),uint256,uint256,uint64,uint16,uint8,address) settings, address token) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) Initialize(opts *bind.TransactOpts, settings PoSValidatorManagerSettings, token common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initialize", settings, token) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf09969ae. +// +// Solidity: function initialize(((bytes32,uint64,uint8),uint256,uint256,uint64,uint16,uint8,address) settings, address token) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) Initialize(settings PoSValidatorManagerSettings, token common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.Initialize(&_ERC20TokenStakingManager.TransactOpts, settings, token) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf09969ae. +// +// Solidity: function initialize(((bytes32,uint64,uint8),uint256,uint256,uint64,uint16,uint8,address) settings, address token) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) Initialize(settings PoSValidatorManagerSettings, token common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.Initialize(&_ERC20TokenStakingManager.TransactOpts, settings, token) +} + +// InitializeDelegatorRegistration is a paid mutator transaction binding the contract method 0x9e1bc4ef. +// +// Solidity: function initializeDelegatorRegistration(bytes32 validationID, uint256 delegationAmount) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) InitializeDelegatorRegistration(opts *bind.TransactOpts, validationID [32]byte, delegationAmount *big.Int) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initializeDelegatorRegistration", validationID, delegationAmount) +} + +// InitializeDelegatorRegistration is a paid mutator transaction binding the contract method 0x9e1bc4ef. +// +// Solidity: function initializeDelegatorRegistration(bytes32 validationID, uint256 delegationAmount) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) InitializeDelegatorRegistration(validationID [32]byte, delegationAmount *big.Int) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeDelegatorRegistration(&_ERC20TokenStakingManager.TransactOpts, validationID, delegationAmount) +} + +// InitializeDelegatorRegistration is a paid mutator transaction binding the contract method 0x9e1bc4ef. +// +// Solidity: function initializeDelegatorRegistration(bytes32 validationID, uint256 delegationAmount) returns(bytes32) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) InitializeDelegatorRegistration(validationID [32]byte, delegationAmount *big.Int) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeDelegatorRegistration(&_ERC20TokenStakingManager.TransactOpts, validationID, delegationAmount) +} + +// InitializeEndDelegation is a paid mutator transaction binding the contract method 0x0118acc4. +// +// Solidity: function initializeEndDelegation(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) InitializeEndDelegation(opts *bind.TransactOpts, delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initializeEndDelegation", delegationID, includeUptimeProof, messageIndex) +} + +// InitializeEndDelegation is a paid mutator transaction binding the contract method 0x0118acc4. +// +// Solidity: function initializeEndDelegation(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) InitializeEndDelegation(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeEndDelegation(&_ERC20TokenStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// InitializeEndDelegation is a paid mutator transaction binding the contract method 0x0118acc4. +// +// Solidity: function initializeEndDelegation(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) InitializeEndDelegation(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeEndDelegation(&_ERC20TokenStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x76f78621. +// +// Solidity: function initializeEndValidation(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) InitializeEndValidation(opts *bind.TransactOpts, validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initializeEndValidation", validationID, includeUptimeProof, messageIndex) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x76f78621. +// +// Solidity: function initializeEndValidation(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) InitializeEndValidation(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeEndValidation(&_ERC20TokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x76f78621. +// +// Solidity: function initializeEndValidation(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) InitializeEndValidation(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeEndValidation(&_ERC20TokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0xeb0acb89. +// +// Solidity: function initializeValidatorRegistration((bytes32,uint64,bytes) registrationInput, uint16 delegationFeeBips, uint64 minStakeDuration, uint256 stakeAmount) returns(bytes32 validationID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) InitializeValidatorRegistration(opts *bind.TransactOpts, registrationInput ValidatorRegistrationInput, delegationFeeBips uint16, minStakeDuration uint64, stakeAmount *big.Int) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initializeValidatorRegistration", registrationInput, delegationFeeBips, minStakeDuration, stakeAmount) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0xeb0acb89. +// +// Solidity: function initializeValidatorRegistration((bytes32,uint64,bytes) registrationInput, uint16 delegationFeeBips, uint64 minStakeDuration, uint256 stakeAmount) returns(bytes32 validationID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) InitializeValidatorRegistration(registrationInput ValidatorRegistrationInput, delegationFeeBips uint16, minStakeDuration uint64, stakeAmount *big.Int) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeValidatorRegistration(&_ERC20TokenStakingManager.TransactOpts, registrationInput, delegationFeeBips, minStakeDuration, stakeAmount) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0xeb0acb89. +// +// Solidity: function initializeValidatorRegistration((bytes32,uint64,bytes) registrationInput, uint16 delegationFeeBips, uint64 minStakeDuration, uint256 stakeAmount) returns(bytes32 validationID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) InitializeValidatorRegistration(registrationInput ValidatorRegistrationInput, delegationFeeBips uint16, minStakeDuration uint64, stakeAmount *big.Int) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeValidatorRegistration(&_ERC20TokenStakingManager.TransactOpts, registrationInput, delegationFeeBips, minStakeDuration, stakeAmount) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x61e2f490. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes32,uint64,bytes)[]) subnetConversionData, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) InitializeValidatorSet(opts *bind.TransactOpts, subnetConversionData SubnetConversionData, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initializeValidatorSet", subnetConversionData, messageIndex) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x61e2f490. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes32,uint64,bytes)[]) subnetConversionData, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) InitializeValidatorSet(subnetConversionData SubnetConversionData, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeValidatorSet(&_ERC20TokenStakingManager.TransactOpts, subnetConversionData, messageIndex) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x61e2f490. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes32,uint64,bytes)[]) subnetConversionData, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) InitializeValidatorSet(subnetConversionData SubnetConversionData, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeValidatorSet(&_ERC20TokenStakingManager.TransactOpts, subnetConversionData, messageIndex) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) ResendEndValidatorMessage(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "resendEndValidatorMessage", validationID) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ResendEndValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ResendEndValidatorMessage(&_ERC20TokenStakingManager.TransactOpts, validationID) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) ResendEndValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ResendEndValidatorMessage(&_ERC20TokenStakingManager.TransactOpts, validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) ResendRegisterValidatorMessage(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "resendRegisterValidatorMessage", validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ResendRegisterValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ResendRegisterValidatorMessage(&_ERC20TokenStakingManager.TransactOpts, validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) ResendRegisterValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ResendRegisterValidatorMessage(&_ERC20TokenStakingManager.TransactOpts, validationID) +} + +// ResendUpdateDelegation is a paid mutator transaction binding the contract method 0xba3a4b97. +// +// Solidity: function resendUpdateDelegation(bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) ResendUpdateDelegation(opts *bind.TransactOpts, delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "resendUpdateDelegation", delegationID) +} + +// ResendUpdateDelegation is a paid mutator transaction binding the contract method 0xba3a4b97. +// +// Solidity: function resendUpdateDelegation(bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ResendUpdateDelegation(delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ResendUpdateDelegation(&_ERC20TokenStakingManager.TransactOpts, delegationID) +} + +// ResendUpdateDelegation is a paid mutator transaction binding the contract method 0xba3a4b97. +// +// Solidity: function resendUpdateDelegation(bytes32 delegationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) ResendUpdateDelegation(delegationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ResendUpdateDelegation(&_ERC20TokenStakingManager.TransactOpts, delegationID) +} + +// ERC20TokenStakingManagerDelegationEndedIterator is returned from FilterDelegationEnded and is used to iterate over the raw logs and unpacked data for DelegationEnded events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerDelegationEndedIterator struct { + Event *ERC20TokenStakingManagerDelegationEnded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerDelegationEndedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerDelegationEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerDelegationEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerDelegationEndedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerDelegationEndedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerDelegationEnded represents a DelegationEnded event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerDelegationEnded struct { + DelegationID [32]byte + ValidationID [32]byte + Rewards *big.Int + Fees *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegationEnded is a free log retrieval operation binding the contract event 0x8ececf510070c320d9a55323ffabe350e294ae505fc0c509dc5736da6f5cc993. +// +// Solidity: event DelegationEnded(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterDelegationEnded(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*ERC20TokenStakingManagerDelegationEndedIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "DelegationEnded", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerDelegationEndedIterator{contract: _ERC20TokenStakingManager.contract, event: "DelegationEnded", logs: logs, sub: sub}, nil +} + +// WatchDelegationEnded is a free log subscription operation binding the contract event 0x8ececf510070c320d9a55323ffabe350e294ae505fc0c509dc5736da6f5cc993. +// +// Solidity: event DelegationEnded(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchDelegationEnded(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerDelegationEnded, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "DelegationEnded", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerDelegationEnded) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "DelegationEnded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDelegationEnded is a log parse operation binding the contract event 0x8ececf510070c320d9a55323ffabe350e294ae505fc0c509dc5736da6f5cc993. +// +// Solidity: event DelegationEnded(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseDelegationEnded(log types.Log) (*ERC20TokenStakingManagerDelegationEnded, error) { + event := new(ERC20TokenStakingManagerDelegationEnded) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "DelegationEnded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerDelegatorAddedIterator is returned from FilterDelegatorAdded and is used to iterate over the raw logs and unpacked data for DelegatorAdded events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerDelegatorAddedIterator struct { + Event *ERC20TokenStakingManagerDelegatorAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerDelegatorAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerDelegatorAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerDelegatorAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerDelegatorAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerDelegatorAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerDelegatorAdded represents a DelegatorAdded event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerDelegatorAdded struct { + DelegationID [32]byte + ValidationID [32]byte + DelegatorAddress common.Address + Nonce uint64 + ValidatorWeight uint64 + DelegatorWeight uint64 + SetWeightMessageID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegatorAdded is a free log retrieval operation binding the contract event 0xb0024b263bc3a0b728a6edea50a69efa841189f8d32ee8af9d1c2b1a1a223426. +// +// Solidity: event DelegatorAdded(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterDelegatorAdded(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte, delegatorAddress []common.Address) (*ERC20TokenStakingManagerDelegatorAddedIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var delegatorAddressRule []interface{} + for _, delegatorAddressItem := range delegatorAddress { + delegatorAddressRule = append(delegatorAddressRule, delegatorAddressItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "DelegatorAdded", delegationIDRule, validationIDRule, delegatorAddressRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerDelegatorAddedIterator{contract: _ERC20TokenStakingManager.contract, event: "DelegatorAdded", logs: logs, sub: sub}, nil +} + +// WatchDelegatorAdded is a free log subscription operation binding the contract event 0xb0024b263bc3a0b728a6edea50a69efa841189f8d32ee8af9d1c2b1a1a223426. +// +// Solidity: event DelegatorAdded(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchDelegatorAdded(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerDelegatorAdded, delegationID [][32]byte, validationID [][32]byte, delegatorAddress []common.Address) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var delegatorAddressRule []interface{} + for _, delegatorAddressItem := range delegatorAddress { + delegatorAddressRule = append(delegatorAddressRule, delegatorAddressItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "DelegatorAdded", delegationIDRule, validationIDRule, delegatorAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerDelegatorAdded) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "DelegatorAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDelegatorAdded is a log parse operation binding the contract event 0xb0024b263bc3a0b728a6edea50a69efa841189f8d32ee8af9d1c2b1a1a223426. +// +// Solidity: event DelegatorAdded(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseDelegatorAdded(log types.Log) (*ERC20TokenStakingManagerDelegatorAdded, error) { + event := new(ERC20TokenStakingManagerDelegatorAdded) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "DelegatorAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerDelegatorRegisteredIterator is returned from FilterDelegatorRegistered and is used to iterate over the raw logs and unpacked data for DelegatorRegistered events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerDelegatorRegisteredIterator struct { + Event *ERC20TokenStakingManagerDelegatorRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerDelegatorRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerDelegatorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerDelegatorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerDelegatorRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerDelegatorRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerDelegatorRegistered represents a DelegatorRegistered event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerDelegatorRegistered struct { + DelegationID [32]byte + ValidationID [32]byte + Nonce uint64 + StartTime *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegatorRegistered is a free log retrieval operation binding the contract event 0x245fc69b36e168426e0306fc8d8300661b9af297c7958820dbf804f9f63e7064. +// +// Solidity: event DelegatorRegistered(bytes32 indexed delegationID, bytes32 indexed validationID, uint64 indexed nonce, uint256 startTime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterDelegatorRegistered(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte, nonce []uint64) (*ERC20TokenStakingManagerDelegatorRegisteredIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "DelegatorRegistered", delegationIDRule, validationIDRule, nonceRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerDelegatorRegisteredIterator{contract: _ERC20TokenStakingManager.contract, event: "DelegatorRegistered", logs: logs, sub: sub}, nil +} + +// WatchDelegatorRegistered is a free log subscription operation binding the contract event 0x245fc69b36e168426e0306fc8d8300661b9af297c7958820dbf804f9f63e7064. +// +// Solidity: event DelegatorRegistered(bytes32 indexed delegationID, bytes32 indexed validationID, uint64 indexed nonce, uint256 startTime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchDelegatorRegistered(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerDelegatorRegistered, delegationID [][32]byte, validationID [][32]byte, nonce []uint64) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "DelegatorRegistered", delegationIDRule, validationIDRule, nonceRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerDelegatorRegistered) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "DelegatorRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDelegatorRegistered is a log parse operation binding the contract event 0x245fc69b36e168426e0306fc8d8300661b9af297c7958820dbf804f9f63e7064. +// +// Solidity: event DelegatorRegistered(bytes32 indexed delegationID, bytes32 indexed validationID, uint64 indexed nonce, uint256 startTime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseDelegatorRegistered(log types.Log) (*ERC20TokenStakingManagerDelegatorRegistered, error) { + event := new(ERC20TokenStakingManagerDelegatorRegistered) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "DelegatorRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerDelegatorRemovalInitializedIterator is returned from FilterDelegatorRemovalInitialized and is used to iterate over the raw logs and unpacked data for DelegatorRemovalInitialized events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerDelegatorRemovalInitializedIterator struct { + Event *ERC20TokenStakingManagerDelegatorRemovalInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerDelegatorRemovalInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerDelegatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerDelegatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerDelegatorRemovalInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerDelegatorRemovalInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerDelegatorRemovalInitialized represents a DelegatorRemovalInitialized event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerDelegatorRemovalInitialized struct { + DelegationID [32]byte + ValidationID [32]byte + EndTime *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegatorRemovalInitialized is a free log retrieval operation binding the contract event 0x5cd7ff518ea5cf079cc34b155d074410ae8c095910ebea921240641508658c69. +// +// Solidity: event DelegatorRemovalInitialized(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 endTime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterDelegatorRemovalInitialized(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*ERC20TokenStakingManagerDelegatorRemovalInitializedIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "DelegatorRemovalInitialized", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerDelegatorRemovalInitializedIterator{contract: _ERC20TokenStakingManager.contract, event: "DelegatorRemovalInitialized", logs: logs, sub: sub}, nil +} + +// WatchDelegatorRemovalInitialized is a free log subscription operation binding the contract event 0x5cd7ff518ea5cf079cc34b155d074410ae8c095910ebea921240641508658c69. +// +// Solidity: event DelegatorRemovalInitialized(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 endTime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchDelegatorRemovalInitialized(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerDelegatorRemovalInitialized, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "DelegatorRemovalInitialized", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerDelegatorRemovalInitialized) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "DelegatorRemovalInitialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDelegatorRemovalInitialized is a log parse operation binding the contract event 0x5cd7ff518ea5cf079cc34b155d074410ae8c095910ebea921240641508658c69. +// +// Solidity: event DelegatorRemovalInitialized(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 endTime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseDelegatorRemovalInitialized(log types.Log) (*ERC20TokenStakingManagerDelegatorRemovalInitialized, error) { + event := new(ERC20TokenStakingManagerDelegatorRemovalInitialized) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "DelegatorRemovalInitialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerInitialValidatorCreatedIterator is returned from FilterInitialValidatorCreated and is used to iterate over the raw logs and unpacked data for InitialValidatorCreated events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitialValidatorCreatedIterator struct { + Event *ERC20TokenStakingManagerInitialValidatorCreated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerInitialValidatorCreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitialValidatorCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitialValidatorCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerInitialValidatorCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerInitialValidatorCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerInitialValidatorCreated represents a InitialValidatorCreated event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitialValidatorCreated struct { + ValidationID [32]byte + NodeID [32]byte + Weight *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialValidatorCreated is a free log retrieval operation binding the contract event 0xb815f891730222788b3f8d66249b3a287ce680c3df13866fd9a4f37743ae1014. +// +// Solidity: event InitialValidatorCreated(bytes32 indexed validationID, bytes32 indexed nodeID, uint256 weight) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterInitialValidatorCreated(opts *bind.FilterOpts, validationID [][32]byte, nodeID [][32]byte) (*ERC20TokenStakingManagerInitialValidatorCreatedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "InitialValidatorCreated", validationIDRule, nodeIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerInitialValidatorCreatedIterator{contract: _ERC20TokenStakingManager.contract, event: "InitialValidatorCreated", logs: logs, sub: sub}, nil +} + +// WatchInitialValidatorCreated is a free log subscription operation binding the contract event 0xb815f891730222788b3f8d66249b3a287ce680c3df13866fd9a4f37743ae1014. +// +// Solidity: event InitialValidatorCreated(bytes32 indexed validationID, bytes32 indexed nodeID, uint256 weight) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchInitialValidatorCreated(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerInitialValidatorCreated, validationID [][32]byte, nodeID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "InitialValidatorCreated", validationIDRule, nodeIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerInitialValidatorCreated) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "InitialValidatorCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialValidatorCreated is a log parse operation binding the contract event 0xb815f891730222788b3f8d66249b3a287ce680c3df13866fd9a4f37743ae1014. +// +// Solidity: event InitialValidatorCreated(bytes32 indexed validationID, bytes32 indexed nodeID, uint256 weight) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseInitialValidatorCreated(log types.Log) (*ERC20TokenStakingManagerInitialValidatorCreated, error) { + event := new(ERC20TokenStakingManagerInitialValidatorCreated) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "InitialValidatorCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitializedIterator struct { + Event *ERC20TokenStakingManagerInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerInitialized represents a Initialized event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*ERC20TokenStakingManagerInitializedIterator, error) { + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerInitializedIterator{contract: _ERC20TokenStakingManager.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerInitialized) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseInitialized(log types.Log) (*ERC20TokenStakingManagerInitialized, error) { + event := new(ERC20TokenStakingManagerInitialized) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerValidationPeriodCreatedIterator is returned from FilterValidationPeriodCreated and is used to iterate over the raw logs and unpacked data for ValidationPeriodCreated events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidationPeriodCreatedIterator struct { + Event *ERC20TokenStakingManagerValidationPeriodCreated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerValidationPeriodCreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidationPeriodCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidationPeriodCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerValidationPeriodCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerValidationPeriodCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerValidationPeriodCreated represents a ValidationPeriodCreated event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidationPeriodCreated struct { + ValidationID [32]byte + NodeID [32]byte + RegisterValidationMessageID [32]byte + Weight *big.Int + RegistrationExpiry uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodCreated is a free log retrieval operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterValidationPeriodCreated(opts *bind.FilterOpts, validationID [][32]byte, nodeID [][32]byte, registerValidationMessageID [][32]byte) (*ERC20TokenStakingManagerValidationPeriodCreatedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var registerValidationMessageIDRule []interface{} + for _, registerValidationMessageIDItem := range registerValidationMessageID { + registerValidationMessageIDRule = append(registerValidationMessageIDRule, registerValidationMessageIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "ValidationPeriodCreated", validationIDRule, nodeIDRule, registerValidationMessageIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerValidationPeriodCreatedIterator{contract: _ERC20TokenStakingManager.contract, event: "ValidationPeriodCreated", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodCreated is a free log subscription operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchValidationPeriodCreated(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerValidationPeriodCreated, validationID [][32]byte, nodeID [][32]byte, registerValidationMessageID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var registerValidationMessageIDRule []interface{} + for _, registerValidationMessageIDItem := range registerValidationMessageID { + registerValidationMessageIDRule = append(registerValidationMessageIDRule, registerValidationMessageIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "ValidationPeriodCreated", validationIDRule, nodeIDRule, registerValidationMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerValidationPeriodCreated) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidationPeriodCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodCreated is a log parse operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseValidationPeriodCreated(log types.Log) (*ERC20TokenStakingManagerValidationPeriodCreated, error) { + event := new(ERC20TokenStakingManagerValidationPeriodCreated) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidationPeriodCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerValidationPeriodEndedIterator is returned from FilterValidationPeriodEnded and is used to iterate over the raw logs and unpacked data for ValidationPeriodEnded events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidationPeriodEndedIterator struct { + Event *ERC20TokenStakingManagerValidationPeriodEnded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerValidationPeriodEndedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidationPeriodEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidationPeriodEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerValidationPeriodEndedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerValidationPeriodEndedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerValidationPeriodEnded represents a ValidationPeriodEnded event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidationPeriodEnded struct { + ValidationID [32]byte + Status uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodEnded is a free log retrieval operation binding the contract event 0x1c08e59656f1a18dc2da76826cdc52805c43e897a17c50faefb8ab3c1526cc16. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID, uint8 indexed status) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterValidationPeriodEnded(opts *bind.FilterOpts, validationID [][32]byte, status []uint8) (*ERC20TokenStakingManagerValidationPeriodEndedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var statusRule []interface{} + for _, statusItem := range status { + statusRule = append(statusRule, statusItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "ValidationPeriodEnded", validationIDRule, statusRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerValidationPeriodEndedIterator{contract: _ERC20TokenStakingManager.contract, event: "ValidationPeriodEnded", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodEnded is a free log subscription operation binding the contract event 0x1c08e59656f1a18dc2da76826cdc52805c43e897a17c50faefb8ab3c1526cc16. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID, uint8 indexed status) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchValidationPeriodEnded(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerValidationPeriodEnded, validationID [][32]byte, status []uint8) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var statusRule []interface{} + for _, statusItem := range status { + statusRule = append(statusRule, statusItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "ValidationPeriodEnded", validationIDRule, statusRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerValidationPeriodEnded) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidationPeriodEnded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodEnded is a log parse operation binding the contract event 0x1c08e59656f1a18dc2da76826cdc52805c43e897a17c50faefb8ab3c1526cc16. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID, uint8 indexed status) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseValidationPeriodEnded(log types.Log) (*ERC20TokenStakingManagerValidationPeriodEnded, error) { + event := new(ERC20TokenStakingManagerValidationPeriodEnded) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidationPeriodEnded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerValidationPeriodRegisteredIterator is returned from FilterValidationPeriodRegistered and is used to iterate over the raw logs and unpacked data for ValidationPeriodRegistered events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidationPeriodRegisteredIterator struct { + Event *ERC20TokenStakingManagerValidationPeriodRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerValidationPeriodRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidationPeriodRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidationPeriodRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerValidationPeriodRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerValidationPeriodRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerValidationPeriodRegistered represents a ValidationPeriodRegistered event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidationPeriodRegistered struct { + ValidationID [32]byte + Weight *big.Int + Timestamp *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodRegistered is a free log retrieval operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 weight, uint256 timestamp) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterValidationPeriodRegistered(opts *bind.FilterOpts, validationID [][32]byte) (*ERC20TokenStakingManagerValidationPeriodRegisteredIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "ValidationPeriodRegistered", validationIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerValidationPeriodRegisteredIterator{contract: _ERC20TokenStakingManager.contract, event: "ValidationPeriodRegistered", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodRegistered is a free log subscription operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 weight, uint256 timestamp) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchValidationPeriodRegistered(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerValidationPeriodRegistered, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "ValidationPeriodRegistered", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerValidationPeriodRegistered) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidationPeriodRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodRegistered is a log parse operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 weight, uint256 timestamp) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseValidationPeriodRegistered(log types.Log) (*ERC20TokenStakingManagerValidationPeriodRegistered, error) { + event := new(ERC20TokenStakingManagerValidationPeriodRegistered) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidationPeriodRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerValidatorRemovalInitializedIterator is returned from FilterValidatorRemovalInitialized and is used to iterate over the raw logs and unpacked data for ValidatorRemovalInitialized events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidatorRemovalInitializedIterator struct { + Event *ERC20TokenStakingManagerValidatorRemovalInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerValidatorRemovalInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerValidatorRemovalInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerValidatorRemovalInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerValidatorRemovalInitialized represents a ValidatorRemovalInitialized event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidatorRemovalInitialized struct { + ValidationID [32]byte + SetWeightMessageID [32]byte + Weight *big.Int + EndTime *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorRemovalInitialized is a free log retrieval operation binding the contract event 0x13d58394cf269d48bcf927959a29a5ffee7c9924dafff8927ecdf3c48ffa7c67. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 weight, uint256 endTime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterValidatorRemovalInitialized(opts *bind.FilterOpts, validationID [][32]byte, setWeightMessageID [][32]byte) (*ERC20TokenStakingManagerValidatorRemovalInitializedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var setWeightMessageIDRule []interface{} + for _, setWeightMessageIDItem := range setWeightMessageID { + setWeightMessageIDRule = append(setWeightMessageIDRule, setWeightMessageIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "ValidatorRemovalInitialized", validationIDRule, setWeightMessageIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerValidatorRemovalInitializedIterator{contract: _ERC20TokenStakingManager.contract, event: "ValidatorRemovalInitialized", logs: logs, sub: sub}, nil +} + +// WatchValidatorRemovalInitialized is a free log subscription operation binding the contract event 0x13d58394cf269d48bcf927959a29a5ffee7c9924dafff8927ecdf3c48ffa7c67. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 weight, uint256 endTime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchValidatorRemovalInitialized(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerValidatorRemovalInitialized, validationID [][32]byte, setWeightMessageID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var setWeightMessageIDRule []interface{} + for _, setWeightMessageIDItem := range setWeightMessageID { + setWeightMessageIDRule = append(setWeightMessageIDRule, setWeightMessageIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "ValidatorRemovalInitialized", validationIDRule, setWeightMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerValidatorRemovalInitialized) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidatorRemovalInitialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorRemovalInitialized is a log parse operation binding the contract event 0x13d58394cf269d48bcf927959a29a5ffee7c9924dafff8927ecdf3c48ffa7c67. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 weight, uint256 endTime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseValidatorRemovalInitialized(log types.Log) (*ERC20TokenStakingManagerValidatorRemovalInitialized, error) { + event := new(ERC20TokenStakingManagerValidatorRemovalInitialized) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidatorRemovalInitialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerValidatorWeightUpdateIterator is returned from FilterValidatorWeightUpdate and is used to iterate over the raw logs and unpacked data for ValidatorWeightUpdate events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidatorWeightUpdateIterator struct { + Event *ERC20TokenStakingManagerValidatorWeightUpdate // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerValidatorWeightUpdateIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerValidatorWeightUpdateIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerValidatorWeightUpdateIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerValidatorWeightUpdate represents a ValidatorWeightUpdate event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidatorWeightUpdate struct { + ValidationID [32]byte + Nonce uint64 + ValidatorWeight uint64 + SetWeightMessageID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorWeightUpdate is a free log retrieval operation binding the contract event 0x07de5ff35a674a8005e661f3333c907ca6333462808762d19dc7b3abb1a8c1df. +// +// Solidity: event ValidatorWeightUpdate(bytes32 indexed validationID, uint64 indexed nonce, uint64 validatorWeight, bytes32 setWeightMessageID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterValidatorWeightUpdate(opts *bind.FilterOpts, validationID [][32]byte, nonce []uint64) (*ERC20TokenStakingManagerValidatorWeightUpdateIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "ValidatorWeightUpdate", validationIDRule, nonceRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerValidatorWeightUpdateIterator{contract: _ERC20TokenStakingManager.contract, event: "ValidatorWeightUpdate", logs: logs, sub: sub}, nil +} + +// WatchValidatorWeightUpdate is a free log subscription operation binding the contract event 0x07de5ff35a674a8005e661f3333c907ca6333462808762d19dc7b3abb1a8c1df. +// +// Solidity: event ValidatorWeightUpdate(bytes32 indexed validationID, uint64 indexed nonce, uint64 validatorWeight, bytes32 setWeightMessageID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchValidatorWeightUpdate(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerValidatorWeightUpdate, validationID [][32]byte, nonce []uint64) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "ValidatorWeightUpdate", validationIDRule, nonceRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerValidatorWeightUpdate) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidatorWeightUpdate", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorWeightUpdate is a log parse operation binding the contract event 0x07de5ff35a674a8005e661f3333c907ca6333462808762d19dc7b3abb1a8c1df. +// +// Solidity: event ValidatorWeightUpdate(bytes32 indexed validationID, uint64 indexed nonce, uint64 validatorWeight, bytes32 setWeightMessageID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseValidatorWeightUpdate(log types.Log) (*ERC20TokenStakingManagerValidatorWeightUpdate, error) { + event := new(ERC20TokenStakingManagerValidatorWeightUpdate) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidatorWeightUpdate", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/validator-manager/ExampleRewardCalculator/ExampleRewardCalculator.go b/abi-bindings/go/validator-manager/ExampleRewardCalculator/ExampleRewardCalculator.go new file mode 100644 index 000000000..d343cda87 --- /dev/null +++ b/abi-bindings/go/validator-manager/ExampleRewardCalculator/ExampleRewardCalculator.go @@ -0,0 +1,327 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package examplerewardcalculator + +import ( + "errors" + "math/big" + "strings" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = interfaces.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// ExampleRewardCalculatorMetaData contains all meta data concerning the ExampleRewardCalculator contract. +var ExampleRewardCalculatorMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"rewardBasisPoints_\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"SECONDS_IN_YEAR\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"UPTIME_REWARDS_THRESHOLD_PERCENTAGE\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"calculateReward\",\"inputs\":[{\"name\":\"stakeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"validatorStartTime\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stakingStartTime\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"stakingEndTime\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"uptimeSeconds\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"rewardBasisPoints\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"}]", + Bin: "0x60a0604052348015600e575f80fd5b50604051610357380380610357833981016040819052602b91603b565b6001600160401b03166080526066565b5f60208284031215604a575f80fd5b81516001600160401b0381168114605f575f80fd5b9392505050565b6080516102d36100845f395f8181609e015261013a01526102d35ff3fe608060405234801561000f575f80fd5b506004361061004a575f3560e01c80635dcc93911461004e578063778c06b51461006c578063afba878a1461007f578063bb65b24214610099575b5f80fd5b6100596301e1338081565b6040519081526020015b60405180910390f35b61005961007a3660046101b6565b6100d9565b610087605081565b60405160ff9091168152602001610063565b6100c07f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff9091168152602001610063565b5f60506100e68887610236565b6100f0919061025e565b67ffffffffffffffff1661010585606461025e565b67ffffffffffffffff16101561011c57505f61018f565b6127106301e1338061012e8888610236565b67ffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168b61016e919061028a565b610178919061028a565b61018291906102a7565b61018c91906102a7565b90505b979650505050505050565b803567ffffffffffffffff811681146101b1575f80fd5b919050565b5f805f805f805f60e0888a0312156101cc575f80fd5b873596506101dc6020890161019a565b95506101ea6040890161019a565b94506101f86060890161019a565b93506102066080890161019a565b925060a0880135915060c0880135905092959891949750929550565b634e487b7160e01b5f52601160045260245ffd5b67ffffffffffffffff82811682821603908082111561025757610257610222565b5092915050565b67ffffffffffffffff81811683821602808216919082811461028257610282610222565b505092915050565b80820281158282048414176102a1576102a1610222565b92915050565b5f826102c157634e487b7160e01b5f52601260045260245ffd5b50049056fea164736f6c6343000819000a", +} + +// ExampleRewardCalculatorABI is the input ABI used to generate the binding from. +// Deprecated: Use ExampleRewardCalculatorMetaData.ABI instead. +var ExampleRewardCalculatorABI = ExampleRewardCalculatorMetaData.ABI + +// ExampleRewardCalculatorBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ExampleRewardCalculatorMetaData.Bin instead. +var ExampleRewardCalculatorBin = ExampleRewardCalculatorMetaData.Bin + +// DeployExampleRewardCalculator deploys a new Ethereum contract, binding an instance of ExampleRewardCalculator to it. +func DeployExampleRewardCalculator(auth *bind.TransactOpts, backend bind.ContractBackend, rewardBasisPoints_ uint64) (common.Address, *types.Transaction, *ExampleRewardCalculator, error) { + parsed, err := ExampleRewardCalculatorMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ExampleRewardCalculatorBin), backend, rewardBasisPoints_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ExampleRewardCalculator{ExampleRewardCalculatorCaller: ExampleRewardCalculatorCaller{contract: contract}, ExampleRewardCalculatorTransactor: ExampleRewardCalculatorTransactor{contract: contract}, ExampleRewardCalculatorFilterer: ExampleRewardCalculatorFilterer{contract: contract}}, nil +} + +// ExampleRewardCalculator is an auto generated Go binding around an Ethereum contract. +type ExampleRewardCalculator struct { + ExampleRewardCalculatorCaller // Read-only binding to the contract + ExampleRewardCalculatorTransactor // Write-only binding to the contract + ExampleRewardCalculatorFilterer // Log filterer for contract events +} + +// ExampleRewardCalculatorCaller is an auto generated read-only Go binding around an Ethereum contract. +type ExampleRewardCalculatorCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ExampleRewardCalculatorTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ExampleRewardCalculatorTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ExampleRewardCalculatorFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ExampleRewardCalculatorFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ExampleRewardCalculatorSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ExampleRewardCalculatorSession struct { + Contract *ExampleRewardCalculator // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ExampleRewardCalculatorCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ExampleRewardCalculatorCallerSession struct { + Contract *ExampleRewardCalculatorCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ExampleRewardCalculatorTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ExampleRewardCalculatorTransactorSession struct { + Contract *ExampleRewardCalculatorTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ExampleRewardCalculatorRaw is an auto generated low-level Go binding around an Ethereum contract. +type ExampleRewardCalculatorRaw struct { + Contract *ExampleRewardCalculator // Generic contract binding to access the raw methods on +} + +// ExampleRewardCalculatorCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ExampleRewardCalculatorCallerRaw struct { + Contract *ExampleRewardCalculatorCaller // Generic read-only contract binding to access the raw methods on +} + +// ExampleRewardCalculatorTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ExampleRewardCalculatorTransactorRaw struct { + Contract *ExampleRewardCalculatorTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewExampleRewardCalculator creates a new instance of ExampleRewardCalculator, bound to a specific deployed contract. +func NewExampleRewardCalculator(address common.Address, backend bind.ContractBackend) (*ExampleRewardCalculator, error) { + contract, err := bindExampleRewardCalculator(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ExampleRewardCalculator{ExampleRewardCalculatorCaller: ExampleRewardCalculatorCaller{contract: contract}, ExampleRewardCalculatorTransactor: ExampleRewardCalculatorTransactor{contract: contract}, ExampleRewardCalculatorFilterer: ExampleRewardCalculatorFilterer{contract: contract}}, nil +} + +// NewExampleRewardCalculatorCaller creates a new read-only instance of ExampleRewardCalculator, bound to a specific deployed contract. +func NewExampleRewardCalculatorCaller(address common.Address, caller bind.ContractCaller) (*ExampleRewardCalculatorCaller, error) { + contract, err := bindExampleRewardCalculator(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ExampleRewardCalculatorCaller{contract: contract}, nil +} + +// NewExampleRewardCalculatorTransactor creates a new write-only instance of ExampleRewardCalculator, bound to a specific deployed contract. +func NewExampleRewardCalculatorTransactor(address common.Address, transactor bind.ContractTransactor) (*ExampleRewardCalculatorTransactor, error) { + contract, err := bindExampleRewardCalculator(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ExampleRewardCalculatorTransactor{contract: contract}, nil +} + +// NewExampleRewardCalculatorFilterer creates a new log filterer instance of ExampleRewardCalculator, bound to a specific deployed contract. +func NewExampleRewardCalculatorFilterer(address common.Address, filterer bind.ContractFilterer) (*ExampleRewardCalculatorFilterer, error) { + contract, err := bindExampleRewardCalculator(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ExampleRewardCalculatorFilterer{contract: contract}, nil +} + +// bindExampleRewardCalculator binds a generic wrapper to an already deployed contract. +func bindExampleRewardCalculator(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ExampleRewardCalculatorMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ExampleRewardCalculator *ExampleRewardCalculatorRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ExampleRewardCalculator.Contract.ExampleRewardCalculatorCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ExampleRewardCalculator *ExampleRewardCalculatorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ExampleRewardCalculator.Contract.ExampleRewardCalculatorTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ExampleRewardCalculator *ExampleRewardCalculatorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ExampleRewardCalculator.Contract.ExampleRewardCalculatorTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ExampleRewardCalculator *ExampleRewardCalculatorCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ExampleRewardCalculator.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ExampleRewardCalculator *ExampleRewardCalculatorTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ExampleRewardCalculator.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ExampleRewardCalculator *ExampleRewardCalculatorTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ExampleRewardCalculator.Contract.contract.Transact(opts, method, params...) +} + +// SECONDSINYEAR is a free data retrieval call binding the contract method 0x5dcc9391. +// +// Solidity: function SECONDS_IN_YEAR() view returns(uint256) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCaller) SECONDSINYEAR(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _ExampleRewardCalculator.contract.Call(opts, &out, "SECONDS_IN_YEAR") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// SECONDSINYEAR is a free data retrieval call binding the contract method 0x5dcc9391. +// +// Solidity: function SECONDS_IN_YEAR() view returns(uint256) +func (_ExampleRewardCalculator *ExampleRewardCalculatorSession) SECONDSINYEAR() (*big.Int, error) { + return _ExampleRewardCalculator.Contract.SECONDSINYEAR(&_ExampleRewardCalculator.CallOpts) +} + +// SECONDSINYEAR is a free data retrieval call binding the contract method 0x5dcc9391. +// +// Solidity: function SECONDS_IN_YEAR() view returns(uint256) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCallerSession) SECONDSINYEAR() (*big.Int, error) { + return _ExampleRewardCalculator.Contract.SECONDSINYEAR(&_ExampleRewardCalculator.CallOpts) +} + +// UPTIMEREWARDSTHRESHOLDPERCENTAGE is a free data retrieval call binding the contract method 0xafba878a. +// +// Solidity: function UPTIME_REWARDS_THRESHOLD_PERCENTAGE() view returns(uint8) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCaller) UPTIMEREWARDSTHRESHOLDPERCENTAGE(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _ExampleRewardCalculator.contract.Call(opts, &out, "UPTIME_REWARDS_THRESHOLD_PERCENTAGE") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// UPTIMEREWARDSTHRESHOLDPERCENTAGE is a free data retrieval call binding the contract method 0xafba878a. +// +// Solidity: function UPTIME_REWARDS_THRESHOLD_PERCENTAGE() view returns(uint8) +func (_ExampleRewardCalculator *ExampleRewardCalculatorSession) UPTIMEREWARDSTHRESHOLDPERCENTAGE() (uint8, error) { + return _ExampleRewardCalculator.Contract.UPTIMEREWARDSTHRESHOLDPERCENTAGE(&_ExampleRewardCalculator.CallOpts) +} + +// UPTIMEREWARDSTHRESHOLDPERCENTAGE is a free data retrieval call binding the contract method 0xafba878a. +// +// Solidity: function UPTIME_REWARDS_THRESHOLD_PERCENTAGE() view returns(uint8) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCallerSession) UPTIMEREWARDSTHRESHOLDPERCENTAGE() (uint8, error) { + return _ExampleRewardCalculator.Contract.UPTIMEREWARDSTHRESHOLDPERCENTAGE(&_ExampleRewardCalculator.CallOpts) +} + +// CalculateReward is a free data retrieval call binding the contract method 0x778c06b5. +// +// Solidity: function calculateReward(uint256 stakeAmount, uint64 validatorStartTime, uint64 stakingStartTime, uint64 stakingEndTime, uint64 uptimeSeconds, uint256 , uint256 ) view returns(uint256) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCaller) CalculateReward(opts *bind.CallOpts, stakeAmount *big.Int, validatorStartTime uint64, stakingStartTime uint64, stakingEndTime uint64, uptimeSeconds uint64, arg5 *big.Int, arg6 *big.Int) (*big.Int, error) { + var out []interface{} + err := _ExampleRewardCalculator.contract.Call(opts, &out, "calculateReward", stakeAmount, validatorStartTime, stakingStartTime, stakingEndTime, uptimeSeconds, arg5, arg6) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CalculateReward is a free data retrieval call binding the contract method 0x778c06b5. +// +// Solidity: function calculateReward(uint256 stakeAmount, uint64 validatorStartTime, uint64 stakingStartTime, uint64 stakingEndTime, uint64 uptimeSeconds, uint256 , uint256 ) view returns(uint256) +func (_ExampleRewardCalculator *ExampleRewardCalculatorSession) CalculateReward(stakeAmount *big.Int, validatorStartTime uint64, stakingStartTime uint64, stakingEndTime uint64, uptimeSeconds uint64, arg5 *big.Int, arg6 *big.Int) (*big.Int, error) { + return _ExampleRewardCalculator.Contract.CalculateReward(&_ExampleRewardCalculator.CallOpts, stakeAmount, validatorStartTime, stakingStartTime, stakingEndTime, uptimeSeconds, arg5, arg6) +} + +// CalculateReward is a free data retrieval call binding the contract method 0x778c06b5. +// +// Solidity: function calculateReward(uint256 stakeAmount, uint64 validatorStartTime, uint64 stakingStartTime, uint64 stakingEndTime, uint64 uptimeSeconds, uint256 , uint256 ) view returns(uint256) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCallerSession) CalculateReward(stakeAmount *big.Int, validatorStartTime uint64, stakingStartTime uint64, stakingEndTime uint64, uptimeSeconds uint64, arg5 *big.Int, arg6 *big.Int) (*big.Int, error) { + return _ExampleRewardCalculator.Contract.CalculateReward(&_ExampleRewardCalculator.CallOpts, stakeAmount, validatorStartTime, stakingStartTime, stakingEndTime, uptimeSeconds, arg5, arg6) +} + +// RewardBasisPoints is a free data retrieval call binding the contract method 0xbb65b242. +// +// Solidity: function rewardBasisPoints() view returns(uint64) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCaller) RewardBasisPoints(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _ExampleRewardCalculator.contract.Call(opts, &out, "rewardBasisPoints") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// RewardBasisPoints is a free data retrieval call binding the contract method 0xbb65b242. +// +// Solidity: function rewardBasisPoints() view returns(uint64) +func (_ExampleRewardCalculator *ExampleRewardCalculatorSession) RewardBasisPoints() (uint64, error) { + return _ExampleRewardCalculator.Contract.RewardBasisPoints(&_ExampleRewardCalculator.CallOpts) +} + +// RewardBasisPoints is a free data retrieval call binding the contract method 0xbb65b242. +// +// Solidity: function rewardBasisPoints() view returns(uint64) +func (_ExampleRewardCalculator *ExampleRewardCalculatorCallerSession) RewardBasisPoints() (uint64, error) { + return _ExampleRewardCalculator.Contract.RewardBasisPoints(&_ExampleRewardCalculator.CallOpts) +} diff --git a/abi-bindings/go/validator-manager/NativeTokenStakingManager/NativeTokenStakingManager.go b/abi-bindings/go/validator-manager/NativeTokenStakingManager/NativeTokenStakingManager.go new file mode 100644 index 000000000..7e43fb0dc --- /dev/null +++ b/abi-bindings/go/validator-manager/NativeTokenStakingManager/NativeTokenStakingManager.go @@ -0,0 +1,2702 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package nativetokenstakingmanager + +import ( + "errors" + "math/big" + "strings" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = interfaces.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// InitialValidator is an auto generated low-level Go binding around an user-defined struct. +type InitialValidator struct { + NodeID [32]byte + Weight uint64 + BlsPublicKey []byte +} + +// PoSValidatorManagerSettings is an auto generated low-level Go binding around an user-defined struct. +type PoSValidatorManagerSettings struct { + BaseSettings ValidatorManagerSettings + MinimumStakeAmount *big.Int + MaximumStakeAmount *big.Int + MinimumStakeDuration uint64 + MinimumDelegationFeeBips uint16 + MaximumStakeMultiplier uint8 + RewardCalculator common.Address +} + +// SubnetConversionData is an auto generated low-level Go binding around an user-defined struct. +type SubnetConversionData struct { + ConvertSubnetTxID [32]byte + ValidatorManagerBlockchainID [32]byte + ValidatorManagerAddress common.Address + InitialValidators []InitialValidator +} + +// Validator is an auto generated low-level Go binding around an user-defined struct. +type Validator struct { + Status uint8 + NodeID [32]byte + StartingWeight uint64 + MessageNonce uint64 + Weight uint64 + StartedAt uint64 + EndedAt uint64 +} + +// ValidatorManagerSettings is an auto generated low-level Go binding around an user-defined struct. +type ValidatorManagerSettings struct { + SubnetID [32]byte + ChurnPeriodSeconds uint64 + MaximumChurnPercentage uint8 +} + +// ValidatorRegistrationInput is an auto generated low-level Go binding around an user-defined struct. +type ValidatorRegistrationInput struct { + NodeID [32]byte + RegistrationExpiry uint64 + BlsPublicKey []byte +} + +// NativeTokenStakingManagerMetaData contains all meta data concerning the NativeTokenStakingManager contract. +var NativeTokenStakingManagerMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"init\",\"type\":\"uint8\",\"internalType\":\"enumICMInitializable\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"ADDRESS_LENGTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"BLS_PUBLIC_KEY_LENGTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAXIMUM_CHURN_PERCENTAGE_LIMIT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAXIMUM_DELEGATION_FEE_BIPS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint16\",\"internalType\":\"uint16\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAXIMUM_REGISTRATION_EXPIRY_LENGTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAXIMUM_STAKE_MULTIPLIER_LIMIT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"NATIVE_MINTER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractINativeMinter\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"P_CHAIN_BLOCKCHAIN_ID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"WARP_MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIWarpMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"claimDelegationFees\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"completeDelegatorRegistration\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"delegationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"completeEndDelegation\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"delegationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"completeEndValidation\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"completeValidatorRegistration\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"endDelegationCompletedValidator\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getValidator\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structValidator\",\"components\":[{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumValidatorStatus\"},{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"startingWeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"messageNonce\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"weight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"startedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"endedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getWeight\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"settings\",\"type\":\"tuple\",\"internalType\":\"structPoSValidatorManagerSettings\",\"components\":[{\"name\":\"baseSettings\",\"type\":\"tuple\",\"internalType\":\"structValidatorManagerSettings\",\"components\":[{\"name\":\"subnetID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"churnPeriodSeconds\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"maximumChurnPercentage\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"minimumStakeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"maximumStakeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"minimumStakeDuration\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"minimumDelegationFeeBips\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"maximumStakeMultiplier\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"rewardCalculator\",\"type\":\"address\",\"internalType\":\"contractIRewardCalculator\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeDelegatorRegistration\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"initializeEndDelegation\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"includeUptimeProof\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeEndValidation\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"includeUptimeProof\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeValidatorRegistration\",\"inputs\":[{\"name\":\"registrationInput\",\"type\":\"tuple\",\"internalType\":\"structValidatorRegistrationInput\",\"components\":[{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registrationExpiry\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"delegationFeeBips\",\"type\":\"uint16\",\"internalType\":\"uint16\"},{\"name\":\"minStakeDuration\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"initializeValidatorSet\",\"inputs\":[{\"name\":\"subnetConversionData\",\"type\":\"tuple\",\"internalType\":\"structSubnetConversionData\",\"components\":[{\"name\":\"convertSubnetTxID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"validatorManagerBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"validatorManagerAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"initialValidators\",\"type\":\"tuple[]\",\"internalType\":\"structInitialValidator[]\",\"components\":[{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"registeredValidators\",\"inputs\":[{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"resendEndValidatorMessage\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resendRegisterValidatorMessage\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resendUpdateDelegation\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"valueToWeight\",\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"weightToValue\",\"inputs\":[{\"name\":\"weight\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"pure\"},{\"type\":\"event\",\"name\":\"DelegationEnded\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"rewards\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"fees\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DelegatorAdded\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"delegatorAddress\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"nonce\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"validatorWeight\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"delegatorWeight\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"setWeightMessageID\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DelegatorRegistered\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nonce\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"startTime\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"DelegatorRemovalInitialized\",\"inputs\":[{\"name\":\"delegationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"endTime\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"InitialValidatorCreated\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nodeID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodCreated\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nodeID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"registerValidationMessageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"registrationExpiry\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodEnded\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"status\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumValidatorStatus\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodRegistered\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorRemovalInitialized\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"setWeightMessageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"endTime\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorWeightUpdate\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nonce\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"validatorWeight\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"setWeightMessageID\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AddressInsufficientBalance\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"FailedInnerCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidAddress\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidBlockchainID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidCodecID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidDelegationFee\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidDelegationID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidDelegatorStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidExpiry\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitializationStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInput\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidMessageLength\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidMessageType\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidNonce\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidStakeAmount\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidStakeDuration\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidStakeMultiplier\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSubnetConversionID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidValidationID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidValidatorStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidWarpMessage\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxChurnRateExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxWeightExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NodeAlreadyRegistered\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"UnexpectedRegistrationStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ValidatorNotPoS\",\"inputs\":[]}]", + Bin: "0x608060405234801561000f575f80fd5b5060405161539b38038061539b83398101604081905261002e91610107565b60018160018111156100425761004261012c565b0361004f5761004f610055565b50610140565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100a55760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101045780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60208284031215610117575f80fd5b815160028110610125575f80fd5b9392505050565b634e487b7160e01b5f52602160045260245ffd5b61524e8061014d5f395ff3fe6080604052600436106101ba575f3560e01c8063732214f8116100f2578063b771b3bc11610092578063c974d1b611610062578063c974d1b6146104eb578063d5f20ff6146104ff578063df93d8de1461052b578063e7d14c1c14610541575f80fd5b8063b771b3bc14610480578063ba3a4b971461049a578063bee0a03f146104b9578063c599e24f146104d8575f80fd5b806393e24598116100cd57806393e245981461040457806398f3e2b4146104235780639dde029a14610442578063a3a65e4814610461575f80fd5b8063732214f8146103be57806376f78621146103d15780638280a25a146103f0575f80fd5b806340034a931161015d57806360305d621161013857806360305d621461033857806361e2f49014610361578063620658561461038057806366435abf1461039f575f80fd5b806340034a93146102d9578063467ef06f146102fa5780635297fae614610319575f80fd5b806320e555651161019857806320e55565146102295780632e2194d814610248578063329c3e121461027f57806335455ded146102b1575f80fd5b80630118acc4146101be5780630322ed98146101df578063151d30d1146101fe575b5f80fd5b3480156101c9575f80fd5b506101dd6101d8366004614828565b61058b565b005b3480156101ea575f80fd5b506101dd6101f9366004614863565b610932565b348015610209575f80fd5b50610212600a81565b60405160ff90911681526020015b60405180910390f35b348015610234575f80fd5b506101dd61024336600461487a565b610aa4565b348015610253575f80fd5b50610267610262366004614863565b610b81565b6040516001600160401b039091168152602001610220565b34801561028a575f80fd5b506102996001600160991b0181565b6040516001600160a01b039091168152602001610220565b3480156102bc575f80fd5b506102c661271081565b60405161ffff9091168152602001610220565b6102ec6102e73660046148b8565b610b97565b604051908152602001610220565b348015610305575f80fd5b506101dd61031436600461490c565b610bcb565b348015610324575f80fd5b506101dd610333366004614925565b610c6c565b348015610343575f80fd5b5061034c601481565b60405163ffffffff9091168152602001610220565b34801561036c575f80fd5b506101dd61037b36600461494d565b611044565b34801561038b575f80fd5b506102ec61039a36600461499b565b6114c8565b3480156103aa575f80fd5b506102676103b9366004614863565b6114e1565b3480156103c9575f80fd5b506102ec5f81565b3480156103dc575f80fd5b506101dd6103eb366004614828565b6114f5565b3480156103fb575f80fd5b50610212603081565b34801561040f575f80fd5b506101dd61041e366004614863565b6116c0565b34801561042e575f80fd5b506101dd61043d366004614925565b61177b565b34801561044d575f80fd5b506101dd61045c366004614863565b61191b565b34801561046c575f80fd5b506101dd61047b36600461490c565b611b92565b34801561048b575f80fd5b506102996005600160991b0181565b3480156104a5575f80fd5b506101dd6104b4366004614863565b611d04565b3480156104c4575f80fd5b506101dd6104d3366004614863565b611ee0565b6102ec6104e6366004614863565b61200a565b3480156104f6575f80fd5b50610212601481565b34801561050a575f80fd5b5061051e610519366004614863565b61203b565b60405161022091906149c8565b348015610536575f80fd5b506102676202a30081565b34801561054c575f80fd5b506102ec61055b366004614863565b5f9081527fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb08602052604090205490565b5f8381525f805160206151a28339815191526020526040808220815160e0810190925280545f805160206151c283398151915293929190829060ff1660038111156105d8576105d86149b4565b60038111156105e9576105e96149b4565b8152815461010090046001600160a01b0316602082015260018201546040808301919091526002909201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c0909101528101519091505f61065f8261203b565b9050600283516003811115610676576106766149b4565b146106945760405163f95c7fe160e01b815260040160405180910390fd5b60208301516001600160a01b031633146106c15760405163e6c4247b60e01b815260040160405180910390fd5b600383819052505f806002835160058111156106df576106df6149b4565b036107305787156106f7576106f48488612103565b91505b5f8560600151846080015161070c9190614a8b565b90506107188582612287565b506001600160401b031660c087015250429050610762565b50505f82815260088501602052604090205460608201516001600160401b0390811660c0808701919091528301519116905b600386015460608601516001600160a01b039091169063778c06b590610787906114c8565b8560a00151886080015185875f806040518863ffffffff1660e01b81526004016107b79796959493929190614aab565b602060405180830381865afa1580156107d2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107f69190614ae9565b5f8a8152600688016020908152604080832093909355600589019052208551815487929190829060ff19166001836003811115610835576108356149b4565b0217905550602082015181546001600160a01b0390911661010002610100600160a81b03199091161781556040808301516001830155606083015160029092018054608085015160a086015160c0909601516001600160401b03908116600160c01b026001600160c01b03978216600160801b02979097166001600160801b03928216600160401b026001600160801b031990941691909616179190911716929092179290921790555184908a907f5cd7ff518ea5cf079cc34b155d074410ae8c095910ebea921240641508658c699061091f9085906001600160401b0391909116815260200190565b60405180910390a3505050505050505050565b5f8181525f805160206152228339815191526020526040808220815160e0810190925280545f805160206151e283398151915293929190829060ff16600581111561097f5761097f6149b4565b6005811115610990576109906149b4565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a08301526003928301541660c090910152909150815160058111156109ff576109ff6149b4565b14610a1d5760405163a36c527f60e01b815260040160405180910390fd5b6005600160991b016001600160a01b031663ee5b48eb610a428584606001515f6123de565b6040518263ffffffff1660e01b8152600401610a5e9190614b22565b6020604051808303815f875af1158015610a7a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9e9190614ae9565b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805460029190600160401b900460ff1680610aed575080546001600160401b03808416911610155b15610b0b5760405163f92ee8a960e01b815260040160405180910390fd5b805468ffffffffffffffffff19166001600160401b03831617600160401b178155610b358361242d565b805460ff60401b191681556040516001600160401b03831681527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a1505050565b5f610b9164e8d4a5100083614b54565b92915050565b5f610ba061243e565b610bac84848434612475565b9050610bc460015f8051602061520283398151915255565b9392505050565b5f805160206151c28339815191525f80610be48461261b565b91509150610bf1826128b9565b610bfb5750505050565b5f82815260048085016020526040909120546001600160a01b03169082516005811115610c2a57610c2a6149b4565b03610c4f575f83815260078501602052604081208054919055610c4d82826128f4565b505b610c6581610c6084604001516114c8565b61295a565b5050505050565b5f8181525f805160206151a28339815191526020526040808220815160e0810190925280545f805160206151c283398151915293929190829060ff166003811115610cb957610cb96149b4565b6003811115610cca57610cca6149b4565b8152815461010090046001600160a01b0316602082015260018201546040808301919091526002909201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c0909101528101519091505f90610d419061203b565b905060015f85815260058501602052604090205460ff166003811115610d6957610d696149b4565b14610d875760405163f95c7fe160e01b815260040160405180910390fd5b600381516005811115610d9c57610d9c6149b4565b03610ee557600380835260c0828101516001600160401b039081166080860152606084015116908401525f8581526005850160205260409020835181548593839160ff1916906001908490811115610df657610df66149b4565b02179055506020828101518254610100600160a81b0319166101006001600160a01b03909216919091021782556040808401516001840155606084015160029093018054608086015160a087015160c0978801516001600160401b039788166001600160801b031990941693909317600160401b92881692909202919091176001600160801b0316600160801b918716919091026001600160c01b031617600160c01b91861691909102179055858101519385015190519216825286917f5cd7ff518ea5cf079cc34b155d074410ae8c095910ebea921240641508658c69910160405180910390a35050505050565b600481516005811115610efa57610efa6149b4565b03610f0857610c658461296d565b5f610f1286612b4a565b90505f80610f238360400151612c4a565b509150915081856040015114610f4c57604051636990657d60e01b815260040160405180910390fd5b806001600160401b031684606001516001600160401b03161080610f9457505f8781526005870160205260409020600201546001600160401b03808316600160801b90920416115b15610fb257604051633ab3447f60e11b815260040160405180910390fd5b5f878152600587016020908152604091829020805460ff1916600290811782550180546001600160401b0342818116600160401b026fffffffffffffffff00000000000000001990931692909217909255925192835283169184918a917f245fc69b36e168426e0306fc8d8300661b9af297c7958820dbf804f9f63e7064910160405180910390a45050505050505050565b7fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb09545f805160206151e28339815191529060ff161561109657604051637fab81e560e01b815260040160405180910390fd5b6005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110fd9190614ae9565b8360200135146111205760405163d040949d60e01b815260040160405180910390fd5b306111316060850160408601614b87565b6001600160a01b0316146111585760405163e6c4247b60e01b815260040160405180910390fd5b5f6111666060850185614ba2565b905090505f805b828163ffffffff161015611412575f6111896060880188614ba2565b8363ffffffff1681811061119f5761119f614be7565b90506020028101906111b19190614bfb565b6111ba90614cab565b80515f81815260088801602052604090205491925090156111ee57604051630eb0d31360e11b815260040160405180910390fd5b5f6002895f01358560405160200161121d92919091825260e01b6001600160e01b031916602082015260240190565b60408051601f198184030181529082905261123791614d42565b602060405180830381855afa158015611252573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906112759190614ae9565b5f8381526008890160209081526040808320849055805160e0810182526002815287518184015287830180516001600160401b039081168385015260608301869052905181166080830152421660a082015260c0810184905284845260078c01909252909120815181549394509192909190829060ff19166001836005811115611301576113016149b4565b0217905550602082810151600183015560408301516002830180546060860151608087015160a08801516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c0909301516003909201805467ffffffffffffffff1916928416929092179091558401516113b4911686614d53565b83516020808601516040516001600160401b039091168152929750909183917fb815f891730222788b3f8d66249b3a287ce680c3df13866fd9a4f37743ae1014910160405180910390a35050508061140b90614d66565b905061116d565b50600483018190555f61142485612b4a565b90505f6114348260400151612e88565b90505f61144088612ffd565b9050816002826040516114539190614d42565b602060405180830381855afa15801561146e573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906114919190614ae9565b146114af57604051631e0e8fbd60e21b815260040160405180910390fd5b5050506009909201805460ff1916600117905550505050565b5f610b916001600160401b03831664e8d4a51000614d88565b5f6114eb8261203b565b6080015192915050565b5f805160206151c28339815191525f61150d85613496565b9050611518856128b9565b611523575050505050565b5f8581526004830160205260409020546001600160a01b0316331461155b5760405163e6c4247b60e01b815260040160405180910390fd5b5f85815260048301602052604090205460a082015161158a91600160b01b90046001600160401b031690614d9f565b6001600160401b03168160c001516001600160401b031610156115c0576040516302336bad60e51b815260040160405180910390fd5b8315610c65575f6115d18685612103565b5f87815260088501602052604090819020805467ffffffffffffffff19166001600160401b0384161790556003850154908401519192506001600160a01b03169063778c06b590611621906114c8565b60a085015160c08601516040516001600160e01b031960e086901b168152611655939291829188905f908190600401614aab565b602060405180830381865afa158015611670573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116949190614ae9565b5f878152600785016020526040812080549091906116b3908490614d53565b9091555050505050505050565b5f805160206151c28339815191525f6116d88361203b565b90506004815160058111156116ef576116ef6149b4565b1461170d5760405163a36c527f60e01b815260040160405180910390fd5b5f8381526004830160205260409020546001600160a01b031633146117455760405163e6c4247b60e01b815260040160405180910390fd5b5f83815260078301602090815260408083208054908490556004860190925290912054610a9e906001600160a01b0316826128f4565b61178361243e565b5f8181525f805160206151a28339815191526020526040808220815160e0810190925280545f805160206151c283398151915293929190829060ff1660038111156117d0576117d06149b4565b60038111156117e1576117e16149b4565b8152815461010090046001600160a01b03166020820152600182015460408201526002909101546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c09091015290505f61184f85612b4a565b90505f806118608360400151612c4a565b50915091508184604001511461188957604051636990657d60e01b815260040160405180910390fd5b806001600160401b03168460c001516001600160401b031611156118c057604051633ab3447f60e11b815260040160405180910390fd5b6003845160038111156118d5576118d56149b4565b146118f35760405163f95c7fe160e01b815260040160405180910390fd5b6118fc8661296d565b505050505061191760015f8051602061520283398151915255565b5050565b61192361243e565b5f8181525f805160206151a28339815191526020526040808220815160e0810190925280545f805160206151c283398151915293929190829060ff166003811115611970576119706149b4565b6003811115611981576119816149b4565b8152815461010090046001600160a01b0316602082015260018201546040808301919091526002909201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c0909101528101519091505f6119f78261203b565b90505f83516003811115611a0d57611a0d6149b4565b03611a2b57604051631d0b665760e21b815260040160405180910390fd5b600481516005811115611a4057611a406149b4565b14611a5e5760405163a36c527f60e01b815260040160405180910390fd5b600183516003811115611a7357611a736149b4565b03611a8a57611a818561296d565b50505050611b79565b600283516003811115611a9f57611a9f6149b4565b03611b6b57600384015460608401516001600160a01b039091169063778c06b590611ac9906114c8565b60a0840151608087015160c08601515f88815260088b0160205260408082205490516001600160e01b031960e089901b168152611b1b96959493926001600160401b0390921691908190600401614aab565b602060405180830381865afa158015611b36573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b5a9190614ae9565b5f8681526006860160205260409020555b611b748561296d565b505050505b611b8f60015f8051602061520283398151915255565b50565b5f805160206151e28339815191525f611baa83612b4a565b90505f80611bbb83604001516136d3565b9150915080611bdd57604051633dbcaef760e01b815260040160405180910390fd5b5f82815260068501602052604090208054611bf790614dbf565b90505f03611c1857604051636990657d60e01b815260040160405180910390fd5b60015f83815260078601602052604090205460ff166005811115611c3e57611c3e6149b4565b14611c5c5760405163a36c527f60e01b815260040160405180910390fd5b5f8281526006850160205260408120611c749161477d565b5f828152600785016020908152604091829020805460ff1916600290811782550180546001600160401b0342818116600160c01b026001600160c01b0390931692909217928390558451600160801b9093041682529181019190915283917ff8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568910160405180910390a25050505050565b5f8181525f805160206151a28339815191526020526040808220815160e0810190925280545f805160206151c283398151915293929190829060ff166003811115611d5157611d516149b4565b6003811115611d6257611d626149b4565b8152815461010090046001600160a01b0316602082015260018083015460408301526002909201546001600160401b038082166060840152600160401b820481166080840152600160801b8204811660a0840152600160c01b9091041660c09091015290915081516003811115611ddb57611ddb6149b4565b14158015611dfc5750600381516003811115611df957611df96149b4565b14155b15611e1a5760405163f95c7fe160e01b815260040160405180910390fd5b5f611e28826040015161203b565b905080606001516001600160401b03165f03611e5757604051631d0b665760e21b815260040160405180910390fd5b6005600160991b016001600160a01b031663ee5b48eb611e848460400151846060015185608001516123de565b6040518263ffffffff1660e01b8152600401611ea09190614b22565b6020604051808303815f875af1158015611ebc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c659190614ae9565b5f8181527fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb066020526040902080545f805160206151e28339815191529190611f2790614dbf565b90505f03611f4857604051636990657d60e01b815260040160405180910390fd5b60015f83815260078301602052604090205460ff166005811115611f6e57611f6e6149b4565b14611f8c5760405163a36c527f60e01b815260040160405180910390fd5b5f82815260068201602052604090819020905163ee5b48eb60e01b81526005600160991b019163ee5b48eb91611fc59190600401614df1565b6020604051808303815f875af1158015611fe1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120059190614ae9565b505050565b5f61201361243e565b61201e823334613877565b905061203660015f8051602061520283398151915255565b919050565b6120436147b4565b5f8281525f80516020615222833981519152602052604090819020815160e0810190925280545f805160206151e2833981519152929190829060ff166005811115612090576120906149b4565b60058111156120a1576120a16149b4565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a083015260039092015490911660c0909101529392505050565b6040516306f8253560e41b815263ffffffff821660048201525f90819081906005600160991b0190636f825350906024015f60405180830381865afa15801561214e573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526121759190810190614e86565b915091508061219757604051636b2f19e960e01b815260040160405180910390fd5b6005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121fe9190614ae9565b82511461221e5760405163d040949d60e01b815260040160405180910390fd5b60208201516001600160a01b03161561224a5760405163e6c4247b60e01b815260040160405180910390fd5b5f806122598460400151613b3b565b9150915081871461227d57604051636990657d60e01b815260040160405180910390fd5b9695505050505050565b5f8281525f80516020615222833981519152602052604081206002015481905f805160206151e283398151915290600160801b90046001600160401b03166122cf8582613d16565b5f6122d987613edf565b5f8881526007850160205260408120600201805467ffffffffffffffff60801b1916600160801b6001600160401b038b16021790559091506005600160991b0163ee5b48eb6123298a858b6123de565b6040518263ffffffff1660e01b81526004016123459190614b22565b6020604051808303815f875af1158015612361573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123859190614ae9565b604080516001600160401b038a811682526020820184905282519394508516928b927f07de5ff35a674a8005e661f3333c907ca6333462808762d19dc7b3abb1a8c1df928290030190a3909450925050505b9250929050565b604080515f6020820152600160e11b602282015260268101949094526001600160c01b031960c093841b811660468601529190921b16604e830152805180830360360181526056909201905290565b612435613f54565b611b8f81613f9f565b5f8051602061520283398151915280546001190161246f57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b7f4317713f7ecbdddd4bc99e95d903adedaa883b2e7c2551610bd13e2c7e473d02545f905f805160206151c283398151915290600160401b900461ffff90811690861610806124c9575061271061ffff8616115b156124e75760405163c98d73a760e01b815260040160405180910390fd5b60028101546001600160401b039081169085161015612519576040516302336bad60e51b815260040160405180910390fd5b805483108061252b5750806001015483115b1561254957604051630103be3b60e21b815260040160405180910390fd5b825f61255482610b81565b90505f612561898361400d565b905060405180606001604052806125753390565b6001600160a01b03908116825261ffff808c166020808501919091526001600160401b03808d166040958601525f8781526004909a0182529884902085518154928701519690950151909916600160b01b0267ffffffffffffffff60b01b1995909216600160a01b026001600160b01b031990911693909216929092171791909116179093555090915050949350505050565b60015f8051602061520283398151915255565b5f6126246147b4565b5f805160206151e28339815191525f61263c85612b4a565b90505f8061264d83604001516136d3565b91509150801561267057604051633dbcaef760e01b815260040160405180910390fd5b5f828152600785016020526040808220815160e081019092528054829060ff1660058111156126a1576126a16149b4565b60058111156126b2576126b26149b4565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a08301526003928301541660c09091015290915081516005811115612721576127216149b4565b14158015612742575060018151600581111561273f5761273f6149b4565b14155b156127605760405163a36c527f60e01b815260040160405180910390fd5b600381516005811115612775576127756149b4565b036127835760048152612788565b600581525b6020808201515f908152600887018252604080822082905585825260078801909252208151815483929190829060ff191660018360058111156127cd576127cd6149b4565b02179055506020820151600182015560408201516002820180546060850151608086015160a08701516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c0909201516003909101805467ffffffffffffffff19169190921617905580516005811115612881576128816149b4565b60405184907f1c08e59656f1a18dc2da76826cdc52805c43e897a17c50faefb8ab3c1526cc16905f90a3919791965090945050505050565b5f9081527f4317713f7ecbdddd4bc99e95d903adedaa883b2e7c2551610bd13e2c7e473d0460205260409020546001600160a01b0316151590565b6040516327ad555d60e11b81526001600160a01b0383166004820152602481018290526001600160991b0190634f5aaaba906044015f604051808303815f87803b158015612940575f80fd5b505af1158015612952573d5f803e3d5ffd5b505050505050565b6119176001600160a01b038316826143f7565b5f8181525f805160206151a28339815191526020526040808220815160e0810190925280545f805160206151c283398151915293929190829060ff1660038111156129ba576129ba6149b4565b60038111156129cb576129cb6149b4565b8152815461010090046001600160a01b03166020808301919091526001808401546040808501919091526002948501546001600160401b038082166060870152600160401b820481166080870152600160801b8204811660a0870152600160c01b9091041660c090940193909352848301515f89815260058901845284812080546001600160a81b0319168155928301819055919094018190556006870182528281208054908290558482526004880190925291822054939450919261271090612aa090600160a01b900461ffff1684614d88565b612aaa9190614b54565b905080856007015f8581526020019081526020015f205f828254612ace9190614d53565b909155505f9050612adf8284614f58565b9050612aef8560200151826128f4565b612b048560200151610c6087606001516114c8565b6040805182815260208101849052859189917f8ececf510070c320d9a55323ffabe350e294ae505fc0c509dc5736da6f5cc993910160405180910390a350505050505050565b60408051606080820183525f8083526020830152918101919091526040516306f8253560e41b815263ffffffff831660048201525f9081906005600160991b0190636f825350906024015f60405180830381865afa158015612bae573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612bd59190810190614e86565b9150915080612bf757604051636b2f19e960e01b815260040160405180910390fd5b815115612c175760405163d040949d60e01b815260040160405180910390fd5b60208201516001600160a01b031615612c435760405163e6c4247b60e01b815260040160405180910390fd5b5092915050565b5f805f8351603614612c6f57604051638d0242c960e01b815260040160405180910390fd5b5f805b6002811015612cbe57612c86816001614f58565b612c91906008614d88565b61ffff16868281518110612ca757612ca7614be7565b016020015160f81c901b9190911790600101612c72565b5061ffff811615612ce25760405163059510e360e31b815260040160405180910390fd5b5f805b6004811015612d3d57612cf9816003614f58565b612d04906008614d88565b63ffffffff1687612d16836002614d53565b81518110612d2657612d26614be7565b016020015160f81c901b9190911790600101612ce5565b5063ffffffff8116600414612d6557604051635b60892f60e01b815260040160405180910390fd5b5f805b6020811015612dba57612d7c81601f614f58565b612d87906008614d88565b88612d93836006614d53565b81518110612da357612da3614be7565b016020015160f81c901b9190911790600101612d68565b505f805b6008811015612e1957612dd2816007614f58565b612ddd906008614d88565b6001600160401b031689612df2836026614d53565b81518110612e0257612e02614be7565b016020015160f81c901b9190911790600101612dbe565b505f805b6008811015612e7857612e31816007614f58565b612e3c906008614d88565b6001600160401b03168a612e5183602e614d53565b81518110612e6157612e61614be7565b016020015160f81c901b9190911790600101612e1d565b5091989097509095509350505050565b5f8151602614612eab57604051638d0242c960e01b815260040160405180910390fd5b5f805b6002811015612efa57612ec2816001614f58565b612ecd906008614d88565b61ffff16848281518110612ee357612ee3614be7565b016020015160f81c901b9190911790600101612eae565b5061ffff811615612f1e5760405163059510e360e31b815260040160405180910390fd5b5f805b6004811015612f7957612f35816003614f58565b612f40906008614d88565b63ffffffff1685612f52836002614d53565b81518110612f6257612f62614be7565b016020015160f81c901b9190911790600101612f21565b5063ffffffff811615612f9f57604051635b60892f60e01b815260040160405180910390fd5b5f805b6020811015612ff457612fb681601f614f58565b612fc1906008614d88565b86612fcd836006614d53565b81518110612fdd57612fdd614be7565b016020015160f81c901b9190911790600101612fa2565b50949350505050565b60605f61300c83830184614ba2565b61301891506058614d88565b61302390605c614d53565b6001600160401b0381111561303a5761303a614c19565b6040519080825280601f01601f191660200182016040528015613064576020820181803683370190505b5090505f5b60208110156130b9578335816020811061308557613085614be7565b1a60f81b82828151811061309b5761309b614be7565b60200101906001600160f81b03191690815f1a905350600101613069565b505f5b602081101561311957836020013581602081106130db576130db614be7565b1a60f81b826130eb836020614d53565b815181106130fb576130fb614be7565b60200101906001600160f81b03191690815f1a9053506001016130bc565b505f5b600481101561317c57613130816003614f58565b61313b906008614d88565b6014901c60f81b8261314e836040614d53565b8151811061315e5761315e614be7565b60200101906001600160f81b03191690815f1a90535060010161311c565b505f61318e6060850160408601614b87565b60601b90505f5b60148110156131ee578181601481106131b0576131b0614be7565b1a60f81b836131c0836044614d53565b815181106131d0576131d0614be7565b60200101906001600160f81b03191690815f1a905350600101613195565b505f6131fd6060860186614ba2565b905090505f5b600481101561326857613217816003614f58565b613222906008614d88565b63ffffffff8316901c60f81b8461323a836058614d53565b8151811061324a5761324a614be7565b60200101906001600160f81b03191690815f1a905350600101613203565b505f5b6132786060870187614ba2565b905081101561348c575f61328d826058614d88565b61329890605c614d53565b90505f5b6020811015613323576132b26060890189614ba2565b848181106132c2576132c2614be7565b90506020028101906132d49190614bfb565b3581602081106132e6576132e6614be7565b1a60f81b866132f58385614d53565b8151811061330557613305614be7565b60200101906001600160f81b03191690815f1a90535060010161329c565b505f5b60088110156133d85761333a816007614f58565b613345906008614d88565b61335260608a018a614ba2565b8581811061336257613362614be7565b90506020028101906133749190614bfb565b61338590604081019060200161499b565b6001600160401b0316901c60f81b86826133a0856020614d53565b6133aa9190614d53565b815181106133ba576133ba614be7565b60200101906001600160f81b03191690815f1a905350600101613326565b505f5b6030811015613482576133f16060890189614ba2565b8481811061340157613401614be7565b90506020028101906134139190614bfb565b613421906040810190614f6b565b8281811061343157613431614be7565b9050013560f81c60f81b868284602861344a9190614d53565b6134549190614d53565b8151811061346457613464614be7565b60200101906001600160f81b03191690815f1a9053506001016133db565b505060010161326b565b5091949350505050565b61349e6147b4565b5f8281525f805160206152228339815191526020526040808220815160e0810190925280545f805160206151e283398151915293929190829060ff1660058111156134eb576134eb6149b4565b60058111156134fc576134fc6149b4565b8152600182015460208201526002808301546001600160401b038082166040850152600160401b820481166060850152600160801b820481166080850152600160c01b909104811660a084015260039093015490921660c0909101529091508151600581111561356e5761356e6149b4565b1461358c5760405163a36c527f60e01b815260040160405180910390fd5b60038152426001600160401b031660c08201525f84815260078301602052604090208151815483929190829060ff191660018360058111156135d0576135d06149b4565b02179055506020820151600182015560408201516002820180546060850151608086015160a08701516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c0909201516003909101805467ffffffffffffffff1916919092161790555f61367c8582612287565b6080840151604080516001600160401b03909216825242602083015291935083925087917f13d58394cf269d48bcf927959a29a5ffee7c9924dafff8927ecdf3c48ffa7c67910160405180910390a3509392505050565b5f8082516027146136f757604051638d0242c960e01b815260040160405180910390fd5b5f805b60028110156137465761370e816001614f58565b613719906008614d88565b61ffff1685828151811061372f5761372f614be7565b016020015160f81c901b91909117906001016136fa565b5061ffff81161561376a5760405163059510e360e31b815260040160405180910390fd5b5f805b60048110156137c557613781816003614f58565b61378c906008614d88565b63ffffffff168661379e836002614d53565b815181106137ae576137ae614be7565b016020015160f81c901b919091179060010161376d565b5063ffffffff81166003146137ed57604051635b60892f60e01b815260040160405180910390fd5b5f805b60208110156138425761380481601f614f58565b61380f906008614d88565b8761381b836006614d53565b8151811061382b5761382b614be7565b016020015160f81c901b91909117906001016137f0565b505f8660268151811061385757613857614be7565b016020015191976001600160f81b03199092161515965090945050505050565b5f5f805160206151c28339815191528161389084610b81565b90505f61389c8761203b565b90506138a7876128b9565b6138c457604051636ca57bcf60e01b815260040160405180910390fd5b6002815160058111156138d9576138d96149b4565b146138f75760405163a36c527f60e01b815260040160405180910390fd5b5f8282608001516139089190614d9f565b905083600201600a9054906101000a90046001600160401b031682604001516139319190614fad565b6001600160401b0316816001600160401b0316111561396357604051630c192e7760e41b815260040160405180910390fd5b5f8061396f8a84612287565b915091505f8a8360405160200161399d92919091825260c01b6001600160c01b031916602082015260280190565b60408051601f19818403018152828252805160209091012060e08301909152915080600181526001600160a01b038c1660208083019190915260408083018f90526001600160401b03808b1660608501525f6080850181905290881660a085015260c090930183905284835260058b01909152902081518154829060ff19166001836003811115613a3057613a306149b4565b02179055506020828101518254610100600160a81b0319166101006001600160a01b039283160217835560408085015160018501556060808601516002909501805460808089015160a08a015160c0909a01516001600160401b03998a166001600160801b031990941693909317600160401b918a1691909102176001600160801b0316600160801b998916999099026001600160c01b031698909817600160c01b91881691909102179055815189861681528a861694810194909452938b1690830152918101859052908c16918d9184917fb0024b263bc3a0b728a6edea50a69efa841189f8d32ee8af9d1c2b1a1a223426910160405180910390a49a9950505050505050505050565b5f808251602e14613b5f57604051638d0242c960e01b815260040160405180910390fd5b5f805b6002811015613bae57613b76816001614f58565b613b81906008614d88565b61ffff16858281518110613b9757613b97614be7565b016020015160f81c901b9190911790600101613b62565b5061ffff811615613bd25760405163059510e360e31b815260040160405180910390fd5b5f805b6004811015613c2d57613be9816003614f58565b613bf4906008614d88565b63ffffffff1686613c06836002614d53565b81518110613c1657613c16614be7565b016020015160f81c901b9190911790600101613bd5565b5063ffffffff8116600514613c5557604051635b60892f60e01b815260040160405180910390fd5b5f805b6020811015613caa57613c6c81601f614f58565b613c77906008614d88565b87613c83836006614d53565b81518110613c9357613c93614be7565b016020015160f81c901b9190911790600101613c58565b505f805b6008811015613d0957613cc2816007614f58565b613ccd906008614d88565b6001600160401b031688613ce2836026614d53565b81518110613cf257613cf2614be7565b016020015160f81c901b9190911790600101613cae565b5090969095509350505050565b5f805160206151e28339815191525f6001600160401b038084169085161115613d4a57613d438385614a8b565b9050613d57565b613d548484614a8b565b90505b6040805160808101825260028401548082526003850154602083015260048501549282019290925260058401546001600160401b0316606082015242911580613db9575060018401548151613db5916001600160401b031690614d53565b8210155b15613ddf576001600160401b038316606082015281815260408101516020820152613dfe565b8281606001818151613df19190614d9f565b6001600160401b03169052505b6060810151613e0e906064614fad565b602082015160018601546001600160401b039290921691613e399190600160401b900460ff16614d88565b1015613e585760405163254d226960e01b815260040160405180910390fd5b856001600160401b031681604001818151613e739190614d53565b9052506040810180516001600160401b0387169190613e93908390614f58565b905250805160028501556020810151600385015560408101516004850155606001516005909301805467ffffffffffffffff19166001600160401b039094169390931790925550505050565b5f8181525f805160206152228339815191526020526040812060020180545f805160206151e28339815191529190600890613f2990600160401b90046001600160401b0316614fd8565b91906101000a8154816001600160401b0302191690836001600160401b031602179055915050919050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16613f9d57604051631afcd79f60e31b815260040160405180910390fd5b565b613fa7613f54565b613fb08161448e565b613fb86144a7565b611b8f60608201356080830135613fd560c0850160a0860161499b565b613fe560e0860160c08701614ff3565b613ff6610100870160e0880161500c565b61400861012088016101008901614b87565b6144b7565b7fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb09545f9060ff1661405157604051637fab81e560e01b815260040160405180910390fd5b5f805160206151e283398151915242614070604086016020870161499b565b6001600160401b03161115806140aa575061408e6202a30042614d53565b61409e604086016020870161499b565b6001600160401b031610155b156140c75760405162d36c8560e81b815260040160405180910390fd5b60306140d66040860186614f6b565b90501415806140e457508335155b156141025760405163b4fa3fb360e01b815260040160405180910390fd5b83355f9081526008820160205260409020541561413257604051630eb0d31360e11b815260040160405180910390fd5b61413c835f613d16565b5f806141d56040518060a00160405280855f01548152602001885f01358152602001876001600160401b03168152602001886020016020810190614180919061499b565b6001600160401b0316815260200161419b60408a018a614f6b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050509152506145d8565b5f828152600686016020526040902091935091506141f38282615070565b5085355f9081526008840160205260408082208490555163ee5b48eb60e01b81526005600160991b019063ee5b48eb90614231908590600401614b22565b6020604051808303815f875af115801561424d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906142719190614ae9565b6040805160e08101909152909150806001815288356020808301919091526001600160401b03891660408084018290525f60608501819052608085019290925260a0840182905260c0909301819052868152600788019091522081518154829060ff191660018360058111156142e9576142e96149b4565b021790555060208281015160018301556040808401516002840180546060870151608088015160a08901516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c0909401516003909301805467ffffffffffffffff19169390941692909217909255829189359186917f79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e918b916143c9918e01908e0161499b565b604080516001600160401b0393841681529290911660208301520160405180910390a4509095945050505050565b8047101561441e5760405163cd78605960e01b815230600482015260240160405180910390fd5b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114614467576040519150601f19603f3d011682016040523d82523d5f602084013e61446c565b606091505b505090508061200557604051630a12f52160e11b815260040160405180910390fd5b614496613f54565b61449e61469b565b611b8f816146a3565b6144af613f54565b613f9d614775565b6144bf613f54565b5f805160206151c283398151915261ffff841615806144e3575061271061ffff8516115b156145015760405163c98d73a760e01b815260040160405180910390fd5b8587111561452257604051630103be3b60e21b815260040160405180910390fd5b60ff831615806145355750600a60ff8416115b15614553576040516373c01c8d60e01b815260040160405180910390fd5b95865560018601949094556002850180546001600160401b039490941669ffffffffffffffffffff1990941693909317600160401b61ffff93909316929092029190911767ffffffffffffffff60501b191660ff91909116600160501b02179055600390910180546001600160a01b0319166001600160a01b03909216919091179055565b5f606082608001515160301461460157604051638d0242c960e01b815260040160405180910390fd5b5f806001855f01518660200151876040015188608001518960600151604051602001614633979695949392919061512b565b60405160208183030381529060405290506002816040516146549190614d42565b602060405180830381855afa15801561466f573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906146929190614ae9565b94909350915050565b613f9d613f54565b6146ab613f54565b80355f805160206151e283398151915290815560146146d0606084016040850161500c565b60ff1611806146ef57506146ea606083016040840161500c565b60ff16155b1561470d5760405163b4fa3fb360e01b815260040160405180910390fd5b61471d606083016040840161500c565b60018201805460ff92909216600160401b0260ff60401b1990921691909117905561474e604083016020840161499b565b600191909101805467ffffffffffffffff19166001600160401b0390921691909117905550565b612608613f54565b50805461478990614dbf565b5f825580601f10614798575050565b601f0160209004905f5260205f2090810190611b8f91906147f0565b6040805160e08101909152805f81525f6020820181905260408201819052606082018190526080820181905260a0820181905260c09091015290565b5b80821115614804575f81556001016147f1565b5090565b8015158114611b8f575f80fd5b803563ffffffff81168114612036575f80fd5b5f805f6060848603121561483a575f80fd5b83359250602084013561484c81614808565b915061485a60408501614815565b90509250925092565b5f60208284031215614873575f80fd5b5035919050565b5f610120828403121561488b575f80fd5b50919050565b803561ffff81168114612036575f80fd5b80356001600160401b0381168114612036575f80fd5b5f805f606084860312156148ca575f80fd5b83356001600160401b038111156148df575f80fd5b8401606081870312156148f0575f80fd5b92506148fe60208501614891565b915061485a604085016148a2565b5f6020828403121561491c575f80fd5b610bc482614815565b5f8060408385031215614936575f80fd5b61493f83614815565b946020939093013593505050565b5f806040838503121561495e575f80fd5b82356001600160401b03811115614973575f80fd5b830160808186031215614984575f80fd5b915061499260208401614815565b90509250929050565b5f602082840312156149ab575f80fd5b610bc4826148a2565b634e487b7160e01b5f52602160045260245ffd5b815160e0820190600681106149eb57634e487b7160e01b5f52602160045260245ffd5b80835250602083015160208301526001600160401b0360408401511660408301526060830151614a2660608401826001600160401b03169052565b506080830151614a4160808401826001600160401b03169052565b5060a0830151614a5c60a08401826001600160401b03169052565b5060c0830151612c4360c08401826001600160401b03169052565b634e487b7160e01b5f52601160045260245ffd5b6001600160401b03828116828216039080821115612c4357612c43614a77565b9687526001600160401b03958616602088015293851660408701529184166060860152909216608084015260a083019190915260c082015260e00190565b5f60208284031215614af9575f80fd5b5051919050565b5f5b83811015614b1a578181015183820152602001614b02565b50505f910152565b602081525f8251806020840152614b40816040850160208701614b00565b601f01601f19169190910160400192915050565b5f82614b6e57634e487b7160e01b5f52601260045260245ffd5b500490565b6001600160a01b0381168114611b8f575f80fd5b5f60208284031215614b97575f80fd5b8135610bc481614b73565b5f808335601e19843603018112614bb7575f80fd5b8301803591506001600160401b03821115614bd0575f80fd5b6020019150600581901b36038213156123d7575f80fd5b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112614c0f575f80fd5b9190910192915050565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b0381118282101715614c4f57614c4f614c19565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614c7d57614c7d614c19565b604052919050565b5f6001600160401b03821115614c9d57614c9d614c19565b50601f01601f191660200190565b5f60608236031215614cbb575f80fd5b614cc3614c2d565b823581526020614cd48185016148a2565b8183015260408401356001600160401b03811115614cf0575f80fd5b840136601f820112614d00575f80fd5b8035614d13614d0e82614c85565b614c55565b8181523684838501011115614d26575f80fd5b81848401858301375f9181019093015250604082015292915050565b5f8251614c0f818460208701614b00565b80820180821115610b9157610b91614a77565b5f63ffffffff808316818103614d7e57614d7e614a77565b6001019392505050565b8082028115828204841417610b9157610b91614a77565b6001600160401b03818116838216019080821115612c4357612c43614a77565b600181811c90821680614dd357607f821691505b60208210810361488b57634e487b7160e01b5f52602260045260245ffd5b5f60208083525f8454614e0381614dbf565b806020870152604060018084165f8114614e245760018114614e4057614e6d565b60ff19851660408a0152604084151560051b8a01019550614e6d565b895f5260205f205f5b85811015614e645781548b8201860152908301908801614e49565b8a016040019650505b509398975050505050505050565b805161203681614808565b5f8060408385031215614e97575f80fd5b82516001600160401b0380821115614ead575f80fd5b9084019060608287031215614ec0575f80fd5b614ec8614c2d565b82518152602080840151614edb81614b73565b82820152604084015183811115614ef0575f80fd5b80850194505087601f850112614f04575f80fd5b83519250614f14614d0e84614c85565b8381528882858701011115614f27575f80fd5b614f3684838301848801614b00565b80604084015250819550614f4b818801614e7b565b9450505050509250929050565b81810381811115610b9157610b91614a77565b5f808335601e19843603018112614f80575f80fd5b8301803591506001600160401b03821115614f99575f80fd5b6020019150368190038213156123d7575f80fd5b6001600160401b03818116838216028082169190828114614fd057614fd0614a77565b505092915050565b5f6001600160401b03808316818103614d7e57614d7e614a77565b5f60208284031215615003575f80fd5b610bc482614891565b5f6020828403121561501c575f80fd5b813560ff81168114610bc4575f80fd5b601f82111561200557805f5260205f20601f840160051c810160208510156150515750805b601f840160051c820191505b81811015610c65575f815560010161505d565b81516001600160401b0381111561508957615089614c19565b61509d816150978454614dbf565b8461502c565b602080601f8311600181146150d0575f84156150b95750858301515b5f19600386901b1c1916600185901b178555612952565b5f85815260208120601f198616915b828110156150fe578886015182559484019460019091019084016150df565b508582101561511b57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b61ffff60f01b8860f01b16815263ffffffff60e01b8760e01b1660028201528560068201528460268201525f6001600160401b0360c01b808660c01b166046840152845161518081604e860160208901614b00565b60c09490941b1691909201604e81019190915260560197965050505050505056fe4317713f7ecbdddd4bc99e95d903adedaa883b2e7c2551610bd13e2c7e473d054317713f7ecbdddd4bc99e95d903adedaa883b2e7c2551610bd13e2c7e473d00e92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00e92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb07a164736f6c6343000819000a", +} + +// NativeTokenStakingManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use NativeTokenStakingManagerMetaData.ABI instead. +var NativeTokenStakingManagerABI = NativeTokenStakingManagerMetaData.ABI + +// NativeTokenStakingManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use NativeTokenStakingManagerMetaData.Bin instead. +var NativeTokenStakingManagerBin = NativeTokenStakingManagerMetaData.Bin + +// DeployNativeTokenStakingManager deploys a new Ethereum contract, binding an instance of NativeTokenStakingManager to it. +func DeployNativeTokenStakingManager(auth *bind.TransactOpts, backend bind.ContractBackend, init uint8) (common.Address, *types.Transaction, *NativeTokenStakingManager, error) { + parsed, err := NativeTokenStakingManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(NativeTokenStakingManagerBin), backend, init) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NativeTokenStakingManager{NativeTokenStakingManagerCaller: NativeTokenStakingManagerCaller{contract: contract}, NativeTokenStakingManagerTransactor: NativeTokenStakingManagerTransactor{contract: contract}, NativeTokenStakingManagerFilterer: NativeTokenStakingManagerFilterer{contract: contract}}, nil +} + +// NativeTokenStakingManager is an auto generated Go binding around an Ethereum contract. +type NativeTokenStakingManager struct { + NativeTokenStakingManagerCaller // Read-only binding to the contract + NativeTokenStakingManagerTransactor // Write-only binding to the contract + NativeTokenStakingManagerFilterer // Log filterer for contract events +} + +// NativeTokenStakingManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type NativeTokenStakingManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenStakingManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type NativeTokenStakingManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenStakingManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type NativeTokenStakingManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenStakingManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type NativeTokenStakingManagerSession struct { + Contract *NativeTokenStakingManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenStakingManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type NativeTokenStakingManagerCallerSession struct { + Contract *NativeTokenStakingManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// NativeTokenStakingManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type NativeTokenStakingManagerTransactorSession struct { + Contract *NativeTokenStakingManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenStakingManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type NativeTokenStakingManagerRaw struct { + Contract *NativeTokenStakingManager // Generic contract binding to access the raw methods on +} + +// NativeTokenStakingManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type NativeTokenStakingManagerCallerRaw struct { + Contract *NativeTokenStakingManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// NativeTokenStakingManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type NativeTokenStakingManagerTransactorRaw struct { + Contract *NativeTokenStakingManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewNativeTokenStakingManager creates a new instance of NativeTokenStakingManager, bound to a specific deployed contract. +func NewNativeTokenStakingManager(address common.Address, backend bind.ContractBackend) (*NativeTokenStakingManager, error) { + contract, err := bindNativeTokenStakingManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NativeTokenStakingManager{NativeTokenStakingManagerCaller: NativeTokenStakingManagerCaller{contract: contract}, NativeTokenStakingManagerTransactor: NativeTokenStakingManagerTransactor{contract: contract}, NativeTokenStakingManagerFilterer: NativeTokenStakingManagerFilterer{contract: contract}}, nil +} + +// NewNativeTokenStakingManagerCaller creates a new read-only instance of NativeTokenStakingManager, bound to a specific deployed contract. +func NewNativeTokenStakingManagerCaller(address common.Address, caller bind.ContractCaller) (*NativeTokenStakingManagerCaller, error) { + contract, err := bindNativeTokenStakingManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerCaller{contract: contract}, nil +} + +// NewNativeTokenStakingManagerTransactor creates a new write-only instance of NativeTokenStakingManager, bound to a specific deployed contract. +func NewNativeTokenStakingManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*NativeTokenStakingManagerTransactor, error) { + contract, err := bindNativeTokenStakingManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerTransactor{contract: contract}, nil +} + +// NewNativeTokenStakingManagerFilterer creates a new log filterer instance of NativeTokenStakingManager, bound to a specific deployed contract. +func NewNativeTokenStakingManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*NativeTokenStakingManagerFilterer, error) { + contract, err := bindNativeTokenStakingManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerFilterer{contract: contract}, nil +} + +// bindNativeTokenStakingManager binds a generic wrapper to an already deployed contract. +func bindNativeTokenStakingManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NativeTokenStakingManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenStakingManager *NativeTokenStakingManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenStakingManager.Contract.NativeTokenStakingManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenStakingManager *NativeTokenStakingManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.NativeTokenStakingManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenStakingManager *NativeTokenStakingManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.NativeTokenStakingManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenStakingManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.contract.Transact(opts, method, params...) +} + +// ADDRESSLENGTH is a free data retrieval call binding the contract method 0x60305d62. +// +// Solidity: function ADDRESS_LENGTH() view returns(uint32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) ADDRESSLENGTH(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "ADDRESS_LENGTH") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// ADDRESSLENGTH is a free data retrieval call binding the contract method 0x60305d62. +// +// Solidity: function ADDRESS_LENGTH() view returns(uint32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ADDRESSLENGTH() (uint32, error) { + return _NativeTokenStakingManager.Contract.ADDRESSLENGTH(&_NativeTokenStakingManager.CallOpts) +} + +// ADDRESSLENGTH is a free data retrieval call binding the contract method 0x60305d62. +// +// Solidity: function ADDRESS_LENGTH() view returns(uint32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) ADDRESSLENGTH() (uint32, error) { + return _NativeTokenStakingManager.Contract.ADDRESSLENGTH(&_NativeTokenStakingManager.CallOpts) +} + +// BLSPUBLICKEYLENGTH is a free data retrieval call binding the contract method 0x8280a25a. +// +// Solidity: function BLS_PUBLIC_KEY_LENGTH() view returns(uint8) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) BLSPUBLICKEYLENGTH(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "BLS_PUBLIC_KEY_LENGTH") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// BLSPUBLICKEYLENGTH is a free data retrieval call binding the contract method 0x8280a25a. +// +// Solidity: function BLS_PUBLIC_KEY_LENGTH() view returns(uint8) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) BLSPUBLICKEYLENGTH() (uint8, error) { + return _NativeTokenStakingManager.Contract.BLSPUBLICKEYLENGTH(&_NativeTokenStakingManager.CallOpts) +} + +// BLSPUBLICKEYLENGTH is a free data retrieval call binding the contract method 0x8280a25a. +// +// Solidity: function BLS_PUBLIC_KEY_LENGTH() view returns(uint8) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) BLSPUBLICKEYLENGTH() (uint8, error) { + return _NativeTokenStakingManager.Contract.BLSPUBLICKEYLENGTH(&_NativeTokenStakingManager.CallOpts) +} + +// MAXIMUMCHURNPERCENTAGELIMIT is a free data retrieval call binding the contract method 0xc974d1b6. +// +// Solidity: function MAXIMUM_CHURN_PERCENTAGE_LIMIT() view returns(uint8) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) MAXIMUMCHURNPERCENTAGELIMIT(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "MAXIMUM_CHURN_PERCENTAGE_LIMIT") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// MAXIMUMCHURNPERCENTAGELIMIT is a free data retrieval call binding the contract method 0xc974d1b6. +// +// Solidity: function MAXIMUM_CHURN_PERCENTAGE_LIMIT() view returns(uint8) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) MAXIMUMCHURNPERCENTAGELIMIT() (uint8, error) { + return _NativeTokenStakingManager.Contract.MAXIMUMCHURNPERCENTAGELIMIT(&_NativeTokenStakingManager.CallOpts) +} + +// MAXIMUMCHURNPERCENTAGELIMIT is a free data retrieval call binding the contract method 0xc974d1b6. +// +// Solidity: function MAXIMUM_CHURN_PERCENTAGE_LIMIT() view returns(uint8) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) MAXIMUMCHURNPERCENTAGELIMIT() (uint8, error) { + return _NativeTokenStakingManager.Contract.MAXIMUMCHURNPERCENTAGELIMIT(&_NativeTokenStakingManager.CallOpts) +} + +// MAXIMUMDELEGATIONFEEBIPS is a free data retrieval call binding the contract method 0x35455ded. +// +// Solidity: function MAXIMUM_DELEGATION_FEE_BIPS() view returns(uint16) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) MAXIMUMDELEGATIONFEEBIPS(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "MAXIMUM_DELEGATION_FEE_BIPS") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +// MAXIMUMDELEGATIONFEEBIPS is a free data retrieval call binding the contract method 0x35455ded. +// +// Solidity: function MAXIMUM_DELEGATION_FEE_BIPS() view returns(uint16) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) MAXIMUMDELEGATIONFEEBIPS() (uint16, error) { + return _NativeTokenStakingManager.Contract.MAXIMUMDELEGATIONFEEBIPS(&_NativeTokenStakingManager.CallOpts) +} + +// MAXIMUMDELEGATIONFEEBIPS is a free data retrieval call binding the contract method 0x35455ded. +// +// Solidity: function MAXIMUM_DELEGATION_FEE_BIPS() view returns(uint16) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) MAXIMUMDELEGATIONFEEBIPS() (uint16, error) { + return _NativeTokenStakingManager.Contract.MAXIMUMDELEGATIONFEEBIPS(&_NativeTokenStakingManager.CallOpts) +} + +// MAXIMUMREGISTRATIONEXPIRYLENGTH is a free data retrieval call binding the contract method 0xdf93d8de. +// +// Solidity: function MAXIMUM_REGISTRATION_EXPIRY_LENGTH() view returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) MAXIMUMREGISTRATIONEXPIRYLENGTH(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "MAXIMUM_REGISTRATION_EXPIRY_LENGTH") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// MAXIMUMREGISTRATIONEXPIRYLENGTH is a free data retrieval call binding the contract method 0xdf93d8de. +// +// Solidity: function MAXIMUM_REGISTRATION_EXPIRY_LENGTH() view returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) MAXIMUMREGISTRATIONEXPIRYLENGTH() (uint64, error) { + return _NativeTokenStakingManager.Contract.MAXIMUMREGISTRATIONEXPIRYLENGTH(&_NativeTokenStakingManager.CallOpts) +} + +// MAXIMUMREGISTRATIONEXPIRYLENGTH is a free data retrieval call binding the contract method 0xdf93d8de. +// +// Solidity: function MAXIMUM_REGISTRATION_EXPIRY_LENGTH() view returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) MAXIMUMREGISTRATIONEXPIRYLENGTH() (uint64, error) { + return _NativeTokenStakingManager.Contract.MAXIMUMREGISTRATIONEXPIRYLENGTH(&_NativeTokenStakingManager.CallOpts) +} + +// MAXIMUMSTAKEMULTIPLIERLIMIT is a free data retrieval call binding the contract method 0x151d30d1. +// +// Solidity: function MAXIMUM_STAKE_MULTIPLIER_LIMIT() view returns(uint8) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) MAXIMUMSTAKEMULTIPLIERLIMIT(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "MAXIMUM_STAKE_MULTIPLIER_LIMIT") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// MAXIMUMSTAKEMULTIPLIERLIMIT is a free data retrieval call binding the contract method 0x151d30d1. +// +// Solidity: function MAXIMUM_STAKE_MULTIPLIER_LIMIT() view returns(uint8) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) MAXIMUMSTAKEMULTIPLIERLIMIT() (uint8, error) { + return _NativeTokenStakingManager.Contract.MAXIMUMSTAKEMULTIPLIERLIMIT(&_NativeTokenStakingManager.CallOpts) +} + +// MAXIMUMSTAKEMULTIPLIERLIMIT is a free data retrieval call binding the contract method 0x151d30d1. +// +// Solidity: function MAXIMUM_STAKE_MULTIPLIER_LIMIT() view returns(uint8) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) MAXIMUMSTAKEMULTIPLIERLIMIT() (uint8, error) { + return _NativeTokenStakingManager.Contract.MAXIMUMSTAKEMULTIPLIERLIMIT(&_NativeTokenStakingManager.CallOpts) +} + +// NATIVEMINTER is a free data retrieval call binding the contract method 0x329c3e12. +// +// Solidity: function NATIVE_MINTER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) NATIVEMINTER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "NATIVE_MINTER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// NATIVEMINTER is a free data retrieval call binding the contract method 0x329c3e12. +// +// Solidity: function NATIVE_MINTER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) NATIVEMINTER() (common.Address, error) { + return _NativeTokenStakingManager.Contract.NATIVEMINTER(&_NativeTokenStakingManager.CallOpts) +} + +// NATIVEMINTER is a free data retrieval call binding the contract method 0x329c3e12. +// +// Solidity: function NATIVE_MINTER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) NATIVEMINTER() (common.Address, error) { + return _NativeTokenStakingManager.Contract.NATIVEMINTER(&_NativeTokenStakingManager.CallOpts) +} + +// PCHAINBLOCKCHAINID is a free data retrieval call binding the contract method 0x732214f8. +// +// Solidity: function P_CHAIN_BLOCKCHAIN_ID() view returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) PCHAINBLOCKCHAINID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "P_CHAIN_BLOCKCHAIN_ID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// PCHAINBLOCKCHAINID is a free data retrieval call binding the contract method 0x732214f8. +// +// Solidity: function P_CHAIN_BLOCKCHAIN_ID() view returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) PCHAINBLOCKCHAINID() ([32]byte, error) { + return _NativeTokenStakingManager.Contract.PCHAINBLOCKCHAINID(&_NativeTokenStakingManager.CallOpts) +} + +// PCHAINBLOCKCHAINID is a free data retrieval call binding the contract method 0x732214f8. +// +// Solidity: function P_CHAIN_BLOCKCHAIN_ID() view returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) PCHAINBLOCKCHAINID() ([32]byte, error) { + return _NativeTokenStakingManager.Contract.PCHAINBLOCKCHAINID(&_NativeTokenStakingManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) WARPMESSENGER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "WARP_MESSENGER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) WARPMESSENGER() (common.Address, error) { + return _NativeTokenStakingManager.Contract.WARPMESSENGER(&_NativeTokenStakingManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) WARPMESSENGER() (common.Address, error) { + return _NativeTokenStakingManager.Contract.WARPMESSENGER(&_NativeTokenStakingManager.CallOpts) +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes32,uint64,uint64,uint64,uint64,uint64)) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) GetValidator(opts *bind.CallOpts, validationID [32]byte) (Validator, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "getValidator", validationID) + + if err != nil { + return *new(Validator), err + } + + out0 := *abi.ConvertType(out[0], new(Validator)).(*Validator) + + return out0, err + +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes32,uint64,uint64,uint64,uint64,uint64)) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) GetValidator(validationID [32]byte) (Validator, error) { + return _NativeTokenStakingManager.Contract.GetValidator(&_NativeTokenStakingManager.CallOpts, validationID) +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes32,uint64,uint64,uint64,uint64,uint64)) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) GetValidator(validationID [32]byte) (Validator, error) { + return _NativeTokenStakingManager.Contract.GetValidator(&_NativeTokenStakingManager.CallOpts, validationID) +} + +// GetWeight is a free data retrieval call binding the contract method 0x66435abf. +// +// Solidity: function getWeight(bytes32 validationID) view returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) GetWeight(opts *bind.CallOpts, validationID [32]byte) (uint64, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "getWeight", validationID) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// GetWeight is a free data retrieval call binding the contract method 0x66435abf. +// +// Solidity: function getWeight(bytes32 validationID) view returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) GetWeight(validationID [32]byte) (uint64, error) { + return _NativeTokenStakingManager.Contract.GetWeight(&_NativeTokenStakingManager.CallOpts, validationID) +} + +// GetWeight is a free data retrieval call binding the contract method 0x66435abf. +// +// Solidity: function getWeight(bytes32 validationID) view returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) GetWeight(validationID [32]byte) (uint64, error) { + return _NativeTokenStakingManager.Contract.GetWeight(&_NativeTokenStakingManager.CallOpts, validationID) +} + +// RegisteredValidators is a free data retrieval call binding the contract method 0xe7d14c1c. +// +// Solidity: function registeredValidators(bytes32 nodeID) view returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) RegisteredValidators(opts *bind.CallOpts, nodeID [32]byte) ([32]byte, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "registeredValidators", nodeID) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// RegisteredValidators is a free data retrieval call binding the contract method 0xe7d14c1c. +// +// Solidity: function registeredValidators(bytes32 nodeID) view returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) RegisteredValidators(nodeID [32]byte) ([32]byte, error) { + return _NativeTokenStakingManager.Contract.RegisteredValidators(&_NativeTokenStakingManager.CallOpts, nodeID) +} + +// RegisteredValidators is a free data retrieval call binding the contract method 0xe7d14c1c. +// +// Solidity: function registeredValidators(bytes32 nodeID) view returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) RegisteredValidators(nodeID [32]byte) ([32]byte, error) { + return _NativeTokenStakingManager.Contract.RegisteredValidators(&_NativeTokenStakingManager.CallOpts, nodeID) +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) pure returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) ValueToWeight(opts *bind.CallOpts, value *big.Int) (uint64, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "valueToWeight", value) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) pure returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ValueToWeight(value *big.Int) (uint64, error) { + return _NativeTokenStakingManager.Contract.ValueToWeight(&_NativeTokenStakingManager.CallOpts, value) +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) pure returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) ValueToWeight(value *big.Int) (uint64, error) { + return _NativeTokenStakingManager.Contract.ValueToWeight(&_NativeTokenStakingManager.CallOpts, value) +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) pure returns(uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) WeightToValue(opts *bind.CallOpts, weight uint64) (*big.Int, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "weightToValue", weight) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) pure returns(uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) WeightToValue(weight uint64) (*big.Int, error) { + return _NativeTokenStakingManager.Contract.WeightToValue(&_NativeTokenStakingManager.CallOpts, weight) +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) pure returns(uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) WeightToValue(weight uint64) (*big.Int, error) { + return _NativeTokenStakingManager.Contract.WeightToValue(&_NativeTokenStakingManager.CallOpts, weight) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) ClaimDelegationFees(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "claimDelegationFees", validationID) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ClaimDelegationFees(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ClaimDelegationFees(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// ClaimDelegationFees is a paid mutator transaction binding the contract method 0x93e24598. +// +// Solidity: function claimDelegationFees(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) ClaimDelegationFees(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ClaimDelegationFees(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x5297fae6. +// +// Solidity: function completeDelegatorRegistration(uint32 messageIndex, bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) CompleteDelegatorRegistration(opts *bind.TransactOpts, messageIndex uint32, delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "completeDelegatorRegistration", messageIndex, delegationID) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x5297fae6. +// +// Solidity: function completeDelegatorRegistration(uint32 messageIndex, bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) CompleteDelegatorRegistration(messageIndex uint32, delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteDelegatorRegistration(&_NativeTokenStakingManager.TransactOpts, messageIndex, delegationID) +} + +// CompleteDelegatorRegistration is a paid mutator transaction binding the contract method 0x5297fae6. +// +// Solidity: function completeDelegatorRegistration(uint32 messageIndex, bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) CompleteDelegatorRegistration(messageIndex uint32, delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteDelegatorRegistration(&_NativeTokenStakingManager.TransactOpts, messageIndex, delegationID) +} + +// CompleteEndDelegation is a paid mutator transaction binding the contract method 0x98f3e2b4. +// +// Solidity: function completeEndDelegation(uint32 messageIndex, bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) CompleteEndDelegation(opts *bind.TransactOpts, messageIndex uint32, delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "completeEndDelegation", messageIndex, delegationID) +} + +// CompleteEndDelegation is a paid mutator transaction binding the contract method 0x98f3e2b4. +// +// Solidity: function completeEndDelegation(uint32 messageIndex, bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) CompleteEndDelegation(messageIndex uint32, delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteEndDelegation(&_NativeTokenStakingManager.TransactOpts, messageIndex, delegationID) +} + +// CompleteEndDelegation is a paid mutator transaction binding the contract method 0x98f3e2b4. +// +// Solidity: function completeEndDelegation(uint32 messageIndex, bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) CompleteEndDelegation(messageIndex uint32, delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteEndDelegation(&_NativeTokenStakingManager.TransactOpts, messageIndex, delegationID) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0x467ef06f. +// +// Solidity: function completeEndValidation(uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) CompleteEndValidation(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "completeEndValidation", messageIndex) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0x467ef06f. +// +// Solidity: function completeEndValidation(uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) CompleteEndValidation(messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteEndValidation(&_NativeTokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0x467ef06f. +// +// Solidity: function completeEndValidation(uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) CompleteEndValidation(messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteEndValidation(&_NativeTokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) CompleteValidatorRegistration(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "completeValidatorRegistration", messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteValidatorRegistration(&_NativeTokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteValidatorRegistration(&_NativeTokenStakingManager.TransactOpts, messageIndex) +} + +// EndDelegationCompletedValidator is a paid mutator transaction binding the contract method 0x9dde029a. +// +// Solidity: function endDelegationCompletedValidator(bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) EndDelegationCompletedValidator(opts *bind.TransactOpts, delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "endDelegationCompletedValidator", delegationID) +} + +// EndDelegationCompletedValidator is a paid mutator transaction binding the contract method 0x9dde029a. +// +// Solidity: function endDelegationCompletedValidator(bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) EndDelegationCompletedValidator(delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.EndDelegationCompletedValidator(&_NativeTokenStakingManager.TransactOpts, delegationID) +} + +// EndDelegationCompletedValidator is a paid mutator transaction binding the contract method 0x9dde029a. +// +// Solidity: function endDelegationCompletedValidator(bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) EndDelegationCompletedValidator(delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.EndDelegationCompletedValidator(&_NativeTokenStakingManager.TransactOpts, delegationID) +} + +// Initialize is a paid mutator transaction binding the contract method 0x20e55565. +// +// Solidity: function initialize(((bytes32,uint64,uint8),uint256,uint256,uint64,uint16,uint8,address) settings) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) Initialize(opts *bind.TransactOpts, settings PoSValidatorManagerSettings) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initialize", settings) +} + +// Initialize is a paid mutator transaction binding the contract method 0x20e55565. +// +// Solidity: function initialize(((bytes32,uint64,uint8),uint256,uint256,uint64,uint16,uint8,address) settings) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) Initialize(settings PoSValidatorManagerSettings) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.Initialize(&_NativeTokenStakingManager.TransactOpts, settings) +} + +// Initialize is a paid mutator transaction binding the contract method 0x20e55565. +// +// Solidity: function initialize(((bytes32,uint64,uint8),uint256,uint256,uint64,uint16,uint8,address) settings) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) Initialize(settings PoSValidatorManagerSettings) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.Initialize(&_NativeTokenStakingManager.TransactOpts, settings) +} + +// InitializeDelegatorRegistration is a paid mutator transaction binding the contract method 0xc599e24f. +// +// Solidity: function initializeDelegatorRegistration(bytes32 validationID) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) InitializeDelegatorRegistration(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initializeDelegatorRegistration", validationID) +} + +// InitializeDelegatorRegistration is a paid mutator transaction binding the contract method 0xc599e24f. +// +// Solidity: function initializeDelegatorRegistration(bytes32 validationID) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) InitializeDelegatorRegistration(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeDelegatorRegistration(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// InitializeDelegatorRegistration is a paid mutator transaction binding the contract method 0xc599e24f. +// +// Solidity: function initializeDelegatorRegistration(bytes32 validationID) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) InitializeDelegatorRegistration(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeDelegatorRegistration(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// InitializeEndDelegation is a paid mutator transaction binding the contract method 0x0118acc4. +// +// Solidity: function initializeEndDelegation(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) InitializeEndDelegation(opts *bind.TransactOpts, delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initializeEndDelegation", delegationID, includeUptimeProof, messageIndex) +} + +// InitializeEndDelegation is a paid mutator transaction binding the contract method 0x0118acc4. +// +// Solidity: function initializeEndDelegation(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) InitializeEndDelegation(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeEndDelegation(&_NativeTokenStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// InitializeEndDelegation is a paid mutator transaction binding the contract method 0x0118acc4. +// +// Solidity: function initializeEndDelegation(bytes32 delegationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) InitializeEndDelegation(delegationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeEndDelegation(&_NativeTokenStakingManager.TransactOpts, delegationID, includeUptimeProof, messageIndex) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x76f78621. +// +// Solidity: function initializeEndValidation(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) InitializeEndValidation(opts *bind.TransactOpts, validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initializeEndValidation", validationID, includeUptimeProof, messageIndex) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x76f78621. +// +// Solidity: function initializeEndValidation(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) InitializeEndValidation(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeEndValidation(&_NativeTokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x76f78621. +// +// Solidity: function initializeEndValidation(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) InitializeEndValidation(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeEndValidation(&_NativeTokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0x40034a93. +// +// Solidity: function initializeValidatorRegistration((bytes32,uint64,bytes) registrationInput, uint16 delegationFeeBips, uint64 minStakeDuration) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) InitializeValidatorRegistration(opts *bind.TransactOpts, registrationInput ValidatorRegistrationInput, delegationFeeBips uint16, minStakeDuration uint64) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initializeValidatorRegistration", registrationInput, delegationFeeBips, minStakeDuration) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0x40034a93. +// +// Solidity: function initializeValidatorRegistration((bytes32,uint64,bytes) registrationInput, uint16 delegationFeeBips, uint64 minStakeDuration) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) InitializeValidatorRegistration(registrationInput ValidatorRegistrationInput, delegationFeeBips uint16, minStakeDuration uint64) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeValidatorRegistration(&_NativeTokenStakingManager.TransactOpts, registrationInput, delegationFeeBips, minStakeDuration) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0x40034a93. +// +// Solidity: function initializeValidatorRegistration((bytes32,uint64,bytes) registrationInput, uint16 delegationFeeBips, uint64 minStakeDuration) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) InitializeValidatorRegistration(registrationInput ValidatorRegistrationInput, delegationFeeBips uint16, minStakeDuration uint64) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeValidatorRegistration(&_NativeTokenStakingManager.TransactOpts, registrationInput, delegationFeeBips, minStakeDuration) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x61e2f490. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes32,uint64,bytes)[]) subnetConversionData, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) InitializeValidatorSet(opts *bind.TransactOpts, subnetConversionData SubnetConversionData, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initializeValidatorSet", subnetConversionData, messageIndex) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x61e2f490. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes32,uint64,bytes)[]) subnetConversionData, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) InitializeValidatorSet(subnetConversionData SubnetConversionData, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeValidatorSet(&_NativeTokenStakingManager.TransactOpts, subnetConversionData, messageIndex) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x61e2f490. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes32,uint64,bytes)[]) subnetConversionData, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) InitializeValidatorSet(subnetConversionData SubnetConversionData, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeValidatorSet(&_NativeTokenStakingManager.TransactOpts, subnetConversionData, messageIndex) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) ResendEndValidatorMessage(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "resendEndValidatorMessage", validationID) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ResendEndValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ResendEndValidatorMessage(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) ResendEndValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ResendEndValidatorMessage(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) ResendRegisterValidatorMessage(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "resendRegisterValidatorMessage", validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ResendRegisterValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ResendRegisterValidatorMessage(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) ResendRegisterValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ResendRegisterValidatorMessage(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// ResendUpdateDelegation is a paid mutator transaction binding the contract method 0xba3a4b97. +// +// Solidity: function resendUpdateDelegation(bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) ResendUpdateDelegation(opts *bind.TransactOpts, delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "resendUpdateDelegation", delegationID) +} + +// ResendUpdateDelegation is a paid mutator transaction binding the contract method 0xba3a4b97. +// +// Solidity: function resendUpdateDelegation(bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ResendUpdateDelegation(delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ResendUpdateDelegation(&_NativeTokenStakingManager.TransactOpts, delegationID) +} + +// ResendUpdateDelegation is a paid mutator transaction binding the contract method 0xba3a4b97. +// +// Solidity: function resendUpdateDelegation(bytes32 delegationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) ResendUpdateDelegation(delegationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ResendUpdateDelegation(&_NativeTokenStakingManager.TransactOpts, delegationID) +} + +// NativeTokenStakingManagerDelegationEndedIterator is returned from FilterDelegationEnded and is used to iterate over the raw logs and unpacked data for DelegationEnded events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerDelegationEndedIterator struct { + Event *NativeTokenStakingManagerDelegationEnded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerDelegationEndedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerDelegationEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerDelegationEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerDelegationEndedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerDelegationEndedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerDelegationEnded represents a DelegationEnded event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerDelegationEnded struct { + DelegationID [32]byte + ValidationID [32]byte + Rewards *big.Int + Fees *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegationEnded is a free log retrieval operation binding the contract event 0x8ececf510070c320d9a55323ffabe350e294ae505fc0c509dc5736da6f5cc993. +// +// Solidity: event DelegationEnded(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterDelegationEnded(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*NativeTokenStakingManagerDelegationEndedIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "DelegationEnded", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerDelegationEndedIterator{contract: _NativeTokenStakingManager.contract, event: "DelegationEnded", logs: logs, sub: sub}, nil +} + +// WatchDelegationEnded is a free log subscription operation binding the contract event 0x8ececf510070c320d9a55323ffabe350e294ae505fc0c509dc5736da6f5cc993. +// +// Solidity: event DelegationEnded(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchDelegationEnded(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerDelegationEnded, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "DelegationEnded", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerDelegationEnded) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "DelegationEnded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDelegationEnded is a log parse operation binding the contract event 0x8ececf510070c320d9a55323ffabe350e294ae505fc0c509dc5736da6f5cc993. +// +// Solidity: event DelegationEnded(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseDelegationEnded(log types.Log) (*NativeTokenStakingManagerDelegationEnded, error) { + event := new(NativeTokenStakingManagerDelegationEnded) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "DelegationEnded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerDelegatorAddedIterator is returned from FilterDelegatorAdded and is used to iterate over the raw logs and unpacked data for DelegatorAdded events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerDelegatorAddedIterator struct { + Event *NativeTokenStakingManagerDelegatorAdded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerDelegatorAddedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerDelegatorAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerDelegatorAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerDelegatorAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerDelegatorAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerDelegatorAdded represents a DelegatorAdded event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerDelegatorAdded struct { + DelegationID [32]byte + ValidationID [32]byte + DelegatorAddress common.Address + Nonce uint64 + ValidatorWeight uint64 + DelegatorWeight uint64 + SetWeightMessageID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegatorAdded is a free log retrieval operation binding the contract event 0xb0024b263bc3a0b728a6edea50a69efa841189f8d32ee8af9d1c2b1a1a223426. +// +// Solidity: event DelegatorAdded(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterDelegatorAdded(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte, delegatorAddress []common.Address) (*NativeTokenStakingManagerDelegatorAddedIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var delegatorAddressRule []interface{} + for _, delegatorAddressItem := range delegatorAddress { + delegatorAddressRule = append(delegatorAddressRule, delegatorAddressItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "DelegatorAdded", delegationIDRule, validationIDRule, delegatorAddressRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerDelegatorAddedIterator{contract: _NativeTokenStakingManager.contract, event: "DelegatorAdded", logs: logs, sub: sub}, nil +} + +// WatchDelegatorAdded is a free log subscription operation binding the contract event 0xb0024b263bc3a0b728a6edea50a69efa841189f8d32ee8af9d1c2b1a1a223426. +// +// Solidity: event DelegatorAdded(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchDelegatorAdded(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerDelegatorAdded, delegationID [][32]byte, validationID [][32]byte, delegatorAddress []common.Address) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var delegatorAddressRule []interface{} + for _, delegatorAddressItem := range delegatorAddress { + delegatorAddressRule = append(delegatorAddressRule, delegatorAddressItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "DelegatorAdded", delegationIDRule, validationIDRule, delegatorAddressRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerDelegatorAdded) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "DelegatorAdded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDelegatorAdded is a log parse operation binding the contract event 0xb0024b263bc3a0b728a6edea50a69efa841189f8d32ee8af9d1c2b1a1a223426. +// +// Solidity: event DelegatorAdded(bytes32 indexed delegationID, bytes32 indexed validationID, address indexed delegatorAddress, uint64 nonce, uint64 validatorWeight, uint64 delegatorWeight, bytes32 setWeightMessageID) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseDelegatorAdded(log types.Log) (*NativeTokenStakingManagerDelegatorAdded, error) { + event := new(NativeTokenStakingManagerDelegatorAdded) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "DelegatorAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerDelegatorRegisteredIterator is returned from FilterDelegatorRegistered and is used to iterate over the raw logs and unpacked data for DelegatorRegistered events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerDelegatorRegisteredIterator struct { + Event *NativeTokenStakingManagerDelegatorRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerDelegatorRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerDelegatorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerDelegatorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerDelegatorRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerDelegatorRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerDelegatorRegistered represents a DelegatorRegistered event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerDelegatorRegistered struct { + DelegationID [32]byte + ValidationID [32]byte + Nonce uint64 + StartTime *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegatorRegistered is a free log retrieval operation binding the contract event 0x245fc69b36e168426e0306fc8d8300661b9af297c7958820dbf804f9f63e7064. +// +// Solidity: event DelegatorRegistered(bytes32 indexed delegationID, bytes32 indexed validationID, uint64 indexed nonce, uint256 startTime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterDelegatorRegistered(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte, nonce []uint64) (*NativeTokenStakingManagerDelegatorRegisteredIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "DelegatorRegistered", delegationIDRule, validationIDRule, nonceRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerDelegatorRegisteredIterator{contract: _NativeTokenStakingManager.contract, event: "DelegatorRegistered", logs: logs, sub: sub}, nil +} + +// WatchDelegatorRegistered is a free log subscription operation binding the contract event 0x245fc69b36e168426e0306fc8d8300661b9af297c7958820dbf804f9f63e7064. +// +// Solidity: event DelegatorRegistered(bytes32 indexed delegationID, bytes32 indexed validationID, uint64 indexed nonce, uint256 startTime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchDelegatorRegistered(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerDelegatorRegistered, delegationID [][32]byte, validationID [][32]byte, nonce []uint64) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "DelegatorRegistered", delegationIDRule, validationIDRule, nonceRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerDelegatorRegistered) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "DelegatorRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDelegatorRegistered is a log parse operation binding the contract event 0x245fc69b36e168426e0306fc8d8300661b9af297c7958820dbf804f9f63e7064. +// +// Solidity: event DelegatorRegistered(bytes32 indexed delegationID, bytes32 indexed validationID, uint64 indexed nonce, uint256 startTime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseDelegatorRegistered(log types.Log) (*NativeTokenStakingManagerDelegatorRegistered, error) { + event := new(NativeTokenStakingManagerDelegatorRegistered) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "DelegatorRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerDelegatorRemovalInitializedIterator is returned from FilterDelegatorRemovalInitialized and is used to iterate over the raw logs and unpacked data for DelegatorRemovalInitialized events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerDelegatorRemovalInitializedIterator struct { + Event *NativeTokenStakingManagerDelegatorRemovalInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerDelegatorRemovalInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerDelegatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerDelegatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerDelegatorRemovalInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerDelegatorRemovalInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerDelegatorRemovalInitialized represents a DelegatorRemovalInitialized event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerDelegatorRemovalInitialized struct { + DelegationID [32]byte + ValidationID [32]byte + EndTime *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterDelegatorRemovalInitialized is a free log retrieval operation binding the contract event 0x5cd7ff518ea5cf079cc34b155d074410ae8c095910ebea921240641508658c69. +// +// Solidity: event DelegatorRemovalInitialized(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 endTime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterDelegatorRemovalInitialized(opts *bind.FilterOpts, delegationID [][32]byte, validationID [][32]byte) (*NativeTokenStakingManagerDelegatorRemovalInitializedIterator, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "DelegatorRemovalInitialized", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerDelegatorRemovalInitializedIterator{contract: _NativeTokenStakingManager.contract, event: "DelegatorRemovalInitialized", logs: logs, sub: sub}, nil +} + +// WatchDelegatorRemovalInitialized is a free log subscription operation binding the contract event 0x5cd7ff518ea5cf079cc34b155d074410ae8c095910ebea921240641508658c69. +// +// Solidity: event DelegatorRemovalInitialized(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 endTime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchDelegatorRemovalInitialized(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerDelegatorRemovalInitialized, delegationID [][32]byte, validationID [][32]byte) (event.Subscription, error) { + + var delegationIDRule []interface{} + for _, delegationIDItem := range delegationID { + delegationIDRule = append(delegationIDRule, delegationIDItem) + } + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "DelegatorRemovalInitialized", delegationIDRule, validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerDelegatorRemovalInitialized) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "DelegatorRemovalInitialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseDelegatorRemovalInitialized is a log parse operation binding the contract event 0x5cd7ff518ea5cf079cc34b155d074410ae8c095910ebea921240641508658c69. +// +// Solidity: event DelegatorRemovalInitialized(bytes32 indexed delegationID, bytes32 indexed validationID, uint256 endTime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseDelegatorRemovalInitialized(log types.Log) (*NativeTokenStakingManagerDelegatorRemovalInitialized, error) { + event := new(NativeTokenStakingManagerDelegatorRemovalInitialized) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "DelegatorRemovalInitialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerInitialValidatorCreatedIterator is returned from FilterInitialValidatorCreated and is used to iterate over the raw logs and unpacked data for InitialValidatorCreated events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitialValidatorCreatedIterator struct { + Event *NativeTokenStakingManagerInitialValidatorCreated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerInitialValidatorCreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitialValidatorCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitialValidatorCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerInitialValidatorCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerInitialValidatorCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerInitialValidatorCreated represents a InitialValidatorCreated event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitialValidatorCreated struct { + ValidationID [32]byte + NodeID [32]byte + Weight *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialValidatorCreated is a free log retrieval operation binding the contract event 0xb815f891730222788b3f8d66249b3a287ce680c3df13866fd9a4f37743ae1014. +// +// Solidity: event InitialValidatorCreated(bytes32 indexed validationID, bytes32 indexed nodeID, uint256 weight) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterInitialValidatorCreated(opts *bind.FilterOpts, validationID [][32]byte, nodeID [][32]byte) (*NativeTokenStakingManagerInitialValidatorCreatedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "InitialValidatorCreated", validationIDRule, nodeIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerInitialValidatorCreatedIterator{contract: _NativeTokenStakingManager.contract, event: "InitialValidatorCreated", logs: logs, sub: sub}, nil +} + +// WatchInitialValidatorCreated is a free log subscription operation binding the contract event 0xb815f891730222788b3f8d66249b3a287ce680c3df13866fd9a4f37743ae1014. +// +// Solidity: event InitialValidatorCreated(bytes32 indexed validationID, bytes32 indexed nodeID, uint256 weight) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchInitialValidatorCreated(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerInitialValidatorCreated, validationID [][32]byte, nodeID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "InitialValidatorCreated", validationIDRule, nodeIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerInitialValidatorCreated) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "InitialValidatorCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialValidatorCreated is a log parse operation binding the contract event 0xb815f891730222788b3f8d66249b3a287ce680c3df13866fd9a4f37743ae1014. +// +// Solidity: event InitialValidatorCreated(bytes32 indexed validationID, bytes32 indexed nodeID, uint256 weight) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseInitialValidatorCreated(log types.Log) (*NativeTokenStakingManagerInitialValidatorCreated, error) { + event := new(NativeTokenStakingManagerInitialValidatorCreated) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "InitialValidatorCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitializedIterator struct { + Event *NativeTokenStakingManagerInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerInitialized represents a Initialized event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*NativeTokenStakingManagerInitializedIterator, error) { + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerInitializedIterator{contract: _NativeTokenStakingManager.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerInitialized) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseInitialized(log types.Log) (*NativeTokenStakingManagerInitialized, error) { + event := new(NativeTokenStakingManagerInitialized) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerValidationPeriodCreatedIterator is returned from FilterValidationPeriodCreated and is used to iterate over the raw logs and unpacked data for ValidationPeriodCreated events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidationPeriodCreatedIterator struct { + Event *NativeTokenStakingManagerValidationPeriodCreated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerValidationPeriodCreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidationPeriodCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidationPeriodCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerValidationPeriodCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerValidationPeriodCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerValidationPeriodCreated represents a ValidationPeriodCreated event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidationPeriodCreated struct { + ValidationID [32]byte + NodeID [32]byte + RegisterValidationMessageID [32]byte + Weight *big.Int + RegistrationExpiry uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodCreated is a free log retrieval operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterValidationPeriodCreated(opts *bind.FilterOpts, validationID [][32]byte, nodeID [][32]byte, registerValidationMessageID [][32]byte) (*NativeTokenStakingManagerValidationPeriodCreatedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var registerValidationMessageIDRule []interface{} + for _, registerValidationMessageIDItem := range registerValidationMessageID { + registerValidationMessageIDRule = append(registerValidationMessageIDRule, registerValidationMessageIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "ValidationPeriodCreated", validationIDRule, nodeIDRule, registerValidationMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerValidationPeriodCreatedIterator{contract: _NativeTokenStakingManager.contract, event: "ValidationPeriodCreated", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodCreated is a free log subscription operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchValidationPeriodCreated(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerValidationPeriodCreated, validationID [][32]byte, nodeID [][32]byte, registerValidationMessageID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var registerValidationMessageIDRule []interface{} + for _, registerValidationMessageIDItem := range registerValidationMessageID { + registerValidationMessageIDRule = append(registerValidationMessageIDRule, registerValidationMessageIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "ValidationPeriodCreated", validationIDRule, nodeIDRule, registerValidationMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerValidationPeriodCreated) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidationPeriodCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodCreated is a log parse operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseValidationPeriodCreated(log types.Log) (*NativeTokenStakingManagerValidationPeriodCreated, error) { + event := new(NativeTokenStakingManagerValidationPeriodCreated) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidationPeriodCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerValidationPeriodEndedIterator is returned from FilterValidationPeriodEnded and is used to iterate over the raw logs and unpacked data for ValidationPeriodEnded events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidationPeriodEndedIterator struct { + Event *NativeTokenStakingManagerValidationPeriodEnded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerValidationPeriodEndedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidationPeriodEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidationPeriodEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerValidationPeriodEndedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerValidationPeriodEndedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerValidationPeriodEnded represents a ValidationPeriodEnded event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidationPeriodEnded struct { + ValidationID [32]byte + Status uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodEnded is a free log retrieval operation binding the contract event 0x1c08e59656f1a18dc2da76826cdc52805c43e897a17c50faefb8ab3c1526cc16. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID, uint8 indexed status) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterValidationPeriodEnded(opts *bind.FilterOpts, validationID [][32]byte, status []uint8) (*NativeTokenStakingManagerValidationPeriodEndedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var statusRule []interface{} + for _, statusItem := range status { + statusRule = append(statusRule, statusItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "ValidationPeriodEnded", validationIDRule, statusRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerValidationPeriodEndedIterator{contract: _NativeTokenStakingManager.contract, event: "ValidationPeriodEnded", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodEnded is a free log subscription operation binding the contract event 0x1c08e59656f1a18dc2da76826cdc52805c43e897a17c50faefb8ab3c1526cc16. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID, uint8 indexed status) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchValidationPeriodEnded(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerValidationPeriodEnded, validationID [][32]byte, status []uint8) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var statusRule []interface{} + for _, statusItem := range status { + statusRule = append(statusRule, statusItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "ValidationPeriodEnded", validationIDRule, statusRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerValidationPeriodEnded) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidationPeriodEnded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodEnded is a log parse operation binding the contract event 0x1c08e59656f1a18dc2da76826cdc52805c43e897a17c50faefb8ab3c1526cc16. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID, uint8 indexed status) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseValidationPeriodEnded(log types.Log) (*NativeTokenStakingManagerValidationPeriodEnded, error) { + event := new(NativeTokenStakingManagerValidationPeriodEnded) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidationPeriodEnded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerValidationPeriodRegisteredIterator is returned from FilterValidationPeriodRegistered and is used to iterate over the raw logs and unpacked data for ValidationPeriodRegistered events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidationPeriodRegisteredIterator struct { + Event *NativeTokenStakingManagerValidationPeriodRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerValidationPeriodRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidationPeriodRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidationPeriodRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerValidationPeriodRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerValidationPeriodRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerValidationPeriodRegistered represents a ValidationPeriodRegistered event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidationPeriodRegistered struct { + ValidationID [32]byte + Weight *big.Int + Timestamp *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodRegistered is a free log retrieval operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 weight, uint256 timestamp) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterValidationPeriodRegistered(opts *bind.FilterOpts, validationID [][32]byte) (*NativeTokenStakingManagerValidationPeriodRegisteredIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "ValidationPeriodRegistered", validationIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerValidationPeriodRegisteredIterator{contract: _NativeTokenStakingManager.contract, event: "ValidationPeriodRegistered", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodRegistered is a free log subscription operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 weight, uint256 timestamp) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchValidationPeriodRegistered(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerValidationPeriodRegistered, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "ValidationPeriodRegistered", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerValidationPeriodRegistered) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidationPeriodRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodRegistered is a log parse operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 weight, uint256 timestamp) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseValidationPeriodRegistered(log types.Log) (*NativeTokenStakingManagerValidationPeriodRegistered, error) { + event := new(NativeTokenStakingManagerValidationPeriodRegistered) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidationPeriodRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerValidatorRemovalInitializedIterator is returned from FilterValidatorRemovalInitialized and is used to iterate over the raw logs and unpacked data for ValidatorRemovalInitialized events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidatorRemovalInitializedIterator struct { + Event *NativeTokenStakingManagerValidatorRemovalInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerValidatorRemovalInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerValidatorRemovalInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerValidatorRemovalInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerValidatorRemovalInitialized represents a ValidatorRemovalInitialized event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidatorRemovalInitialized struct { + ValidationID [32]byte + SetWeightMessageID [32]byte + Weight *big.Int + EndTime *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorRemovalInitialized is a free log retrieval operation binding the contract event 0x13d58394cf269d48bcf927959a29a5ffee7c9924dafff8927ecdf3c48ffa7c67. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 weight, uint256 endTime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterValidatorRemovalInitialized(opts *bind.FilterOpts, validationID [][32]byte, setWeightMessageID [][32]byte) (*NativeTokenStakingManagerValidatorRemovalInitializedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var setWeightMessageIDRule []interface{} + for _, setWeightMessageIDItem := range setWeightMessageID { + setWeightMessageIDRule = append(setWeightMessageIDRule, setWeightMessageIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "ValidatorRemovalInitialized", validationIDRule, setWeightMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerValidatorRemovalInitializedIterator{contract: _NativeTokenStakingManager.contract, event: "ValidatorRemovalInitialized", logs: logs, sub: sub}, nil +} + +// WatchValidatorRemovalInitialized is a free log subscription operation binding the contract event 0x13d58394cf269d48bcf927959a29a5ffee7c9924dafff8927ecdf3c48ffa7c67. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 weight, uint256 endTime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchValidatorRemovalInitialized(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerValidatorRemovalInitialized, validationID [][32]byte, setWeightMessageID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var setWeightMessageIDRule []interface{} + for _, setWeightMessageIDItem := range setWeightMessageID { + setWeightMessageIDRule = append(setWeightMessageIDRule, setWeightMessageIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "ValidatorRemovalInitialized", validationIDRule, setWeightMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerValidatorRemovalInitialized) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidatorRemovalInitialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorRemovalInitialized is a log parse operation binding the contract event 0x13d58394cf269d48bcf927959a29a5ffee7c9924dafff8927ecdf3c48ffa7c67. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 weight, uint256 endTime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseValidatorRemovalInitialized(log types.Log) (*NativeTokenStakingManagerValidatorRemovalInitialized, error) { + event := new(NativeTokenStakingManagerValidatorRemovalInitialized) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidatorRemovalInitialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerValidatorWeightUpdateIterator is returned from FilterValidatorWeightUpdate and is used to iterate over the raw logs and unpacked data for ValidatorWeightUpdate events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidatorWeightUpdateIterator struct { + Event *NativeTokenStakingManagerValidatorWeightUpdate // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerValidatorWeightUpdateIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerValidatorWeightUpdateIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerValidatorWeightUpdateIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerValidatorWeightUpdate represents a ValidatorWeightUpdate event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidatorWeightUpdate struct { + ValidationID [32]byte + Nonce uint64 + ValidatorWeight uint64 + SetWeightMessageID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorWeightUpdate is a free log retrieval operation binding the contract event 0x07de5ff35a674a8005e661f3333c907ca6333462808762d19dc7b3abb1a8c1df. +// +// Solidity: event ValidatorWeightUpdate(bytes32 indexed validationID, uint64 indexed nonce, uint64 validatorWeight, bytes32 setWeightMessageID) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterValidatorWeightUpdate(opts *bind.FilterOpts, validationID [][32]byte, nonce []uint64) (*NativeTokenStakingManagerValidatorWeightUpdateIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "ValidatorWeightUpdate", validationIDRule, nonceRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerValidatorWeightUpdateIterator{contract: _NativeTokenStakingManager.contract, event: "ValidatorWeightUpdate", logs: logs, sub: sub}, nil +} + +// WatchValidatorWeightUpdate is a free log subscription operation binding the contract event 0x07de5ff35a674a8005e661f3333c907ca6333462808762d19dc7b3abb1a8c1df. +// +// Solidity: event ValidatorWeightUpdate(bytes32 indexed validationID, uint64 indexed nonce, uint64 validatorWeight, bytes32 setWeightMessageID) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchValidatorWeightUpdate(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerValidatorWeightUpdate, validationID [][32]byte, nonce []uint64) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "ValidatorWeightUpdate", validationIDRule, nonceRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerValidatorWeightUpdate) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidatorWeightUpdate", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorWeightUpdate is a log parse operation binding the contract event 0x07de5ff35a674a8005e661f3333c907ca6333462808762d19dc7b3abb1a8c1df. +// +// Solidity: event ValidatorWeightUpdate(bytes32 indexed validationID, uint64 indexed nonce, uint64 validatorWeight, bytes32 setWeightMessageID) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseValidatorWeightUpdate(log types.Log) (*NativeTokenStakingManagerValidatorWeightUpdate, error) { + event := new(NativeTokenStakingManagerValidatorWeightUpdate) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidatorWeightUpdate", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/validator-manager/PoAValidatorManager/PoAValidatorManager.go b/abi-bindings/go/validator-manager/PoAValidatorManager/PoAValidatorManager.go new file mode 100644 index 000000000..a59f4e021 --- /dev/null +++ b/abi-bindings/go/validator-manager/PoAValidatorManager/PoAValidatorManager.go @@ -0,0 +1,1977 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package poavalidatormanager + +import ( + "errors" + "math/big" + "strings" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = interfaces.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// InitialValidator is an auto generated low-level Go binding around an user-defined struct. +type InitialValidator struct { + NodeID [32]byte + Weight uint64 + BlsPublicKey []byte +} + +// SubnetConversionData is an auto generated low-level Go binding around an user-defined struct. +type SubnetConversionData struct { + ConvertSubnetTxID [32]byte + ValidatorManagerBlockchainID [32]byte + ValidatorManagerAddress common.Address + InitialValidators []InitialValidator +} + +// Validator is an auto generated low-level Go binding around an user-defined struct. +type Validator struct { + Status uint8 + NodeID [32]byte + StartingWeight uint64 + MessageNonce uint64 + Weight uint64 + StartedAt uint64 + EndedAt uint64 +} + +// ValidatorManagerSettings is an auto generated low-level Go binding around an user-defined struct. +type ValidatorManagerSettings struct { + SubnetID [32]byte + ChurnPeriodSeconds uint64 + MaximumChurnPercentage uint8 +} + +// ValidatorRegistrationInput is an auto generated low-level Go binding around an user-defined struct. +type ValidatorRegistrationInput struct { + NodeID [32]byte + RegistrationExpiry uint64 + BlsPublicKey []byte +} + +// PoAValidatorManagerMetaData contains all meta data concerning the PoAValidatorManager contract. +var PoAValidatorManagerMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"init\",\"type\":\"uint8\",\"internalType\":\"enumICMInitializable\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"ADDRESS_LENGTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"BLS_PUBLIC_KEY_LENGTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAXIMUM_CHURN_PERCENTAGE_LIMIT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"MAXIMUM_REGISTRATION_EXPIRY_LENGTH\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"P_CHAIN_BLOCKCHAIN_ID\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"WARP_MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIWarpMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"completeEndValidation\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"completeValidatorRegistration\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getValidator\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structValidator\",\"components\":[{\"name\":\"status\",\"type\":\"uint8\",\"internalType\":\"enumValidatorStatus\"},{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"startingWeight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"messageNonce\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"weight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"startedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"endedAt\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getWeight\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"settings\",\"type\":\"tuple\",\"internalType\":\"structValidatorManagerSettings\",\"components\":[{\"name\":\"subnetID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"churnPeriodSeconds\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"maximumChurnPercentage\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"initialOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeEndValidation\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeValidatorRegistration\",\"inputs\":[{\"name\":\"registrationInput\",\"type\":\"tuple\",\"internalType\":\"structValidatorRegistrationInput\",\"components\":[{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registrationExpiry\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]},{\"name\":\"weight\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeValidatorSet\",\"inputs\":[{\"name\":\"subnetConversionData\",\"type\":\"tuple\",\"internalType\":\"structSubnetConversionData\",\"components\":[{\"name\":\"convertSubnetTxID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"validatorManagerBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"validatorManagerAddress\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"initialValidators\",\"type\":\"tuple[]\",\"internalType\":\"structInitialValidator[]\",\"components\":[{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"registeredValidators\",\"inputs\":[{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resendEndValidatorMessage\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resendRegisterValidatorMessage\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"InitialValidatorCreated\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nodeID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodCreated\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nodeID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"registerValidationMessageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"registrationExpiry\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodEnded\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"status\",\"type\":\"uint8\",\"indexed\":true,\"internalType\":\"enumValidatorStatus\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodRegistered\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorRemovalInitialized\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"setWeightMessageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"endTime\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorWeightUpdate\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nonce\",\"type\":\"uint64\",\"indexed\":true,\"internalType\":\"uint64\"},{\"name\":\"validatorWeight\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"},{\"name\":\"setWeightMessageID\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"InvalidAddress\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidBlockchainID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidCodecID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidExpiry\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitializationStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInput\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidMessageLength\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidMessageType\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidSubnetConversionID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidValidationID\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidValidatorStatus\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidWarpMessage\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"MaxChurnRateExceeded\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NodeAlreadyRegistered\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"OwnableInvalidOwner\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"OwnableUnauthorizedAccount\",\"inputs\":[{\"name\":\"account\",\"type\":\"address\",\"internalType\":\"address\"}]},{\"type\":\"error\",\"name\":\"UnexpectedRegistrationStatus\",\"inputs\":[]}]", + Bin: "0x608060405234801561000f575f80fd5b5060405161318538038061318583398101604081905261002e91610107565b60018160018111156100425761004261012c565b0361004f5761004f610055565b50610140565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100a55760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101045780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60208284031215610117575f80fd5b815160028110610125575f80fd5b9392505050565b634e487b7160e01b5f52602160045260245ffd5b6130388061014d5f395ff3fe608060405234801561000f575f80fd5b5060043610610127575f3560e01c806397fb70d4116100a9578063d588c18f1161006e578063d588c18f14610290578063d5f20ff6146102a3578063df93d8de146102c3578063e7d14c1c146102cd578063f2fde38b1461030b575f80fd5b806397fb70d414610241578063a3a65e4814610254578063b771b3bc14610267578063bee0a03f14610275578063c974d1b614610288575f80fd5b8063715018a6116100ef578063715018a6146101b3578063732214f8146101bb5780638280a25a146101d05780638994ab49146101ea5780638da5cb5b146101fd575f80fd5b80630322ed981461012b578063467ef06f1461014057806360305d621461015357806361e2f4901461017557806366435abf14610188575b5f80fd5b61013e61013936600461270c565b61031e565b005b61013e61014e36600461273b565b610490565b61015b601481565b60405163ffffffff90911681526020015b60405180910390f35b61013e610183366004612754565b61049e565b61019b61019636600461270c565b610922565b6040516001600160401b03909116815260200161016c565b61013e610936565b6101c25f81565b60405190815260200161016c565b6101d8603081565b60405160ff909116815260200161016c565b6101c26101f83660046127ce565b610949565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03165b6040516001600160a01b03909116815260200161016c565b61013e61024f36600461270c565b610965565b61013e61026236600461273b565b61097a565b6102296005600160991b0181565b61013e61028336600461270c565b610aec565b6101d8601481565b61013e61029e366004612823565b610c11565b6102b66102b136600461270c565b610d1f565b60405161016c919061286d565b61019b6202a30081565b6101c26102db36600461270c565b5f9081527fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb08602052604090205490565b61013e61031936600461291c565b610de7565b5f8181525f8051602061300c8339815191526020526040808220815160e0810190925280545f80516020612fec83398151915293929190829060ff16600581111561036b5761036b612859565b600581111561037c5761037c612859565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a08301526003928301541660c090910152909150815160058111156103eb576103eb612859565b146104095760405163a36c527f60e01b815260040160405180910390fd5b6005600160991b016001600160a01b031663ee5b48eb61042e8584606001515f610e29565b6040518263ffffffff1660e01b815260040161044a9190612960565b6020604051808303815f875af1158015610466573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061048a9190612992565b50505050565b61049981610e78565b505050565b7fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb09545f80516020612fec8339815191529060ff16156104f057604051637fab81e560e01b815260040160405180910390fd5b6005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610533573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105579190612992565b83602001351461057a5760405163d040949d60e01b815260040160405180910390fd5b3061058b606085016040860161291c565b6001600160a01b0316146105b25760405163e6c4247b60e01b815260040160405180910390fd5b5f6105c060608501856129a9565b905090505f805b828163ffffffff16101561086c575f6105e360608801886129a9565b8363ffffffff168181106105f9576105f96129ee565b905060200281019061060b9190612a02565b61061490612ab2565b80515f818152600888016020526040902054919250901561064857604051630eb0d31360e11b815260040160405180910390fd5b5f6002895f01358560405160200161067792919091825260e01b6001600160e01b031916602082015260240190565b60408051601f198184030181529082905261069191612b49565b602060405180830381855afa1580156106ac573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906106cf9190612992565b5f8381526008890160209081526040808320849055805160e0810182526002815287518184015287830180516001600160401b039081168385015260608301869052905181166080830152421660a082015260c0810184905284845260078c01909252909120815181549394509192909190829060ff1916600183600581111561075b5761075b612859565b0217905550602082810151600183015560408301516002830180546060860151608087015160a08801516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c0909301516003909201805467ffffffffffffffff19169284169290921790915584015161080e911686612b6e565b83516020808601516040516001600160401b039091168152929750909183917fb815f891730222788b3f8d66249b3a287ce680c3df13866fd9a4f37743ae1014910160405180910390a35050508061086590612b81565b90506105c7565b50600483018190555f61087e85611116565b90505f61088e8260400151611216565b90505f61089a8861138b565b9050816002826040516108ad9190612b49565b602060405180830381855afa1580156108c8573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906108eb9190612992565b1461090957604051631e0e8fbd60e21b815260040160405180910390fd5b5050506009909201805460ff1916600117905550505050565b5f61092c82610d1f565b6080015192915050565b61093e611824565b6109475f61187f565b565b5f610952611824565b61095c83836118ef565b90505b92915050565b61096d611824565b61097681611cd9565b5050565b5f80516020612fec8339815191525f61099283611116565b90505f806109a38360400151611f16565b91509150806109c557604051633dbcaef760e01b815260040160405180910390fd5b5f828152600685016020526040902080546109df90612ba3565b90505f03610a0057604051636990657d60e01b815260040160405180910390fd5b60015f83815260078601602052604090205460ff166005811115610a2657610a26612859565b14610a445760405163a36c527f60e01b815260040160405180910390fd5b5f8281526006850160205260408120610a5c91612681565b5f828152600785016020908152604091829020805460ff1916600290811782550180546001600160401b0342818116600160c01b026001600160c01b0390931692909217928390558451600160801b9093041682529181019190915283917ff8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568910160405180910390a25050505050565b5f8181527fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb066020526040902080545f80516020612fec8339815191529190610b3390612ba3565b90505f03610b5457604051636990657d60e01b815260040160405180910390fd5b60015f83815260078301602052604090205460ff166005811115610b7a57610b7a612859565b14610b985760405163a36c527f60e01b815260040160405180910390fd5b5f82815260068201602052604090819020905163ee5b48eb60e01b81526005600160991b019163ee5b48eb91610bd19190600401612bd5565b6020604051808303815f875af1158015610bed573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104999190612992565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f81158015610c555750825b90505f826001600160401b03166001148015610c705750303b155b905081158015610c7e575080155b15610c9c5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610cc657845460ff60401b1916600160401b1785555b610cd087876120ba565b8315610d1657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b610d276126b8565b5f8281525f8051602061300c833981519152602052604090819020815160e0810190925280545f80516020612fec833981519152929190829060ff166005811115610d7457610d74612859565b6005811115610d8557610d85612859565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a083015260039092015490911660c0909101529392505050565b610def611824565b6001600160a01b038116610e1d57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b610e268161187f565b50565b604080515f6020820152600160e11b602282015260268101949094526001600160c01b031960c093841b811660468601529190921b16604e830152805180830360360181526056909201905290565b5f610e816126b8565b5f80516020612fec8339815191525f610e9985611116565b90505f80610eaa8360400151611f16565b915091508015610ecd57604051633dbcaef760e01b815260040160405180910390fd5b5f828152600785016020526040808220815160e081019092528054829060ff166005811115610efe57610efe612859565b6005811115610f0f57610f0f612859565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a08301526003928301541660c09091015290915081516005811115610f7e57610f7e612859565b14158015610f9f5750600181516005811115610f9c57610f9c612859565b14155b15610fbd5760405163a36c527f60e01b815260040160405180910390fd5b600381516005811115610fd257610fd2612859565b03610fe05760048152610fe5565b600581525b6020808201515f908152600887018252604080822082905585825260078801909252208151815483929190829060ff1916600183600581111561102a5761102a612859565b02179055506020820151600182015560408201516002820180546060850151608086015160a08701516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c0909201516003909101805467ffffffffffffffff191691909216179055805160058111156110de576110de612859565b60405184907f1c08e59656f1a18dc2da76826cdc52805c43e897a17c50faefb8ab3c1526cc16905f90a3919791965090945050505050565b60408051606080820183525f8083526020830152918101919091526040516306f8253560e41b815263ffffffff831660048201525f9081906005600160991b0190636f825350906024015f60405180830381865afa15801561117a573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526111a19190810190612c6e565b91509150806111c357604051636b2f19e960e01b815260040160405180910390fd5b8151156111e35760405163d040949d60e01b815260040160405180910390fd5b60208201516001600160a01b03161561120f5760405163e6c4247b60e01b815260040160405180910390fd5b5092915050565b5f815160261461123957604051638d0242c960e01b815260040160405180910390fd5b5f805b600281101561128857611250816001612d40565b61125b906008612d53565b61ffff16848281518110611271576112716129ee565b016020015160f81c901b919091179060010161123c565b5061ffff8116156112ac5760405163059510e360e31b815260040160405180910390fd5b5f805b6004811015611307576112c3816003612d40565b6112ce906008612d53565b63ffffffff16856112e0836002612b6e565b815181106112f0576112f06129ee565b016020015160f81c901b91909117906001016112af565b5063ffffffff81161561132d57604051635b60892f60e01b815260040160405180910390fd5b5f805b60208110156113825761134481601f612d40565b61134f906008612d53565b8661135b836006612b6e565b8151811061136b5761136b6129ee565b016020015160f81c901b9190911790600101611330565b50949350505050565b60605f61139a838301846129a9565b6113a691506058612d53565b6113b190605c612b6e565b6001600160401b038111156113c8576113c8612a20565b6040519080825280601f01601f1916602001820160405280156113f2576020820181803683370190505b5090505f5b60208110156114475783358160208110611413576114136129ee565b1a60f81b828281518110611429576114296129ee565b60200101906001600160f81b03191690815f1a9053506001016113f7565b505f5b60208110156114a75783602001358160208110611469576114696129ee565b1a60f81b82611479836020612b6e565b81518110611489576114896129ee565b60200101906001600160f81b03191690815f1a90535060010161144a565b505f5b600481101561150a576114be816003612d40565b6114c9906008612d53565b6014901c60f81b826114dc836040612b6e565b815181106114ec576114ec6129ee565b60200101906001600160f81b03191690815f1a9053506001016114aa565b505f61151c606085016040860161291c565b60601b90505f5b601481101561157c5781816014811061153e5761153e6129ee565b1a60f81b8361154e836044612b6e565b8151811061155e5761155e6129ee565b60200101906001600160f81b03191690815f1a905350600101611523565b505f61158b60608601866129a9565b905090505f5b60048110156115f6576115a5816003612d40565b6115b0906008612d53565b63ffffffff8316901c60f81b846115c8836058612b6e565b815181106115d8576115d86129ee565b60200101906001600160f81b03191690815f1a905350600101611591565b505f5b61160660608701876129a9565b905081101561181a575f61161b826058612d53565b61162690605c612b6e565b90505f5b60208110156116b15761164060608901896129a9565b84818110611650576116506129ee565b90506020028101906116629190612a02565b358160208110611674576116746129ee565b1a60f81b866116838385612b6e565b81518110611693576116936129ee565b60200101906001600160f81b03191690815f1a90535060010161162a565b505f5b6008811015611766576116c8816007612d40565b6116d3906008612d53565b6116e060608a018a6129a9565b858181106116f0576116f06129ee565b90506020028101906117029190612a02565b611713906040810190602001612d6a565b6001600160401b0316901c60f81b868261172e856020612b6e565b6117389190612b6e565b81518110611748576117486129ee565b60200101906001600160f81b03191690815f1a9053506001016116b4565b505f5b60308110156118105761177f60608901896129a9565b8481811061178f5761178f6129ee565b90506020028101906117a19190612a02565b6117af906040810190612d83565b828181106117bf576117bf6129ee565b9050013560f81c60f81b86828460286117d89190612b6e565b6117e29190612b6e565b815181106117f2576117f26129ee565b60200101906001600160f81b03191690815f1a905350600101611769565b50506001016115f9565b5091949350505050565b336118567f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146109475760405163118cdaa760e01b8152336004820152602401610e14565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b7fe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb09545f9060ff1661193357604051637fab81e560e01b815260040160405180910390fd5b5f80516020612fec833981519152426119526040860160208701612d6a565b6001600160401b031611158061198c57506119706202a30042612b6e565b6119806040860160208701612d6a565b6001600160401b031610155b156119a95760405162d36c8560e81b815260040160405180910390fd5b60306119b86040860186612d83565b90501415806119c657508335155b156119e45760405163b4fa3fb360e01b815260040160405180910390fd5b83355f90815260088201602052604090205415611a1457604051630eb0d31360e11b815260040160405180910390fd5b611a1e835f6120d4565b5f80611ab76040518060a00160405280855f01548152602001885f01358152602001876001600160401b03168152602001886020016020810190611a629190612d6a565b6001600160401b03168152602001611a7d60408a018a612d83565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250505091525061229d565b5f82815260068601602052604090209193509150611ad58282612e10565b5085355f9081526008840160205260408082208490555163ee5b48eb60e01b81526005600160991b019063ee5b48eb90611b13908590600401612960565b6020604051808303815f875af1158015611b2f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b539190612992565b6040805160e08101909152909150806001815288356020808301919091526001600160401b03891660408084018290525f60608501819052608085019290925260a0840182905260c0909301819052868152600788019091522081518154829060ff19166001836005811115611bcb57611bcb612859565b021790555060208281015160018301556040808401516002840180546060870151608088015160a08901516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c0909401516003909301805467ffffffffffffffff19169390941692909217909255829189359186917f79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e918b91611cab918e01908e01612d6a565b604080516001600160401b0393841681529290911660208301520160405180910390a4509095945050505050565b611ce16126b8565b5f8281525f8051602061300c8339815191526020526040808220815160e0810190925280545f80516020612fec83398151915293929190829060ff166005811115611d2e57611d2e612859565b6005811115611d3f57611d3f612859565b8152600182015460208201526002808301546001600160401b038082166040850152600160401b820481166060850152600160801b820481166080850152600160c01b909104811660a084015260039093015490921660c09091015290915081516005811115611db157611db1612859565b14611dcf5760405163a36c527f60e01b815260040160405180910390fd5b60038152426001600160401b031660c08201525f84815260078301602052604090208151815483929190829060ff19166001836005811115611e1357611e13612859565b02179055506020820151600182015560408201516002820180546060850151608086015160a08701516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c0909201516003909101805467ffffffffffffffff1916919092161790555f611ebf8582612360565b6080840151604080516001600160401b03909216825242602083015291935083925087917f13d58394cf269d48bcf927959a29a5ffee7c9924dafff8927ecdf3c48ffa7c67910160405180910390a3509392505050565b5f808251602714611f3a57604051638d0242c960e01b815260040160405180910390fd5b5f805b6002811015611f8957611f51816001612d40565b611f5c906008612d53565b61ffff16858281518110611f7257611f726129ee565b016020015160f81c901b9190911790600101611f3d565b5061ffff811615611fad5760405163059510e360e31b815260040160405180910390fd5b5f805b600481101561200857611fc4816003612d40565b611fcf906008612d53565b63ffffffff1686611fe1836002612b6e565b81518110611ff157611ff16129ee565b016020015160f81c901b9190911790600101611fb0565b5063ffffffff811660031461203057604051635b60892f60e01b815260040160405180910390fd5b5f805b60208110156120855761204781601f612d40565b612052906008612d53565b8761205e836006612b6e565b8151811061206e5761206e6129ee565b016020015160f81c901b9190911790600101612033565b505f8660268151811061209a5761209a6129ee565b016020015191976001600160f81b03199092161515965090945050505050565b6120c26124b7565b6120cb82612500565b61097681612519565b5f80516020612fec8339815191525f6001600160401b038084169085161115612108576121018385612ecf565b9050612115565b6121128484612ecf565b90505b6040805160808101825260028401548082526003850154602083015260048501549282019290925260058401546001600160401b0316606082015242911580612177575060018401548151612173916001600160401b031690612b6e565b8210155b1561219d576001600160401b0383166060820152818152604081015160208201526121bc565b82816060018181516121af9190612eef565b6001600160401b03169052505b60608101516121cc906064612f0f565b602082015160018601546001600160401b0392909216916121f79190600160401b900460ff16612d53565b10156122165760405163254d226960e01b815260040160405180910390fd5b856001600160401b0316816040018181516122319190612b6e565b9052506040810180516001600160401b0387169190612251908390612d40565b905250805160028501556020810151600385015560408101516004850155606001516005909301805467ffffffffffffffff19166001600160401b039094169390931790925550505050565b5f60608260800151516030146122c657604051638d0242c960e01b815260040160405180910390fd5b5f806001855f015186602001518760400151886080015189606001516040516020016122f89796959493929190612f3a565b60405160208183030381529060405290506002816040516123199190612b49565b602060405180830381855afa158015612334573d5f803e3d5ffd5b5050506040513d601f19601f820116820180604052508101906123579190612992565b94909350915050565b5f8281525f8051602061300c833981519152602052604081206002015481905f80516020612fec83398151915290600160801b90046001600160401b03166123a885826120d4565b5f6123b28761252a565b5f8881526007850160205260408120600201805467ffffffffffffffff60801b1916600160801b6001600160401b038b16021790559091506005600160991b0163ee5b48eb6124028a858b610e29565b6040518263ffffffff1660e01b815260040161241e9190612960565b6020604051808303815f875af115801561243a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061245e9190612992565b604080516001600160401b038a811682526020820184905282519394508516928b927f07de5ff35a674a8005e661f3333c907ca6333462808762d19dc7b3abb1a8c1df928290030190a3909450925050505b9250929050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661094757604051631afcd79f60e31b815260040160405180910390fd5b6125086124b7565b61251061259f565b610e26816125a7565b6125216124b7565b610e2681612679565b5f8181525f8051602061300c8339815191526020526040812060020180545f80516020612fec833981519152919060089061257490600160401b90046001600160401b0316612fb0565b91906101000a8154816001600160401b0302191690836001600160401b031602179055915050919050565b6109476124b7565b6125af6124b7565b80355f80516020612fec83398151915290815560146125d46060840160408501612fcb565b60ff1611806125f357506125ee6060830160408401612fcb565b60ff16155b156126115760405163b4fa3fb360e01b815260040160405180910390fd5b6126216060830160408401612fcb565b60018201805460ff92909216600160401b0260ff60401b199092169190911790556126526040830160208401612d6a565b600191909101805467ffffffffffffffff19166001600160401b0390921691909117905550565b610def6124b7565b50805461268d90612ba3565b5f825580601f1061269c575050565b601f0160209004905f5260205f2090810190610e2691906126f4565b6040805160e08101909152805f81525f6020820181905260408201819052606082018190526080820181905260a0820181905260c09091015290565b5b80821115612708575f81556001016126f5565b5090565b5f6020828403121561271c575f80fd5b5035919050565b803563ffffffff81168114612736575f80fd5b919050565b5f6020828403121561274b575f80fd5b61095c82612723565b5f8060408385031215612765575f80fd5b82356001600160401b0381111561277a575f80fd5b83016080818603121561278b575f80fd5b915061279960208401612723565b90509250929050565b5f606082840312156127b2575f80fd5b50919050565b80356001600160401b0381168114612736575f80fd5b5f80604083850312156127df575f80fd5b82356001600160401b038111156127f4575f80fd5b612800858286016127a2565b925050612799602084016127b8565b6001600160a01b0381168114610e26575f80fd5b5f8060808385031215612834575f80fd5b61283e84846127a2565b9150606083013561284e8161280f565b809150509250929050565b634e487b7160e01b5f52602160045260245ffd5b815160e08201906006811061289057634e487b7160e01b5f52602160045260245ffd5b80835250602083015160208301526001600160401b03604084015116604083015260608301516128cb60608401826001600160401b03169052565b5060808301516128e660808401826001600160401b03169052565b5060a083015161290160a08401826001600160401b03169052565b5060c083015161120f60c08401826001600160401b03169052565b5f6020828403121561292c575f80fd5b81356129378161280f565b9392505050565b5f5b83811015612958578181015183820152602001612940565b50505f910152565b602081525f825180602084015261297e81604085016020870161293e565b601f01601f19169190910160400192915050565b5f602082840312156129a2575f80fd5b5051919050565b5f808335601e198436030181126129be575f80fd5b8301803591506001600160401b038211156129d7575f80fd5b6020019150600581901b36038213156124b0575f80fd5b634e487b7160e01b5f52603260045260245ffd5b5f8235605e19833603018112612a16575f80fd5b9190910192915050565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b0381118282101715612a5657612a56612a20565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612a8457612a84612a20565b604052919050565b5f6001600160401b03821115612aa457612aa4612a20565b50601f01601f191660200190565b5f60608236031215612ac2575f80fd5b612aca612a34565b823581526020612adb8185016127b8565b8183015260408401356001600160401b03811115612af7575f80fd5b840136601f820112612b07575f80fd5b8035612b1a612b1582612a8c565b612a5c565b8181523684838501011115612b2d575f80fd5b81848401858301375f9181019093015250604082015292915050565b5f8251612a1681846020870161293e565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561095f5761095f612b5a565b5f63ffffffff808316818103612b9957612b99612b5a565b6001019392505050565b600181811c90821680612bb757607f821691505b6020821081036127b257634e487b7160e01b5f52602260045260245ffd5b5f60208083525f8454612be781612ba3565b806020870152604060018084165f8114612c085760018114612c2457612c51565b60ff19851660408a0152604084151560051b8a01019550612c51565b895f5260205f205f5b85811015612c485781548b8201860152908301908801612c2d565b8a016040019650505b509398975050505050505050565b80518015158114612736575f80fd5b5f8060408385031215612c7f575f80fd5b82516001600160401b0380821115612c95575f80fd5b9084019060608287031215612ca8575f80fd5b612cb0612a34565b82518152602080840151612cc38161280f565b82820152604084015183811115612cd8575f80fd5b80850194505087601f850112612cec575f80fd5b83519250612cfc612b1584612a8c565b8381528882858701011115612d0f575f80fd5b612d1e8483830184880161293e565b80604084015250819550612d33818801612c5f565b9450505050509250929050565b8181038181111561095f5761095f612b5a565b808202811582820484141761095f5761095f612b5a565b5f60208284031215612d7a575f80fd5b61095c826127b8565b5f808335601e19843603018112612d98575f80fd5b8301803591506001600160401b03821115612db1575f80fd5b6020019150368190038213156124b0575f80fd5b601f82111561049957805f5260205f20601f840160051c81016020851015612dea5750805b601f840160051c820191505b81811015612e09575f8155600101612df6565b5050505050565b81516001600160401b03811115612e2957612e29612a20565b612e3d81612e378454612ba3565b84612dc5565b602080601f831160018114612e70575f8415612e595750858301515b5f19600386901b1c1916600185901b178555612ec7565b5f85815260208120601f198616915b82811015612e9e57888601518255948401946001909101908401612e7f565b5085821015612ebb57878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b6001600160401b0382811682821603908082111561120f5761120f612b5a565b6001600160401b0381811683821601908082111561120f5761120f612b5a565b6001600160401b03818116838216028082169190828114612f3257612f32612b5a565b505092915050565b61ffff60f01b8860f01b16815263ffffffff60e01b8760e01b1660028201528560068201528460268201525f6001600160401b0360c01b808660c01b1660468401528451612f8f81604e86016020890161293e565b60c09490941b1691909201604e810191909152605601979650505050505050565b5f6001600160401b03808316818103612b9957612b99612b5a565b5f60208284031215612fdb575f80fd5b813560ff81168114612937575f80fdfee92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb00e92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb07a164736f6c6343000819000a", +} + +// PoAValidatorManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use PoAValidatorManagerMetaData.ABI instead. +var PoAValidatorManagerABI = PoAValidatorManagerMetaData.ABI + +// PoAValidatorManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use PoAValidatorManagerMetaData.Bin instead. +var PoAValidatorManagerBin = PoAValidatorManagerMetaData.Bin + +// DeployPoAValidatorManager deploys a new Ethereum contract, binding an instance of PoAValidatorManager to it. +func DeployPoAValidatorManager(auth *bind.TransactOpts, backend bind.ContractBackend, init uint8) (common.Address, *types.Transaction, *PoAValidatorManager, error) { + parsed, err := PoAValidatorManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PoAValidatorManagerBin), backend, init) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PoAValidatorManager{PoAValidatorManagerCaller: PoAValidatorManagerCaller{contract: contract}, PoAValidatorManagerTransactor: PoAValidatorManagerTransactor{contract: contract}, PoAValidatorManagerFilterer: PoAValidatorManagerFilterer{contract: contract}}, nil +} + +// PoAValidatorManager is an auto generated Go binding around an Ethereum contract. +type PoAValidatorManager struct { + PoAValidatorManagerCaller // Read-only binding to the contract + PoAValidatorManagerTransactor // Write-only binding to the contract + PoAValidatorManagerFilterer // Log filterer for contract events +} + +// PoAValidatorManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type PoAValidatorManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PoAValidatorManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type PoAValidatorManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PoAValidatorManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type PoAValidatorManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PoAValidatorManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type PoAValidatorManagerSession struct { + Contract *PoAValidatorManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PoAValidatorManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type PoAValidatorManagerCallerSession struct { + Contract *PoAValidatorManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// PoAValidatorManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type PoAValidatorManagerTransactorSession struct { + Contract *PoAValidatorManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PoAValidatorManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type PoAValidatorManagerRaw struct { + Contract *PoAValidatorManager // Generic contract binding to access the raw methods on +} + +// PoAValidatorManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type PoAValidatorManagerCallerRaw struct { + Contract *PoAValidatorManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// PoAValidatorManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type PoAValidatorManagerTransactorRaw struct { + Contract *PoAValidatorManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewPoAValidatorManager creates a new instance of PoAValidatorManager, bound to a specific deployed contract. +func NewPoAValidatorManager(address common.Address, backend bind.ContractBackend) (*PoAValidatorManager, error) { + contract, err := bindPoAValidatorManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &PoAValidatorManager{PoAValidatorManagerCaller: PoAValidatorManagerCaller{contract: contract}, PoAValidatorManagerTransactor: PoAValidatorManagerTransactor{contract: contract}, PoAValidatorManagerFilterer: PoAValidatorManagerFilterer{contract: contract}}, nil +} + +// NewPoAValidatorManagerCaller creates a new read-only instance of PoAValidatorManager, bound to a specific deployed contract. +func NewPoAValidatorManagerCaller(address common.Address, caller bind.ContractCaller) (*PoAValidatorManagerCaller, error) { + contract, err := bindPoAValidatorManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &PoAValidatorManagerCaller{contract: contract}, nil +} + +// NewPoAValidatorManagerTransactor creates a new write-only instance of PoAValidatorManager, bound to a specific deployed contract. +func NewPoAValidatorManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*PoAValidatorManagerTransactor, error) { + contract, err := bindPoAValidatorManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &PoAValidatorManagerTransactor{contract: contract}, nil +} + +// NewPoAValidatorManagerFilterer creates a new log filterer instance of PoAValidatorManager, bound to a specific deployed contract. +func NewPoAValidatorManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*PoAValidatorManagerFilterer, error) { + contract, err := bindPoAValidatorManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PoAValidatorManagerFilterer{contract: contract}, nil +} + +// bindPoAValidatorManager binds a generic wrapper to an already deployed contract. +func bindPoAValidatorManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := PoAValidatorManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PoAValidatorManager *PoAValidatorManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PoAValidatorManager.Contract.PoAValidatorManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PoAValidatorManager *PoAValidatorManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.PoAValidatorManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PoAValidatorManager *PoAValidatorManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.PoAValidatorManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PoAValidatorManager *PoAValidatorManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PoAValidatorManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PoAValidatorManager *PoAValidatorManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PoAValidatorManager *PoAValidatorManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.contract.Transact(opts, method, params...) +} + +// ADDRESSLENGTH is a free data retrieval call binding the contract method 0x60305d62. +// +// Solidity: function ADDRESS_LENGTH() view returns(uint32) +func (_PoAValidatorManager *PoAValidatorManagerCaller) ADDRESSLENGTH(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _PoAValidatorManager.contract.Call(opts, &out, "ADDRESS_LENGTH") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// ADDRESSLENGTH is a free data retrieval call binding the contract method 0x60305d62. +// +// Solidity: function ADDRESS_LENGTH() view returns(uint32) +func (_PoAValidatorManager *PoAValidatorManagerSession) ADDRESSLENGTH() (uint32, error) { + return _PoAValidatorManager.Contract.ADDRESSLENGTH(&_PoAValidatorManager.CallOpts) +} + +// ADDRESSLENGTH is a free data retrieval call binding the contract method 0x60305d62. +// +// Solidity: function ADDRESS_LENGTH() view returns(uint32) +func (_PoAValidatorManager *PoAValidatorManagerCallerSession) ADDRESSLENGTH() (uint32, error) { + return _PoAValidatorManager.Contract.ADDRESSLENGTH(&_PoAValidatorManager.CallOpts) +} + +// BLSPUBLICKEYLENGTH is a free data retrieval call binding the contract method 0x8280a25a. +// +// Solidity: function BLS_PUBLIC_KEY_LENGTH() view returns(uint8) +func (_PoAValidatorManager *PoAValidatorManagerCaller) BLSPUBLICKEYLENGTH(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _PoAValidatorManager.contract.Call(opts, &out, "BLS_PUBLIC_KEY_LENGTH") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// BLSPUBLICKEYLENGTH is a free data retrieval call binding the contract method 0x8280a25a. +// +// Solidity: function BLS_PUBLIC_KEY_LENGTH() view returns(uint8) +func (_PoAValidatorManager *PoAValidatorManagerSession) BLSPUBLICKEYLENGTH() (uint8, error) { + return _PoAValidatorManager.Contract.BLSPUBLICKEYLENGTH(&_PoAValidatorManager.CallOpts) +} + +// BLSPUBLICKEYLENGTH is a free data retrieval call binding the contract method 0x8280a25a. +// +// Solidity: function BLS_PUBLIC_KEY_LENGTH() view returns(uint8) +func (_PoAValidatorManager *PoAValidatorManagerCallerSession) BLSPUBLICKEYLENGTH() (uint8, error) { + return _PoAValidatorManager.Contract.BLSPUBLICKEYLENGTH(&_PoAValidatorManager.CallOpts) +} + +// MAXIMUMCHURNPERCENTAGELIMIT is a free data retrieval call binding the contract method 0xc974d1b6. +// +// Solidity: function MAXIMUM_CHURN_PERCENTAGE_LIMIT() view returns(uint8) +func (_PoAValidatorManager *PoAValidatorManagerCaller) MAXIMUMCHURNPERCENTAGELIMIT(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _PoAValidatorManager.contract.Call(opts, &out, "MAXIMUM_CHURN_PERCENTAGE_LIMIT") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// MAXIMUMCHURNPERCENTAGELIMIT is a free data retrieval call binding the contract method 0xc974d1b6. +// +// Solidity: function MAXIMUM_CHURN_PERCENTAGE_LIMIT() view returns(uint8) +func (_PoAValidatorManager *PoAValidatorManagerSession) MAXIMUMCHURNPERCENTAGELIMIT() (uint8, error) { + return _PoAValidatorManager.Contract.MAXIMUMCHURNPERCENTAGELIMIT(&_PoAValidatorManager.CallOpts) +} + +// MAXIMUMCHURNPERCENTAGELIMIT is a free data retrieval call binding the contract method 0xc974d1b6. +// +// Solidity: function MAXIMUM_CHURN_PERCENTAGE_LIMIT() view returns(uint8) +func (_PoAValidatorManager *PoAValidatorManagerCallerSession) MAXIMUMCHURNPERCENTAGELIMIT() (uint8, error) { + return _PoAValidatorManager.Contract.MAXIMUMCHURNPERCENTAGELIMIT(&_PoAValidatorManager.CallOpts) +} + +// MAXIMUMREGISTRATIONEXPIRYLENGTH is a free data retrieval call binding the contract method 0xdf93d8de. +// +// Solidity: function MAXIMUM_REGISTRATION_EXPIRY_LENGTH() view returns(uint64) +func (_PoAValidatorManager *PoAValidatorManagerCaller) MAXIMUMREGISTRATIONEXPIRYLENGTH(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _PoAValidatorManager.contract.Call(opts, &out, "MAXIMUM_REGISTRATION_EXPIRY_LENGTH") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// MAXIMUMREGISTRATIONEXPIRYLENGTH is a free data retrieval call binding the contract method 0xdf93d8de. +// +// Solidity: function MAXIMUM_REGISTRATION_EXPIRY_LENGTH() view returns(uint64) +func (_PoAValidatorManager *PoAValidatorManagerSession) MAXIMUMREGISTRATIONEXPIRYLENGTH() (uint64, error) { + return _PoAValidatorManager.Contract.MAXIMUMREGISTRATIONEXPIRYLENGTH(&_PoAValidatorManager.CallOpts) +} + +// MAXIMUMREGISTRATIONEXPIRYLENGTH is a free data retrieval call binding the contract method 0xdf93d8de. +// +// Solidity: function MAXIMUM_REGISTRATION_EXPIRY_LENGTH() view returns(uint64) +func (_PoAValidatorManager *PoAValidatorManagerCallerSession) MAXIMUMREGISTRATIONEXPIRYLENGTH() (uint64, error) { + return _PoAValidatorManager.Contract.MAXIMUMREGISTRATIONEXPIRYLENGTH(&_PoAValidatorManager.CallOpts) +} + +// PCHAINBLOCKCHAINID is a free data retrieval call binding the contract method 0x732214f8. +// +// Solidity: function P_CHAIN_BLOCKCHAIN_ID() view returns(bytes32) +func (_PoAValidatorManager *PoAValidatorManagerCaller) PCHAINBLOCKCHAINID(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _PoAValidatorManager.contract.Call(opts, &out, "P_CHAIN_BLOCKCHAIN_ID") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// PCHAINBLOCKCHAINID is a free data retrieval call binding the contract method 0x732214f8. +// +// Solidity: function P_CHAIN_BLOCKCHAIN_ID() view returns(bytes32) +func (_PoAValidatorManager *PoAValidatorManagerSession) PCHAINBLOCKCHAINID() ([32]byte, error) { + return _PoAValidatorManager.Contract.PCHAINBLOCKCHAINID(&_PoAValidatorManager.CallOpts) +} + +// PCHAINBLOCKCHAINID is a free data retrieval call binding the contract method 0x732214f8. +// +// Solidity: function P_CHAIN_BLOCKCHAIN_ID() view returns(bytes32) +func (_PoAValidatorManager *PoAValidatorManagerCallerSession) PCHAINBLOCKCHAINID() ([32]byte, error) { + return _PoAValidatorManager.Contract.PCHAINBLOCKCHAINID(&_PoAValidatorManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_PoAValidatorManager *PoAValidatorManagerCaller) WARPMESSENGER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PoAValidatorManager.contract.Call(opts, &out, "WARP_MESSENGER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_PoAValidatorManager *PoAValidatorManagerSession) WARPMESSENGER() (common.Address, error) { + return _PoAValidatorManager.Contract.WARPMESSENGER(&_PoAValidatorManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_PoAValidatorManager *PoAValidatorManagerCallerSession) WARPMESSENGER() (common.Address, error) { + return _PoAValidatorManager.Contract.WARPMESSENGER(&_PoAValidatorManager.CallOpts) +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes32,uint64,uint64,uint64,uint64,uint64)) +func (_PoAValidatorManager *PoAValidatorManagerCaller) GetValidator(opts *bind.CallOpts, validationID [32]byte) (Validator, error) { + var out []interface{} + err := _PoAValidatorManager.contract.Call(opts, &out, "getValidator", validationID) + + if err != nil { + return *new(Validator), err + } + + out0 := *abi.ConvertType(out[0], new(Validator)).(*Validator) + + return out0, err + +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes32,uint64,uint64,uint64,uint64,uint64)) +func (_PoAValidatorManager *PoAValidatorManagerSession) GetValidator(validationID [32]byte) (Validator, error) { + return _PoAValidatorManager.Contract.GetValidator(&_PoAValidatorManager.CallOpts, validationID) +} + +// GetValidator is a free data retrieval call binding the contract method 0xd5f20ff6. +// +// Solidity: function getValidator(bytes32 validationID) view returns((uint8,bytes32,uint64,uint64,uint64,uint64,uint64)) +func (_PoAValidatorManager *PoAValidatorManagerCallerSession) GetValidator(validationID [32]byte) (Validator, error) { + return _PoAValidatorManager.Contract.GetValidator(&_PoAValidatorManager.CallOpts, validationID) +} + +// GetWeight is a free data retrieval call binding the contract method 0x66435abf. +// +// Solidity: function getWeight(bytes32 validationID) view returns(uint64) +func (_PoAValidatorManager *PoAValidatorManagerCaller) GetWeight(opts *bind.CallOpts, validationID [32]byte) (uint64, error) { + var out []interface{} + err := _PoAValidatorManager.contract.Call(opts, &out, "getWeight", validationID) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// GetWeight is a free data retrieval call binding the contract method 0x66435abf. +// +// Solidity: function getWeight(bytes32 validationID) view returns(uint64) +func (_PoAValidatorManager *PoAValidatorManagerSession) GetWeight(validationID [32]byte) (uint64, error) { + return _PoAValidatorManager.Contract.GetWeight(&_PoAValidatorManager.CallOpts, validationID) +} + +// GetWeight is a free data retrieval call binding the contract method 0x66435abf. +// +// Solidity: function getWeight(bytes32 validationID) view returns(uint64) +func (_PoAValidatorManager *PoAValidatorManagerCallerSession) GetWeight(validationID [32]byte) (uint64, error) { + return _PoAValidatorManager.Contract.GetWeight(&_PoAValidatorManager.CallOpts, validationID) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_PoAValidatorManager *PoAValidatorManagerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _PoAValidatorManager.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_PoAValidatorManager *PoAValidatorManagerSession) Owner() (common.Address, error) { + return _PoAValidatorManager.Contract.Owner(&_PoAValidatorManager.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address) +func (_PoAValidatorManager *PoAValidatorManagerCallerSession) Owner() (common.Address, error) { + return _PoAValidatorManager.Contract.Owner(&_PoAValidatorManager.CallOpts) +} + +// RegisteredValidators is a free data retrieval call binding the contract method 0xe7d14c1c. +// +// Solidity: function registeredValidators(bytes32 nodeID) view returns(bytes32) +func (_PoAValidatorManager *PoAValidatorManagerCaller) RegisteredValidators(opts *bind.CallOpts, nodeID [32]byte) ([32]byte, error) { + var out []interface{} + err := _PoAValidatorManager.contract.Call(opts, &out, "registeredValidators", nodeID) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// RegisteredValidators is a free data retrieval call binding the contract method 0xe7d14c1c. +// +// Solidity: function registeredValidators(bytes32 nodeID) view returns(bytes32) +func (_PoAValidatorManager *PoAValidatorManagerSession) RegisteredValidators(nodeID [32]byte) ([32]byte, error) { + return _PoAValidatorManager.Contract.RegisteredValidators(&_PoAValidatorManager.CallOpts, nodeID) +} + +// RegisteredValidators is a free data retrieval call binding the contract method 0xe7d14c1c. +// +// Solidity: function registeredValidators(bytes32 nodeID) view returns(bytes32) +func (_PoAValidatorManager *PoAValidatorManagerCallerSession) RegisteredValidators(nodeID [32]byte) ([32]byte, error) { + return _PoAValidatorManager.Contract.RegisteredValidators(&_PoAValidatorManager.CallOpts, nodeID) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0x467ef06f. +// +// Solidity: function completeEndValidation(uint32 messageIndex) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactor) CompleteEndValidation(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _PoAValidatorManager.contract.Transact(opts, "completeEndValidation", messageIndex) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0x467ef06f. +// +// Solidity: function completeEndValidation(uint32 messageIndex) returns() +func (_PoAValidatorManager *PoAValidatorManagerSession) CompleteEndValidation(messageIndex uint32) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.CompleteEndValidation(&_PoAValidatorManager.TransactOpts, messageIndex) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0x467ef06f. +// +// Solidity: function completeEndValidation(uint32 messageIndex) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactorSession) CompleteEndValidation(messageIndex uint32) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.CompleteEndValidation(&_PoAValidatorManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactor) CompleteValidatorRegistration(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _PoAValidatorManager.contract.Transact(opts, "completeValidatorRegistration", messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_PoAValidatorManager *PoAValidatorManagerSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.CompleteValidatorRegistration(&_PoAValidatorManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactorSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.CompleteValidatorRegistration(&_PoAValidatorManager.TransactOpts, messageIndex) +} + +// Initialize is a paid mutator transaction binding the contract method 0xd588c18f. +// +// Solidity: function initialize((bytes32,uint64,uint8) settings, address initialOwner) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactor) Initialize(opts *bind.TransactOpts, settings ValidatorManagerSettings, initialOwner common.Address) (*types.Transaction, error) { + return _PoAValidatorManager.contract.Transact(opts, "initialize", settings, initialOwner) +} + +// Initialize is a paid mutator transaction binding the contract method 0xd588c18f. +// +// Solidity: function initialize((bytes32,uint64,uint8) settings, address initialOwner) returns() +func (_PoAValidatorManager *PoAValidatorManagerSession) Initialize(settings ValidatorManagerSettings, initialOwner common.Address) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.Initialize(&_PoAValidatorManager.TransactOpts, settings, initialOwner) +} + +// Initialize is a paid mutator transaction binding the contract method 0xd588c18f. +// +// Solidity: function initialize((bytes32,uint64,uint8) settings, address initialOwner) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactorSession) Initialize(settings ValidatorManagerSettings, initialOwner common.Address) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.Initialize(&_PoAValidatorManager.TransactOpts, settings, initialOwner) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x97fb70d4. +// +// Solidity: function initializeEndValidation(bytes32 validationID) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactor) InitializeEndValidation(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _PoAValidatorManager.contract.Transact(opts, "initializeEndValidation", validationID) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x97fb70d4. +// +// Solidity: function initializeEndValidation(bytes32 validationID) returns() +func (_PoAValidatorManager *PoAValidatorManagerSession) InitializeEndValidation(validationID [32]byte) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.InitializeEndValidation(&_PoAValidatorManager.TransactOpts, validationID) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x97fb70d4. +// +// Solidity: function initializeEndValidation(bytes32 validationID) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactorSession) InitializeEndValidation(validationID [32]byte) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.InitializeEndValidation(&_PoAValidatorManager.TransactOpts, validationID) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0x8994ab49. +// +// Solidity: function initializeValidatorRegistration((bytes32,uint64,bytes) registrationInput, uint64 weight) returns(bytes32 validationID) +func (_PoAValidatorManager *PoAValidatorManagerTransactor) InitializeValidatorRegistration(opts *bind.TransactOpts, registrationInput ValidatorRegistrationInput, weight uint64) (*types.Transaction, error) { + return _PoAValidatorManager.contract.Transact(opts, "initializeValidatorRegistration", registrationInput, weight) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0x8994ab49. +// +// Solidity: function initializeValidatorRegistration((bytes32,uint64,bytes) registrationInput, uint64 weight) returns(bytes32 validationID) +func (_PoAValidatorManager *PoAValidatorManagerSession) InitializeValidatorRegistration(registrationInput ValidatorRegistrationInput, weight uint64) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.InitializeValidatorRegistration(&_PoAValidatorManager.TransactOpts, registrationInput, weight) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0x8994ab49. +// +// Solidity: function initializeValidatorRegistration((bytes32,uint64,bytes) registrationInput, uint64 weight) returns(bytes32 validationID) +func (_PoAValidatorManager *PoAValidatorManagerTransactorSession) InitializeValidatorRegistration(registrationInput ValidatorRegistrationInput, weight uint64) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.InitializeValidatorRegistration(&_PoAValidatorManager.TransactOpts, registrationInput, weight) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x61e2f490. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes32,uint64,bytes)[]) subnetConversionData, uint32 messageIndex) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactor) InitializeValidatorSet(opts *bind.TransactOpts, subnetConversionData SubnetConversionData, messageIndex uint32) (*types.Transaction, error) { + return _PoAValidatorManager.contract.Transact(opts, "initializeValidatorSet", subnetConversionData, messageIndex) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x61e2f490. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes32,uint64,bytes)[]) subnetConversionData, uint32 messageIndex) returns() +func (_PoAValidatorManager *PoAValidatorManagerSession) InitializeValidatorSet(subnetConversionData SubnetConversionData, messageIndex uint32) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.InitializeValidatorSet(&_PoAValidatorManager.TransactOpts, subnetConversionData, messageIndex) +} + +// InitializeValidatorSet is a paid mutator transaction binding the contract method 0x61e2f490. +// +// Solidity: function initializeValidatorSet((bytes32,bytes32,address,(bytes32,uint64,bytes)[]) subnetConversionData, uint32 messageIndex) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactorSession) InitializeValidatorSet(subnetConversionData SubnetConversionData, messageIndex uint32) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.InitializeValidatorSet(&_PoAValidatorManager.TransactOpts, subnetConversionData, messageIndex) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PoAValidatorManager.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_PoAValidatorManager *PoAValidatorManagerSession) RenounceOwnership() (*types.Transaction, error) { + return _PoAValidatorManager.Contract.RenounceOwnership(&_PoAValidatorManager.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _PoAValidatorManager.Contract.RenounceOwnership(&_PoAValidatorManager.TransactOpts) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactor) ResendEndValidatorMessage(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _PoAValidatorManager.contract.Transact(opts, "resendEndValidatorMessage", validationID) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_PoAValidatorManager *PoAValidatorManagerSession) ResendEndValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.ResendEndValidatorMessage(&_PoAValidatorManager.TransactOpts, validationID) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactorSession) ResendEndValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.ResendEndValidatorMessage(&_PoAValidatorManager.TransactOpts, validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactor) ResendRegisterValidatorMessage(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _PoAValidatorManager.contract.Transact(opts, "resendRegisterValidatorMessage", validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_PoAValidatorManager *PoAValidatorManagerSession) ResendRegisterValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.ResendRegisterValidatorMessage(&_PoAValidatorManager.TransactOpts, validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactorSession) ResendRegisterValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.ResendRegisterValidatorMessage(&_PoAValidatorManager.TransactOpts, validationID) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _PoAValidatorManager.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_PoAValidatorManager *PoAValidatorManagerSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.TransferOwnership(&_PoAValidatorManager.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) returns() +func (_PoAValidatorManager *PoAValidatorManagerTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _PoAValidatorManager.Contract.TransferOwnership(&_PoAValidatorManager.TransactOpts, newOwner) +} + +// PoAValidatorManagerInitialValidatorCreatedIterator is returned from FilterInitialValidatorCreated and is used to iterate over the raw logs and unpacked data for InitialValidatorCreated events raised by the PoAValidatorManager contract. +type PoAValidatorManagerInitialValidatorCreatedIterator struct { + Event *PoAValidatorManagerInitialValidatorCreated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PoAValidatorManagerInitialValidatorCreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerInitialValidatorCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerInitialValidatorCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PoAValidatorManagerInitialValidatorCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PoAValidatorManagerInitialValidatorCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PoAValidatorManagerInitialValidatorCreated represents a InitialValidatorCreated event raised by the PoAValidatorManager contract. +type PoAValidatorManagerInitialValidatorCreated struct { + ValidationID [32]byte + NodeID [32]byte + Weight *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialValidatorCreated is a free log retrieval operation binding the contract event 0xb815f891730222788b3f8d66249b3a287ce680c3df13866fd9a4f37743ae1014. +// +// Solidity: event InitialValidatorCreated(bytes32 indexed validationID, bytes32 indexed nodeID, uint256 weight) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) FilterInitialValidatorCreated(opts *bind.FilterOpts, validationID [][32]byte, nodeID [][32]byte) (*PoAValidatorManagerInitialValidatorCreatedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + + logs, sub, err := _PoAValidatorManager.contract.FilterLogs(opts, "InitialValidatorCreated", validationIDRule, nodeIDRule) + if err != nil { + return nil, err + } + return &PoAValidatorManagerInitialValidatorCreatedIterator{contract: _PoAValidatorManager.contract, event: "InitialValidatorCreated", logs: logs, sub: sub}, nil +} + +// WatchInitialValidatorCreated is a free log subscription operation binding the contract event 0xb815f891730222788b3f8d66249b3a287ce680c3df13866fd9a4f37743ae1014. +// +// Solidity: event InitialValidatorCreated(bytes32 indexed validationID, bytes32 indexed nodeID, uint256 weight) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) WatchInitialValidatorCreated(opts *bind.WatchOpts, sink chan<- *PoAValidatorManagerInitialValidatorCreated, validationID [][32]byte, nodeID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + + logs, sub, err := _PoAValidatorManager.contract.WatchLogs(opts, "InitialValidatorCreated", validationIDRule, nodeIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PoAValidatorManagerInitialValidatorCreated) + if err := _PoAValidatorManager.contract.UnpackLog(event, "InitialValidatorCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialValidatorCreated is a log parse operation binding the contract event 0xb815f891730222788b3f8d66249b3a287ce680c3df13866fd9a4f37743ae1014. +// +// Solidity: event InitialValidatorCreated(bytes32 indexed validationID, bytes32 indexed nodeID, uint256 weight) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) ParseInitialValidatorCreated(log types.Log) (*PoAValidatorManagerInitialValidatorCreated, error) { + event := new(PoAValidatorManagerInitialValidatorCreated) + if err := _PoAValidatorManager.contract.UnpackLog(event, "InitialValidatorCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// PoAValidatorManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the PoAValidatorManager contract. +type PoAValidatorManagerInitializedIterator struct { + Event *PoAValidatorManagerInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PoAValidatorManagerInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PoAValidatorManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PoAValidatorManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PoAValidatorManagerInitialized represents a Initialized event raised by the PoAValidatorManager contract. +type PoAValidatorManagerInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*PoAValidatorManagerInitializedIterator, error) { + + logs, sub, err := _PoAValidatorManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &PoAValidatorManagerInitializedIterator{contract: _PoAValidatorManager.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *PoAValidatorManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _PoAValidatorManager.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PoAValidatorManagerInitialized) + if err := _PoAValidatorManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) ParseInitialized(log types.Log) (*PoAValidatorManagerInitialized, error) { + event := new(PoAValidatorManagerInitialized) + if err := _PoAValidatorManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// PoAValidatorManagerOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the PoAValidatorManager contract. +type PoAValidatorManagerOwnershipTransferredIterator struct { + Event *PoAValidatorManagerOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PoAValidatorManagerOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PoAValidatorManagerOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PoAValidatorManagerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PoAValidatorManagerOwnershipTransferred represents a OwnershipTransferred event raised by the PoAValidatorManager contract. +type PoAValidatorManagerOwnershipTransferred struct { + PreviousOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, previousOwner []common.Address, newOwner []common.Address) (*PoAValidatorManagerOwnershipTransferredIterator, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _PoAValidatorManager.contract.FilterLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &PoAValidatorManagerOwnershipTransferredIterator{contract: _PoAValidatorManager.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *PoAValidatorManagerOwnershipTransferred, previousOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var previousOwnerRule []interface{} + for _, previousOwnerItem := range previousOwner { + previousOwnerRule = append(previousOwnerRule, previousOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _PoAValidatorManager.contract.WatchLogs(opts, "OwnershipTransferred", previousOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PoAValidatorManagerOwnershipTransferred) + if err := _PoAValidatorManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) ParseOwnershipTransferred(log types.Log) (*PoAValidatorManagerOwnershipTransferred, error) { + event := new(PoAValidatorManagerOwnershipTransferred) + if err := _PoAValidatorManager.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// PoAValidatorManagerValidationPeriodCreatedIterator is returned from FilterValidationPeriodCreated and is used to iterate over the raw logs and unpacked data for ValidationPeriodCreated events raised by the PoAValidatorManager contract. +type PoAValidatorManagerValidationPeriodCreatedIterator struct { + Event *PoAValidatorManagerValidationPeriodCreated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PoAValidatorManagerValidationPeriodCreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerValidationPeriodCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerValidationPeriodCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PoAValidatorManagerValidationPeriodCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PoAValidatorManagerValidationPeriodCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PoAValidatorManagerValidationPeriodCreated represents a ValidationPeriodCreated event raised by the PoAValidatorManager contract. +type PoAValidatorManagerValidationPeriodCreated struct { + ValidationID [32]byte + NodeID [32]byte + RegisterValidationMessageID [32]byte + Weight *big.Int + RegistrationExpiry uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodCreated is a free log retrieval operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) FilterValidationPeriodCreated(opts *bind.FilterOpts, validationID [][32]byte, nodeID [][32]byte, registerValidationMessageID [][32]byte) (*PoAValidatorManagerValidationPeriodCreatedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var registerValidationMessageIDRule []interface{} + for _, registerValidationMessageIDItem := range registerValidationMessageID { + registerValidationMessageIDRule = append(registerValidationMessageIDRule, registerValidationMessageIDItem) + } + + logs, sub, err := _PoAValidatorManager.contract.FilterLogs(opts, "ValidationPeriodCreated", validationIDRule, nodeIDRule, registerValidationMessageIDRule) + if err != nil { + return nil, err + } + return &PoAValidatorManagerValidationPeriodCreatedIterator{contract: _PoAValidatorManager.contract, event: "ValidationPeriodCreated", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodCreated is a free log subscription operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) WatchValidationPeriodCreated(opts *bind.WatchOpts, sink chan<- *PoAValidatorManagerValidationPeriodCreated, validationID [][32]byte, nodeID [][32]byte, registerValidationMessageID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var registerValidationMessageIDRule []interface{} + for _, registerValidationMessageIDItem := range registerValidationMessageID { + registerValidationMessageIDRule = append(registerValidationMessageIDRule, registerValidationMessageIDItem) + } + + logs, sub, err := _PoAValidatorManager.contract.WatchLogs(opts, "ValidationPeriodCreated", validationIDRule, nodeIDRule, registerValidationMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PoAValidatorManagerValidationPeriodCreated) + if err := _PoAValidatorManager.contract.UnpackLog(event, "ValidationPeriodCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodCreated is a log parse operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) ParseValidationPeriodCreated(log types.Log) (*PoAValidatorManagerValidationPeriodCreated, error) { + event := new(PoAValidatorManagerValidationPeriodCreated) + if err := _PoAValidatorManager.contract.UnpackLog(event, "ValidationPeriodCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// PoAValidatorManagerValidationPeriodEndedIterator is returned from FilterValidationPeriodEnded and is used to iterate over the raw logs and unpacked data for ValidationPeriodEnded events raised by the PoAValidatorManager contract. +type PoAValidatorManagerValidationPeriodEndedIterator struct { + Event *PoAValidatorManagerValidationPeriodEnded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PoAValidatorManagerValidationPeriodEndedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerValidationPeriodEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerValidationPeriodEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PoAValidatorManagerValidationPeriodEndedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PoAValidatorManagerValidationPeriodEndedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PoAValidatorManagerValidationPeriodEnded represents a ValidationPeriodEnded event raised by the PoAValidatorManager contract. +type PoAValidatorManagerValidationPeriodEnded struct { + ValidationID [32]byte + Status uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodEnded is a free log retrieval operation binding the contract event 0x1c08e59656f1a18dc2da76826cdc52805c43e897a17c50faefb8ab3c1526cc16. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID, uint8 indexed status) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) FilterValidationPeriodEnded(opts *bind.FilterOpts, validationID [][32]byte, status []uint8) (*PoAValidatorManagerValidationPeriodEndedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var statusRule []interface{} + for _, statusItem := range status { + statusRule = append(statusRule, statusItem) + } + + logs, sub, err := _PoAValidatorManager.contract.FilterLogs(opts, "ValidationPeriodEnded", validationIDRule, statusRule) + if err != nil { + return nil, err + } + return &PoAValidatorManagerValidationPeriodEndedIterator{contract: _PoAValidatorManager.contract, event: "ValidationPeriodEnded", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodEnded is a free log subscription operation binding the contract event 0x1c08e59656f1a18dc2da76826cdc52805c43e897a17c50faefb8ab3c1526cc16. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID, uint8 indexed status) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) WatchValidationPeriodEnded(opts *bind.WatchOpts, sink chan<- *PoAValidatorManagerValidationPeriodEnded, validationID [][32]byte, status []uint8) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var statusRule []interface{} + for _, statusItem := range status { + statusRule = append(statusRule, statusItem) + } + + logs, sub, err := _PoAValidatorManager.contract.WatchLogs(opts, "ValidationPeriodEnded", validationIDRule, statusRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PoAValidatorManagerValidationPeriodEnded) + if err := _PoAValidatorManager.contract.UnpackLog(event, "ValidationPeriodEnded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodEnded is a log parse operation binding the contract event 0x1c08e59656f1a18dc2da76826cdc52805c43e897a17c50faefb8ab3c1526cc16. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID, uint8 indexed status) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) ParseValidationPeriodEnded(log types.Log) (*PoAValidatorManagerValidationPeriodEnded, error) { + event := new(PoAValidatorManagerValidationPeriodEnded) + if err := _PoAValidatorManager.contract.UnpackLog(event, "ValidationPeriodEnded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// PoAValidatorManagerValidationPeriodRegisteredIterator is returned from FilterValidationPeriodRegistered and is used to iterate over the raw logs and unpacked data for ValidationPeriodRegistered events raised by the PoAValidatorManager contract. +type PoAValidatorManagerValidationPeriodRegisteredIterator struct { + Event *PoAValidatorManagerValidationPeriodRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PoAValidatorManagerValidationPeriodRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerValidationPeriodRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerValidationPeriodRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PoAValidatorManagerValidationPeriodRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PoAValidatorManagerValidationPeriodRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PoAValidatorManagerValidationPeriodRegistered represents a ValidationPeriodRegistered event raised by the PoAValidatorManager contract. +type PoAValidatorManagerValidationPeriodRegistered struct { + ValidationID [32]byte + Weight *big.Int + Timestamp *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodRegistered is a free log retrieval operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 weight, uint256 timestamp) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) FilterValidationPeriodRegistered(opts *bind.FilterOpts, validationID [][32]byte) (*PoAValidatorManagerValidationPeriodRegisteredIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _PoAValidatorManager.contract.FilterLogs(opts, "ValidationPeriodRegistered", validationIDRule) + if err != nil { + return nil, err + } + return &PoAValidatorManagerValidationPeriodRegisteredIterator{contract: _PoAValidatorManager.contract, event: "ValidationPeriodRegistered", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodRegistered is a free log subscription operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 weight, uint256 timestamp) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) WatchValidationPeriodRegistered(opts *bind.WatchOpts, sink chan<- *PoAValidatorManagerValidationPeriodRegistered, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _PoAValidatorManager.contract.WatchLogs(opts, "ValidationPeriodRegistered", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PoAValidatorManagerValidationPeriodRegistered) + if err := _PoAValidatorManager.contract.UnpackLog(event, "ValidationPeriodRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodRegistered is a log parse operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 weight, uint256 timestamp) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) ParseValidationPeriodRegistered(log types.Log) (*PoAValidatorManagerValidationPeriodRegistered, error) { + event := new(PoAValidatorManagerValidationPeriodRegistered) + if err := _PoAValidatorManager.contract.UnpackLog(event, "ValidationPeriodRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// PoAValidatorManagerValidatorRemovalInitializedIterator is returned from FilterValidatorRemovalInitialized and is used to iterate over the raw logs and unpacked data for ValidatorRemovalInitialized events raised by the PoAValidatorManager contract. +type PoAValidatorManagerValidatorRemovalInitializedIterator struct { + Event *PoAValidatorManagerValidatorRemovalInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PoAValidatorManagerValidatorRemovalInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerValidatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerValidatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PoAValidatorManagerValidatorRemovalInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PoAValidatorManagerValidatorRemovalInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PoAValidatorManagerValidatorRemovalInitialized represents a ValidatorRemovalInitialized event raised by the PoAValidatorManager contract. +type PoAValidatorManagerValidatorRemovalInitialized struct { + ValidationID [32]byte + SetWeightMessageID [32]byte + Weight *big.Int + EndTime *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorRemovalInitialized is a free log retrieval operation binding the contract event 0x13d58394cf269d48bcf927959a29a5ffee7c9924dafff8927ecdf3c48ffa7c67. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 weight, uint256 endTime) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) FilterValidatorRemovalInitialized(opts *bind.FilterOpts, validationID [][32]byte, setWeightMessageID [][32]byte) (*PoAValidatorManagerValidatorRemovalInitializedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var setWeightMessageIDRule []interface{} + for _, setWeightMessageIDItem := range setWeightMessageID { + setWeightMessageIDRule = append(setWeightMessageIDRule, setWeightMessageIDItem) + } + + logs, sub, err := _PoAValidatorManager.contract.FilterLogs(opts, "ValidatorRemovalInitialized", validationIDRule, setWeightMessageIDRule) + if err != nil { + return nil, err + } + return &PoAValidatorManagerValidatorRemovalInitializedIterator{contract: _PoAValidatorManager.contract, event: "ValidatorRemovalInitialized", logs: logs, sub: sub}, nil +} + +// WatchValidatorRemovalInitialized is a free log subscription operation binding the contract event 0x13d58394cf269d48bcf927959a29a5ffee7c9924dafff8927ecdf3c48ffa7c67. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 weight, uint256 endTime) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) WatchValidatorRemovalInitialized(opts *bind.WatchOpts, sink chan<- *PoAValidatorManagerValidatorRemovalInitialized, validationID [][32]byte, setWeightMessageID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var setWeightMessageIDRule []interface{} + for _, setWeightMessageIDItem := range setWeightMessageID { + setWeightMessageIDRule = append(setWeightMessageIDRule, setWeightMessageIDItem) + } + + logs, sub, err := _PoAValidatorManager.contract.WatchLogs(opts, "ValidatorRemovalInitialized", validationIDRule, setWeightMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PoAValidatorManagerValidatorRemovalInitialized) + if err := _PoAValidatorManager.contract.UnpackLog(event, "ValidatorRemovalInitialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorRemovalInitialized is a log parse operation binding the contract event 0x13d58394cf269d48bcf927959a29a5ffee7c9924dafff8927ecdf3c48ffa7c67. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 weight, uint256 endTime) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) ParseValidatorRemovalInitialized(log types.Log) (*PoAValidatorManagerValidatorRemovalInitialized, error) { + event := new(PoAValidatorManagerValidatorRemovalInitialized) + if err := _PoAValidatorManager.contract.UnpackLog(event, "ValidatorRemovalInitialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// PoAValidatorManagerValidatorWeightUpdateIterator is returned from FilterValidatorWeightUpdate and is used to iterate over the raw logs and unpacked data for ValidatorWeightUpdate events raised by the PoAValidatorManager contract. +type PoAValidatorManagerValidatorWeightUpdateIterator struct { + Event *PoAValidatorManagerValidatorWeightUpdate // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *PoAValidatorManagerValidatorWeightUpdateIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(PoAValidatorManagerValidatorWeightUpdate) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *PoAValidatorManagerValidatorWeightUpdateIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *PoAValidatorManagerValidatorWeightUpdateIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// PoAValidatorManagerValidatorWeightUpdate represents a ValidatorWeightUpdate event raised by the PoAValidatorManager contract. +type PoAValidatorManagerValidatorWeightUpdate struct { + ValidationID [32]byte + Nonce uint64 + ValidatorWeight uint64 + SetWeightMessageID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorWeightUpdate is a free log retrieval operation binding the contract event 0x07de5ff35a674a8005e661f3333c907ca6333462808762d19dc7b3abb1a8c1df. +// +// Solidity: event ValidatorWeightUpdate(bytes32 indexed validationID, uint64 indexed nonce, uint64 validatorWeight, bytes32 setWeightMessageID) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) FilterValidatorWeightUpdate(opts *bind.FilterOpts, validationID [][32]byte, nonce []uint64) (*PoAValidatorManagerValidatorWeightUpdateIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + + logs, sub, err := _PoAValidatorManager.contract.FilterLogs(opts, "ValidatorWeightUpdate", validationIDRule, nonceRule) + if err != nil { + return nil, err + } + return &PoAValidatorManagerValidatorWeightUpdateIterator{contract: _PoAValidatorManager.contract, event: "ValidatorWeightUpdate", logs: logs, sub: sub}, nil +} + +// WatchValidatorWeightUpdate is a free log subscription operation binding the contract event 0x07de5ff35a674a8005e661f3333c907ca6333462808762d19dc7b3abb1a8c1df. +// +// Solidity: event ValidatorWeightUpdate(bytes32 indexed validationID, uint64 indexed nonce, uint64 validatorWeight, bytes32 setWeightMessageID) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) WatchValidatorWeightUpdate(opts *bind.WatchOpts, sink chan<- *PoAValidatorManagerValidatorWeightUpdate, validationID [][32]byte, nonce []uint64) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nonceRule []interface{} + for _, nonceItem := range nonce { + nonceRule = append(nonceRule, nonceItem) + } + + logs, sub, err := _PoAValidatorManager.contract.WatchLogs(opts, "ValidatorWeightUpdate", validationIDRule, nonceRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(PoAValidatorManagerValidatorWeightUpdate) + if err := _PoAValidatorManager.contract.UnpackLog(event, "ValidatorWeightUpdate", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorWeightUpdate is a log parse operation binding the contract event 0x07de5ff35a674a8005e661f3333c907ca6333462808762d19dc7b3abb1a8c1df. +// +// Solidity: event ValidatorWeightUpdate(bytes32 indexed validationID, uint64 indexed nonce, uint64 validatorWeight, bytes32 setWeightMessageID) +func (_PoAValidatorManager *PoAValidatorManagerFilterer) ParseValidatorWeightUpdate(log types.Log) (*PoAValidatorManagerValidatorWeightUpdate, error) { + event := new(PoAValidatorManagerValidatorWeightUpdate) + if err := _PoAValidatorManager.contract.UnpackLog(event, "ValidatorWeightUpdate", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/contracts/mocks/ExampleERC20.sol b/contracts/mocks/ExampleERC20.sol index db4d6cb92..d7d348702 100644 --- a/contracts/mocks/ExampleERC20.sol +++ b/contracts/mocks/ExampleERC20.sol @@ -13,12 +13,13 @@ import { ERC20Burnable, ERC20 } from "@openzeppelin/contracts@5.0.2/token/ERC20/extensions/ERC20Burnable.sol"; +import {IERC20Mintable} from "../validator-manager/interfaces/IERC20Mintable.sol"; -contract ExampleERC20 is ERC20Burnable { +contract ExampleERC20 is ERC20Burnable, IERC20Mintable { string private constant _TOKEN_NAME = "Mock Token"; string private constant _TOKEN_SYMBOL = "EXMP"; - uint256 private constant _MAX_MINT = 1e16; + uint256 private constant _MAX_MINT = 1e19; constructor() ERC20(_TOKEN_NAME, _TOKEN_SYMBOL) { _mint(msg.sender, 1e28); @@ -30,4 +31,11 @@ contract ExampleERC20 is ERC20Burnable { _mint(msg.sender, amount); } + + function mint(address account, uint256 amount) external { + // Can only mint 10 at a time. + require(amount <= _MAX_MINT, "ExampleERC20: max mint exceeded"); + + _mint(account, amount); + } } diff --git a/contracts/teleporter/README.md b/contracts/teleporter/README.md index b0f38a3c3..c5ca8c236 100644 --- a/contracts/teleporter/README.md +++ b/contracts/teleporter/README.md @@ -69,7 +69,7 @@ Once sent on chain, Warp messages cannot be re-signed by a new validator set in **Do not deploy the `TeleporterMessenger` contract using `forge create`**. The `TeleporterMessenger` contract must be deployed to the same contract address on every chain. To achieve this, the contract can be deployed using a static transaction that uses Nick's method as documented in [this guide](../..//utils/contract-deployment/README.md). Alternatively, if creating a new Subnet, the contract can be pre-allocated with the proper address and state in the new chain's [genesis file](https://docs.avax.network/build/subnet/upgrade/customize-a-subnet#setting-the-genesis-allocation). -As an example, to include `TeleporterMessenger` `v1.0.0` in the genesis file, include the following values in the `alloc` settings, as documented at the link above. The `storage` values included below correspond to the two contract values that are initialized as part of the default constructor of `TeleporterMessenger`. These are the `ReentrancyGuard` values set in this [abstract contract](../utilities/ReentrancyGuards.sol). Future versions of `TeleporterMessenger` may require different storage value intializations. +As an example, to include `TeleporterMessenger` `v1.0.0` in the genesis file, include the following values in the `alloc` settings, as documented at the link above. The `storage` values included below correspond to the two contract values that are initialized as part of the default constructor of `TeleporterMessenger`. These are the `ReentrancyGuard` values set in this [abstract contract](../utilities/ReentrancyGuards.sol). Future versions of `TeleporterMessenger` may require different storage value initializations. ```json "alloc": { "0x253b2784c75e510dD0fF1da844684a1aC0aa5fcf": { diff --git a/contracts/utilities/ICMInitializable.sol b/contracts/utilities/ICMInitializable.sol new file mode 100644 index 000000000..9e9c1ae88 --- /dev/null +++ b/contracts/utilities/ICMInitializable.sol @@ -0,0 +1,10 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem +pragma solidity 0.8.25; + +enum ICMInitializable { + Allowed, + Disallowed +} diff --git a/contracts/validator-manager/ERC20TokenStakingManager.sol b/contracts/validator-manager/ERC20TokenStakingManager.sol new file mode 100644 index 000000000..16af3c64c --- /dev/null +++ b/contracts/validator-manager/ERC20TokenStakingManager.sol @@ -0,0 +1,132 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {IERC20TokenStakingManager} from "./interfaces/IERC20TokenStakingManager.sol"; +import {Initializable} from + "@openzeppelin/contracts-upgradeable@5.0.2/proxy/utils/Initializable.sol"; +import {IERC20Mintable} from "./interfaces/IERC20Mintable.sol"; +import {SafeERC20TransferFrom} from "@utilities/SafeERC20TransferFrom.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; +import {ICMInitializable} from "../utilities/ICMInitializable.sol"; +import {PoSValidatorManager} from "./PoSValidatorManager.sol"; +import {PoSValidatorManagerSettings} from "./interfaces/IPoSValidatorManager.sol"; +import {ValidatorRegistrationInput} from "./interfaces/IValidatorManager.sol"; + +contract ERC20TokenStakingManager is + Initializable, + PoSValidatorManager, + IERC20TokenStakingManager +{ + using SafeERC20 for IERC20Mintable; + using SafeERC20TransferFrom for IERC20Mintable; + + // solhint-disable private-vars-leading-underscore + /// @custom:storage-location erc7201:avalanche-icm.storage.ERC20TokenStakingManager + struct ERC20TokenStakingManagerStorage { + IERC20Mintable _token; + uint8 _tokenDecimals; + } + // solhint-enable private-vars-leading-underscore + + // keccak256(abi.encode(uint256(keccak256("avalanche-icm.storage.ERC20TokenStakingManager")) - 1)) & ~bytes32(uint256(0xff)); + // TODO: Update to correct storage slot + bytes32 private constant _ERC20_STAKING_MANAGER_STORAGE_LOCATION = + 0x6e5bdfcce15e53c3406ea67bfce37dcd26f5152d5492824e43fd5e3c8ac5ab00; + + // solhint-disable ordering + function _getERC20StakingManagerStorage() + private + pure + returns (ERC20TokenStakingManagerStorage storage $) + { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := _ERC20_STAKING_MANAGER_STORAGE_LOCATION + } + } + + constructor(ICMInitializable init) { + if (init == ICMInitializable.Disallowed) { + _disableInitializers(); + } + } + + /** + * @notice Initialize the ERC20 token staking manager + * @dev Uses reinitializer(2) on the PoS staking contracts to make sure after migration from PoA, the PoS contracts can reinitialize with its needed values. + * @param settings Initial settings for the PoS validator manager + * @param token The ERC20 token to be staked + */ + function initialize( + PoSValidatorManagerSettings calldata settings, + IERC20Mintable token + ) external reinitializer(2) { + __ERC20TokenStakingManager_init(settings, token); + } + + // solhint-disable func-name-mixedcase + function __ERC20TokenStakingManager_init( + PoSValidatorManagerSettings calldata settings, + IERC20Mintable token + ) internal onlyInitializing { + __POS_Validator_Manager_init(settings); + __ERC20TokenStakingManager_init_unchained(token); + } + + // solhint-disable func-name-mixedcase + function __ERC20TokenStakingManager_init_unchained(IERC20Mintable token) + internal + onlyInitializing + { + ERC20TokenStakingManagerStorage storage $ = _getERC20StakingManagerStorage(); + if (address(token) == address(0)) { + revert InvalidAddress(); + } + $._token = token; + } + + /** + * @notice See {IERC20TokenStakingManager-initializeValidatorRegistration} + * Begins the validator registration process. Locks the configured ERC20 in the contract as the stake. + */ + function initializeValidatorRegistration( + ValidatorRegistrationInput calldata registrationInput, + uint16 delegationFeeBips, + uint64 minStakeDuration, + uint256 stakeAmount + ) external nonReentrant returns (bytes32 validationID) { + return _initializeValidatorRegistration( + registrationInput, delegationFeeBips, minStakeDuration, stakeAmount + ); + } + + /** + * @notice Begins the delegator registration process. Locks the configured ERC20 in the contract as the delegated stake. + * @param validationID The ID of the validation period being delegated to. + * @param delegationAmount The amount to be delegated. + */ + function initializeDelegatorRegistration( + bytes32 validationID, + uint256 delegationAmount + ) external nonReentrant returns (bytes32) { + return _initializeDelegatorRegistration(validationID, _msgSender(), delegationAmount); + } + + // Must be guarded with reentrancy guard for safe transfer from + function _lock(uint256 value) internal virtual override returns (uint256) { + return _getERC20StakingManagerStorage()._token.safeTransferFrom(value); + } + + function _unlock(address to, uint256 value) internal virtual override { + _getERC20StakingManagerStorage()._token.safeTransfer(to, value); + } + + function _reward(address account, uint256 amount) internal virtual override { + ERC20TokenStakingManagerStorage storage $ = _getERC20StakingManagerStorage(); + $._token.mint(account, amount); + } +} diff --git a/contracts/validator-manager/ExampleRewardCalculator.sol b/contracts/validator-manager/ExampleRewardCalculator.sol new file mode 100644 index 000000000..79740d61a --- /dev/null +++ b/contracts/validator-manager/ExampleRewardCalculator.sol @@ -0,0 +1,45 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {IRewardCalculator} from "./interfaces/IRewardCalculator.sol"; + +contract ExampleRewardCalculator is IRewardCalculator { + uint256 public constant SECONDS_IN_YEAR = 31536000; + + uint8 public constant UPTIME_REWARDS_THRESHOLD_PERCENTAGE = 80; + + uint64 public immutable rewardBasisPoints; + + constructor(uint64 rewardBasisPoints_) { + rewardBasisPoints = rewardBasisPoints_; + } + + /** + * @notice A linear, non-compounding reward calculation that rewards a set percentage of tokens per year. + */ + function calculateReward( + uint256 stakeAmount, + uint64 validatorStartTime, + uint64 stakingStartTime, + uint64 stakingEndTime, + uint64 uptimeSeconds, + uint256, // initialSupply + uint256 // endSupply + ) external view returns (uint256) { + // Equivalent to uptimeSeconds/(validator.endedAt - validator.startedAt) < UPTIME_REWARDS_THRESHOLD_PERCENTAGE/100 + // Rearranged to prevent integer division truncation. + if ( + uptimeSeconds * 100 + < (stakingEndTime - validatorStartTime) * UPTIME_REWARDS_THRESHOLD_PERCENTAGE + ) { + return 0; + } + + return (stakeAmount * rewardBasisPoints * (stakingEndTime - stakingStartTime)) + / SECONDS_IN_YEAR / 10000; + } +} diff --git a/contracts/validator-manager/NativeTokenStakingManager.sol b/contracts/validator-manager/NativeTokenStakingManager.sol new file mode 100644 index 000000000..9209ef83f --- /dev/null +++ b/contracts/validator-manager/NativeTokenStakingManager.sol @@ -0,0 +1,95 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {INativeTokenStakingManager} from "./interfaces/INativeTokenStakingManager.sol"; +import {INativeMinter} from + "@avalabs/subnet-evm-contracts@1.2.0/contracts/interfaces/INativeMinter.sol"; +import {Address} from "@openzeppelin/contracts@5.0.2/utils/Address.sol"; +import {Initializable} from + "@openzeppelin/contracts-upgradeable@5.0.2/proxy/utils/Initializable.sol"; +import {ICMInitializable} from "../utilities/ICMInitializable.sol"; +import {PoSValidatorManager} from "./PoSValidatorManager.sol"; +import {PoSValidatorManagerSettings} from "./interfaces/IPoSValidatorManager.sol"; +import {ValidatorRegistrationInput} from "./interfaces/IValidatorManager.sol"; + +contract NativeTokenStakingManager is + Initializable, + PoSValidatorManager, + INativeTokenStakingManager +{ + using Address for address payable; + + INativeMinter public constant NATIVE_MINTER = + INativeMinter(0x0200000000000000000000000000000000000001); + + constructor(ICMInitializable init) { + if (init == ICMInitializable.Disallowed) { + _disableInitializers(); + } + } + + /** + * @notice Initialize the ERC20 token staking manager + * @dev Uses reinitializer(2) on the PoS staking contracts to make sure after migration from PoA, the PoS contracts can reinitialize with its needed values. + * @param settings Initial settings for the PoS validator manager + */ + // solhint-disable ordering + function initialize(PoSValidatorManagerSettings calldata settings) external reinitializer(2) { + __NativeTokenStakingManager_init(settings); + } + + // solhint-disable-next-line func-name-mixedcase + function __NativeTokenStakingManager_init(PoSValidatorManagerSettings calldata settings) + internal + onlyInitializing + { + __POS_Validator_Manager_init(settings); + } + + // solhint-disable-next-line func-name-mixedcase, no-empty-blocks + function __NativeTokenStakingManager_init_unchained() internal onlyInitializing {} + + /** + * @notice See {INativeTokenStakingManager-initializeValidatorRegistration}. + * Begins the validator registration process. Locks the provided native asset in the contract as the stake. + */ + function initializeValidatorRegistration( + ValidatorRegistrationInput calldata registrationInput, + uint16 delegationFeeBips, + uint64 minStakeDuration + ) external payable nonReentrant returns (bytes32) { + return _initializeValidatorRegistration( + registrationInput, delegationFeeBips, minStakeDuration, msg.value + ); + } + + /** + * @notice Begins the delegator registration process. Locks the provided native asset in the contract as the delegated stake. + * @param validationID The ID of the validation period being delegated to. + */ + function initializeDelegatorRegistration(bytes32 validationID) + external + payable + nonReentrant + returns (bytes32) + { + return _initializeDelegatorRegistration(validationID, _msgSender(), msg.value); + } + + // solhint-enable ordering + function _lock(uint256 value) internal virtual override returns (uint256) { + return value; + } + + function _unlock(address to, uint256 value) internal virtual override { + payable(to).sendValue(value); + } + + function _reward(address account, uint256 amount) internal virtual override { + NATIVE_MINTER.mintNativeCoin(account, amount); + } +} diff --git a/contracts/validator-manager/PoAValidatorManager.sol b/contracts/validator-manager/PoAValidatorManager.sol new file mode 100644 index 000000000..43d5e5aaf --- /dev/null +++ b/contracts/validator-manager/PoAValidatorManager.sol @@ -0,0 +1,61 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {IPoAValidatorManager} from "./interfaces/IPoAValidatorManager.sol"; +import {OwnableUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/access/OwnableUpgradeable.sol"; +import {ICMInitializable} from "../utilities/ICMInitializable.sol"; +import { + ValidatorManagerSettings, + ValidatorRegistrationInput +} from "./interfaces/IValidatorManager.sol"; +import {ValidatorManager} from "./ValidatorManager.sol"; + +contract PoAValidatorManager is IPoAValidatorManager, ValidatorManager, OwnableUpgradeable { + constructor(ICMInitializable init) { + if (init == ICMInitializable.Disallowed) { + _disableInitializers(); + } + } + + function initialize( + ValidatorManagerSettings calldata settings, + address initialOwner + ) external initializer { + __PoAValidatorManager_init(settings, initialOwner); + } + + // solhint-disable func-name-mixedcase, ordering + function __PoAValidatorManager_init( + ValidatorManagerSettings calldata settings, + address initialOwner + ) internal onlyInitializing { + __ValidatorManager_init(settings); + __Ownable_init(initialOwner); + } + + // solhint-disable-next-line no-empty-blocks + function __PoAValidatorManager_init_unchained() internal onlyInitializing {} + + // solhint-enable func-name-mixedcase + + function initializeValidatorRegistration( + ValidatorRegistrationInput calldata registrationInput, + uint64 weight + ) external onlyOwner returns (bytes32 validationID) { + return _initializeValidatorRegistration(registrationInput, weight); + } + + // solhint-enable ordering + function initializeEndValidation(bytes32 validationID) external override onlyOwner { + _initializeEndValidation(validationID); + } + + function completeEndValidation(uint32 messageIndex) external { + _completeEndValidation(messageIndex); + } +} diff --git a/contracts/validator-manager/PoSValidatorManager.sol b/contracts/validator-manager/PoSValidatorManager.sol new file mode 100644 index 000000000..ba51178f3 --- /dev/null +++ b/contracts/validator-manager/PoSValidatorManager.sol @@ -0,0 +1,633 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import { + IPoSValidatorManager, Delegator, DelegatorStatus +} from "./interfaces/IPoSValidatorManager.sol"; +import { + PoSValidatorManagerSettings, PoSValidatorInfo +} from "./interfaces/IPoSValidatorManager.sol"; +import {Validator} from "./interfaces/IValidatorManager.sol"; +import {ValidatorManager} from "./ValidatorManager.sol"; +import { + Validator, + ValidatorStatus, + ValidatorRegistrationInput +} from "./interfaces/IValidatorManager.sol"; +import {WarpMessage} from + "@avalabs/subnet-evm-contracts@1.2.0/contracts/interfaces/IWarpMessenger.sol"; +import {ValidatorMessages} from "./ValidatorMessages.sol"; +import {IRewardCalculator} from "./interfaces/IRewardCalculator.sol"; +import {ReentrancyGuardUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/utils/ReentrancyGuardUpgradeable.sol"; + +abstract contract PoSValidatorManager is + IPoSValidatorManager, + ValidatorManager, + ReentrancyGuardUpgradeable +{ + // solhint-disable private-vars-leading-underscore + /// @custom:storage-location erc7201:avalanche-icm.storage.PoSValidatorManager + struct PoSValidatorManagerStorage { + /// @notice The minimum amount of stake required to be a validator. + uint256 _minimumStakeAmount; + /// @notice The maximum amount of stake allowed to be a validator. + uint256 _maximumStakeAmount; + /// @notice The minimum amount of time a validator must be staked for. + uint64 _minimumStakeDuration; + /// @notice The minimum delegation fee percentage, in basis points, required to delegate to a validator. + uint16 _minimumDelegationFeeBips; + /** + * @notice A multiplier applied to validator's initial stake amount to determine + * the maximum amount of stake a validator can have with delegations. + * + * Note: Setting this value to 1 would disable delegations to validators, since + * the maximum stake would be equal to the initial stake. + */ + uint64 _maximumStakeMultiplier; + /// @notice The reward calculator for this validator manager. + IRewardCalculator _rewardCalculator; + /// @notice Maps the validation ID to its requirements. + mapping(bytes32 validationID => PoSValidatorInfo) _posValidatorInfo; + /// @notice Maps the delegation ID to the delegator information. + mapping(bytes32 delegationID => Delegator) _delegatorStakes; + /// @notice Maps the delegation ID to its pending staking rewards. + mapping(bytes32 delegationID => uint256) _redeemableDelegatorRewards; + /// @notice Maps the validation ID to its pending staking rewards. + mapping(bytes32 validationID => uint256) _redeemableValidatorRewards; + /// @notice Saves the uptime of a pending completed or completed validation period so that delegators can collect rewards. + mapping(bytes32 validationID => uint64) _completedValidationUptimeSeconds; + } + // solhint-enable private-vars-leading-underscore + + // keccak256(abi.encode(uint256(keccak256("avalanche-icm.storage.PoSValidatorManager")) - 1)) & ~bytes32(uint256(0xff)); + // TODO: Unit test for storage slot and update slot + bytes32 private constant _POS_VALIDATOR_MANAGER_STORAGE_LOCATION = + 0x4317713f7ecbdddd4bc99e95d903adedaa883b2e7c2551610bd13e2c7e473d00; + + uint8 public constant MAXIMUM_STAKE_MULTIPLIER_LIMIT = 10; + + uint16 public constant MAXIMUM_DELEGATION_FEE_BIPS = 10000; + + error InvalidDelegatorStatus(); + error InvalidNonce(); + error InvalidDelegationID(); + error ValidatorNotPoS(); + error MaxWeightExceeded(); + error InvalidDelegationFee(); + error InvalidStakeDuration(); + error InvalidStakeAmount(); + error InvalidStakeMultiplier(); + + // solhint-disable ordering + function _getPoSValidatorManagerStorage() + private + pure + returns (PoSValidatorManagerStorage storage $) + { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := _POS_VALIDATOR_MANAGER_STORAGE_LOCATION + } + } + + // solhint-disable-next-line func-name-mixedcase + function __POS_Validator_Manager_init(PoSValidatorManagerSettings calldata settings) + internal + onlyInitializing + { + __ValidatorManager_init(settings.baseSettings); + __ReentrancyGuard_init(); + __POS_Validator_Manager_init_unchained({ + minimumStakeAmount: settings.minimumStakeAmount, + maximumStakeAmount: settings.maximumStakeAmount, + minimumStakeDuration: settings.minimumStakeDuration, + minimumDelegationFeeBips: settings.minimumDelegationFeeBips, + maximumStakeMultiplier: settings.maximumStakeMultiplier, + rewardCalculator: settings.rewardCalculator + }); + } + + // solhint-disable-next-line func-name-mixedcase + function __POS_Validator_Manager_init_unchained( + uint256 minimumStakeAmount, + uint256 maximumStakeAmount, + uint64 minimumStakeDuration, + uint16 minimumDelegationFeeBips, + uint8 maximumStakeMultiplier, + IRewardCalculator rewardCalculator + ) internal onlyInitializing { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + if (minimumDelegationFeeBips == 0 || minimumDelegationFeeBips > MAXIMUM_DELEGATION_FEE_BIPS) + { + revert InvalidDelegationFee(); + } + if (minimumStakeAmount > maximumStakeAmount) { + revert InvalidStakeAmount(); + } + if (maximumStakeMultiplier == 0 || maximumStakeMultiplier > MAXIMUM_STAKE_MULTIPLIER_LIMIT) + { + revert InvalidStakeMultiplier(); + } + + $._minimumStakeAmount = minimumStakeAmount; + $._maximumStakeAmount = maximumStakeAmount; + $._minimumStakeDuration = minimumStakeDuration; + $._minimumDelegationFeeBips = minimumDelegationFeeBips; + $._maximumStakeMultiplier = maximumStakeMultiplier; + $._rewardCalculator = rewardCalculator; + } + + function claimDelegationFees(bytes32 validationID) external { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + + Validator memory validator = getValidator(validationID); + + if (validator.status != ValidatorStatus.Completed) { + revert InvalidValidatorStatus(); + } + + if ($._posValidatorInfo[validationID].owner != _msgSender()) { + revert InvalidAddress(); + } + + uint256 rewards = $._redeemableValidatorRewards[validationID]; + delete $._redeemableValidatorRewards[validationID]; + _reward($._posValidatorInfo[validationID].owner, rewards); + } + + function initializeEndValidation( + bytes32 validationID, + bool includeUptimeProof, + uint32 messageIndex + ) external { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + + Validator memory validator = _initializeEndValidation(validationID); + + // Non-PoS validators are required to boostrap the network, but are not eligible for rewards. + if (!_isPoSValidator(validationID)) { + return; + } + + // PoS validations can only be ended by their owners. + if ($._posValidatorInfo[validationID].owner != _msgSender()) { + revert InvalidAddress(); + } + + // Check that minimum stake duration has passed. + if ( + validator.endedAt + < validator.startedAt + $._posValidatorInfo[validationID].minStakeDuration + ) { + revert InvalidStakeDuration(); + } + + if (includeUptimeProof) { + // Uptime proofs include the absolute number of seconds the validator has been active. + uint64 uptimeSeconds = _getUptime(validationID, messageIndex); + // Save this value for use by this validator's delegators. + $._completedValidationUptimeSeconds[validationID] = uptimeSeconds; + + $._redeemableValidatorRewards[validationID] += $._rewardCalculator.calculateReward({ + stakeAmount: weightToValue(validator.startingWeight), + validatorStartTime: validator.startedAt, + stakingStartTime: validator.startedAt, + stakingEndTime: validator.endedAt, + uptimeSeconds: uptimeSeconds, + initialSupply: 0, + endSupply: 0 + }); + } + } + + function completeEndValidation(uint32 messageIndex) external { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + + (bytes32 validationID, Validator memory validator) = _completeEndValidation(messageIndex); + + // Return now if this was originally a PoA validator that was later migrated to this PoS manager, + // or the validator was part of the initial validator set. + if (!_isPoSValidator(validationID)) { + return; + } + + address owner = $._posValidatorInfo[validationID].owner; + // The validator can either be Completed or Invalidated here. We only grant rewards for Completed. + if (validator.status == ValidatorStatus.Completed) { + uint256 rewards = $._redeemableValidatorRewards[validationID]; + delete $._redeemableValidatorRewards[validationID]; + _reward(owner, rewards); + } + + // We unlock the stake whether the validation period is completed or invalidated. + _unlock(owner, weightToValue(validator.startingWeight)); + } + + function _getUptime(bytes32 validationID, uint32 messageIndex) internal view returns (uint64) { + (WarpMessage memory warpMessage, bool valid) = + WARP_MESSENGER.getVerifiedWarpMessage(messageIndex); + if (!valid) { + revert InvalidWarpMessage(); + } + + if (warpMessage.sourceChainID != WARP_MESSENGER.getBlockchainID()) { + revert InvalidBlockchainID(); + } + if (warpMessage.originSenderAddress != address(0)) { + revert InvalidAddress(); + } + + (bytes32 uptimeValidationID, uint64 uptime) = + ValidatorMessages.unpackValidationUptimeMessage(warpMessage.payload); + if (validationID != uptimeValidationID) { + revert InvalidValidationID(); + } + + return uptime; + } + + function _initializeValidatorRegistration( + ValidatorRegistrationInput calldata registrationInput, + uint16 delegationFeeBips, + uint64 minStakeDuration, + uint256 stakeAmount + ) internal virtual returns (bytes32) { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + // Validate and save the validator requirements + if ( + delegationFeeBips < $._minimumDelegationFeeBips + || delegationFeeBips > MAXIMUM_DELEGATION_FEE_BIPS + ) { + revert InvalidDelegationFee(); + } + + if (minStakeDuration < $._minimumStakeDuration) { + revert InvalidStakeDuration(); + } + + // Ensure the weight is within the valid range. + if (stakeAmount < $._minimumStakeAmount || stakeAmount > $._maximumStakeAmount) { + revert InvalidStakeAmount(); + } + + // Lock the stake in the contract. + uint256 lockedValue = _lock(stakeAmount); + + uint64 weight = valueToWeight(lockedValue); + bytes32 validationID = _initializeValidatorRegistration(registrationInput, weight); + + $._posValidatorInfo[validationID] = PoSValidatorInfo({ + owner: _msgSender(), + delegationFeeBips: delegationFeeBips, + minStakeDuration: minStakeDuration + }); + return validationID; + } + + function valueToWeight(uint256 value) public pure returns (uint64) { + return uint64(value / 1e12); + } + + function weightToValue(uint64 weight) public pure returns (uint256) { + return uint256(weight) * 1e12; + } + + function _lock(uint256 value) internal virtual returns (uint256); + function _unlock(address to, uint256 value) internal virtual; + + function _initializeDelegatorRegistration( + bytes32 validationID, + address delegatorAddress, + uint256 delegationAmount + ) internal returns (bytes32) { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + uint64 weight = valueToWeight(_lock(delegationAmount)); + + // Ensure the validation period is active + Validator memory validator = getValidator(validationID); + // Check that the validation ID is a PoS validator + if (!_isPoSValidator(validationID)) { + revert ValidatorNotPoS(); + } + if (validator.status != ValidatorStatus.Active) { + revert InvalidValidatorStatus(); + } + + // Update the validator weight + uint64 newValidatorWeight = validator.weight + weight; + if (newValidatorWeight > validator.startingWeight * $._maximumStakeMultiplier) { + revert MaxWeightExceeded(); + } + + (uint64 nonce, bytes32 messageID) = _setValidatorWeight(validationID, newValidatorWeight); + + bytes32 delegationID = keccak256(abi.encodePacked(validationID, nonce)); + + // Store the delegation information. Set the delegator status to pending added, + // so that it can be properly started in the complete step, even if the delivered + // nonce is greater than the nonce used to initialize registration. + $._delegatorStakes[delegationID] = Delegator({ + status: DelegatorStatus.PendingAdded, + owner: delegatorAddress, + validationID: validationID, + weight: weight, + startedAt: 0, + startingNonce: nonce, + endingNonce: 0 + }); + + emit DelegatorAdded({ + delegationID: delegationID, + validationID: validationID, + delegatorAddress: delegatorAddress, + nonce: nonce, + validatorWeight: newValidatorWeight, + delegatorWeight: weight, + setWeightMessageID: messageID + }); + return delegationID; + } + + function completeDelegatorRegistration(uint32 messageIndex, bytes32 delegationID) external { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + + Delegator memory delegator = $._delegatorStakes[delegationID]; + Validator memory validator = getValidator(delegator.validationID); + + // Ensure the delegator is pending added. Since anybody can call this function once + // delegator registration has been initialized, we need to make sure that this function is only + // callable after that has been done. + if ($._delegatorStakes[delegationID].status != DelegatorStatus.PendingAdded) { + revert InvalidDelegatorStatus(); + } + + // In the case where the validator has initiated ending its validation period, we can no + // longer stake, but the validator's weight may not have been removed from the p-chain yet, + // so we have to wait for confirmation that the validator has been removed before returning the stake. + if (validator.status == ValidatorStatus.PendingRemoved) { + delegator.status = DelegatorStatus.PendingRemoved; + delegator.startedAt = validator.endedAt; + delegator.endingNonce = validator.messageNonce; + + // Write back the delegator + $._delegatorStakes[delegationID] = delegator; + + emit DelegatorRemovalInitialized({ + delegationID: delegationID, + validationID: delegator.validationID, + endTime: validator.endedAt + }); + + return; + } + + // In the case where the validator has completed its validation period, we can no + // longer stake and should move our status directly to completed and return the stake. + if (validator.status == ValidatorStatus.Completed) { + _completeEndDelegation(delegationID); + return; + } + + // Unpack the Warp message + WarpMessage memory warpMessage = _getPChainWarpMessage(messageIndex); + (bytes32 validationID, uint64 nonce,) = + ValidatorMessages.unpackSubnetValidatorWeightUpdateMessage(warpMessage.payload); + + if (delegator.validationID != validationID) { + revert InvalidValidationID(); + } + + // The received nonce should be no greater than the highest sent nonce, and at least as high as + // the delegation's starting nonce. This allows a weight update using a higher nonce + // (which implicitly includes the delegation's weight update) to be used to complete delisting + // for an earlier delegation. This is necessary because the P-Chain is only willing to sign the latest weight update. + if ( + validator.messageNonce < nonce || $._delegatorStakes[delegationID].startingNonce > nonce + ) { + revert InvalidNonce(); + } + + // Update the delegation status + $._delegatorStakes[delegationID].status = DelegatorStatus.Active; + $._delegatorStakes[delegationID].startedAt = uint64(block.timestamp); + + emit DelegatorRegistered({ + delegationID: delegationID, + validationID: validationID, + nonce: nonce, + startTime: block.timestamp + }); + } + + function endDelegationCompletedValidator(bytes32 delegationID) external nonReentrant { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + + Delegator memory delegator = $._delegatorStakes[delegationID]; + bytes32 validationID = delegator.validationID; + Validator memory validator = getValidator(validationID); + + // Ensure the delegation is found + if (delegator.status == DelegatorStatus.Unknown) { + revert InvalidDelegationID(); + } + + // Ensure the validation is completed + if (validator.status != ValidatorStatus.Completed) { + revert InvalidValidatorStatus(); + } + + // If the validator completes before the delegator is added, let them exit from here. + if (delegator.status == DelegatorStatus.PendingAdded) { + _completeEndDelegation(delegationID); + return; + } + + // Calculate and set rewards if the delegator is active. + if (delegator.status == DelegatorStatus.Active) { + $._redeemableDelegatorRewards[delegationID] = $._rewardCalculator.calculateReward({ + stakeAmount: weightToValue(delegator.weight), + validatorStartTime: validator.startedAt, + stakingStartTime: delegator.startedAt, + stakingEndTime: validator.endedAt, + uptimeSeconds: $._completedValidationUptimeSeconds[validationID], + initialSupply: 0, + endSupply: 0 + }); + } + + _completeEndDelegation(delegationID); + } + + function initializeEndDelegation( + bytes32 delegationID, + bool includeUptimeProof, + uint32 messageIndex + ) external { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + + Delegator memory delegator = $._delegatorStakes[delegationID]; + bytes32 validationID = delegator.validationID; + Validator memory validator = getValidator(validationID); + + // Ensure the delegator is active + if (delegator.status != DelegatorStatus.Active) { + revert InvalidDelegatorStatus(); + } + // Only the delegation owner can end the delegation. + if (delegator.owner != _msgSender()) { + revert InvalidAddress(); + } + + // Set the delegator status to pending removed, so that it can be properly removed in + // the complete step, even if the delivered nonce is greater than the nonce used to + // initialize the removal. + delegator.status = DelegatorStatus.PendingRemoved; + + uint64 validatorUptimeSeconds; + uint64 delegationEndTime; + if (validator.status == ValidatorStatus.Active) { + if (includeUptimeProof) { + // Uptime proofs include the absolute number of seconds the validator has been active. + validatorUptimeSeconds = _getUptime(validationID, messageIndex); + } + uint64 newValidatorWeight = validator.weight - delegator.weight; + (delegator.endingNonce,) = _setValidatorWeight(validationID, newValidatorWeight); + + delegationEndTime = uint64(block.timestamp); + } else { + // If the validation period has already ended, we have saved the uptime. + // Further, it is impossible to retrieve an uptime proof for an already ended validation, + // so there's no need to check any uptime proof provided in this function call. + validatorUptimeSeconds = $._completedValidationUptimeSeconds[validationID]; + + delegator.endingNonce = validator.messageNonce; + delegationEndTime = validator.endedAt; + } + + $._redeemableDelegatorRewards[delegationID] = $._rewardCalculator.calculateReward({ + stakeAmount: weightToValue(delegator.weight), + validatorStartTime: validator.startedAt, + stakingStartTime: delegator.startedAt, + stakingEndTime: delegationEndTime, + uptimeSeconds: validatorUptimeSeconds, + initialSupply: 0, + endSupply: 0 + }); + + $._delegatorStakes[delegationID] = delegator; + + emit DelegatorRemovalInitialized({ + delegationID: delegationID, + validationID: validationID, + endTime: delegationEndTime + }); + } + + /** + * @dev Resending the latest validator weight with the latest nonce is safe because all weight changes are + * cumulative, so the latest weight change will always include the weight change for any added delegators. + */ + function resendUpdateDelegation(bytes32 delegationID) external { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + Delegator memory delegator = $._delegatorStakes[delegationID]; + if ( + delegator.status != DelegatorStatus.PendingAdded + && delegator.status != DelegatorStatus.PendingRemoved + ) { + revert InvalidDelegatorStatus(); + } + + Validator memory validator = getValidator(delegator.validationID); + if (validator.messageNonce == 0) { + revert InvalidDelegationID(); + } + + // Submit the message to the Warp precompile. + WARP_MESSENGER.sendWarpMessage( + ValidatorMessages.packSetSubnetValidatorWeightMessage( + delegator.validationID, validator.messageNonce, validator.weight + ) + ); + } + + function completeEndDelegation( + uint32 messageIndex, + bytes32 delegationID + ) external nonReentrant { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + Delegator memory delegator = $._delegatorStakes[delegationID]; + + // Unpack the Warp message + WarpMessage memory warpMessage = _getPChainWarpMessage(messageIndex); + (bytes32 validationID, uint64 nonce,) = + ValidatorMessages.unpackSubnetValidatorWeightUpdateMessage(warpMessage.payload); + + if (delegator.validationID != validationID) { + revert InvalidValidationID(); + } + + // The received nonce should be at least as high as the delegation's ending nonce. This allows a weight + // update using a higher nonce (which implicitly includes the delegation's weight update) to be used to + // complete delisting for an earlier delegation. This is necessary because the P-Chain is only willing + // to sign the latest weight update. + if (delegator.endingNonce > nonce) { + revert InvalidNonce(); + } + + // Ensure the delegator is pending removed. Since anybody can call this function once + // end delegation has been initialized, we need to make sure that this function is only + // callable after that has been done. + if (delegator.status != DelegatorStatus.PendingRemoved) { + revert InvalidDelegatorStatus(); + } + + _completeEndDelegation(delegationID); + } + + function _completeEndDelegation(bytes32 delegationID) internal { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + + Delegator memory delegator = $._delegatorStakes[delegationID]; + bytes32 validationID = delegator.validationID; + + // Once this function completes, the delegation is completed so we can clear it from state now. + delete $._delegatorStakes[delegationID]; + + uint256 rewards = $._redeemableDelegatorRewards[delegationID]; + delete $._redeemableDelegatorRewards[delegationID]; + + uint256 validatorFees = + rewards * $._posValidatorInfo[validationID].delegationFeeBips / 10000; + + // Allocate the delegation fees to the validator. + $._redeemableValidatorRewards[validationID] += validatorFees; + + // Reward the remaining tokens to the delegator. + uint256 delegatorRewards = rewards - validatorFees; + _reward(delegator.owner, delegatorRewards); + + // Unlock the delegator's stake. + _unlock(delegator.owner, weightToValue(delegator.weight)); + + emit DelegationEnded(delegationID, validationID, delegatorRewards, validatorFees); + } + + /** + * @dev This function must be implemented to mint rewards to validators and delegators. + */ + function _reward(address account, uint256 amount) internal virtual; + + /** + * @dev Return true if this is a PoS validator with locked stake. Returns false if this was originally a PoA + * validator that was later migrated to this PoS manager, or the validator was part of the initial validator set. + */ + function _isPoSValidator(bytes32 validationID) internal view returns (bool) { + PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); + return $._posValidatorInfo[validationID].owner != address(0); + } +} diff --git a/contracts/validator-manager/README.md b/contracts/validator-manager/README.md new file mode 100644 index 000000000..22ada1f53 --- /dev/null +++ b/contracts/validator-manager/README.md @@ -0,0 +1,154 @@ +# Validator Manager Contract + +`ValidatorManager.sol` defines the abstract staking contract used to manage subnet-only validators, as defined in [ACP-77](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets). + +_Disclaimer:_ The contracts in this directory are still under active development, are unaudited, and should not be used in production. + +## Usage + +The common case for adding or removing a validator from a Subnet's validator set follows these general steps: + +1. Initiate the change through the Validator Manager contract. The Validator Manager contract will construct a Warp message attesting to the change in the validator set. +2. Deliver the Warp message containing the validator set change to the P-Chain. The P-Chain will construct a Warp message acknowledging the change to the validator set. +3. Deliver the Warp message containing the P-Chain acknowledgement back to the Validator Manager contract on the Subnet. The Validator Manager contract finalizes the validator set change. + +### Initializing a Validator Set + +If the Subnet has no validators registered on the P-Chain, then it will not be able to sign a Warp message to add a validator (step 1 above). In this case, Subnet recovery must be performed on the P-Chain, which allows an initial validator set to be specified, along with each validator's expiry. These validators are *not* registered with the Subnet's Validator Manager, and are only used to bootstrap subnet consensus and Warp message signing. The following steps describe how to register validators with the Subnet's Validator Manager, after which the initial validator set specified during Subnet recovery may safely exit the validator set or expire. + +### Registering a Validator + +Validator registration is initiated with a call to `initializeValidatorRegistration` on the concrete Validator Manager contract. The Validator Manager contract constructs a [`RegisterSubnetValidatorMessage`](#registersubnetvalidatormessage) Warp message to be sent to the P-Chain. Each validator registration request includes all of the information needed to identify the validator and its stake weight, as well as an `expiry` timestamp before which the `RegisterSubnetValidatorMessage` must be delivered to the P-Chain. + +The `RegisterSubnetValidatorMessage` is delivered to the P-Chain as the Warp message payload of a [`RegisterSubnetValidatorTx`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#registersubnetvalidatortx). Please see the transaction [specification](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#step-2-issue-a-registersubnetvalidatortx-on-the-p-chain) for validity requirements. The successful `RegisterSubnetValidatorTx` results in a [`SubnetValidatorRegistrationMessage`](#subnetvalidatorregistrationmessage) Warp message indicating that the specified validator was successfully registered on the P-Chain. + +The `SubnetValidatorRegistrationMessage` is delivered to the Validator Manager contract via a call to `completeValidatorRegistration`. For PoS Validator Managers, staking rewards begin accruing at this time. + +#### Handling a Missed Expiry + +In the case of a missed expiry, the `RegisterSubnetValidatorTx` will result in a `SubnetValidatorRegistrationMessage` Warp message with `valid=0`. This serves as proof that the corresponding validation has not started and may never start. The `SubnetValidatorRegistrationMessage` can be provided to the Validator Manager contract by calling `completeEndValidation` with `setWeightMessageType=false`. + +### Exiting the Validator Set + +Validator exit is initiated with a call to `initializeEndValidation` on the Validator Manager contract. For PoS Validator Managers, a [`ValidationUptimeMessage`](#validationuptimemessage) Warp message may optionally be provided in order to calculate the staking rewards; otherwise the validator's uptime will be set to `0`. This proof may be requested directly from the Subnet validators, which will provide it in a `ValidationUptimeMessage` Warp message. Once `initializeEndValidation` is called, staking rewards cease accruing for PoS Validator Managers: the Validator Manager contract constructs a [`SetSubnetValidatorWeightMessage`](#setsubnetvalidatorweightmessage) Warp message, setting the weight to `0`. + +The `SetSubnetValidatorWeightMessage` is delivered to the P-Chain as the payload of a [`SetSubnetValidatorWeightTx`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#setsubnetvalidatorweighttx). The P-Chain acknowledges validator exit by signing a `SubnetValidatorRegistrationMessage` with `valid=0`, which is delivered to the Validator Manager by calling `completeEndValidation`. The validation is removed from the contract's state, and for PoS Validator Managers, staking rewards are disbursed and stake is returned. + +#### Disable a Validator Directly on the P-Chain + +ACP-77 also provides a method to disable a validator without interacting with the Subnet directly. The P-Chain transaction [`DisableValidatorTx`](https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/77-reinventing-subnets#disablevalidatortx) disables the validator on the P-Chain. The disabled validator's weight will still count towards the Subnet's total weight. + +Disabled Subnet validators can re-activate at any time by increasing their balance with an `IncreaseBalanceTx`. Anyone can call `IncreaseBalanceTx` for any validator on the P-Chain. A disabled validator can only be totally removed from the validator set by a call to `initializeEndValidation`. + +## Warp Message Format Reference + +### `RegisterSubnetValidatorMessage` + +Description: Issued by the Validator Manager contract in order to register a Subnet validator + +Signed by: Subnet +Consumed by: P-Chain + +Specification: + +``` ++--------------+----------+-----------+ +| codecID : uint16 | 2 bytes | ++--------------+----------+-----------+ +| typeID : uint32 | 4 bytes | ++--------------+----------+-----------+ +| subnetID : [32]byte | 32 bytes | ++--------------+----------+-----------+ +| nodeID : [32]byte | 32 bytes | ++--------------+----------+-----------+ +| weight : uint64 | 8 bytes | ++--------------+----------+-----------+ +| blsPublicKey : [48]byte | 48 bytes | ++--------------+----------+-----------+ +| expiry : uint64 | 8 bytes | ++--------------+----------+-----------+ + | 134 bytes | + +-----------+ + +``` + +### `SubnetValidatorRegistrationMessage` + +Description: Issued by the P-Chain in order to confirm Subnet validator registration + +Signed by: P-Chain +Consumed by: Validator Manager contract + +Specification: + +``` ++--------------+----------+----------+ +| codecID : uint16 | 2 bytes | ++--------------+----------+----------+ +| typeID : uint32 | 4 bytes | ++--------------+----------+----------+ +| validationID : [32]byte | 32 bytes | ++--------------+----------+----------+ +| valid : bool | 1 byte | ++--------------+----------+----------+ + | 39 bytes | + +----------+ +``` + +### `ValidationUptimeMessage` + +Description: Issued by the Subnet in order to provide validator uptime to the Subnet to calculate staking rewards + +Signed by: Subnet +Consumed by: Validator Manager contract + +Specification: + +``` ++--------------+----------+----------+ +| codecID : uint16 | 2 bytes | ++--------------+----------+----------+ +| typeID : uint32 | 4 bytes | ++--------------+----------+----------+ +| validationID : [32]byte | 32 bytes | ++--------------+----------+----------+ +| uptime : uint64 | 8 bytes | ++--------------+----------+----------+ + | 46 bytes | + +----------+ +``` + +### `SetSubnetValidatorWeightMessage` + +Description: Used to set a validator's stake weight on another chain + +Signed by: Subnet +Consumed by: P-Chain + +Specification: + +``` ++--------------+----------+----------+ +| codecID : uint16 | 2 bytes | ++--------------+----------+----------+ +| typeID : uint32 | 4 bytes | ++--------------+----------+----------+ +| validationID : [32]byte | 32 bytes | ++--------------+----------+----------+ +| nonce : uint64 | 8 bytes | ++--------------+----------+----------+ +| weight : uint64 | 8 bytes | ++--------------+----------+----------+ + | 54 bytes | + +----------+ +``` + +## Types of Validator Managers + +### Proof of Authority + +The Proof of Authority (PoA) validator manager is ownable, and only allows the owner to modify changes to the validator set of the Subnet. Validators are given a weight by the owner, but do not accrue staking rewards. + +### Proof of Stake + +The Proof of Stake (PoS) validator manager allows any validator to register and exit the Subnet validator set. Validators are given a weight based on the amount of stake they provide, and accrue staking rewards based on their uptime. The staking rewards can be either native or erc20 tokens. diff --git a/contracts/validator-manager/ValidatorManager.sol b/contracts/validator-manager/ValidatorManager.sol new file mode 100644 index 000000000..d480697bf --- /dev/null +++ b/contracts/validator-manager/ValidatorManager.sol @@ -0,0 +1,544 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import { + IValidatorManager, + ValidatorManagerSettings, + ValidatorChurnPeriod, + ValidatorStatus, + Validator, + ValidatorChurnPeriod, + ValidatorWeightUpdate, + SubnetConversionData, + InitialValidator, + ValidatorRegistrationInput +} from "./interfaces/IValidatorManager.sol"; +import { + WarpMessage, + IWarpMessenger +} from "@avalabs/subnet-evm-contracts@1.2.0/contracts/interfaces/IWarpMessenger.sol"; +import {ValidatorMessages} from "./ValidatorMessages.sol"; +import {ContextUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/utils/ContextUpgradeable.sol"; +import {Initializable} from + "@openzeppelin/contracts-upgradeable@5.0.2/proxy/utils/Initializable.sol"; + +abstract contract ValidatorManager is Initializable, ContextUpgradeable, IValidatorManager { + // solhint-disable private-vars-leading-underscore + /// @custom:storage-location erc7201:avalanche-icm.storage.ValidatorManager + + struct ValidatorManagerStorage { + /// @notice The subnetID associated with this validator manager. + bytes32 _subnetID; + /// @notice The number of seconds after which to reset the churn tracker. + uint64 _churnPeriodSeconds; + /// @notice The maximum churn rate allowed per churn period. + uint8 _maximumChurnPercentage; + /// @notice The churn tracker used to track the amount of stake added or removed in the churn period. + ValidatorChurnPeriod _churnTracker; + /// @notice Maps the validationID to the registration message such that the message can be re-sent if needed. + mapping(bytes32 => bytes) _pendingRegisterValidationMessages; + /// @notice Maps the validationID to the validator information. + mapping(bytes32 => Validator) _validationPeriods; + /// @notice Maps the nodeID to the validationID for validation periods that have not ended. + mapping(bytes32 => bytes32) _registeredValidators; + /// @notice Boolean that indicates if the initial validator set has been set. + bool _initializedValidatorSet; + } + // solhint-enable private-vars-leading-underscore + + // keccak256(abi.encode(uint256(keccak256("avalanche-icm.storage.ValidatorManager")) - 1)) & ~bytes32(uint256(0xff)); + // TODO: Unit test for storage slot and update slot + bytes32 private constant _VALIDATOR_MANAGER_STORAGE_LOCATION = + 0xe92546d698950ddd38910d2e15ed1d923cd0a7b3dde9e2a6a3f380565559cb00; + + uint8 public constant MAXIMUM_CHURN_PERCENTAGE_LIMIT = 20; + uint64 public constant MAXIMUM_REGISTRATION_EXPIRY_LENGTH = 2 days; + uint32 public constant ADDRESS_LENGTH = 20; // This is only used as a packed uint32 + uint8 public constant BLS_PUBLIC_KEY_LENGTH = 48; + bytes32 public constant P_CHAIN_BLOCKCHAIN_ID = bytes32(0); + + error MaxChurnRateExceeded(); + error InvalidWarpMessage(); + error InvalidBlockchainID(); + error InvalidAddress(); + error UnexpectedRegistrationStatus(); + error InvalidValidatorStatus(); + error InvalidValidationID(); + error NodeAlreadyRegistered(); + error InvalidSubnetConversionID(); + error InvalidInput(); + error InvalidExpiry(); + error InvalidInitializationStatus(); + + // solhint-disable ordering + function _getValidatorManagerStorage() + private + pure + returns (ValidatorManagerStorage storage $) + { + // solhint-disable-next-line no-inline-assembly + assembly { + $.slot := _VALIDATOR_MANAGER_STORAGE_LOCATION + } + } + + /** + * @notice Warp precompile used for sending and receiving Warp messages. + */ + IWarpMessenger public constant WARP_MESSENGER = + IWarpMessenger(0x0200000000000000000000000000000000000005); + + // solhint-disable-next-line func-name-mixedcase + function __ValidatorManager_init(ValidatorManagerSettings calldata settings) + internal + onlyInitializing + { + __Context_init(); + __ValidatorManager_init_unchained(settings); + } + + // solhint-disable-next-line func-name-mixedcase + function __ValidatorManager_init_unchained(ValidatorManagerSettings calldata settings) + internal + onlyInitializing + { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + $._subnetID = settings.subnetID; + + if ( + settings.maximumChurnPercentage > MAXIMUM_CHURN_PERCENTAGE_LIMIT + || settings.maximumChurnPercentage == 0 + ) { + revert InvalidInput(); + } + + $._maximumChurnPercentage = settings.maximumChurnPercentage; + $._churnPeriodSeconds = settings.churnPeriodSeconds; + } + + modifier initializedValidatorSet() { + if (!_getValidatorManagerStorage()._initializedValidatorSet) { + revert InvalidInitializationStatus(); + } + _; + } + + /** + * @notice See {IValidatorManager-initializeValidatorSet}. + */ + function initializeValidatorSet( + SubnetConversionData calldata subnetConversionData, + uint32 messageIndex + ) external { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + if ($._initializedValidatorSet) { + revert InvalidInitializationStatus(); + } + // Check that the blockchainID and validator manager address in the subnetConversionData correspond to this contract. + // Other validation checks are done by the P-Chain when converting the subnet, so are not required here. + if (subnetConversionData.validatorManagerBlockchainID != WARP_MESSENGER.getBlockchainID()) { + revert InvalidBlockchainID(); + } + if (address(subnetConversionData.validatorManagerAddress) != address(this)) { + revert InvalidAddress(); + } + + uint256 numInitialValidators = subnetConversionData.initialValidators.length; + + uint256 totalWeight; + for (uint32 i; i < numInitialValidators; ++i) { + InitialValidator memory initialValidator = subnetConversionData.initialValidators[i]; + bytes32 nodeID = initialValidator.nodeID; + + if ($._registeredValidators[nodeID] != bytes32(0)) { + revert NodeAlreadyRegistered(); + } + + // Validation ID of the initial validators is the sha256 hash of the + // convert Subnet tx ID and the index of the initial validator. + bytes32 validationID = + sha256(abi.encodePacked(subnetConversionData.convertSubnetTxID, i)); + + // Save the initial validator as an active validator. + + $._registeredValidators[nodeID] = validationID; + $._validationPeriods[validationID] = Validator({ + status: ValidatorStatus.Active, + nodeID: initialValidator.nodeID, + startingWeight: initialValidator.weight, + messageNonce: 0, + weight: initialValidator.weight, + startedAt: uint64(block.timestamp), + endedAt: 0 + }); + totalWeight += initialValidator.weight; + + emit InitialValidatorCreated( + validationID, initialValidator.nodeID, initialValidator.weight + ); + } + $._churnTracker.totalWeight = totalWeight; + + // Verify that the sha256 hash of the Subnet conversion data matches with the Warp message's subnetConversionID. + WarpMessage memory warpMessage = _getPChainWarpMessage(messageIndex); + // Parse the Warp message into SubnetConversionMessage + bytes32 subnetConversionID = + ValidatorMessages.unpackSubnetConversionMessage(warpMessage.payload); + bytes memory encodedConversion = + ValidatorMessages.packSubnetConversionData(subnetConversionData); + if (sha256(encodedConversion) != subnetConversionID) { + revert InvalidSubnetConversionID(); + } + + $._initializedValidatorSet = true; + } + + /** + * @notice Begins the validator registration process, and sets the initial weight for the validator. + * This is the only method related to validator registration and removal that needs the initializedValidatorSet + * modifier. All others are guarded by checking the validator status changes initialized in this function. + * @param input The inputs for a validator registration. + * @param weight The weight of the validator being registered. + */ + function _initializeValidatorRegistration( + ValidatorRegistrationInput calldata input, + uint64 weight + ) internal virtual initializedValidatorSet returns (bytes32) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + + if ( + input.registrationExpiry <= block.timestamp + || input.registrationExpiry >= block.timestamp + MAXIMUM_REGISTRATION_EXPIRY_LENGTH + ) { + revert InvalidExpiry(); + } + + // Ensure the nodeID is not the zero address, and is not already an active validator. + + if (input.blsPublicKey.length != BLS_PUBLIC_KEY_LENGTH || input.nodeID == bytes32(0)) { + revert InvalidInput(); + } + if ($._registeredValidators[input.nodeID] != bytes32(0)) { + revert NodeAlreadyRegistered(); + } + + // Check that adding this validator would not exceed the maximum churn rate. + _checkAndUpdateChurnTracker(weight, 0); + + (bytes32 validationID, bytes memory registerSubnetValidatorMessage) = ValidatorMessages + .packRegisterSubnetValidatorMessage( + ValidatorMessages.ValidationPeriod({ + subnetID: $._subnetID, + nodeID: input.nodeID, + weight: weight, + blsPublicKey: input.blsPublicKey, + registrationExpiry: input.registrationExpiry + }) + ); + $._pendingRegisterValidationMessages[validationID] = registerSubnetValidatorMessage; + $._registeredValidators[input.nodeID] = validationID; + + // Submit the message to the Warp precompile. + bytes32 messageID = WARP_MESSENGER.sendWarpMessage(registerSubnetValidatorMessage); + $._validationPeriods[validationID] = Validator({ + status: ValidatorStatus.PendingAdded, + nodeID: input.nodeID, + startingWeight: weight, + messageNonce: 0, + weight: weight, + startedAt: 0, // The validation period only starts once the registration is acknowledged. + endedAt: 0 + }); + + emit ValidationPeriodCreated( + validationID, input.nodeID, messageID, weight, input.registrationExpiry + ); + + return validationID; + } + + /** + * @notice Resubmits a validator registration message to be sent to P-Chain to the Warp precompile. + * Only necessary if the original message can't be delivered due to validator churn. + */ + function resendRegisterValidatorMessage(bytes32 validationID) external { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + // The initial validator set must have been set already to have pending register validation messages. + if ($._pendingRegisterValidationMessages[validationID].length == 0) { + revert InvalidValidationID(); + } + if ($._validationPeriods[validationID].status != ValidatorStatus.PendingAdded) { + revert InvalidValidatorStatus(); + } + + // Submit the message to the Warp precompile. + WARP_MESSENGER.sendWarpMessage($._pendingRegisterValidationMessages[validationID]); + } + + /** + * @notice Completes the validator registration process by returning an acknowledgement of the registration of a + * validationID from the P-Chain. + * @param messageIndex The index of the Warp message to be received providing the acknowledgement. + */ + function completeValidatorRegistration(uint32 messageIndex) external { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + WarpMessage memory warpMessage = _getPChainWarpMessage(messageIndex); + (bytes32 validationID, bool validRegistration) = + ValidatorMessages.unpackSubnetValidatorRegistrationMessage(warpMessage.payload); + + if (!validRegistration) { + revert UnexpectedRegistrationStatus(); + } + // The initial validator set must have been set already to have pending register validation messages. + if ($._pendingRegisterValidationMessages[validationID].length == 0) { + revert InvalidValidationID(); + } + if ($._validationPeriods[validationID].status != ValidatorStatus.PendingAdded) { + revert InvalidValidatorStatus(); + } + + delete $._pendingRegisterValidationMessages[validationID]; + $._validationPeriods[validationID].status = ValidatorStatus.Active; + $._validationPeriods[validationID].startedAt = uint64(block.timestamp); + emit ValidationPeriodRegistered( + validationID, $._validationPeriods[validationID].weight, block.timestamp + ); + } + + function registeredValidators(bytes32 nodeID) public view returns (bytes32) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + return $._registeredValidators[nodeID]; + } + + function getValidator(bytes32 validationID) public view returns (Validator memory) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + return $._validationPeriods[validationID]; + } + + /** + * @notice Begins the process of ending an active validation period. The validation period must have been previously + * started by a successful call to {completeValidatorRegistration} with the given validationID. + * Any rewards for this validation period will stop accruing when this function is called. + * @param validationID The ID of the validation being ended. + */ + function _initializeEndValidation(bytes32 validationID) + internal + virtual + returns (Validator memory) + { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + + // Ensure the validation period is active. + // The initial validator set must have been set already to have active validators. + Validator memory validator = $._validationPeriods[validationID]; + if (validator.status != ValidatorStatus.Active) { + revert InvalidValidatorStatus(); + } + + // Update the validator status to pending removal. + // They are not removed from the active validators mapping until the P-Chain acknowledges the removal. + validator.status = ValidatorStatus.PendingRemoved; + + // Set the end time of the validation period, since it is no longer known to be an active validator + // on the P-Chain. + validator.endedAt = uint64(block.timestamp); + + // Save the validator updates. + // TODO: Optimize storage writes here (probably don't need to write the whole value). + $._validationPeriods[validationID] = validator; + + (, bytes32 messageID) = _setValidatorWeight(validationID, 0); + + // Emit the event to signal the start of the validator removal process. + emit ValidatorRemovalInitialized(validationID, messageID, validator.weight, block.timestamp); + + return validator; + } + + /** + * @notice Resubmits a validator end message to be sent to P-Chain to the Warp precompile. + * Only necessary if the original message can't be delivered due to validator churn. + */ + // solhint-disable-next-line + function resendEndValidatorMessage(bytes32 validationID) external { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + Validator memory validator = $._validationPeriods[validationID]; + + // The initial validator set must have been set already to have pending end validation messages. + if (validator.status != ValidatorStatus.PendingRemoved) { + revert InvalidValidatorStatus(); + } + + WARP_MESSENGER.sendWarpMessage( + ValidatorMessages.packSetSubnetValidatorWeightMessage( + validationID, validator.messageNonce, 0 + ) + ); + } + + /** + * @notice Completes the process of ending a validation period by receiving an acknowledgement from the P-Chain + * that the validation ID is not active and will never be active in the future. + * Note that this function can be used for successful validation periods that have been explicitly + * ended by calling {initializeEndValidation} or for validation periods that never began on the P-Chain due to the + * {registrationExpiry} being reached. + * @return The Validator instance representing the completed validation period and the corresponding validation ID. + */ + function _completeEndValidation(uint32 messageIndex) + internal + returns (bytes32, Validator memory) + { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + + // Get the Warp message. + WarpMessage memory warpMessage = _getPChainWarpMessage(messageIndex); + + (bytes32 validationID, bool validRegistration) = + ValidatorMessages.unpackSubnetValidatorRegistrationMessage(warpMessage.payload); + if (validRegistration) { + revert UnexpectedRegistrationStatus(); + } + + Validator memory validator = $._validationPeriods[validationID]; + + // The validation status is PendingRemoved if validator removal was initiated with a call to {initiateEndValidation}. + // The validation status is PendingAdded if the validator was never registered on the P-Chain. + // The initial validator set must have been set already to have pending validation messages. + if ( + validator.status != ValidatorStatus.PendingRemoved + && validator.status != ValidatorStatus.PendingAdded + ) { + revert InvalidValidatorStatus(); + } + + if (validator.status == ValidatorStatus.PendingRemoved) { + validator.status = ValidatorStatus.Completed; + } else { + validator.status = ValidatorStatus.Invalidated; + } + // Remove the validator from the registered validators mapping. + delete $._registeredValidators[validator.nodeID]; + + // Update the validator. + $._validationPeriods[validationID] = validator; + + // Emit event. + emit ValidationPeriodEnded(validationID, validator.status); + + return (validationID, validator); + } + + /** + * @notice Returns the validator's weight. This weight is not guaranteed to be known by the P-Chain + * @return The weight of the validator. If the validation ID does not exist, the weight will be 0. + */ + function getWeight(bytes32 validationID) external view returns (uint64) { + return getValidator(validationID).weight; + } + + function _incrementAndGetNonce(bytes32 validationID) internal returns (uint64) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + return ++$._validationPeriods[validationID].messageNonce; + } + + function _getPChainWarpMessage(uint32 messageIndex) + internal + view + returns (WarpMessage memory) + { + (WarpMessage memory warpMessage, bool valid) = + WARP_MESSENGER.getVerifiedWarpMessage(messageIndex); + if (!valid) { + revert InvalidWarpMessage(); + } + // Must match to P-Chain blockchain id, which is 0. + if (warpMessage.sourceChainID != P_CHAIN_BLOCKCHAIN_ID) { + revert InvalidBlockchainID(); + } + if (warpMessage.originSenderAddress != address(0)) { + revert InvalidAddress(); + } + + return warpMessage; + } + + function _setValidatorWeight( + bytes32 validationID, + uint64 newWeight + ) internal returns (uint64, bytes32) { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + uint64 validatorWeight = $._validationPeriods[validationID].weight; + + // Check that changing the validator weight would not exceed the maximum churn rate. + _checkAndUpdateChurnTracker(newWeight, validatorWeight); + + uint64 nonce = _incrementAndGetNonce(validationID); + + $._validationPeriods[validationID].weight = newWeight; + + // Submit the message to the Warp precompile. + bytes32 messageID = WARP_MESSENGER.sendWarpMessage( + ValidatorMessages.packSetSubnetValidatorWeightMessage(validationID, nonce, newWeight) + ); + + emit ValidatorWeightUpdate({ + validationID: validationID, + nonce: nonce, + validatorWeight: newWeight, + setWeightMessageID: messageID + }); + + return (nonce, messageID); + } + + /** + * @dev Helper function to check if the stake weight to be added or removed would exceed the maximum stake churn + * rate for the past churn period. If the churn rate is exceeded, the function will revert. If the churn rate is + * not exceeded, the function will update the churn tracker with the new weight. + */ + function _checkAndUpdateChurnTracker( + uint64 newValidatorWeight, + uint64 oldValidatorWeight + ) private { + ValidatorManagerStorage storage $ = _getValidatorManagerStorage(); + + uint64 weightChange; + if (newValidatorWeight > oldValidatorWeight) { + weightChange = newValidatorWeight - oldValidatorWeight; + } else { + weightChange = oldValidatorWeight - newValidatorWeight; + } + + uint256 currentTime = block.timestamp; + ValidatorChurnPeriod memory churnTracker = $._churnTracker; + + if ( + churnTracker.startedAt == 0 + || currentTime >= churnTracker.startedAt + $._churnPeriodSeconds + ) { + churnTracker.churnAmount = weightChange; + churnTracker.startedAt = currentTime; + churnTracker.initialWeight = churnTracker.totalWeight; + } else { + // Churn is always additive whether the weight is being added or removed. + churnTracker.churnAmount += weightChange; + } + + // Rearranged equation of maximumChurnPercentage >= currentChurnPercentage to avoid integer division truncation. + if ($._maximumChurnPercentage * churnTracker.initialWeight < churnTracker.churnAmount * 100) + { + revert MaxChurnRateExceeded(); + } + + // Two separate calculations because we're using uints and (newValidatorWeight - oldValidatorWeight) could underflow. + churnTracker.totalWeight += newValidatorWeight; + churnTracker.totalWeight -= oldValidatorWeight; + + $._churnTracker = churnTracker; + } +} diff --git a/contracts/validator-manager/ValidatorMessages.sol b/contracts/validator-manager/ValidatorMessages.sol new file mode 100644 index 000000000..a59981932 --- /dev/null +++ b/contracts/validator-manager/ValidatorMessages.sol @@ -0,0 +1,633 @@ +// (c) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem +pragma solidity 0.8.25; + +import {SubnetConversionData} from "./interfaces/IValidatorManager.sol"; + +library ValidatorMessages { + // The information that uniquely identifies a subnet validation period. + // The validationID is the SHA-256 hash of the concatenation of the CODEC_ID, + // REGISTER_SUBNET_VALIDATOR_MESSAGE_TYPE_ID, and the concatenated ValidationPeriod fields. + struct ValidationPeriod { + bytes32 subnetID; + bytes32 nodeID; + uint64 weight; + uint64 registrationExpiry; + bytes blsPublicKey; + } + + // The P-Chain uses a hardcoded codecID of 0 for all messages. + uint16 internal constant CODEC_ID = 0; + + // The P-Chain signs a SubnetConversion message that is used to verify the Subnet's initial validators. + uint32 internal constant SUBNET_CONVERSION_MESSAGE_TYPE_ID = 0; + + // Subnets send a RegisterSubnetValidator message to the P-Chain to register a validator. + uint32 internal constant REGISTER_SUBNET_VALIDATOR_MESSAGE_TYPE_ID = 1; + + // Subnets can send a SetSubnetValidatorWeight message to the P-Chain to update a validator's weight. + // The P-Chain responds with a SetSubnetValidatorWeight message acknowledging the weight update. + uint32 internal constant SET_SUBNET_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID = 2; + + // The P-Chain responds with a RegisterSubnetValidator message indicating whether the registration was successful + // for the given validation ID. + uint32 internal constant SUBNET_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID = 3; + + // The P-Chain responds with a SubnetValidatorWeightUpdateMessage message indicating whether the weight update was successful + // for the given validation ID. + uint32 internal constant SUBNET_VALIDATOR_WEIGHT_UPDATE_MESSAGE_TYPE_ID = 4; + + // The Subnet will self-sign a ValidationUptimeMessage to be provided when a validator is initiating + // the end of their validation period. + uint32 internal constant VALIDATION_UPTIME_MESSAGE_TYPE_ID = 5; + + error InvalidMessageLength(); + error InvalidCodecID(); + error InvalidMessageType(); + error InvalidSignatureLength(); + + /** + * @notice Packs a SubnetConversionMessage message into a byte array. + * The message format specification is: + * +--------------------+----------+----------+ + * | codecID : uint16 | 2 bytes | + * +--------------------+----------+----------+ + * | typeID : uint32 | 4 bytes | + * +--------------------+----------+----------+ + * | subnetConversionID : [32]byte | 32 bytes | + * +--------------------+----------+----------+ + * | 38 bytes | + * +----------+ + * + * @param subnetConversionID The subnet conversion ID to pack into the message. + * @return The packed message. + */ + function packSubnetConversionMessage(bytes32 subnetConversionID) + internal + pure + returns (bytes memory) + { + return abi.encodePacked(CODEC_ID, SUBNET_CONVERSION_MESSAGE_TYPE_ID, subnetConversionID); + } + + /** + * @notice Unpacks a byte array as a SubnetConversionMessage message. + * The message format specification is the same as the one used in above for packing. + * + * @param input The byte array to unpack. + * @return the unpacked subnetConversionID. + */ + function unpackSubnetConversionMessage(bytes memory input) internal pure returns (bytes32) { + if (input.length != 38) { + revert InvalidMessageLength(); + } + + // Unpack the codec ID + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + if (codecID != CODEC_ID) { + revert InvalidCodecID(); + } + + // Unpack the type ID + uint32 typeID; + for (uint256 i; i < 4; ++i) { + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); + } + if (typeID != SUBNET_CONVERSION_MESSAGE_TYPE_ID) { + revert InvalidMessageType(); + } + + // Unpack the subnetConversionID + bytes32 subnetConversionID; + for (uint256 i; i < 32; ++i) { + subnetConversionID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); + } + + return subnetConversionID; + } + + /** + * @notice Packs SubnetConversionData into a byte array. + * This byte array is the SHA256 pre-image of the subnetConversionID hash + * The message format specification is: + * + * +-------------------+---------------+---------------------------------------------------------+ + * | convertSubnetTxID : [32]byte | 32 bytes | + * +-------------------+-----------------+-------------------------------------------------------+ + * | managerChainID : [32]byte | 32 bytes | + * +-------------------+-----------------+-------------------------------------------------------+ + * | managerAddress : []byte | 4 + len(managerAddress) bytes | + * +-------------------+-----------------+-------------------------------------------------------+ + * | validators : []ValidatorData | 4 + len(validators) * 88 bytes | + * +-------------------+-----------------+-------------------------------------------------------+ + * | 72 + len(managerAddress) + len(validators) * 88 bytes | + * +-------------------------------------------------------+ + * And ValidatorData: + * +--------------+----------+-----------+ + * | nodeID : [32]byte | 32 bytes | + * +--------------+----------+-----------+ + * | weight : uint64 | 8 bytes | + * +--------------+----------+-----------+ + * | blsPublicKey : [48]byte | 48 bytes | + * +--------------+----------+-----------+ + * | 88 bytes | + * +-----------+ + * + * @param subnetConversionData The struct representing data to pack into the message. + * @return The packed message. + */ + function packSubnetConversionData(SubnetConversionData calldata subnetConversionData) + internal + pure + returns (bytes memory) + { + // The formula for the length in the comment above is VM agnostic, but in EVM + // the address length is always 20 bytes so the constant term is 72 + 20 = 92. + bytes memory res = new bytes(92 + subnetConversionData.initialValidators.length * 88); + // Pack the convertSubnetTx ID + for (uint256 i; i < 32; ++i) { + res[i] = subnetConversionData.convertSubnetTxID[i]; + } + // Pack the validatorManagerBlockchainID + for (uint256 i; i < 32; ++i) { + res[i + 32] = subnetConversionData.validatorManagerBlockchainID[i]; + } + // Pack the ADDRESS_LENGTH + for (uint256 i; i < 4; ++i) { + res[i + 64] = bytes1(uint8(20 >> (8 * (3 - i)))); + } + // Pack the address + bytes20 addrBytes = bytes20(subnetConversionData.validatorManagerAddress); + for (uint256 i = 0; i < 20; ++i) { + res[i + 68] = addrBytes[i]; + } + + // Pack the initial validators length + uint32 ivLength = uint32(subnetConversionData.initialValidators.length); + for (uint256 i; i < 4; ++i) { + res[i + 88] = bytes1(uint8(ivLength >> (8 * (3 - i)))); + } + + for (uint256 i = 0; i < subnetConversionData.initialValidators.length; i++) { + uint256 offset = 92 + i * 88; + // Pack the nodeID + for (uint256 j; j < 32; ++j) { + res[offset + j] = subnetConversionData.initialValidators[i].nodeID[j]; + } + // Pack the weight + for (uint256 j; j < 8; ++j) { + res[offset + 32 + j] = + bytes1(uint8(subnetConversionData.initialValidators[i].weight >> (8 * (7 - j)))); + } + // Pack the blsPublicKey + for (uint256 j; j < 48; ++j) { + res[offset + 40 + j] = subnetConversionData.initialValidators[i].blsPublicKey[j]; + } + } + return res; + } + + /** + * @notice Packs a RegisterSubnetValidatorMessage message into a byte array. + * The message format specification is: + * +--------------+----------+-----------+ + * | codecID : uint16 | 2 bytes | + * +--------------+----------+-----------+ + * | typeID : uint32 | 4 bytes | + * +--------------+----------+-----------+ + * | subnetID : [32]byte | 32 bytes | + * +--------------+----------+-----------+ + * | nodeID : [32]byte | 32 bytes | + * +--------------+----------+-----------+ + * | weight : uint64 | 8 bytes | + * +--------------+----------+-----------+ + * | blsPublicKey : [48]byte | 48 bytes | + * +--------------+----------+-----------+ + * | expiry : uint64 | 8 bytes | + * +--------------+----------+-----------+ + * | 134 bytes | + * +-----------+ + * + * @param validationPeriod The information to pack into the message. + * @return The validationID and the packed message. + */ + function packRegisterSubnetValidatorMessage(ValidationPeriod memory validationPeriod) + internal + pure + returns (bytes32, bytes memory) + { + if (validationPeriod.blsPublicKey.length != 48) { + revert InvalidMessageLength(); + } + + // solhint-disable-next-line func-named-parameters + bytes memory res = abi.encodePacked( + CODEC_ID, + REGISTER_SUBNET_VALIDATOR_MESSAGE_TYPE_ID, + validationPeriod.subnetID, + validationPeriod.nodeID, + validationPeriod.weight, + validationPeriod.blsPublicKey, + validationPeriod.registrationExpiry + ); + return (sha256(res), res); + } + + /** + * @notice Unpacks a byte array as a RegisterSubnetValidatorMessage message. + * The message format specification is the same as the one used in above for packing. + * + * @param input The byte array to unpack. + * @return the unpacked ValidationPeriod. + */ + function unpackRegisterSubnetValidatorMessage(bytes memory input) + internal + pure + returns (ValidationPeriod memory) + { + if (input.length != 134) { + revert InvalidMessageLength(); + } + + // Unpack the codec ID + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + if (codecID != CODEC_ID) { + revert InvalidCodecID(); + } + + // Unpack the type ID + uint32 typeID; + for (uint256 i; i < 4; ++i) { + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); + } + if (typeID != REGISTER_SUBNET_VALIDATOR_MESSAGE_TYPE_ID) { + revert InvalidMessageType(); + } + + // Unpack the subnetID + bytes32 subnetID; + for (uint256 i; i < 32; ++i) { + subnetID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); + } + + // Unpack the nodeID + bytes32 nodeID; + for (uint256 i; i < 32; ++i) { + nodeID |= bytes32(uint256(uint8(input[i + 38])) << (8 * (31 - i))); + } + + // Unpack the weight + uint64 weight; + for (uint256 i; i < 8; ++i) { + weight |= uint64(uint8(input[i + 70])) << uint64((8 * (7 - i))); + } + + // Unpack the blsPublicKey + bytes memory blsPublicKey = new bytes(48); + for (uint256 i; i < 48; ++i) { + blsPublicKey[i] = input[i + 78]; + } + + // Unpack the registration expiry + uint64 expiry; + for (uint256 i; i < 8; ++i) { + expiry |= uint64(uint8(input[i + 126])) << uint64((8 * (7 - i))); + } + + return ValidationPeriod({ + subnetID: subnetID, + nodeID: nodeID, + weight: weight, + registrationExpiry: expiry, + blsPublicKey: blsPublicKey + }); + } + + /** + * @notice Packs a SubnetValidatorRegistrationMessage into a byte array. + * The message format specification is: + * +--------------+----------+----------+ + * | codecID : uint16 | 2 bytes | + * +--------------+----------+----------+ + * | typeID : uint32 | 4 bytes | + * +--------------+----------+----------+ + * | validationID : [32]byte | 32 bytes | + * +--------------+----------+----------+ + * | valid : bool | 1 byte | + * +--------------+----------+----------+ + * | 39 bytes | + * +----------+ + * + * @param validationID The ID of the validation period. + * @param valid true if the validation period was registered, false if it was not and never will be. + * @return The packed message. + * + */ + function packSubnetValidatorRegistrationMessage( + bytes32 validationID, + bool valid + ) internal pure returns (bytes memory) { + return abi.encodePacked( + CODEC_ID, SUBNET_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID, validationID, valid + ); + } + + /** + * @notice Unpacks a byte array as a SubnetValidatorRegistrationMessage message. + * The message format specification is the same as the one used in above for packing. + * + * @param input The byte array to unpack. + * @return The validationID and whether or the validation period was registered + * or is not a validator and never will be a validator to do the expiry time passing. + */ + function unpackSubnetValidatorRegistrationMessage(bytes memory input) + internal + pure + returns (bytes32, bool) + { + if (input.length != 39) { + revert InvalidMessageLength(); + } + // Unpack the codec ID + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + if (codecID != CODEC_ID) { + revert InvalidCodecID(); + } + + // Unpack the type ID + uint32 typeID; + for (uint256 i; i < 4; ++i) { + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); + } + if (typeID != SUBNET_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID) { + revert InvalidMessageType(); + } + + // Unpack the validation ID. + bytes32 validationID; + for (uint256 i; i < 32; ++i) { + validationID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); + } + + // Unpack the validity + bool valid = input[38] != 0; + + return (validationID, valid); + } + + /** + * @notice Packs a SetSubnetValidatorWeightMessage message into a byte array. + * The message format specification is: + * +--------------+----------+----------+ + * | codecID : uint16 | 2 bytes | + * +--------------+----------+----------+ + * | typeID : uint32 | 4 bytes | + * +--------------+----------+----------+ + * | validationID : [32]byte | 32 bytes | + * +--------------+----------+----------+ + * | nonce : uint64 | 8 bytes | + * +--------------+----------+----------+ + * | weight : uint64 | 8 bytes | + * +--------------+----------+----------+ + * | 54 bytes | + * +----------+ + * + * @param validationID The ID of the validation period. + * @param nonce The nonce of the validation ID. + * @param weight The new weight of the validator. + * @return The packed message. + */ + function packSetSubnetValidatorWeightMessage( + bytes32 validationID, + uint64 nonce, + uint64 weight + ) internal pure returns (bytes memory) { + return abi.encodePacked( + CODEC_ID, SET_SUBNET_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID, validationID, nonce, weight + ); + } + + /** + * @notice Unpacks a byte array as a SetSubnetValidatorWeight message. + * The message format specification is the same as the one used in above for packing. + * + * @param input The byte array to unpack. + * @return The validationID, nonce, and weight. + */ + function unpackSetSubnetValidatorWeightMessage(bytes memory input) + internal + pure + returns (bytes32, uint64, uint64) + { + if (input.length != 54) { + revert InvalidMessageLength(); + } + + // Unpack the codec ID. + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + if (codecID != CODEC_ID) { + revert InvalidCodecID(); + } + + // Unpack the type ID. + uint32 typeID; + for (uint256 i; i < 4; ++i) { + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); + } + if (typeID != SET_SUBNET_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID) { + revert InvalidMessageType(); + } + + // Unpack the validation ID. + bytes32 validationID; + for (uint256 i; i < 32; ++i) { + validationID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); + } + + // Unpack the nonce. + uint64 nonce; + for (uint256 i; i < 8; ++i) { + nonce |= uint64(uint8(input[i + 38])) << uint64((8 * (7 - i))); + } + + // Unpack the weight. + uint64 weight; + for (uint256 i; i < 8; ++i) { + weight |= uint64(uint8(input[i + 46])) << uint64((8 * (7 - i))); + } + + return (validationID, nonce, weight); + } + + /** + * @notice Packs a SubnetValidatorWeightUpdateMessage into a byte array. + * The message format specification is: + * +--------------+----------+----------+ + * | codecID : uint16 | 2 bytes | + * +--------------+----------+----------+ + * | typeID : uint32 | 4 bytes | + * +--------------+----------+----------+ + * | validationID : [32]byte | 32 bytes | + * +--------------+----------+----------+ + * | nonce : uint64 | 8 bytes | + * +--------------+----------+----------+ + * | weight : uint64 | 8 bytes | + * +--------------+----------+----------+ + * | 54 bytes | + * +----------+ + */ + function packSubnetValidatorWeightUpdateMessage( + bytes32 validationID, + uint64 nonce, + uint64 weight + ) internal pure returns (bytes memory) { + return abi.encodePacked( + CODEC_ID, SUBNET_VALIDATOR_WEIGHT_UPDATE_MESSAGE_TYPE_ID, validationID, nonce, weight + ); + } + + /** + * @notice Unpacks a byte array as a SubnetValidatorWeightUpdateMessag. + * The message format specification is the same as the one used in above for packing. + * + * @param input The byte array to unpack. + * @return The validationID, weight, and nonce. + */ + function unpackSubnetValidatorWeightUpdateMessage(bytes memory input) + internal + pure + returns (bytes32, uint64, uint64) + { + if (input.length != 54) { + revert InvalidMessageLength(); + } + + // Unpack the codec ID. + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + if (codecID != CODEC_ID) { + revert InvalidCodecID(); + } + + // Unpack the type ID. + uint32 typeID; + for (uint256 i; i < 4; ++i) { + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); + } + + if (typeID != SUBNET_VALIDATOR_WEIGHT_UPDATE_MESSAGE_TYPE_ID) { + revert InvalidMessageType(); + } + + // Unpack the validation ID. + bytes32 validationID; + for (uint256 i; i < 32; ++i) { + validationID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); + } + + // Unpack the nonce. + uint64 nonce; + for (uint256 i; i < 8; ++i) { + nonce |= uint64(uint8(input[i + 38])) << uint64((8 * (7 - i))); + } + + // Unpack the weight. + uint64 weight; + for (uint256 i; i < 8; ++i) { + weight |= uint64(uint8(input[i + 46])) << uint64((8 * (7 - i))); + } + + return (validationID, nonce, weight); + } + + /** + * @notice Packs a ValidationUptimeMessage into a byte array. + * The message format specification is: + * +--------------+----------+----------+ + * | codecID : uint16 | 2 bytes | + * +--------------+----------+----------+ + * | typeID : uint32 | 4 bytes | + * +--------------+----------+----------+ + * | validationID : [32]byte | 32 bytes | + * +--------------+----------+----------+ + * | uptime : uint64 | 8 bytes | + * +--------------+----------+----------+ + * | 46 bytes | + * +----------+ + * + * @param validationID The ID of the validation period. + * @param uptime The uptime of the validator. + * @return The packed message. + */ + function packValidationUptimeMessage( + bytes32 validationID, + uint64 uptime + ) internal pure returns (bytes memory) { + return abi.encodePacked(CODEC_ID, VALIDATION_UPTIME_MESSAGE_TYPE_ID, validationID, uptime); + } + + /** + * @notice Unpacks a byte array as a ValidationUptimeMessage. + * The message format specification is the same as the one used in above for packing. + * + * @param input The byte array to unpack. + * @return The validationID and uptime. + */ + function unpackValidationUptimeMessage(bytes memory input) + internal + pure + returns (bytes32, uint64) + { + if (input.length != 46) { + revert InvalidMessageLength(); + } + + // Unpack the codec ID. + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + if (codecID != CODEC_ID) { + revert InvalidCodecID(); + } + + // Unpack the type ID. + uint32 typeID; + for (uint256 i; i < 4; ++i) { + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); + } + if (typeID != VALIDATION_UPTIME_MESSAGE_TYPE_ID) { + revert InvalidMessageType(); + } + + // Unpack the validation ID. + bytes32 validationID; + for (uint256 i; i < 32; ++i) { + validationID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); + } + + // Unpack the uptime. + uint64 uptime; + for (uint256 i; i < 8; ++i) { + uptime |= uint64(uint8(input[i + 38])) << uint64((8 * (7 - i))); + } + + return (validationID, uptime); + } +} diff --git a/contracts/validator-manager/interfaces/IERC20Mintable.sol b/contracts/validator-manager/interfaces/IERC20Mintable.sol new file mode 100644 index 000000000..dd2225ceb --- /dev/null +++ b/contracts/validator-manager/interfaces/IERC20Mintable.sol @@ -0,0 +1,18 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; + +interface IERC20Mintable is IERC20 { + /** + * @notice Mint tokens to the specified address. + * @param account The address to mint tokens to. + * @param amount How many tokens to mint. + * @dev This function should have appropriate user controls to ensure that only the staking contract can mint. + */ + function mint(address account, uint256 amount) external; +} diff --git a/contracts/validator-manager/interfaces/IERC20TokenStakingManager.sol b/contracts/validator-manager/interfaces/IERC20TokenStakingManager.sol new file mode 100644 index 000000000..88a903d14 --- /dev/null +++ b/contracts/validator-manager/interfaces/IERC20TokenStakingManager.sol @@ -0,0 +1,29 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {ValidatorRegistrationInput} from "./IValidatorManager.sol"; +import {IPoSValidatorManager} from "./IPoSValidatorManager.sol"; + +interface IERC20TokenStakingManager is IPoSValidatorManager { + /** + * @notice Begins the validator registration process. Locks the {stakeAmount} of the managers specified ERC20 token. + * @param registrationInput The inputs for a validator registration. + * @param delegationFeeBips The fee that delegators must pay to delegate to this validator. + * @param minStakeDuration The minimum amount of time this validator must be staked for. + */ + function initializeValidatorRegistration( + ValidatorRegistrationInput calldata registrationInput, + uint16 delegationFeeBips, + uint64 minStakeDuration, + uint256 stakeAmount + ) external returns (bytes32 validationID); + + function initializeDelegatorRegistration( + bytes32 validationID, + uint256 stakeAmount + ) external returns (bytes32); +} diff --git a/contracts/validator-manager/interfaces/INativeTokenStakingManager.sol b/contracts/validator-manager/interfaces/INativeTokenStakingManager.sol new file mode 100644 index 000000000..f46d6e649 --- /dev/null +++ b/contracts/validator-manager/interfaces/INativeTokenStakingManager.sol @@ -0,0 +1,28 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {ValidatorRegistrationInput} from "./IValidatorManager.sol"; +import {IPoSValidatorManager} from "./IPoSValidatorManager.sol"; + +interface INativeTokenStakingManager is IPoSValidatorManager { + /** + * @notice Begins the validator registration process. Locks the provided native asset in the contract as the stake. + * @param registrationInput The inputs for a validator registration. + * @param delegationFeeBips The fee that delegators must pay to delegate to this validator. + * @param minStakeDuration The minimum amount of time this validator must be staked for. + */ + function initializeValidatorRegistration( + ValidatorRegistrationInput calldata registrationInput, + uint16 delegationFeeBips, + uint64 minStakeDuration + ) external payable returns (bytes32 validationID); + + function initializeDelegatorRegistration(bytes32 validationID) + external + payable + returns (bytes32); +} diff --git a/contracts/validator-manager/interfaces/IPoAValidatorManager.sol b/contracts/validator-manager/interfaces/IPoAValidatorManager.sol new file mode 100644 index 000000000..9418a8331 --- /dev/null +++ b/contracts/validator-manager/interfaces/IPoAValidatorManager.sol @@ -0,0 +1,28 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {IValidatorManager, ValidatorRegistrationInput} from "./IValidatorManager.sol"; + +interface IPoAValidatorManager is IValidatorManager { + /** + * @notice Begins the validator registration process, and sets the {weight} of the validator. + * @param registrationInput The inputs for a validator registration. + * @param weight The weight of the validator being registered. + */ + function initializeValidatorRegistration( + ValidatorRegistrationInput calldata registrationInput, + uint64 weight + ) external returns (bytes32 validationID); + + /** + * @notice Begins the process of ending an active validation period. The validation period must have been previously + * started by a successful call to {completeValidatorRegistration} with the given validationID. + * Any rewards for this validation period will stop accruing when this function is called. + * @param validationID The ID of the validation being ended. + */ + function initializeEndValidation(bytes32 validationID) external; +} diff --git a/contracts/validator-manager/interfaces/IPoSValidatorManager.sol b/contracts/validator-manager/interfaces/IPoSValidatorManager.sol new file mode 100644 index 000000000..ca9ba291b --- /dev/null +++ b/contracts/validator-manager/interfaces/IPoSValidatorManager.sol @@ -0,0 +1,184 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {IValidatorManager, ValidatorManagerSettings} from "./IValidatorManager.sol"; +import {IRewardCalculator} from "./IRewardCalculator.sol"; + +enum DelegatorStatus { + Unknown, + PendingAdded, + Active, + PendingRemoved +} + +// TODO: visit types of these fields, for example uint64 might be too big for stake duration seconds. +struct PoSValidatorManagerSettings { + ValidatorManagerSettings baseSettings; + uint256 minimumStakeAmount; + uint256 maximumStakeAmount; + uint64 minimumStakeDuration; + uint16 minimumDelegationFeeBips; + uint8 maximumStakeMultiplier; + IRewardCalculator rewardCalculator; +} + +struct Delegator { + DelegatorStatus status; + address owner; + bytes32 validationID; + uint64 weight; + uint64 startedAt; + uint64 startingNonce; + uint64 endingNonce; +} + +struct PoSValidatorInfo { + address owner; + uint16 delegationFeeBips; + uint64 minStakeDuration; +} + +interface IPoSValidatorManager is IValidatorManager { + /** + * @notice Event emitted when a delegator registration is initiated + * @param delegationID The ID of the delegation + * @param validationID The ID of the validation period + * @param delegatorAddress The address of the delegator + * @param nonce The message nonce used to update the validator weight + * @param validatorWeight The updated validator weight that is sent to the P-Chain + * @param delegatorWeight The weight of the delegator + * @param setWeightMessageID The ID of the Warp message that updates the validator's weight on the P-Chain + */ + event DelegatorAdded( + bytes32 indexed delegationID, + bytes32 indexed validationID, + address indexed delegatorAddress, + uint64 nonce, + uint64 validatorWeight, + uint64 delegatorWeight, + bytes32 setWeightMessageID + ); + + /** + * @notice Event emitted when a delegator registration is completed + * @param delegationID The ID of the delegation + * @param validationID The ID of the validation period + * @param nonce The message nonce used to update the validator weight, as returned by the P-Chain + * @param startTime The time at which the registration was completed + */ + event DelegatorRegistered( + bytes32 indexed delegationID, + bytes32 indexed validationID, + uint64 indexed nonce, + uint256 startTime + ); + + /** + * @notice Event emitted when delegator removal is initiated + * @param delegationID The ID of the delegation + * @param validationID The ID of the validation period + * @param endTime The time at which the removal was initiated + */ + event DelegatorRemovalInitialized( + bytes32 indexed delegationID, bytes32 indexed validationID, uint256 endTime + ); + + /** + * @notice Event emitted when delegator removal is completed + * @param delegationID The ID of the delegation + * @param validationID The ID of the validator the delegator was staked to + * @param rewards The rewards given to the delegator + * @param fees The portion of the delegator's rewards paid to the validator + */ + event DelegationEnded( + bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees + ); + + /** + * @notice Begins the process of ending an active validation period. The validation period must have been previously + * started by a successful call to {completeValidatorRegistration} with the given validationID. + * Any rewards for this validation period will stop accruing when this function is called. + * @param validationID The ID of the validation being ended. + * @param includeUptimeProof Whether or not an uptime proof is provided for the validation period. + * If no uptime proof is provided, the validation uptime will be assumed to be 0. + * @param messageIndex If {includeUptimeProof} is true, the index of the Warp message to be received providing the + * uptime proof. + */ + function initializeEndValidation( + bytes32 validationID, + bool includeUptimeProof, + uint32 messageIndex + ) external; + + /** + * @notice Completes the delegator registration process by returning an acknowledgement of the registration of a + * validationID from the P-Chain. After this function is called, the validator's weight is updated in the contract state. + * Any P-Chain acknowledgement with a nonce greater than or equal to the nonce used to initialize registration of the + * delegator is valid, as long as that nonce has been sent by the contract. For the purposes of computing delegation rewards, + * the delegation is considered active after this function is called. + * Note: only the specified delegation will be marked as registered, even if the validator weight update + * message implicitly includes multiple weight changes. + * @param messageIndex The index of the Warp message to be received providing the acknowledgement. + * @param delegationID The ID of the delegation being registered. + */ + function completeDelegatorRegistration(uint32 messageIndex, bytes32 delegationID) external; + + /** + * @notice Removes a delegator from a completed validation period. The delegator can be in either the pending added, active + * or pending removed state. No uptime proof is required in this case, because it will have been provided by the validator + * upon their exit. + * Note that this function can be called by any address to clean up the delegation. + * @param delegationID The ID of the delegation being removed. + */ + function endDelegationCompletedValidator(bytes32 delegationID) external; + + /** + * @notice Begins the process of removing a delegator from a validation period. The delegator must have been previously + * registered with the given validationID. For the purposes of computing delegation rewards, the delegation period is + * considered ended when this function is called. In order to be eligible for rewards, an uptime proof must be provided. + * Note that this function can only be called by the address that registered the delegation. + * @param delegationID The ID of the delegation being removed. + * @param includeUptimeProof Whether or not an uptime proof is provided for the validation period. + * If the validator has completed its validation period, it has already provided an uptime proof, so {includeUptimeProof} + * will be ignored and can be set to false. If the validator has not completed its validation period and no uptime proof + * is provided, the validation uptime for the delegation period will be assumed to be 0. + * @param messageIndex If {includeUptimeProof} is true, the index of the Warp message to be received providing the + * uptime proof. + */ + function initializeEndDelegation( + bytes32 delegationID, + bool includeUptimeProof, + uint32 messageIndex + ) external; + + /** + * @notice Resubmits a delegator registration or delegator end message to be sent to the P-Chain. + * Only necessary if the original message can't be delivered due to validator churn. + * @param delegationID The ID of the delegation. + */ + function resendUpdateDelegation(bytes32 delegationID) external; + + /** + * @notice Completes the process of ending a delegation by receiving an acknowledgement from the P-Chain. + * After this function is called, the validator's weight is updated in the contract state. + * Any P-Chain acknowledgement with a nonce greater than or equal to the nonce used to initialize the end of the + * delegator's delegation is valid, as long as that nonce has been sent by the contract. This is because the validator + * weight change pertaining to the delegation ending is included in any subsequent validator weight update messages. + * Note: only the specified delegation will be marked as completed, even if the validator weight update + * message implicitly includes multiple weight changes. + * @param messageIndex The index of the Warp message to be received providing the acknowledgement. + * @param delegationID The ID of the delegation being removed. + */ + function completeEndDelegation(uint32 messageIndex, bytes32 delegationID) external; + + /** + * @notice Withdraws the delegation fees from completed delegations to the owner of the validator. + * Can currently only be called once the validator has completed its validation period. + * @param validationID The ID of the validation being ended. + */ + function claimDelegationFees(bytes32 validationID) external; +} diff --git a/contracts/validator-manager/interfaces/IRewardCalculator.sol b/contracts/validator-manager/interfaces/IRewardCalculator.sol new file mode 100644 index 000000000..b7f9a35c4 --- /dev/null +++ b/contracts/validator-manager/interfaces/IRewardCalculator.sol @@ -0,0 +1,18 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +interface IRewardCalculator { + function calculateReward( + uint256 stakeAmount, + uint64 validatorStartTime, + uint64 stakingStartTime, + uint64 stakingEndTime, + uint64 uptimeSeconds, + uint256 initialSupply, + uint256 endSupply + ) external view returns (uint256); +} diff --git a/contracts/validator-manager/interfaces/IValidatorManager.sol b/contracts/validator-manager/interfaces/IValidatorManager.sol new file mode 100644 index 000000000..a505f5605 --- /dev/null +++ b/contracts/validator-manager/interfaces/IValidatorManager.sol @@ -0,0 +1,175 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +enum ValidatorStatus { + Unknown, + PendingAdded, + Active, + PendingRemoved, + Completed, + Invalidated +} + +struct Validator { + ValidatorStatus status; + bytes32 nodeID; + uint64 startingWeight; + uint64 messageNonce; + uint64 weight; + uint64 startedAt; + uint64 endedAt; +} + +struct ValidatorChurnPeriod { + uint256 startedAt; + uint256 initialWeight; + uint256 totalWeight; // TODO add initial validator set to total weight. + uint64 churnAmount; +} + +/** + * @notice Event emitted when validator weight is updated. + * @param validationID The ID of the validation period + * @param nonce The message nonce used to update the validator weight + * @param validatorWeight The updated validator weight that is sent to the P-Chain + * @param setWeightMessageID The ID of the Warp message that updates the validator's weight on the P-Chain + */ +event ValidatorWeightUpdate( + bytes32 indexed validationID, + uint64 indexed nonce, + uint64 validatorWeight, + bytes32 setWeightMessageID +); + +struct ValidatorManagerSettings { + bytes32 subnetID; + uint64 churnPeriodSeconds; + uint8 maximumChurnPercentage; +} + +struct SubnetConversionData { + bytes32 convertSubnetTxID; + bytes32 validatorManagerBlockchainID; + address validatorManagerAddress; + InitialValidator[] initialValidators; +} + +struct InitialValidator { + bytes32 nodeID; + uint64 weight; + bytes blsPublicKey; +} + +struct ValidatorRegistrationInput { + bytes32 nodeID; + uint64 registrationExpiry; + bytes blsPublicKey; +} + +interface IValidatorManager { + /** + * @notice Emitted when a new validation period is created by stake being locked in the manager contract. + * Note that this event does not mean that the validation period has been successfully registered on the P-Chain, + * and rewards for this validation period will not begin accruing until the {ValidationPeriodRegistered} event is + * emitted. + * @param validationID The ID of the validation period being created. + * @param nodeID The node ID of the validator being registered. + * @param registerValidationMessageID The ID of the Warp message that will be sent to the P-Chain to register the + * validation period. + * @param weight The weight of the validator being registered. + * @param registrationExpiry The Unix timestamp after which the reigistration is no longer valid on the P-Chain. + */ + event ValidationPeriodCreated( + bytes32 indexed validationID, + bytes32 indexed nodeID, + bytes32 indexed registerValidationMessageID, + uint256 weight, + uint64 registrationExpiry + ); + + event InitialValidatorCreated( + bytes32 indexed validationID, bytes32 indexed nodeID, uint256 weight + ); + + /** + * @notice Emitted when the staking manager learns that the validation period has been successfully registered + * on the P-Chain. Rewards for this validation period will begin accruing when this event is emitted. + * @param validationID The ID of the validation period being registered. + * @param weight The weight of the validator being registered. + * @param timestamp The time at which the validation period was registered with the contract. + */ + event ValidationPeriodRegistered( + bytes32 indexed validationID, uint256 weight, uint256 timestamp + ); + + /** + * @notice Emitted when the process of ending a registered validation period is started by calling + * {initializeEndValidation}. Note that the stake for this validation period remains locked until + * a {ValidationPeriodRemoved} event is emitted. + * @param validationID The ID of the validation period being removed. + * @param setWeightMessageID The ID of the Warp message that updates the validator's weight on the P-Chain. + * @param weight The weight of the validator being removed. + * @param endTime The time at which the removal was initiated. + */ + event ValidatorRemovalInitialized( + bytes32 indexed validationID, + bytes32 indexed setWeightMessageID, + uint256 weight, + uint256 endTime + ); + + /** + * @notice Emitted when the stake for a validation period is unlocked and returned to the staker. + * This is done by calling {completeEndValidation}, which provides proof from the P-Chain that the + * validation period is not active and will never be active in the future. + * @param validationID The ID of the validation period being removed. + */ + event ValidationPeriodEnded(bytes32 indexed validationID, ValidatorStatus indexed status); + + /** + * @notice Verifies and sets the initial validator set for the chain through a P-Chain + * SubnetConversionMessage. + * @param subnetConversionData The subnet conversion message data used to recompute and verify against the subnetConversionID. + * @param messsageIndex The index that contains the SubnetConversionMessage Warp message containing the subnetConversionID to be verified against the provided {subnetConversionData} + */ + function initializeValidatorSet( + SubnetConversionData calldata subnetConversionData, + uint32 messsageIndex + ) external; + + /** + * @notice Resubmits a validator registration message to be sent to the P-Chain. + * Only necessary if the original message can't be delivered due to validator churn. + * @param validationID The ID of the validation period being registered. + */ + function resendRegisterValidatorMessage(bytes32 validationID) external; + + /** + * @notice Completes the validator registration process by returning an acknowledgement of the registration of a + * validationID from the P-Chain. + * @param messageIndex The index of the Warp message to be received providing the acknowledgement. + */ + function completeValidatorRegistration(uint32 messageIndex) external; + + /** + * @notice Resubmits a validator end message to be sent to the P-Chain. + * Only necessary if the original message can't be delivered due to validator churn. + * @param validationID The ID of the validation period being ended. + */ + function resendEndValidatorMessage(bytes32 validationID) external; + + /** + * @notice Completes the process of ending a validation period by receiving an acknowledgement from the P-Chain + * that the validation ID is not active and will never be active in the future. Returns the the stake associated + * with the validation. Note that this function can be used for successful validation periods that have been explicitly + * ended by calling {initializeEndValidation} or for validation periods that never began on the P-Chain due to the + * {registrationExpiry} being reached. + * @param messageIndex The index of the Warp message to be received providing the proof the validation is not active + * and never will be active on the P-Chain. + */ + function completeEndValidation(uint32 messageIndex) external; +} diff --git a/contracts/validator-manager/tests/ERC20TokenStakingManagerTests.t.sol b/contracts/validator-manager/tests/ERC20TokenStakingManagerTests.t.sol new file mode 100644 index 000000000..fee9cde4b --- /dev/null +++ b/contracts/validator-manager/tests/ERC20TokenStakingManagerTests.t.sol @@ -0,0 +1,233 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {PoSValidatorManagerTest} from "./PoSValidatorManagerTests.t.sol"; +import {ERC20TokenStakingManager} from "../ERC20TokenStakingManager.sol"; +import {PoSValidatorManager} from "../PoSValidatorManager.sol"; +import {ExampleRewardCalculator} from "../ExampleRewardCalculator.sol"; +import { + ValidatorManagerSettings, + ValidatorRegistrationInput +} from "../interfaces/IValidatorManager.sol"; +import {PoSValidatorManagerSettings} from "../interfaces/IPoSValidatorManager.sol"; +import {IRewardCalculator} from "../interfaces/IRewardCalculator.sol"; +import {ICMInitializable} from "../../utilities/ICMInitializable.sol"; +import {ExampleERC20} from "@mocks/ExampleERC20.sol"; +import {IERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/IERC20.sol"; +import {IERC20Mintable} from "../interfaces/IERC20Mintable.sol"; +import {SafeERC20} from "@openzeppelin/contracts@5.0.2/token/ERC20/utils/SafeERC20.sol"; + +// TODO: Remove this once all unit tests implemented +// solhint-disable no-empty-blocks +contract ERC20TokenStakingManagerTest is PoSValidatorManagerTest { + using SafeERC20 for IERC20Mintable; + + ERC20TokenStakingManager public app; + IERC20Mintable public token; + + function setUp() public virtual { + // Construct the object under test + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + token = new ExampleERC20(); + rewardCalculator = new ExampleRewardCalculator(DEFAULT_REWARD_RATE); + app.initialize( + PoSValidatorManagerSettings({ + baseSettings: ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + minimumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: DEFAULT_MINIMUM_DELEGATION_FEE_BIPS, + maximumStakeMultiplier: DEFAULT_MAXIMUM_STAKE_MULTIPLIER, + rewardCalculator: rewardCalculator + }), + token + ); + validatorManager = app; + posValidatorManager = app; + _mockGetBlockchainID(); + _mockInitializeValidatorSet(); + app.initializeValidatorSet(_defaultSubnetConversionData(), 0); + } + + function testZeroMinimumDelegationFee() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(PoSValidatorManager.InvalidDelegationFee.selector); + app.initialize( + PoSValidatorManagerSettings({ + baseSettings: ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + minimumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: 0, + maximumStakeMultiplier: DEFAULT_MAXIMUM_STAKE_MULTIPLIER, + rewardCalculator: IRewardCalculator(address(0)) + }), + token + ); + } + + function testMaxMinimumDelegationFee() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + uint16 minimumDelegationFeeBips = app.MAXIMUM_DELEGATION_FEE_BIPS() + 1; + vm.expectRevert(PoSValidatorManager.InvalidDelegationFee.selector); + app.initialize( + PoSValidatorManagerSettings({ + baseSettings: ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + minimumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: minimumDelegationFeeBips, + maximumStakeMultiplier: DEFAULT_MAXIMUM_STAKE_MULTIPLIER, + rewardCalculator: IRewardCalculator(address(0)) + }), + token + ); + } + + function testInvalidStakeAmountRange() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(PoSValidatorManager.InvalidStakeAmount.selector); + app.initialize( + PoSValidatorManagerSettings({ + baseSettings: ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + minimumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: DEFAULT_MINIMUM_DELEGATION_FEE_BIPS, + maximumStakeMultiplier: DEFAULT_MAXIMUM_STAKE_MULTIPLIER, + rewardCalculator: IRewardCalculator(address(0)) + }), + token + ); + } + + function testZeroMaxStakeMultiplier() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(PoSValidatorManager.InvalidStakeMultiplier.selector); + app.initialize( + PoSValidatorManagerSettings({ + baseSettings: ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + minimumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: DEFAULT_MINIMUM_DELEGATION_FEE_BIPS, + maximumStakeMultiplier: 0, + rewardCalculator: IRewardCalculator(address(0)) + }), + token + ); + } + + function testMaxStakeMultiplierOverLimit() public { + app = new ERC20TokenStakingManager(ICMInitializable.Allowed); + uint8 maximumStakeMultiplier = app.MAXIMUM_STAKE_MULTIPLIER_LIMIT() + 1; + vm.expectRevert(PoSValidatorManager.InvalidStakeMultiplier.selector); + app.initialize( + PoSValidatorManagerSettings({ + baseSettings: ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + minimumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: DEFAULT_MINIMUM_DELEGATION_FEE_BIPS, + maximumStakeMultiplier: maximumStakeMultiplier, + rewardCalculator: IRewardCalculator(address(0)) + }), + token + ); + } + + function testInvalidValidatorMinStakeDuration() public { + ValidatorRegistrationInput memory input = + ValidatorRegistrationInput(DEFAULT_NODE_ID, DEFAULT_EXPIRY, DEFAULT_BLS_PUBLIC_KEY); + uint256 stakeAmount = _weightToValue(DEFAULT_WEIGHT); + vm.expectRevert(PoSValidatorManager.InvalidStakeDuration.selector); + app.initializeValidatorRegistration( + input, DEFAULT_DELEGATION_FEE_BIPS, DEFAULT_MINIMUM_STAKE_DURATION - 1, stakeAmount + ); + } + + function _initializeValidatorRegistration( + ValidatorRegistrationInput memory registrationInput, + uint16 delegationFeeBips, + uint64 minStakeDuration, + uint256 stakeAmount + ) internal virtual override returns (bytes32) { + return app.initializeValidatorRegistration( + registrationInput, delegationFeeBips, minStakeDuration, stakeAmount + ); + } + + function _initializeValidatorRegistration( + ValidatorRegistrationInput memory input, + uint64 weight + ) internal virtual override returns (bytes32) { + return app.initializeValidatorRegistration( + input, + DEFAULT_DELEGATION_FEE_BIPS, + DEFAULT_MINIMUM_STAKE_DURATION, + _weightToValue(weight) + ); + } + + function _initializeDelegatorRegistration( + bytes32 validationID, + address delegatorAddress, + uint64 weight + ) internal virtual override returns (bytes32) { + uint256 value = _weightToValue(weight); + vm.startPrank(delegatorAddress); + bytes32 delegationID = app.initializeDelegatorRegistration(validationID, value); + vm.stopPrank(); + return delegationID; + } + + function _beforeSend(uint256 amount, address spender) internal override { + token.safeIncreaseAllowance(spender, amount); + token.safeTransfer(spender, amount); + + // ERC20 tokens need to be pre-approved + vm.startPrank(spender); + token.safeIncreaseAllowance(address(app), amount); + vm.stopPrank(); + } + + function _expectStakeUnlock(address account, uint256 amount) internal override { + vm.expectCall(address(token), abi.encodeCall(IERC20.transfer, (account, amount))); + } + + function _expectRewardIssuance(address account, uint256 amount) internal override { + vm.expectCall(address(token), abi.encodeCall(IERC20Mintable.mint, (account, amount))); + } + + function _getStakeAssetBalance(address account) internal view override returns (uint256) { + return token.balanceOf(account); + } +} diff --git a/contracts/validator-manager/tests/ExamplesRewardCalculatorTests.t.sol b/contracts/validator-manager/tests/ExamplesRewardCalculatorTests.t.sol new file mode 100644 index 000000000..87b18020c --- /dev/null +++ b/contracts/validator-manager/tests/ExamplesRewardCalculatorTests.t.sol @@ -0,0 +1,50 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {ExampleRewardCalculator} from "../ExampleRewardCalculator.sol"; +import {IRewardCalculator} from "../interfaces/IRewardCalculator.sol"; + +contract ExampleRewardCalculatorTest is Test { + IRewardCalculator public exampleRewardCalculator; + + uint256 public constant DEFAULT_STAKE_AMOUNT = 1e12; + uint64 public constant DEFAULT_START_TIME = 1000; + uint64 public constant DEFAULT_END_TIME = 31537000; // a year + 1000 seonds + uint64 public constant DEFAULT_UPTIME = (DEFAULT_END_TIME - DEFAULT_START_TIME) * 80 / 100; + uint64 public constant DEFAULT_REWARD_BASIS_POINTS = 42; + + function setUp() public { + exampleRewardCalculator = new ExampleRewardCalculator(DEFAULT_REWARD_BASIS_POINTS); + } + + function testRewardCalculation() public view { + uint256 output = exampleRewardCalculator.calculateReward({ + stakeAmount: DEFAULT_STAKE_AMOUNT, + validatorStartTime: DEFAULT_START_TIME, + stakingStartTime: DEFAULT_START_TIME, + stakingEndTime: DEFAULT_END_TIME, + uptimeSeconds: DEFAULT_UPTIME, + initialSupply: 0, + endSupply: 0 + }); + assertEq(output, 42e8); + } + + function testInsufficientUptime() public view { + uint256 output = exampleRewardCalculator.calculateReward({ + stakeAmount: DEFAULT_STAKE_AMOUNT, + validatorStartTime: DEFAULT_START_TIME, + stakingStartTime: DEFAULT_START_TIME, + stakingEndTime: DEFAULT_END_TIME, + uptimeSeconds: DEFAULT_UPTIME - 1, + initialSupply: 0, + endSupply: 0 + }); + assertEq(output, 0); + } +} diff --git a/contracts/validator-manager/tests/NativeTokenStakingManagerTests.t.sol b/contracts/validator-manager/tests/NativeTokenStakingManagerTests.t.sol new file mode 100644 index 000000000..78ba2629c --- /dev/null +++ b/contracts/validator-manager/tests/NativeTokenStakingManagerTests.t.sol @@ -0,0 +1,218 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {PoSValidatorManagerTest} from "./PoSValidatorManagerTests.t.sol"; +import {NativeTokenStakingManager} from "../NativeTokenStakingManager.sol"; +import {PoSValidatorManager} from "../PoSValidatorManager.sol"; +import { + ValidatorManagerSettings, + ValidatorRegistrationInput +} from "../interfaces/IValidatorManager.sol"; +import {PoSValidatorManagerSettings} from "../interfaces/IPoSValidatorManager.sol"; +import {IRewardCalculator} from "../interfaces/IRewardCalculator.sol"; +import {ExampleRewardCalculator} from "../ExampleRewardCalculator.sol"; +import {ICMInitializable} from "../../utilities/ICMInitializable.sol"; +import {INativeMinter} from + "@avalabs/subnet-evm-contracts@1.2.0/contracts/interfaces/INativeMinter.sol"; + +// TODO: Remove this once all unit tests implemented +// solhint-disable no-empty-blocks +contract NativeTokenStakingManagerTest is PoSValidatorManagerTest { + NativeTokenStakingManager public app; + + function setUp() public virtual { + // Construct the object under test + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + rewardCalculator = new ExampleRewardCalculator(DEFAULT_REWARD_RATE); + app.initialize( + PoSValidatorManagerSettings({ + baseSettings: ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + minimumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: DEFAULT_MINIMUM_DELEGATION_FEE_BIPS, + maximumStakeMultiplier: DEFAULT_MAXIMUM_STAKE_MULTIPLIER, + rewardCalculator: rewardCalculator + }) + ); + validatorManager = app; + posValidatorManager = app; + _mockGetBlockchainID(); + _mockInitializeValidatorSet(); + app.initializeValidatorSet(_defaultSubnetConversionData(), 0); + } + + function testZeroMinimumDelegationFee() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(PoSValidatorManager.InvalidDelegationFee.selector); + app.initialize( + PoSValidatorManagerSettings({ + baseSettings: ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + minimumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: 0, + maximumStakeMultiplier: DEFAULT_MAXIMUM_STAKE_MULTIPLIER, + rewardCalculator: IRewardCalculator(address(0)) + }) + ); + } + + function testMaxMinimumDelegationFee() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + uint16 minimumDelegationFeeBips = app.MAXIMUM_DELEGATION_FEE_BIPS() + 1; + vm.expectRevert(PoSValidatorManager.InvalidDelegationFee.selector); + app.initialize( + PoSValidatorManagerSettings({ + baseSettings: ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + minimumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: minimumDelegationFeeBips, + maximumStakeMultiplier: DEFAULT_MAXIMUM_STAKE_MULTIPLIER, + rewardCalculator: IRewardCalculator(address(0)) + }) + ); + } + + function testInvalidStakeAmountRange() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(PoSValidatorManager.InvalidStakeAmount.selector); + app.initialize( + PoSValidatorManagerSettings({ + baseSettings: ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + minimumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: DEFAULT_MINIMUM_DELEGATION_FEE_BIPS, + maximumStakeMultiplier: DEFAULT_MAXIMUM_STAKE_MULTIPLIER, + rewardCalculator: IRewardCalculator(address(0)) + }) + ); + } + + function testZeroMaxStakeMultiplier() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + vm.expectRevert(PoSValidatorManager.InvalidStakeMultiplier.selector); + app.initialize( + PoSValidatorManagerSettings({ + baseSettings: ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + minimumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: DEFAULT_MINIMUM_DELEGATION_FEE_BIPS, + maximumStakeMultiplier: 0, + rewardCalculator: IRewardCalculator(address(0)) + }) + ); + } + + function testMaxStakeMultiplierOverLimit() public { + app = new NativeTokenStakingManager(ICMInitializable.Allowed); + uint8 maximumStakeMultiplier = app.MAXIMUM_STAKE_MULTIPLIER_LIMIT() + 1; + vm.expectRevert(PoSValidatorManager.InvalidStakeMultiplier.selector); + app.initialize( + PoSValidatorManagerSettings({ + baseSettings: ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + minimumStakeAmount: DEFAULT_MINIMUM_STAKE_AMOUNT, + maximumStakeAmount: DEFAULT_MAXIMUM_STAKE_AMOUNT, + minimumStakeDuration: DEFAULT_MINIMUM_STAKE_DURATION, + minimumDelegationFeeBips: DEFAULT_MINIMUM_DELEGATION_FEE_BIPS, + maximumStakeMultiplier: maximumStakeMultiplier, + rewardCalculator: IRewardCalculator(address(0)) + }) + ); + } + + // Helpers + function _initializeValidatorRegistration( + ValidatorRegistrationInput memory registrationInput, + uint16 delegationFeeBips, + uint64 minStakeDuration, + uint256 stakeAmount + ) internal virtual override returns (bytes32) { + return app.initializeValidatorRegistration{value: stakeAmount}( + registrationInput, delegationFeeBips, minStakeDuration + ); + } + + function _initializeValidatorRegistration( + ValidatorRegistrationInput memory input, + uint64 weight + ) internal virtual override returns (bytes32) { + return app.initializeValidatorRegistration{value: _weightToValue(weight)}( + input, DEFAULT_DELEGATION_FEE_BIPS, DEFAULT_MINIMUM_STAKE_DURATION + ); + } + + function _initializeDelegatorRegistration( + bytes32 validationID, + address delegatorAddress, + uint64 weight + ) internal virtual override returns (bytes32) { + uint256 value = _weightToValue(weight); + vm.prank(delegatorAddress); + vm.deal(delegatorAddress, value); + return app.initializeDelegatorRegistration{value: value}(validationID); + } + + function _beforeSend(uint256 amount, address spender) internal override { + // Native tokens no need pre approve + } + + function _expectStakeUnlock(address account, uint256 amount) internal override { + // empty calldata implies the receive function will be called + vm.expectCall(account, amount, ""); + } + + function _expectRewardIssuance(address account, uint256 amount) internal override { + vm.mockCall( + address(app.NATIVE_MINTER()), + abi.encodeCall(INativeMinter.mintNativeCoin, (account, amount)), + "" + ); + // empty calldata implies the receive function will be called: + vm.mockCall({ + callee: account, + msgValue: amount, + data: "", // implies receive() + returnData: "" + }); + // Units tests don't have access to the native minter precompile, so use vm.deal instead. + vm.deal(account, account.balance + amount); + } + + function _getStakeAssetBalance(address account) internal view override returns (uint256) { + return account.balance; + } +} +// TODO: Remove this once all unit tests implemented +// solhint-enable no-empty-blocks diff --git a/contracts/validator-manager/tests/PoAValidatorManagerTests.t.sol b/contracts/validator-manager/tests/PoAValidatorManagerTests.t.sol new file mode 100644 index 000000000..1f3339537 --- /dev/null +++ b/contracts/validator-manager/tests/PoAValidatorManagerTests.t.sol @@ -0,0 +1,65 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {ValidatorManagerTest} from "./ValidatorManagerTests.t.sol"; +import {PoAValidatorManager} from "../PoAValidatorManager.sol"; +import {ICMInitializable} from "@utilities/ICMInitializable.sol"; +import { + ValidatorManagerSettings, + ValidatorRegistrationInput +} from "../interfaces/IValidatorManager.sol"; +import {OwnableUpgradeable} from + "@openzeppelin/contracts-upgradeable@5.0.2/access/OwnableUpgradeable.sol"; + +contract PoAValidatorManagerTest is ValidatorManagerTest { + PoAValidatorManager public app; + + address public constant DEFAULT_OWNER = address(0x1); + + function setUp() public { + app = new PoAValidatorManager(ICMInitializable.Allowed); + app.initialize( + ValidatorManagerSettings({ + subnetID: DEFAULT_SUBNET_ID, + churnPeriodSeconds: DEFAULT_CHURN_PERIOD, + maximumChurnPercentage: DEFAULT_MAXIMUM_CHURN_PERCENTAGE + }), + address(this) + ); + validatorManager = app; + _mockGetBlockchainID(); + _mockInitializeValidatorSet(); + app.initializeValidatorSet(_defaultSubnetConversionData(), 0); + } + + function testInvalidOwnerRegistration() public { + vm.prank(vm.addr(1)); + vm.expectRevert( + abi.encodeWithSelector( + OwnableUpgradeable.OwnableUnauthorizedAccount.selector, vm.addr(1) + ) + ); + _initializeValidatorRegistration( + ValidatorRegistrationInput(DEFAULT_NODE_ID, DEFAULT_EXPIRY, DEFAULT_BLS_PUBLIC_KEY), + DEFAULT_WEIGHT + ); + } + + function _initializeValidatorRegistration( + ValidatorRegistrationInput memory input, + uint64 weight + ) internal virtual override returns (bytes32) { + return app.initializeValidatorRegistration(input, weight); + } + + function _initializeEndValidation(bytes32 validationID, bool) internal virtual override { + return app.initializeEndValidation(validationID); + } + + // solhint-disable-next-line no-empty-blocks + function _beforeSend(uint256 amount, address spender) internal virtual override {} +} diff --git a/contracts/validator-manager/tests/PoSValidatorManagerTests.t.sol b/contracts/validator-manager/tests/PoSValidatorManagerTests.t.sol new file mode 100644 index 000000000..f4dbfc027 --- /dev/null +++ b/contracts/validator-manager/tests/PoSValidatorManagerTests.t.sol @@ -0,0 +1,988 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {IRewardCalculator} from "../interfaces/IRewardCalculator.sol"; +import {ValidatorManagerTest} from "./ValidatorManagerTests.t.sol"; +import {PoSValidatorManager} from "../PoSValidatorManager.sol"; +import {ValidatorManager} from "../ValidatorManager.sol"; +import { + WarpMessage, + IWarpMessenger +} from "@avalabs/subnet-evm-contracts@1.2.0/contracts/interfaces/IWarpMessenger.sol"; +import {ValidatorMessages} from "../ValidatorMessages.sol"; +import {ValidatorRegistrationInput, ValidatorStatus} from "../interfaces/IValidatorManager.sol"; + +abstract contract PoSValidatorManagerTest is ValidatorManagerTest { + uint64 public constant DEFAULT_UPTIME = uint64(100); + uint64 public constant DEFAULT_DELEGATOR_WEIGHT = uint64(1e5); + uint64 public constant DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP = + DEFAULT_REGISTRATION_TIMESTAMP + DEFAULT_EXPIRY; + uint64 public constant DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP = + DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP + DEFAULT_EXPIRY; + uint64 public constant DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP = + DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP + DEFAULT_MINIMUM_STAKE_DURATION; + address public constant DEFAULT_DELEGATOR_ADDRESS = + address(0x1234123412341234123412341234123412341234); + address public constant DEFAULT_VALIDATOR_OWNER_ADDRESS = + address(0x2345234523452345234523452345234523452345); + uint64 public constant DEFAULT_REWARD_RATE = uint64(10); + uint64 public constant DEFAULT_MINIMUM_STAKE_DURATION = 24 hours; + uint16 public constant DEFAULT_MINIMUM_DELEGATION_FEE_BIPS = 100; + uint16 public constant DEFAULT_DELEGATION_FEE_BIPS = 150; + uint8 public constant DEFAULT_MAXIMUM_STAKE_MULTIPLIER = 4; + uint256 public constant SECONDS_IN_YEAR = 31536000; + + PoSValidatorManager public posValidatorManager; + IRewardCalculator public rewardCalculator; + + event ValidationUptimeUpdated(bytes32 indexed validationID, uint64 uptime); + + event DelegatorAdded( + bytes32 indexed delegationID, + bytes32 indexed validationID, + address indexed delegatorAddress, + uint64 nonce, + uint64 validatorWeight, + uint64 delegatorWeight, + bytes32 setWeightMessageID + ); + + event DelegatorRegistered( + bytes32 indexed delegationID, + bytes32 indexed validationID, + uint64 indexed nonce, + uint256 startTime + ); + + event DelegatorRemovalInitialized( + bytes32 indexed delegationID, bytes32 indexed validationID, uint256 endTime + ); + + event ValidatorWeightUpdate( + bytes32 indexed validationID, + uint64 indexed nonce, + uint64 validatorWeight, + bytes32 setWeightMessageID + ); + + event DelegationEnded( + bytes32 indexed delegationID, bytes32 indexed validationID, uint256 rewards, uint256 fees + ); + + function testDelegationFeeBipsTooLow() public { + ValidatorRegistrationInput memory registrationInput = ValidatorRegistrationInput({ + nodeID: DEFAULT_NODE_ID, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + vm.expectRevert(PoSValidatorManager.InvalidDelegationFee.selector); + _initializeValidatorRegistration( + registrationInput, + DEFAULT_MINIMUM_DELEGATION_FEE_BIPS - 1, + DEFAULT_MINIMUM_STAKE_DURATION, + DEFAULT_MINIMUM_STAKE_AMOUNT + ); + } + + function testDelegationFeeBipsTooHigh() public { + ValidatorRegistrationInput memory registrationInput = ValidatorRegistrationInput({ + nodeID: DEFAULT_NODE_ID, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + uint16 delegationFeeBips = posValidatorManager.MAXIMUM_DELEGATION_FEE_BIPS() + 1; + vm.expectRevert(PoSValidatorManager.InvalidDelegationFee.selector); + + _initializeValidatorRegistration( + registrationInput, + delegationFeeBips, + DEFAULT_MINIMUM_STAKE_DURATION, + DEFAULT_MINIMUM_STAKE_AMOUNT + ); + } + + function testInvalidMinStakeDuration() public { + ValidatorRegistrationInput memory registrationInput = ValidatorRegistrationInput({ + nodeID: DEFAULT_NODE_ID, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + vm.expectRevert(PoSValidatorManager.InvalidStakeDuration.selector); + _initializeValidatorRegistration( + registrationInput, + DEFAULT_DELEGATION_FEE_BIPS, + DEFAULT_MINIMUM_STAKE_DURATION - 1, + DEFAULT_MINIMUM_STAKE_AMOUNT + ); + } + + function testStakeAmountTooLow() public { + ValidatorRegistrationInput memory registrationInput = ValidatorRegistrationInput({ + nodeID: DEFAULT_NODE_ID, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + vm.expectRevert(PoSValidatorManager.InvalidStakeAmount.selector); + _initializeValidatorRegistration( + registrationInput, + DEFAULT_DELEGATION_FEE_BIPS, + DEFAULT_MINIMUM_STAKE_DURATION, + DEFAULT_MINIMUM_STAKE_AMOUNT - 1 + ); + } + + function testStakeAmountTooHigh() public { + ValidatorRegistrationInput memory registrationInput = ValidatorRegistrationInput({ + nodeID: DEFAULT_NODE_ID, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + vm.expectRevert(PoSValidatorManager.InvalidStakeAmount.selector); + _initializeValidatorRegistration( + registrationInput, + DEFAULT_DELEGATION_FEE_BIPS, + DEFAULT_MINIMUM_STAKE_DURATION, + DEFAULT_MAXIMUM_STAKE_AMOUNT + 1 + ); + } + + function testInvalidInitializeEndTime() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + vm.expectRevert(PoSValidatorManager.InvalidStakeDuration.selector); + posValidatorManager.initializeEndValidation(validationID, false, 0); + } + + function testInvalidUptimeWarpMessage() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + _mockGetUptimeWarpMessage(new bytes(0), false); + vm.warp(DEFAULT_REGISTRATION_TIMESTAMP + DEFAULT_MINIMUM_STAKE_DURATION); + vm.expectRevert(ValidatorManager.InvalidWarpMessage.selector); + posValidatorManager.initializeEndValidation(validationID, true, 0); + } + + function testInvalidUptimeChainID() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + + _mockGetUptimeWarpMessage(new bytes(0), true); + _mockGetBlockchainID(posValidatorManager.P_CHAIN_BLOCKCHAIN_ID()); + vm.warp(DEFAULT_REGISTRATION_TIMESTAMP + DEFAULT_MINIMUM_STAKE_DURATION); + vm.expectRevert(ValidatorManager.InvalidBlockchainID.selector); + posValidatorManager.initializeEndValidation(validationID, true, 0); + } + + function testInvalidUptimeSenderAddress() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + + _mockGetBlockchainID(); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode( + WarpMessage({ + sourceChainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + originSenderAddress: address(this), + payload: new bytes(0) + }), + true + ) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, 0) + ); + + vm.warp(DEFAULT_REGISTRATION_TIMESTAMP + DEFAULT_MINIMUM_STAKE_DURATION); + vm.expectRevert(ValidatorManager.InvalidAddress.selector); + posValidatorManager.initializeEndValidation(validationID, true, 0); + } + + function testInvalidUptimeValidationID() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + + _mockGetBlockchainID(); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode( + WarpMessage({ + sourceChainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + originSenderAddress: address(0), + payload: ValidatorMessages.packValidationUptimeMessage(bytes32(0), 0) + }), + true + ) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, 0) + ); + + vm.warp(DEFAULT_REGISTRATION_TIMESTAMP + DEFAULT_MINIMUM_STAKE_DURATION); + vm.expectRevert(ValidatorManager.InvalidValidationID.selector); + posValidatorManager.initializeEndValidation(validationID, true, 0); + } + + function testInitializeDelegatorRegistration() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1 + }); + } + + function testResendDelegatorRegistration() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + bytes32 delegationID = _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1 + }); + bytes memory setValidatorWeightPayload = ValidatorMessages + .packSetSubnetValidatorWeightMessage( + validationID, 1, DEFAULT_WEIGHT + DEFAULT_DELEGATOR_WEIGHT + ); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + posValidatorManager.resendUpdateDelegation(delegationID); + } + + function testCompleteDelegatorRegistration() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + bytes32 delegationID = _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1 + }); + _setUpCompleteDelegatorRegistration( + validationID, + delegationID, + DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + 1 + ); + } + + function testCompleteDelegatorRegistrationWrongNonce() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + // Initialize two delegations + address delegator1 = DEFAULT_DELEGATOR_ADDRESS; + _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegator1, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1 + }); + address delegator2 = address(0x5678567856785678567856785678567856785678); + bytes32 delegationID2 = _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegator2, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP + 1, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_DELEGATOR_WEIGHT + + DEFAULT_WEIGHT, + expectedNonce: 2 + }); + + // Complete registration of delegator2 with delegator1's nonce + // Note that registering delegator1 with delegator2's nonce is valid + bytes memory setValidatorWeightPayload = ValidatorMessages + .packSubnetValidatorWeightUpdateMessage( + validationID, 1, DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT + ); + _mockGetPChainWarpMessage(setValidatorWeightPayload, true); + + vm.warp(DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP); + vm.expectRevert(PoSValidatorManager.InvalidNonce.selector); + posValidatorManager.completeDelegatorRegistration(0, delegationID2); + } + + function testCompleteDelegatorRegistrationImplicitNonce() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + // Initialize two delegations + address delegator1 = DEFAULT_DELEGATOR_ADDRESS; + bytes32 delegationID1 = _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegator1, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1 + }); + address delegator2 = address(0x5678567856785678567856785678567856785678); + _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegator2, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP + 1, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_DELEGATOR_WEIGHT + + DEFAULT_WEIGHT, + expectedNonce: 2 + }); + // Mark delegator1 as registered by delivering the weight update from nonce 2 (delegator 2's nonce) + _setUpCompleteDelegatorRegistration( + validationID, + delegationID1, + DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + 2 + ); + } + + function testInitializeEndValidationNotOwner() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + vm.prank(address(1)); + vm.expectRevert(ValidatorManager.InvalidAddress.selector); + posValidatorManager.initializeEndValidation(validationID, false, 0); + } + + function testInitializeEndDelegation() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + bytes32 delegationID = _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1 + }); + _setUpCompleteDelegatorRegistration( + validationID, + delegationID, + DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + 1 + ); + _setUpInitializeEndDelegation({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2 + }); + } + + function testResendEndDelegation() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + bytes32 delegationID = _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1 + }); + _setUpCompleteDelegatorRegistration( + validationID, + delegationID, + DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + 1 + ); + _setUpInitializeEndDelegation({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2 + }); + bytes memory setValidatorWeightPayload = + ValidatorMessages.packSetSubnetValidatorWeightMessage(validationID, 2, DEFAULT_WEIGHT); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + posValidatorManager.resendUpdateDelegation(delegationID); + } + + function testResendEndValidation() public override { + bytes32 validationID = _setUpInitializeEndValidation({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + includeUptime: true + }); + bytes memory setValidatorWeightPayload = + ValidatorMessages.packSetSubnetValidatorWeightMessage(validationID, 1, 0); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + validatorManager.resendEndValidatorMessage(validationID); + } + + function testCompleteEndDelegation() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + bytes32 delegationID = _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1 + }); + _setUpCompleteDelegatorRegistration({ + validationID: validationID, + delegationID: delegationID, + completeRegistrationTimestamp: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1 + }); + uint64 delgationEndTime = + DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP + DEFAULT_MINIMUM_STAKE_DURATION; + _setUpInitializeEndDelegation({ + validationID: validationID, + delegatorAddress: DEFAULT_DELEGATOR_ADDRESS, + delegationID: delegationID, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: delgationEndTime, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2 + }); + + uint256 expectedTotalReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_DELEGATOR_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + stakingEndTime: delgationEndTime, + uptimeSeconds: delgationEndTime - DEFAULT_REGISTRATION_TIMESTAMP, + initialSupply: 0, + endSupply: 0 + }); + + uint256 expectedValidatorFees = expectedTotalReward * DEFAULT_DELEGATION_FEE_BIPS / 10000; + uint256 expectedDelegatorReward = expectedTotalReward - expectedValidatorFees; + + _setUpCompleteEndDelegation({ + validationID: validationID, + delegationID: delegationID, + delegator: DEFAULT_DELEGATOR_ADDRESS, + delegatorWeight: DEFAULT_DELEGATOR_WEIGHT, + expectedReward: expectedDelegatorReward, + expectedFees: expectedValidatorFees, + validatorWeight: DEFAULT_WEIGHT, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 2 + }); + } + + function testCompleteEndDelegationWrongNonce() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + // Register two delegations + address delegator1 = DEFAULT_DELEGATOR_ADDRESS; + bytes32 delegationID1 = _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegator1, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1 + }); + _setUpCompleteDelegatorRegistration( + validationID, + delegationID1, + DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + 1 + ); + address delegator2 = address(0x5678567856785678567856785678567856785678); + bytes32 delegationID2 = _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegator2, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP + 1, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_DELEGATOR_WEIGHT + + DEFAULT_WEIGHT, + expectedNonce: 2 + }); + _setUpCompleteDelegatorRegistration( + validationID, + delegationID2, + DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + 2 + ); + + // Initialize end delegation for both delegators + _setUpInitializeEndDelegation({ + validationID: validationID, + delegatorAddress: delegator1, + delegationID: delegationID1, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 3 + }); + _setUpInitializeEndDelegation({ + validationID: validationID, + delegatorAddress: delegator2, + delegationID: delegationID2, + startDelegationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP + 1, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 4 + }); + + // Complete ending delegator2 with delegator1's nonce + // Note that ending delegator1 with delegator2's nonce is valid + bytes memory setValidatorWeightPayload = ValidatorMessages + .packSubnetValidatorWeightUpdateMessage( + validationID, 3, DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT + ); + _mockGetPChainWarpMessage(setValidatorWeightPayload, true); + + vm.expectRevert(PoSValidatorManager.InvalidNonce.selector); + posValidatorManager.completeEndDelegation(0, delegationID2); + } + + function testCompleteEndDelegationImplicitNonce() public { + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + // Register two delegations + address delegator1 = DEFAULT_DELEGATOR_ADDRESS; + bytes32 delegationID1 = _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegator1, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 1 + }); + _setUpCompleteDelegatorRegistration( + validationID, + delegationID1, + DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + 1 + ); + address delegator2 = address(0x5678567856785678567856785678567856785678); + bytes32 delegationID2 = _setUpInitializeDelegatorRegistration({ + validationID: validationID, + delegatorAddress: delegator2, + weight: DEFAULT_DELEGATOR_WEIGHT, + registrationTimestamp: DEFAULT_DELEGATOR_INIT_REGISTRATION_TIMESTAMP + 1, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_DELEGATOR_WEIGHT + + DEFAULT_WEIGHT, + expectedNonce: 2 + }); + _setUpCompleteDelegatorRegistration( + validationID, + delegationID2, + DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + 2 + ); + + // Initialize end delegation for both delegators + _setUpInitializeEndDelegation({ + validationID: validationID, + delegatorAddress: delegator1, + delegationID: delegationID1, + startDelegationTimestamp: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + expectedValidatorWeight: DEFAULT_DELEGATOR_WEIGHT + DEFAULT_WEIGHT, + expectedNonce: 3 + }); + _setUpInitializeEndDelegation({ + validationID: validationID, + delegatorAddress: delegator2, + delegationID: delegationID2, + startDelegationTimestamp: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + endDelegationTimestamp: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP + 1, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 4 + }); + + uint256 expectedTotalReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_DELEGATOR_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_DELEGATOR_COMPLETE_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP, + uptimeSeconds: DEFAULT_DELEGATOR_END_DELEGATION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP, + initialSupply: 0, + endSupply: 0 + }); + + uint256 expectedValidatorFees = expectedTotalReward * DEFAULT_DELEGATION_FEE_BIPS / 10000; + uint256 expectedDelegatorReward = expectedTotalReward - expectedValidatorFees; + + // Complete delegation1 by delivering the weight update from nonce 4 (delegator2's nonce) + _setUpCompleteEndDelegation({ + validationID: validationID, + delegationID: delegationID1, + delegator: DEFAULT_DELEGATOR_ADDRESS, + delegatorWeight: DEFAULT_DELEGATOR_WEIGHT, + expectedReward: expectedDelegatorReward, + expectedFees: expectedValidatorFees, + validatorWeight: DEFAULT_WEIGHT, + expectedValidatorWeight: DEFAULT_WEIGHT, + expectedNonce: 4 + }); + } + + function testCompleteEndValidation() public virtual override { + bytes32 validationID = _setUpInitializeEndValidation({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + includeUptime: true + }); + + uint256 expectedReward = rewardCalculator.calculateReward({ + stakeAmount: _weightToValue(DEFAULT_WEIGHT), + validatorStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingStartTime: DEFAULT_REGISTRATION_TIMESTAMP, + stakingEndTime: DEFAULT_COMPLETION_TIMESTAMP, + uptimeSeconds: DEFAULT_COMPLETION_TIMESTAMP - DEFAULT_REGISTRATION_TIMESTAMP, + initialSupply: 0, + endSupply: 0 + }); + + _setUpCompleteEndValidation({ + validationID: validationID, + validatorOwner: address(this), + expectedReward: expectedReward, + validatorWeight: DEFAULT_WEIGHT + }); + } + + function testInitializeEndValidation() public virtual override { + _setUpInitializeEndValidation({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP, + includeUptime: true + }); + } + + function testValueToWeight() public view { + uint64 w1 = posValidatorManager.valueToWeight(1e12); + uint64 w2 = posValidatorManager.valueToWeight(1e18); + uint64 w3 = posValidatorManager.valueToWeight(1e27); + + assertEq(w1, 1); + assertEq(w2, 1e6); + assertEq(w3, 1e15); + } + + function testWeightToValue() public view { + uint256 v1 = posValidatorManager.weightToValue(1); + uint256 v2 = posValidatorManager.weightToValue(1e6); + uint256 v3 = posValidatorManager.weightToValue(1e15); + + assertEq(v1, 1e12); + assertEq(v2, 1e18); + assertEq(v3, 1e27); + } + + function _initializeValidatorRegistration( + ValidatorRegistrationInput memory registrationInput, + uint16 delegationFeeBips, + uint64 minStakeDuration, + uint256 stakeAmount + ) internal virtual returns (bytes32); + + function _initializeEndValidation( + bytes32 validationID, + bool includeUptime + ) internal virtual override { + return posValidatorManager.initializeEndValidation(validationID, includeUptime, 0); + } + + function _initializeDelegatorRegistration( + bytes32 validationID, + address delegatorAddress, + uint64 weight + ) internal virtual returns (bytes32); + + // + // Delegation setup utilities + // + function _setUpInitializeDelegatorRegistration( + bytes32 validationID, + address delegatorAddress, + uint64 weight, + uint64 registrationTimestamp, + uint64 expectedValidatorWeight, + uint64 expectedNonce + ) internal returns (bytes32) { + bytes memory setValidatorWeightPayload = ValidatorMessages + .packSetSubnetValidatorWeightMessage(validationID, expectedNonce, expectedValidatorWeight); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + vm.warp(registrationTimestamp); + + _beforeSend(_weightToValue(weight), delegatorAddress); + + vm.expectEmit(true, true, true, true, address(posValidatorManager)); + emit DelegatorAdded({ + delegationID: keccak256(abi.encodePacked(validationID, expectedNonce)), + validationID: validationID, + delegatorAddress: delegatorAddress, + nonce: expectedNonce, + validatorWeight: expectedValidatorWeight, + delegatorWeight: weight, + setWeightMessageID: bytes32(0) + }); + + return _initializeDelegatorRegistration(validationID, delegatorAddress, weight); + } + + function _setUpCompleteDelegatorRegistration( + bytes32 validationID, + bytes32 delegationID, + uint64 completeRegistrationTimestamp, + uint64 expectedValidatorWeight, + uint64 expectedNonce + ) internal returns (bytes32) { + bytes memory setValidatorWeightPayload = ValidatorMessages + .packSubnetValidatorWeightUpdateMessage( + validationID, expectedNonce, expectedValidatorWeight + ); + _mockGetPChainWarpMessage(setValidatorWeightPayload, true); + + vm.warp(completeRegistrationTimestamp); + vm.expectEmit(true, true, true, true, address(posValidatorManager)); + emit DelegatorRegistered({ + delegationID: delegationID, + validationID: validationID, + nonce: expectedNonce, + startTime: completeRegistrationTimestamp + }); + posValidatorManager.completeDelegatorRegistration(0, delegationID); + return delegationID; + } + + function _setUpInitializeEndDelegation( + bytes32 validationID, + address delegatorAddress, + bytes32 delegationID, + uint64 startDelegationTimestamp, + uint64 endDelegationTimestamp, + uint64 expectedValidatorWeight, + uint64 expectedNonce + ) internal returns (bytes32) { + vm.warp(endDelegationTimestamp); + bytes memory setValidatorWeightPayload = ValidatorMessages + .packSetSubnetValidatorWeightMessage(validationID, expectedNonce, expectedValidatorWeight); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + bytes memory uptimeMsg = ValidatorMessages.packValidationUptimeMessage( + validationID, endDelegationTimestamp - startDelegationTimestamp + ); + _mockGetUptimeWarpMessage(uptimeMsg, true); + _mockGetBlockchainID(); + + vm.expectEmit(true, true, true, true, address(posValidatorManager)); + emit ValidatorWeightUpdate({ + validationID: validationID, + nonce: expectedNonce, + validatorWeight: expectedValidatorWeight, + setWeightMessageID: bytes32(0) + }); + vm.expectEmit(true, true, true, true, address(posValidatorManager)); + emit DelegatorRemovalInitialized({ + delegationID: delegationID, + validationID: validationID, + endTime: endDelegationTimestamp + }); + + vm.prank(delegatorAddress); + posValidatorManager.initializeEndDelegation(delegationID, true, 0); + return delegationID; + } + + function _setUpCompleteEndValidation( + bytes32 validationID, + address validatorOwner, + uint256 expectedReward, + uint64 validatorWeight + ) internal { + bytes memory subnetValidatorRegistrationMessage = + ValidatorMessages.packSubnetValidatorRegistrationMessage(validationID, false); + + _mockGetPChainWarpMessage(subnetValidatorRegistrationMessage, true); + + vm.expectEmit(true, true, true, true, address(posValidatorManager)); + emit ValidationPeriodEnded(validationID, ValidatorStatus.Completed); + uint256 balanceBefore = _getStakeAssetBalance(validatorOwner); + + _expectStakeUnlock(validatorOwner, _weightToValue(validatorWeight)); + _expectRewardIssuance(validatorOwner, expectedReward); + + posValidatorManager.completeEndValidation(0); + + assertEq( + _getStakeAssetBalance(validatorOwner), + balanceBefore + _weightToValue(validatorWeight) + expectedReward + ); + } + + function _setUpCompleteEndDelegation( + bytes32 validationID, + bytes32 delegationID, + address delegator, + uint64 delegatorWeight, + uint256 expectedReward, + uint256 expectedFees, + uint64 validatorWeight, + uint64 expectedValidatorWeight, + uint64 expectedNonce + ) internal returns (bytes32) { + bytes memory weightUpdateMessage = ValidatorMessages.packSubnetValidatorWeightUpdateMessage( + validationID, expectedNonce, validatorWeight + ); + _mockGetPChainWarpMessage(weightUpdateMessage, true); + + vm.expectEmit(true, true, true, true, address(posValidatorManager)); + emit DelegationEnded(delegationID, validationID, expectedReward, expectedFees); + uint256 balanceBefore = _getStakeAssetBalance(delegator); + + _expectStakeUnlock(delegator, _weightToValue(delegatorWeight)); + _expectRewardIssuance(delegator, expectedReward); + + posValidatorManager.completeEndDelegation(0, delegationID); + + assertEq(posValidatorManager.getWeight(validationID), expectedValidatorWeight); + assertEq( + _getStakeAssetBalance(delegator), + balanceBefore + _weightToValue(delegatorWeight) + expectedReward + ); + return delegationID; + } + + function _getStakeAssetBalance(address account) internal virtual returns (uint256); + function _expectStakeUnlock(address account, uint256 amount) internal virtual; + function _expectRewardIssuance(address account, uint256 amount) internal virtual; +} diff --git a/contracts/validator-manager/tests/ValidatorManagerTests.t.sol b/contracts/validator-manager/tests/ValidatorManagerTests.t.sol new file mode 100644 index 000000000..373acd357 --- /dev/null +++ b/contracts/validator-manager/tests/ValidatorManagerTests.t.sol @@ -0,0 +1,499 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {ValidatorManager, SubnetConversionData, InitialValidator} from "../ValidatorManager.sol"; +import {ValidatorMessages} from "../ValidatorMessages.sol"; +import {ValidatorStatus, ValidatorRegistrationInput} from "../interfaces/IValidatorManager.sol"; +import { + WarpMessage, + IWarpMessenger +} from "@avalabs/subnet-evm-contracts@1.2.0/contracts/interfaces/IWarpMessenger.sol"; + +// TODO: Remove this once all unit tests implemented +// solhint-disable no-empty-blocks +abstract contract ValidatorManagerTest is Test { + bytes32 public constant DEFAULT_SUBNET_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + bytes32 public constant DEFAULT_NODE_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + bytes32 public constant DEFAULT_INITIAL_VALIDATOR_NODE_ID = + bytes32(hex"2345678123456781234567812345678123456781234567812345678123456781"); + bytes public constant DEFAULT_BLS_PUBLIC_KEY = bytes( + hex"123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678" + ); + bytes32 public constant DEFAULT_SOURCE_BLOCKCHAIN_ID = + bytes32(hex"abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd"); + bytes32 public constant DEFAULT_SUBNET_CONVERSION_TX_ID = + bytes32(hex"1fa884c03c55ff866c210963db9100dd14964615da464c6b9871854374bb6026"); + address public constant WARP_PRECOMPILE_ADDRESS = 0x0200000000000000000000000000000000000005; + + uint64 public constant DEFAULT_WEIGHT = 1e6; + uint64 public constant DEFAULT_INITIAL_VALIDATOR_WEIGHT = DEFAULT_WEIGHT * 1e4; + uint256 public constant DEFAULT_MINIMUM_STAKE_AMOUNT = 20e12; + uint256 public constant DEFAULT_MAXIMUM_STAKE_AMOUNT = 1e22; + uint64 public constant DEFAULT_CHURN_PERIOD = 1 hours; + uint8 public constant DEFAULT_MAXIMUM_CHURN_PERCENTAGE = 20; + uint64 public constant DEFAULT_EXPIRY = 1000; + uint8 public constant DEFAULT_MAXIMUM_HOURLY_CHURN = 0; + uint64 public constant DEFAULT_REGISTRATION_TIMESTAMP = 1000; + uint256 public constant DEFAULT_STARTING_TOTAL_WEIGHT = 1e10; + uint64 public constant DEFAULT_COMPLETION_TIMESTAMP = 100_000; + + ValidatorManager public validatorManager; + + // Used to create unique validator IDs in {_newNodeID} + uint64 public nodeIDCounter = 0; + + event ValidationPeriodCreated( + bytes32 indexed validationID, + bytes32 indexed nodeID, + bytes32 indexed registerValidationMessageID, + uint256 weight, + uint64 registrationExpiry + ); + + event ValidationPeriodRegistered( + bytes32 indexed validationID, uint256 stakeAmount, uint256 timestamp + ); + + event ValidatorRemovalInitialized( + bytes32 indexed validationID, + bytes32 indexed setWeightMessageID, + uint256 stakeAmount, + uint256 endTime + ); + + event ValidationPeriodEnded(bytes32 indexed validationID, ValidatorStatus indexed status); + + receive() external payable {} + fallback() external payable {} + + function testInitializeValidatorRegistrationSuccess() public { + _setUpInitializeValidatorRegistration( + DEFAULT_NODE_ID, + DEFAULT_SUBNET_ID, + DEFAULT_WEIGHT, + DEFAULT_EXPIRY, + DEFAULT_BLS_PUBLIC_KEY + ); + } + + function testInitializeValidatorRegistrationExcessiveChurn() public { + // TODO: implement + } + + function testInitializeValidatorRegistrationInsufficientStake() public { + // TODO: implement + } + + function testInitializeValidatorRegistrationExcessiveStake() public { + // TODO: implement + } + + function testInitializeValidatorRegistrationInsufficientDuration() public { + // TODO: implement + } + + // The following tests call functions that are implemented in ValidatorManager, but access state that's + // only set in NativeTokenValidatorManager. Therefore we call them via the concrete type, rather than a + // reference to the abstract type. + function testResendRegisterValidatorMessage() public { + bytes32 validationID = _setUpInitializeValidatorRegistration( + DEFAULT_NODE_ID, + DEFAULT_SUBNET_ID, + DEFAULT_WEIGHT, + DEFAULT_EXPIRY, + DEFAULT_BLS_PUBLIC_KEY + ); + (, bytes memory registerSubnetValidatorMessage) = ValidatorMessages + .packRegisterSubnetValidatorMessage( + ValidatorMessages.ValidationPeriod({ + subnetID: DEFAULT_SUBNET_ID, + nodeID: DEFAULT_NODE_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }) + ); + _mockSendWarpMessage(registerSubnetValidatorMessage, bytes32(0)); + validatorManager.resendRegisterValidatorMessage(validationID); + } + + function testCompleteValidatorRegistration() public { + _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + } + + function testInitializeEndValidation() public virtual { + _setUpInitializeEndValidation({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP + }); + } + + function testResendEndValidation() public virtual { + bytes32 validationID = _setUpInitializeEndValidation({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP + }); + bytes memory setValidatorWeightPayload = + ValidatorMessages.packSetSubnetValidatorWeightMessage(validationID, 1, 0); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + validatorManager.resendEndValidatorMessage(validationID); + } + + function testCompleteEndValidation() public virtual { + bytes32 validationID = _setUpInitializeEndValidation({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, + completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP + }); + bytes memory subnetValidatorRegistrationMessage = + ValidatorMessages.packSubnetValidatorRegistrationMessage(validationID, false); + + _mockGetPChainWarpMessage(subnetValidatorRegistrationMessage, true); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit ValidationPeriodEnded(validationID, ValidatorStatus.Completed); + + validatorManager.completeEndValidation(0); + } + + function testCompleteInvalidatedValidation() public { + bytes32 validationID = _setUpInitializeValidatorRegistration( + DEFAULT_NODE_ID, + DEFAULT_SUBNET_ID, + DEFAULT_WEIGHT, + DEFAULT_EXPIRY, + DEFAULT_BLS_PUBLIC_KEY + ); + bytes memory subnetValidatorRegistrationMessage = + ValidatorMessages.packSubnetValidatorRegistrationMessage(validationID, false); + + _mockGetPChainWarpMessage(subnetValidatorRegistrationMessage, true); + + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit ValidationPeriodEnded(validationID, ValidatorStatus.Invalidated); + + validatorManager.completeEndValidation(0); + } + + function testCummulativeChurnRegistration() public { + uint64 churnThreshold = + uint64(DEFAULT_STARTING_TOTAL_WEIGHT) * DEFAULT_MAXIMUM_CHURN_PERCENTAGE / 100; + _beforeSend(_weightToValue(churnThreshold), address(this)); + + // First registration should succeed + _setUpCompleteValidatorRegistration({ + nodeID: _newNodeID(), + subnetID: DEFAULT_SUBNET_ID, + weight: churnThreshold, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + + _beforeSend(DEFAULT_MINIMUM_STAKE_AMOUNT, address(this)); // TODO may need to be updated with minimum stake amount + + // Second call should fail + vm.expectRevert(ValidatorManager.MaxChurnRateExceeded.selector); + _initializeValidatorRegistration( + ValidatorRegistrationInput({ + nodeID: DEFAULT_NODE_ID, + registrationExpiry: DEFAULT_REGISTRATION_TIMESTAMP + 1, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }), + _valueToWeight(DEFAULT_MINIMUM_STAKE_AMOUNT) + ); + } + + function testCummulativeChurnRegistrationAndEndValidation() public { + // Registration should succeed + bytes32 validationID = _setUpCompleteValidatorRegistration({ + nodeID: DEFAULT_NODE_ID, + subnetID: DEFAULT_SUBNET_ID, + weight: _valueToWeight(DEFAULT_MINIMUM_STAKE_AMOUNT), + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + }); + + uint64 churnThreshold = + uint64(DEFAULT_STARTING_TOTAL_WEIGHT) * DEFAULT_MAXIMUM_CHURN_PERCENTAGE / 100; + _beforeSend(_weightToValue(churnThreshold), address(this)); + + // Registration should succeed + _setUpCompleteValidatorRegistration({ + nodeID: _newNodeID(), + subnetID: DEFAULT_SUBNET_ID, + weight: churnThreshold, + registrationExpiry: DEFAULT_EXPIRY + 25 hours, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, + registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP + 25 hours + }); + + // Second call should fail + vm.expectRevert(ValidatorManager.MaxChurnRateExceeded.selector); + _initializeEndValidation(validationID, false); + } + + function _newNodeID() internal returns (bytes32) { + nodeIDCounter++; + return sha256(new bytes(nodeIDCounter)); + } + + function _setUpInitializeValidatorRegistration( + bytes32 nodeID, + bytes32 subnetID, + uint64 weight, + uint64 registrationExpiry, + bytes memory blsPublicKey + ) internal returns (bytes32 validationID) { + (validationID,) = ValidatorMessages.packRegisterSubnetValidatorMessage( + ValidatorMessages.ValidationPeriod({ + nodeID: nodeID, + subnetID: subnetID, + weight: weight, + registrationExpiry: registrationExpiry, + blsPublicKey: blsPublicKey + }) + ); + (, bytes memory registerSubnetValidatorMessage) = ValidatorMessages + .packRegisterSubnetValidatorMessage( + ValidatorMessages.ValidationPeriod({ + subnetID: subnetID, + nodeID: nodeID, + weight: weight, + registrationExpiry: registrationExpiry, + blsPublicKey: blsPublicKey + }) + ); + vm.warp(registrationExpiry - 1); + _mockSendWarpMessage(registerSubnetValidatorMessage, bytes32(0)); + + _beforeSend(_weightToValue(weight), address(this)); + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit ValidationPeriodCreated(validationID, nodeID, bytes32(0), weight, registrationExpiry); + + _initializeValidatorRegistration( + ValidatorRegistrationInput({ + nodeID: nodeID, + registrationExpiry: registrationExpiry, + blsPublicKey: blsPublicKey + }), + weight + ); + } + + function _setUpCompleteValidatorRegistration( + bytes32 nodeID, + bytes32 subnetID, + uint64 weight, + uint64 registrationExpiry, + bytes memory blsPublicKey, + uint64 registrationTimestamp + ) internal returns (bytes32 validationID) { + validationID = _setUpInitializeValidatorRegistration( + nodeID, subnetID, weight, registrationExpiry, blsPublicKey + ); + bytes memory subnetValidatorRegistrationMessage = + ValidatorMessages.packSubnetValidatorRegistrationMessage(validationID, true); + + _mockGetPChainWarpMessage(subnetValidatorRegistrationMessage, true); + + vm.warp(registrationTimestamp); + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit ValidationPeriodRegistered(validationID, weight, registrationTimestamp); + + validatorManager.completeValidatorRegistration(0); + } + + function _setUpInitializeEndValidation( + bytes32 nodeID, + bytes32 subnetID, + uint64 weight, + uint64 registrationExpiry, + bytes memory blsPublicKey, + uint64 registrationTimestamp, + uint64 completionTimestamp + ) internal returns (bytes32 validationID) { + return _setUpInitializeEndValidation({ + nodeID: nodeID, + subnetID: subnetID, + weight: weight, + registrationExpiry: registrationExpiry, + blsPublicKey: blsPublicKey, + registrationTimestamp: registrationTimestamp, + completionTimestamp: completionTimestamp, + includeUptime: false + }); + } + + function _setUpInitializeEndValidation( + bytes32 nodeID, + bytes32 subnetID, + uint64 weight, + uint64 registrationExpiry, + bytes memory blsPublicKey, + uint64 registrationTimestamp, + uint64 completionTimestamp, + bool includeUptime + ) internal returns (bytes32 validationID) { + validationID = _setUpCompleteValidatorRegistration({ + nodeID: nodeID, + subnetID: subnetID, + weight: weight, + registrationExpiry: registrationExpiry, + blsPublicKey: blsPublicKey, + registrationTimestamp: registrationTimestamp + }); + + vm.warp(completionTimestamp); + bytes memory setValidatorWeightPayload = + ValidatorMessages.packSetSubnetValidatorWeightMessage(validationID, 1, 0); + _mockSendWarpMessage(setValidatorWeightPayload, bytes32(0)); + if (includeUptime) { + bytes memory uptimeMsg = ValidatorMessages.packValidationUptimeMessage( + validationID, completionTimestamp - registrationTimestamp + ); + _mockGetUptimeWarpMessage(uptimeMsg, true); + _mockGetBlockchainID(); + } + vm.expectEmit(true, true, true, true, address(validatorManager)); + emit ValidatorRemovalInitialized(validationID, bytes32(0), weight, completionTimestamp); + + _initializeEndValidation(validationID, includeUptime); + } + + function _mockSendWarpMessage(bytes memory payload, bytes32 expectedMessageID) internal { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encode(IWarpMessenger.sendWarpMessage.selector), + abi.encode(expectedMessageID) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.sendWarpMessage, payload) + ); + } + + function _mockGetPChainWarpMessage(bytes memory expectedPayload, bool valid) internal { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode( + WarpMessage({ + sourceChainID: validatorManager.P_CHAIN_BLOCKCHAIN_ID(), + originSenderAddress: address(0), + payload: expectedPayload + }), + valid + ) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, 0) + ); + } + + function _mockGetUptimeWarpMessage(bytes memory expectedPayload, bool valid) internal { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getVerifiedWarpMessage.selector, uint32(0)), + abi.encode( + WarpMessage({ + sourceChainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + originSenderAddress: address(0), + payload: expectedPayload + }), + valid + ) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeCall(IWarpMessenger.getVerifiedWarpMessage, 0) + ); + } + + function _mockGetBlockchainID() internal { + _mockGetBlockchainID(DEFAULT_SOURCE_BLOCKCHAIN_ID); + } + + function _mockGetBlockchainID(bytes32 blockchainID) internal { + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector), + abi.encode(blockchainID) + ); + vm.expectCall( + WARP_PRECOMPILE_ADDRESS, abi.encodeWithSelector(IWarpMessenger.getBlockchainID.selector) + ); + } + + function _mockInitializeValidatorSet() internal { + _mockGetPChainWarpMessage( + ValidatorMessages.packSubnetConversionMessage(DEFAULT_SUBNET_CONVERSION_TX_ID), true + ); + } + + function _initializeValidatorRegistration( + ValidatorRegistrationInput memory input, + uint64 weight + ) internal virtual returns (bytes32); + + function _initializeEndValidation(bytes32 validationID, bool includeUptime) internal virtual; + + function _beforeSend(uint256 amount, address spender) internal virtual; + + function _defaultSubnetConversionData() internal view returns (SubnetConversionData memory) { + InitialValidator[] memory initialValidators = new InitialValidator[](1); + initialValidators[0] = InitialValidator({ + nodeID: DEFAULT_INITIAL_VALIDATOR_NODE_ID, + weight: DEFAULT_INITIAL_VALIDATOR_WEIGHT, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }); + return SubnetConversionData({ + convertSubnetTxID: bytes32(0), + validatorManagerBlockchainID: DEFAULT_SOURCE_BLOCKCHAIN_ID, + validatorManagerAddress: address(validatorManager), + initialValidators: initialValidators + }); + } + + // TODO this needs to be kept in line with the contract conversions, but we can't make external calls + // to the contract and use vm.expectRevert at the same time. + // These are okay to use for PoA as well, because they're just used for conversions inside the tests. + function _valueToWeight(uint256 value) internal pure returns (uint64) { + return uint64(value / 1e12); + } + + // TODO this needs to be kept in line with the contract conversions, but we can't make external calls + // to the contract and use vm.expectRevert at the same time. + // These are okay to use for PoA as well, because they're just used for conversions inside the tests. + function _weightToValue(uint64 weight) internal pure returns (uint256) { + return uint256(weight) * 1e12; + } +} +// solhint-enable no-empty-blocks diff --git a/contracts/validator-manager/tests/ValidatorMessagesTests.t.sol b/contracts/validator-manager/tests/ValidatorMessagesTests.t.sol new file mode 100644 index 000000000..b8fb9e1a2 --- /dev/null +++ b/contracts/validator-manager/tests/ValidatorMessagesTests.t.sol @@ -0,0 +1,87 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.25; + +import {Test} from "@forge-std/Test.sol"; +import {ValidatorMessages} from "../ValidatorMessages.sol"; + +contract ValidatorMessagesTest is Test { + bytes32 public constant DEFAULT_SUBNET_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + bytes32 public constant DEFAULT_NODE_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + bytes public constant DEFAULT_BLS_PUBLIC_KEY = bytes( + hex"123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678" + ); + bytes32 public constant DEFAULT_VALIDATION_ID = + bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); + uint64 public constant DEFAULT_WEIGHT = 1e6; + uint64 public constant DEFAULT_EXPIRY = 1000; + + function testRegisterSubnetValidatorMessage() public pure { + (bytes32 validationID, bytes memory packed) = ValidatorMessages + .packRegisterSubnetValidatorMessage( + ValidatorMessages.ValidationPeriod({ + subnetID: DEFAULT_SUBNET_ID, + nodeID: DEFAULT_NODE_ID, + weight: DEFAULT_WEIGHT, + registrationExpiry: DEFAULT_EXPIRY, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY + }) + ); + + ValidatorMessages.ValidationPeriod memory info = + ValidatorMessages.unpackRegisterSubnetValidatorMessage(packed); + assertEq(info.subnetID, DEFAULT_SUBNET_ID); + assertEq(info.nodeID, DEFAULT_NODE_ID); + assertEq(info.weight, DEFAULT_WEIGHT); + assertEq(info.registrationExpiry, DEFAULT_EXPIRY); + assertEq(info.blsPublicKey, DEFAULT_BLS_PUBLIC_KEY); + + (bytes32 recoveredID,) = ValidatorMessages.packRegisterSubnetValidatorMessage(info); + assertEq(recoveredID, validationID); + } + + function testSubnetValidatorRegistrationMessage() public pure { + bytes memory packed = + ValidatorMessages.packSubnetValidatorRegistrationMessage(DEFAULT_VALIDATION_ID, true); + (bytes32 validationID, bool valid) = + ValidatorMessages.unpackSubnetValidatorRegistrationMessage(packed); + assertEq(validationID, DEFAULT_VALIDATION_ID); + assert(valid); + } + + function testSetSubnetValidatorWeightMessage() public pure { + bytes memory packed = ValidatorMessages.packSetSubnetValidatorWeightMessage( + DEFAULT_VALIDATION_ID, 100, DEFAULT_WEIGHT + ); + (bytes32 validationID, uint64 nonce, uint64 weight) = + ValidatorMessages.unpackSetSubnetValidatorWeightMessage(packed); + assertEq(validationID, DEFAULT_VALIDATION_ID); + assertEq(nonce, 100); + assertEq(weight, DEFAULT_WEIGHT); + } + + function testSubnetValidatorWeightUpdateMessag() public pure { + bytes memory packed = ValidatorMessages.packSubnetValidatorWeightUpdateMessage( + DEFAULT_VALIDATION_ID, 100, DEFAULT_WEIGHT + ); + (bytes32 validationID, uint64 nonce, uint64 weight) = + ValidatorMessages.unpackSubnetValidatorWeightUpdateMessage(packed); + assertEq(validationID, DEFAULT_VALIDATION_ID); + assertEq(nonce, 100); + assertEq(weight, DEFAULT_WEIGHT); + } + + function testValidationUptimeMessage() public pure { + bytes memory packed = + ValidatorMessages.packValidationUptimeMessage(DEFAULT_VALIDATION_ID, 100); + (bytes32 validationID, uint64 uptime) = + ValidatorMessages.unpackValidationUptimeMessage(packed); + assertEq(validationID, DEFAULT_VALIDATION_ID); + assertEq(uptime, 100); + } +} diff --git a/go.mod b/go.mod index 0f21e7966..da15b08a4 100644 --- a/go.mod +++ b/go.mod @@ -3,16 +3,18 @@ module github.com/ava-labs/teleporter go 1.22.6 require ( - github.com/ava-labs/avalanchego v1.11.10 + github.com/ava-labs/avalanchego v1.11.11-0.20240916181957-b328a0503042 github.com/supranational/blst v0.3.11 // indirect ) require ( - github.com/ava-labs/subnet-evm v0.6.8 + github.com/ava-labs/awm-relayer v1.4.0-rc.2.0.20240814200841-1c435873fd12 + github.com/ava-labs/subnet-evm v0.6.9-0.20240813192818-4d5aebb6decc github.com/ethereum/go-ethereum v1.13.8 github.com/onsi/ginkgo/v2 v2.20.2 github.com/onsi/gomega v1.34.2 github.com/pkg/errors v0.9.1 + github.com/prometheus/client_golang v1.19.1 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 @@ -23,13 +25,13 @@ require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect - github.com/ava-labs/coreth v0.13.7 // indirect + github.com/ava-labs/coreth v0.13.8-fix-genesis-upgrade // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/btcutil v1.1.3 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect @@ -58,7 +60,6 @@ require ( github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -69,7 +70,7 @@ require ( github.com/gorilla/rpc v1.2.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect github.com/hashicorp/go-bexpr v0.1.10 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -87,7 +88,6 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect @@ -97,10 +97,9 @@ require ( github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pires/go-proxyproto v0.6.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.48.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/cors v1.7.0 // indirect @@ -140,9 +139,9 @@ require ( golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.3.0 // indirect gonum.org/v1/gonum v0.11.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect - google.golang.org/grpc v1.64.1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect diff --git a/go.sum b/go.sum index 53120677d..e3aceb38b 100644 --- a/go.sum +++ b/go.sum @@ -56,12 +56,14 @@ github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/avalanchego v1.11.10 h1:QujciF5OEp5FwAoe/RciFF/i47rxU5rkEr6fVuUBS1Q= -github.com/ava-labs/avalanchego v1.11.10/go.mod h1:POgZPryqe80OeHCDNrXrPOKoFre736iFuMgmUBeKaLc= -github.com/ava-labs/coreth v0.13.7 h1:k8T9u/ROifl8f7oXjHRc1KvSISRl9txvy7gGVmHEz6g= -github.com/ava-labs/coreth v0.13.7/go.mod h1:tXDujonxXFOF6oK5HS2EmgtSXJK3Gy6RpZxb5WzR9rM= -github.com/ava-labs/subnet-evm v0.6.8 h1:IrHGajBYWs692YIYdd5J0oVWWt88Q/XAZQq/dOtkHFw= -github.com/ava-labs/subnet-evm v0.6.8/go.mod h1:qt8DXyGm40CY9yffNOe1+4yUyL9mD3v5RPWqAuGj5u4= +github.com/ava-labs/avalanchego v1.11.11-0.20240916181957-b328a0503042 h1:Hk9sK9TPPXoVyIvl4rC+v1HF2M2BvjINCLtLmkbqWMo= +github.com/ava-labs/avalanchego v1.11.11-0.20240916181957-b328a0503042/go.mod h1:8pnf2At/q0LRq5dvYJYn3CkhKzZNHRd5pjARC9psu+g= +github.com/ava-labs/awm-relayer v1.4.0-rc.2.0.20240814200841-1c435873fd12 h1:vcCa4wZTDPObQFauhjtkAqbHWty3vXQaoPJMFgptnWM= +github.com/ava-labs/awm-relayer v1.4.0-rc.2.0.20240814200841-1c435873fd12/go.mod h1:cpfI3E4g0NsEjhJ9VHJ4xMLyOOAqqL1by0MhTIito/c= +github.com/ava-labs/coreth v0.13.8-fix-genesis-upgrade h1:xWsvSGtZcGna3B2BLU2BvK3qskbcc9ZNtgC0ck91CkI= +github.com/ava-labs/coreth v0.13.8-fix-genesis-upgrade/go.mod h1:Ouul9dJouniUIJVX1gDqx8CrHyGvmwZkK28mrgKb/4I= +github.com/ava-labs/subnet-evm v0.6.9-0.20240813192818-4d5aebb6decc h1:FZ09oIkRnrI+FLTReCKfWqNHFDrNQVr629NTkdfr22Y= +github.com/ava-labs/subnet-evm v0.6.9-0.20240813192818-4d5aebb6decc/go.mod h1:nWP5feXpdvF4Kv10V0vrP9bYqt5yYvp2I5bBXY2xa7U= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -96,8 +98,9 @@ github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -230,8 +233,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= -github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -319,8 +322,8 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -414,8 +417,6 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -479,15 +480,15 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -962,10 +963,10 @@ google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= -google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -984,8 +985,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= -google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts index 659f3063f..dbb6104ce 160000 --- a/lib/openzeppelin-contracts +++ b/lib/openzeppelin-contracts @@ -1 +1 @@ -Subproject commit 659f3063f82422cef820de746444e6f6cba6ca7c +Subproject commit dbb6104ce834628e473d2173bbc9d47f81a9eec3 diff --git a/lib/openzeppelin-contracts-upgradeable b/lib/openzeppelin-contracts-upgradeable index f1b3e103c..723f8cab0 160000 --- a/lib/openzeppelin-contracts-upgradeable +++ b/lib/openzeppelin-contracts-upgradeable @@ -1 +1 @@ -Subproject commit f1b3e103cd6d48861e71357a7ac32b416c1b066f +Subproject commit 723f8cab09cdae1aca9ec9cc1cfa040c2d4b06c1 diff --git a/scripts/abi_bindings.sh b/scripts/abi_bindings.sh index 737b13eec..b93d76422 100755 --- a/scripts/abi_bindings.sh +++ b/scripts/abi_bindings.sh @@ -16,7 +16,11 @@ export ARCH=$(uname -m) [ $ARCH = x86_64 ] && ARCH=amd64 echo "ARCH set to $ARCH" -DEFAULT_CONTRACT_LIST="TeleporterMessenger TeleporterRegistry ExampleERC20 TestMessenger ValidatorSetSig" +DEFAULT_CONTRACT_LIST="TeleporterMessenger TeleporterRegistry ExampleERC20 ExampleRewardCalculator TestMessenger ValidatorSetSig NativeTokenStakingManager ERC20TokenStakingManager PoAValidatorManager" + +PROXY_LIST="TransparentUpgradeableProxy ProxyAdmin" + +SUBNET_EVM_LIST="INativeMinter" CONTRACT_LIST= HELP= @@ -50,7 +54,7 @@ go install github.com/ava-labs/subnet-evm/cmd/abigen@${SUBNET_EVM_VERSION} # compilations that did not generate new ABI files. echo "Building Contracts" cd $TELEPORTER_PATH -forge build --force --extra-output-files abi bin +forge build --skip test --force --extra-output-files abi bin function convertToLower() { if [ "$ARCH" = 'arm64' ]; then @@ -60,6 +64,30 @@ function convertToLower() { fi } +function generate_bindings() { + local contract_names=("$@") + for contract_name in "${contract_names[@]}" + do + path=$(find . -name $contract_name.sol) + dir=$(dirname $path) + abi_file=$TELEPORTER_PATH/out/$contract_name.sol/$contract_name.abi.json + if ! [ -f $abi_file ]; then + echo "Error: Contract $contract_name abi file not found" + exit 1 + fi + + echo "Generating Go bindings for $contract_name..." + gen_path=$TELEPORTER_PATH/abi-bindings/go/$dir/$contract_name + mkdir -p $gen_path + $GOPATH/bin/abigen --abi $abi_file \ + --pkg $(convertToLower $contract_name) \ + --bin $TELEPORTER_PATH/out/$contract_name.sol/$contract_name.bin \ + --type $contract_name \ + --out $gen_path/$contract_name.go + echo "Done generating Go bindings for $contract_name." + done +} + contract_names=($CONTRACT_LIST) # If CONTRACT_LIST is empty, use DEFAULT_CONTRACT_LIST @@ -68,25 +96,20 @@ if [[ -z "${CONTRACT_LIST}" ]]; then fi cd $TELEPORTER_PATH/contracts -for contract_name in "${contract_names[@]}" -do - path=$(find . -name $contract_name.sol) - dir=$(dirname $path) - abi_file=$TELEPORTER_PATH/out/$contract_name.sol/$contract_name.abi.json - if ! [ -f $abi_file ]; then - echo "Error: Contract $contract_name abi file not found" - exit 1 - fi +generate_bindings "${contract_names[@]}" - echo "Generating Go bindings for $contract_name..." - gen_path=$TELEPORTER_PATH/abi-bindings/go/$dir/$contract_name - mkdir -p $gen_path - $GOPATH/bin/abigen --abi $abi_file \ - --pkg $(convertToLower $contract_name) \ - --bin $TELEPORTER_PATH/out/$contract_name.sol/$contract_name.bin \ - --type $contract_name \ - --out $gen_path/$contract_name.go - echo "Done generating Go bindings for $contract_name." -done +contract_names=($PROXY_LIST) +cd $TELEPORTER_PATH/ +forge build --skip test --force --extra-output-files abi bin --contracts lib/openzeppelin-contracts/contracts/proxy/transparent + +cd $TELEPORTER_PATH/lib/openzeppelin-contracts/contracts/proxy/transparent +generate_bindings "${contract_names[@]}" + +contract_names=($SUBNET_EVM_LIST) +cd $TELEPORTER_PATH/ +forge build --skip test --force --extra-output-files abi bin --contracts lib/subnet-evm/contracts/contracts/interfaces + +cd $TELEPORTER_PATH/lib/subnet-evm/contracts/contracts/interfaces +generate_bindings "${contract_names[@]}" exit 0 diff --git a/scripts/local/e2e_test.sh b/scripts/local/e2e_test.sh index ba0b7db67..cb77922f8 100755 --- a/scripts/local/e2e_test.sh +++ b/scripts/local/e2e_test.sh @@ -27,7 +27,7 @@ export AVALANCHEGO_BUILD_PATH=$BASEDIR/avalanchego cd $TELEPORTER_PATH if command -v forge &> /dev/null; then - forge build + forge build --skip test else echo "Forge command not found, attempting to use from $HOME" $HOME/.foundry/bin/forge build diff --git a/scripts/versions.sh b/scripts/versions.sh index a168ee2c2..fe3fbd81a 100755 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -16,7 +16,7 @@ function getDepVersion() { grep -m1 "^\s*$1" $TELEPORTER_PATH/go.mod | cut -d ' ' -f2 } -extract_commit() { +function extract_commit() { local version=$1 if [[ $version == *-* ]]; then # Extract the substring after the last '-' @@ -29,9 +29,10 @@ extract_commit() { AWM_RELAYER_VERSION=${AWM_RELAYER_VERSION:-'v1.0.0'} # Don't export them as they're used in the context of other calls -AVALANCHEGO_VERSION=${AVALANCHEGO_VERSION:-$(getDepVersion github.com/ava-labs/avalanchego)} -GINKGO_VERSION=${GINKGO_VERSION:-$(getDepVersion github.com/onsi/ginkgo/v2)} -SUBNET_EVM_VERSION=${SUBNET_EVM_VERSION:-$(getDepVersion github.com/ava-labs/subnet-evm)} +AVALANCHEGO_VERSION=${AVALANCHEGO_VERSION:-$(extract_commit "$(getDepVersion github.com/ava-labs/avalanchego)")} +GINKGO_VERSION=${GINKGO_VERSION:-$(extract_commit "$(getDepVersion github.com/onsi/ginkgo/v2)")} +SUBNET_EVM_VERSION=${SUBNET_EVM_VERSION:-$(extract_commit "$(getDepVersion github.com/ava-labs/subnet-evm)")} + # Set golangci-lint version GOLANGCI_LINT_VERSION=${GOLANGCI_LINT_VERSION:-'v1.60'} diff --git a/tests/flows/errors.go b/tests/flows/errors.go index c3efc7ec4..9ba39996c 100644 --- a/tests/flows/errors.go +++ b/tests/flows/errors.go @@ -1,5 +1,5 @@ package flows const ( - errTxReverted = "execution reverted" + ErrTxReverted = "execution reverted" ) diff --git a/tests/flows/validator_set_sig.go b/tests/flows/governance/validator_set_sig.go similarity index 95% rename from tests/flows/validator_set_sig.go rename to tests/flows/governance/validator_set_sig.go index 20ed36e67..2901f1f9b 100644 --- a/tests/flows/validator_set_sig.go +++ b/tests/flows/governance/validator_set_sig.go @@ -1,4 +1,4 @@ -package flows +package governance import ( "context" @@ -85,7 +85,7 @@ func ValidatorSetSig(network interfaces.LocalNetwork) { // Construct a ValidatorSetSig message with mock ERC20 as the target contract // and mint 100 tokens as the TxPayload - callData, err := erc20ABI.Pack("mint", big.NewInt(100)) + callData, err := erc20ABI.Pack("mint", validatorSetSigContractAddress, big.NewInt(100)) Expect(err).Should(BeNil()) vssMessage1 := validatorsetsig.ValidatorSetSigMessage{ @@ -99,7 +99,7 @@ func ValidatorSetSig(network interfaces.LocalNetwork) { // Construct a second ValidatorSetSig message with mock ERC20 as the target contract // and mint 50 tokens as the TxPayload - callData2, err := erc20ABI.Pack("mint", big.NewInt(50)) + callData2, err := erc20ABI.Pack("mint", validatorSetSigContractAddress, big.NewInt(50)) Expect(err).Should(BeNil()) vssMessage2 := validatorsetsig.ValidatorSetSigMessage{ ValidatorSetSigAddress: validatorSetSigContractAddress, @@ -111,13 +111,18 @@ func ValidatorSetSig(network interfaces.LocalNetwork) { } // Create a message for the case where validatorSetSig contract and targetContract are on the same chain. + // Construct a ValidatorSetSig message with mock ERC20 as the target contract + // and mint 100 tokens as the TxPayload + callData3, err := erc20ABI.Pack("mint", validatorSetSigContractAddress2, big.NewInt(100)) + Expect(err).Should(BeNil()) + vssMessage3 := validatorsetsig.ValidatorSetSigMessage{ ValidatorSetSigAddress: validatorSetSigContractAddress2, TargetContractAddress: exampleERC20ContractAddressB, TargetBlockchainID: subnetB.BlockchainID, Nonce: big.NewInt(0), Value: big.NewInt(0), - Payload: callData, + Payload: callData3, } // Create chain config file with off-chain validatorsetsig message diff --git a/tests/flows/add_fee_amount.go b/tests/flows/teleporter/add_fee_amount.go similarity index 99% rename from tests/flows/add_fee_amount.go rename to tests/flows/teleporter/add_fee_amount.go index 0771d450d..1a05e6e81 100644 --- a/tests/flows/add_fee_amount.go +++ b/tests/flows/teleporter/add_fee_amount.go @@ -1,4 +1,4 @@ -package flows +package teleporter import ( "context" diff --git a/tests/flows/basic_send_receive.go b/tests/flows/teleporter/basic_send_receive.go similarity index 99% rename from tests/flows/basic_send_receive.go rename to tests/flows/teleporter/basic_send_receive.go index 8e4f8e036..fe31746c5 100644 --- a/tests/flows/basic_send_receive.go +++ b/tests/flows/teleporter/basic_send_receive.go @@ -1,4 +1,4 @@ -package flows +package teleporter import ( "context" diff --git a/tests/flows/deliver_to_nonexistent_contract.go b/tests/flows/teleporter/deliver_to_nonexistent_contract.go similarity index 99% rename from tests/flows/deliver_to_nonexistent_contract.go rename to tests/flows/teleporter/deliver_to_nonexistent_contract.go index d5502b26e..ce54899bb 100644 --- a/tests/flows/deliver_to_nonexistent_contract.go +++ b/tests/flows/teleporter/deliver_to_nonexistent_contract.go @@ -1,4 +1,4 @@ -package flows +package teleporter import ( "context" diff --git a/tests/flows/deliver_to_wrong_chain.go b/tests/flows/teleporter/deliver_to_wrong_chain.go similarity index 99% rename from tests/flows/deliver_to_wrong_chain.go rename to tests/flows/teleporter/deliver_to_wrong_chain.go index c0c406584..cbd83754c 100644 --- a/tests/flows/deliver_to_wrong_chain.go +++ b/tests/flows/teleporter/deliver_to_wrong_chain.go @@ -1,4 +1,4 @@ -package flows +package teleporter import ( "context" diff --git a/tests/flows/insufficient_gas.go b/tests/flows/teleporter/insufficient_gas.go similarity index 99% rename from tests/flows/insufficient_gas.go rename to tests/flows/teleporter/insufficient_gas.go index bd5761f08..0ce3b1ca6 100644 --- a/tests/flows/insufficient_gas.go +++ b/tests/flows/teleporter/insufficient_gas.go @@ -1,4 +1,4 @@ -package flows +package teleporter import ( "context" diff --git a/tests/flows/check_upgrade_access.go b/tests/flows/teleporter/registry/check_upgrade_access.go similarity index 95% rename from tests/flows/check_upgrade_access.go rename to tests/flows/teleporter/registry/check_upgrade_access.go index 023c47dd7..61f9b1683 100644 --- a/tests/flows/check_upgrade_access.go +++ b/tests/flows/teleporter/registry/check_upgrade_access.go @@ -1,13 +1,15 @@ -package flows +package registry import ( "context" "math/big" "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/teleporter/tests/flows" "github.com/ava-labs/teleporter/tests/interfaces" "github.com/ava-labs/teleporter/tests/utils" "github.com/ethereum/go-ethereum/crypto" + . "github.com/onsi/gomega" ) @@ -53,7 +55,7 @@ func CheckUpgradeAccess(network interfaces.Network) { Expect(err).Should(BeNil()) _, err = testMessenger.PauseTeleporterAddress(nonOwnerOpts, teleporterAddress) Expect(err).ShouldNot(BeNil()) - Expect(err.Error()).Should(ContainSubstring(errTxReverted)) + Expect(err.Error()).Should(ContainSubstring(flows.ErrTxReverted)) // Check that the teleporter address is not paused, because previous call should have failed isPaused, err := testMessenger.IsTeleporterAddressPaused(&bind.CallOpts{}, teleporterAddress) @@ -84,7 +86,7 @@ func CheckUpgradeAccess(network interfaces.Network) { // Try to call unpauseTeleporterAddress from the previous owner account _, err = testMessenger.UnpauseTeleporterAddress(ownerOpts, teleporterAddress) Expect(err).ShouldNot(BeNil()) - Expect(err.Error()).Should(ContainSubstring(errTxReverted)) + Expect(err.Error()).Should(ContainSubstring(flows.ErrTxReverted)) // Make sure the teleporter address is still paused isPaused, err = testMessenger.IsTeleporterAddressPaused(&bind.CallOpts{}, teleporterAddress) diff --git a/tests/flows/pause_teleporter.go b/tests/flows/teleporter/registry/pause_teleporter.go similarity index 99% rename from tests/flows/pause_teleporter.go rename to tests/flows/teleporter/registry/pause_teleporter.go index 8cde4a3ad..41b44849d 100644 --- a/tests/flows/pause_teleporter.go +++ b/tests/flows/teleporter/registry/pause_teleporter.go @@ -1,4 +1,4 @@ -package flows +package registry import ( "context" diff --git a/tests/flows/teleporter_registry.go b/tests/flows/teleporter/registry/teleporter_registry.go similarity index 99% rename from tests/flows/teleporter_registry.go rename to tests/flows/teleporter/registry/teleporter_registry.go index da7bf91a9..d1d00d5d6 100644 --- a/tests/flows/teleporter_registry.go +++ b/tests/flows/teleporter/registry/teleporter_registry.go @@ -1,4 +1,4 @@ -package flows +package registry import ( "context" diff --git a/tests/flows/relay_message_twice.go b/tests/flows/teleporter/relay_message_twice.go similarity index 99% rename from tests/flows/relay_message_twice.go rename to tests/flows/teleporter/relay_message_twice.go index 3c91b7cd9..fec7100c4 100644 --- a/tests/flows/relay_message_twice.go +++ b/tests/flows/teleporter/relay_message_twice.go @@ -1,4 +1,4 @@ -package flows +package teleporter import ( "context" diff --git a/tests/flows/relayer_modifies_message.go b/tests/flows/teleporter/relayer_modifies_message.go similarity index 99% rename from tests/flows/relayer_modifies_message.go rename to tests/flows/teleporter/relayer_modifies_message.go index a0999f6b1..4011ebc6f 100644 --- a/tests/flows/relayer_modifies_message.go +++ b/tests/flows/teleporter/relayer_modifies_message.go @@ -1,4 +1,4 @@ -package flows +package teleporter import ( "context" diff --git a/tests/flows/resubmit_altered_message.go b/tests/flows/teleporter/resubmit_altered_message.go similarity index 99% rename from tests/flows/resubmit_altered_message.go rename to tests/flows/teleporter/resubmit_altered_message.go index 18435a9df..268c8b6cf 100644 --- a/tests/flows/resubmit_altered_message.go +++ b/tests/flows/teleporter/resubmit_altered_message.go @@ -1,4 +1,4 @@ -package flows +package teleporter import ( "context" diff --git a/tests/flows/retry_successful_execution.go b/tests/flows/teleporter/retry_successful_execution.go similarity index 99% rename from tests/flows/retry_successful_execution.go rename to tests/flows/teleporter/retry_successful_execution.go index f9834bbc5..d75439e0f 100644 --- a/tests/flows/retry_successful_execution.go +++ b/tests/flows/teleporter/retry_successful_execution.go @@ -1,4 +1,4 @@ -package flows +package teleporter import ( "context" diff --git a/tests/flows/send_specific_receipts.go b/tests/flows/teleporter/send_specific_receipts.go similarity index 99% rename from tests/flows/send_specific_receipts.go rename to tests/flows/teleporter/send_specific_receipts.go index 3e165a311..603074fe5 100644 --- a/tests/flows/send_specific_receipts.go +++ b/tests/flows/teleporter/send_specific_receipts.go @@ -1,4 +1,4 @@ -package flows +package teleporter import ( "bytes" diff --git a/tests/flows/teleporter_message_ids.go b/tests/flows/teleporter/teleporter_message_ids.go similarity index 98% rename from tests/flows/teleporter_message_ids.go rename to tests/flows/teleporter/teleporter_message_ids.go index 1ae8285b3..f0005c8a1 100644 --- a/tests/flows/teleporter_message_ids.go +++ b/tests/flows/teleporter/teleporter_message_ids.go @@ -1,7 +1,7 @@ // (c) 2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package flows +package teleporter import ( "math/big" diff --git a/tests/flows/unallowed_relayer.go b/tests/flows/teleporter/unallowed_relayer.go similarity index 99% rename from tests/flows/unallowed_relayer.go rename to tests/flows/teleporter/unallowed_relayer.go index 155f55079..fe9ba6c1e 100644 --- a/tests/flows/unallowed_relayer.go +++ b/tests/flows/teleporter/unallowed_relayer.go @@ -1,4 +1,4 @@ -package flows +package teleporter import ( "context" diff --git a/tests/flows/validator_churn.go b/tests/flows/teleporter/validator_churn.go similarity index 99% rename from tests/flows/validator_churn.go rename to tests/flows/teleporter/validator_churn.go index 316c4c8b9..8de4a8c3a 100644 --- a/tests/flows/validator_churn.go +++ b/tests/flows/teleporter/validator_churn.go @@ -1,4 +1,4 @@ -package flows +package teleporter import ( "context" diff --git a/tests/flows/validator-manager/erc20_delegation.go b/tests/flows/validator-manager/erc20_delegation.go new file mode 100644 index 000000000..4dd2cdc5e --- /dev/null +++ b/tests/flows/validator-manager/erc20_delegation.go @@ -0,0 +1,210 @@ +package staking + +import ( + "context" + "math/big" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ava-labs/teleporter/tests/utils" + . "github.com/onsi/gomega" +) + +/* + * Registers a delegator with an ERC20 token staking validator on a subnet. The steps are as follows: + * - Deploy the ERCTokenStakingManager + * - Register a validator + * - Register a delegator + * - Deleist the delegator + * + * TODO: as delegation gets built out, this test will need to be updated to cover: + * - Delegator rewards + * - Implicit delegation end at validation end + */ +func ERC20Delegation(network interfaces.LocalNetwork) { + // Get the subnets info + cChainInfo := network.GetPrimaryNetworkInfo() + subnetAInfo, _ := utils.GetTwoSubnets(network) + _, fundedKey := network.GetFundedAccountInfo() + pChainInfo := utils.GetPChainInfo(cChainInfo) + + signatureAggregator := utils.NewSignatureAggregator( + cChainInfo.NodeURIs[0], + []ids.ID{ + subnetAInfo.SubnetID, + ids.Empty, // Primary network subnet ID + }, + ) + ctx := context.Background() + + // Deploy the staking manager contract + stakingManagerAddress, stakingManager, _, erc20 := utils.DeployAndInitializeERC20TokenStakingManager( + ctx, + fundedKey, + subnetAInfo, + pChainInfo, + ) + + _ = utils.InitializeERC20TokenValidatorSet( + ctx, + fundedKey, + subnetAInfo, + pChainInfo, + stakingManager, + stakingManagerAddress, + network, + signatureAggregator, + utils.DefaultMinStakeAmount*10, + ) + + // + // Register a validator + // + var validationID ids.ID // To be used in the delisting step + validatorStake := new(big.Int).SetUint64(utils.DefaultMinStakeAmount) + validatorWeight, err := stakingManager.ValueToWeight( + &bind.CallOpts{}, + validatorStake, + ) + Expect(err).Should(BeNil()) + validationID = utils.InitializeAndCompleteERC20ValidatorRegistration( + network, + signatureAggregator, + fundedKey, + subnetAInfo, + pChainInfo, + stakingManager, + stakingManagerAddress, + erc20, + validatorStake, + ) + + // + // Register a delegator + // + var delegationID ids.ID + { + delegatorStake := big.NewInt(1e17) + delegatorWeight, err := stakingManager.ValueToWeight( + &bind.CallOpts{}, + delegatorStake, + ) + Expect(err).Should(BeNil()) + newValidatorWeight := validatorWeight + delegatorWeight + + nonce := uint64(1) + + receipt := utils.InitializeERC20DelegatorRegistration( + fundedKey, + subnetAInfo, + validationID, + delegatorStake, + erc20, + stakingManagerAddress, + stakingManager, + ) + initRegistrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorAdded, + ) + Expect(err).Should(BeNil()) + delegationID = initRegistrationEvent.DelegationID + + // Gather subnet-evm Warp signatures for the SubnetValidatorWeightUpdateMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + utils.ValidateSetSubnetValidatorWeightMessage( + signedWarpMessage, + validationID, + newValidatorWeight, + nonce, + ) + + // Construct a SubnetValidatorWeightUpdateMessage Warp message from the P-Chain + registrationSignedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( + validationID, + nonce, + newValidatorWeight, + subnetAInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = utils.CompleteERC20DelegatorRegistration( + fundedKey, + delegationID, + subnetAInfo, + stakingManagerAddress, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorRegistered, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } + // + // Delist the delegator + // + { + nonce := uint64(2) + receipt := utils.InitializeEndERC20Delegation( + fundedKey, + subnetAInfo, + stakingManager, + delegationID, + ) + delegatorRemovalEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorRemovalInitialized, + ) + Expect(err).Should(BeNil()) + Expect(delegatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(delegatorRemovalEvent.DelegationID[:]).Should(Equal(delegationID[:])) + + // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + Expect(err).Should(BeNil()) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + utils.ValidateSetSubnetValidatorWeightMessage(signedWarpMessage, validationID, validatorWeight, 2) + + // Construct a SubnetValidatorWeightUpdateMessage Warp message from the P-Chain + signedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( + validationID, + nonce, + validatorWeight, + subnetAInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = utils.CompleteEndERC20Delegation( + fundedKey, + delegationID, + subnetAInfo, + stakingManagerAddress, + signedMessage, + ) + + // Check that the delegator has been delisted from the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegationEnded, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } +} diff --git a/tests/flows/validator-manager/erc20_token_staking.go b/tests/flows/validator-manager/erc20_token_staking.go new file mode 100644 index 000000000..a6c3f9b72 --- /dev/null +++ b/tests/flows/validator-manager/erc20_token_staking.go @@ -0,0 +1,102 @@ +package staking + +import ( + "context" + "math/big" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ava-labs/teleporter/tests/utils" + . "github.com/onsi/gomega" +) + +/* + * Registers a erc20 token staking validator on a subnet. The steps are as follows: + * - Deploy the ERCTokenStakingManager + * - Initiate validator registration + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the subnet + * - Verify that the validator is registered in the staking contract + * + * Delists the validator from the subnet. The steps are as follows: + * - Initiate validator delisting + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the subnet + * - Verify that the validator is delisted from the staking contract + */ +func ERC20TokenStakingManager(network interfaces.LocalNetwork) { + // Get the subnets info + cChainInfo := network.GetPrimaryNetworkInfo() + subnetAInfo, _ := utils.GetTwoSubnets(network) + _, fundedKey := network.GetFundedAccountInfo() + pChainInfo := utils.GetPChainInfo(cChainInfo) + + signatureAggregator := utils.NewSignatureAggregator( + cChainInfo.NodeURIs[0], + []ids.ID{ + subnetAInfo.SubnetID, + ids.Empty, // Primary network subnet ID + }, + ) + ctx := context.Background() + + // Deploy the staking manager contract + stakingManagerAddress, stakingManager, _, erc20 := utils.DeployAndInitializeERC20TokenStakingManager( + ctx, + fundedKey, + subnetAInfo, + pChainInfo, + ) + + _ = utils.InitializeERC20TokenValidatorSet( + ctx, + fundedKey, + subnetAInfo, + pChainInfo, + stakingManager, + stakingManagerAddress, + network, + signatureAggregator, + utils.DefaultMinStakeAmount*10, + ) + + // + // Register a validator + // + stakeAmount := new(big.Int).SetUint64(utils.DefaultMinStakeAmount) + weight, err := stakingManager.ValueToWeight( + &bind.CallOpts{}, + stakeAmount, + ) + Expect(err).Should(BeNil()) + validationID := utils.InitializeAndCompleteERC20ValidatorRegistration( + network, + signatureAggregator, + fundedKey, + subnetAInfo, + pChainInfo, + stakingManager, + stakingManagerAddress, + erc20, + stakeAmount, + ) + + // + // Delist the validator + // + utils.InitializeAndCompleteEndERC20Validation( + network, + signatureAggregator, + fundedKey, + subnetAInfo, + pChainInfo, + stakingManager, + stakingManagerAddress, + validationID, + weight, + 1, + ) +} diff --git a/tests/flows/validator-manager/native_delegation.go b/tests/flows/validator-manager/native_delegation.go new file mode 100644 index 000000000..cda020dcc --- /dev/null +++ b/tests/flows/validator-manager/native_delegation.go @@ -0,0 +1,210 @@ +package staking + +import ( + "context" + "math/big" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ava-labs/teleporter/tests/utils" + . "github.com/onsi/gomega" +) + +/* + * Registers a delegator with a native token staking validator on a subnet. The steps are as follows: + * - Deploy the NativeTokenStakingManager + * - Register a validator + * - Register a delegator + * - Deleist the delegator + * + * TODO: as delegation gets built out, this test will need to be updated to cover: + * - Delegator rewards + * - Implicit delegation end at validation end + */ +func NativeDelegation(network interfaces.LocalNetwork) { + // Get the subnets info + cChainInfo := network.GetPrimaryNetworkInfo() + subnetAInfo, _ := utils.GetTwoSubnets(network) + _, fundedKey := network.GetFundedAccountInfo() + pChainInfo := utils.GetPChainInfo(cChainInfo) + + signatureAggregator := utils.NewSignatureAggregator( + cChainInfo.NodeURIs[0], + []ids.ID{ + subnetAInfo.SubnetID, + ids.Empty, // Primary network subnet ID + }, + ) + ctx := context.Background() + + // Deploy the staking manager contract + stakingManagerAddress, stakingManager := utils.DeployAndInitializeNativeTokenStakingManager( + ctx, + fundedKey, + subnetAInfo, + pChainInfo, + ) + + utils.AddNativeMinterAdmin(ctx, subnetAInfo, fundedKey, stakingManagerAddress) + + _ = utils.InitializeNativeTokenValidatorSet( + ctx, + fundedKey, + subnetAInfo, + pChainInfo, + stakingManager, + stakingManagerAddress, + network, + signatureAggregator, + utils.DefaultMinStakeAmount*10, + ) + + // + // Register a validator + // + var validationID ids.ID // To be used in the delisting step + validatorStake := new(big.Int).SetUint64(utils.DefaultMinStakeAmount) + validatorWeight, err := stakingManager.ValueToWeight( + &bind.CallOpts{}, + validatorStake, + ) + Expect(err).Should(BeNil()) + stakeAmount := new(big.Int).SetUint64(utils.DefaultMinStakeAmount) + validationID = utils.InitializeAndCompleteNativeValidatorRegistration( + network, + signatureAggregator, + fundedKey, + subnetAInfo, + pChainInfo, + stakingManager, + stakingManagerAddress, + stakeAmount, + ) + // + // Register a delegator + // + var delegationID ids.ID + { + delegatorStake := big.NewInt(1e17) + delegatorWeight, err := stakingManager.ValueToWeight( + &bind.CallOpts{}, + delegatorStake, + ) + Expect(err).Should(BeNil()) + newValidatorWeight := validatorWeight + delegatorWeight + + nonce := uint64(1) + + receipt := utils.InitializeNativeDelegatorRegistration( + fundedKey, + subnetAInfo, + validationID, + delegatorStake, + stakingManagerAddress, + stakingManager, + ) + initRegistrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorAdded, + ) + Expect(err).Should(BeNil()) + delegationID = initRegistrationEvent.DelegationID + + // Gather subnet-evm Warp signatures for the SubnetValidatorWeightUpdateMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + utils.ValidateSetSubnetValidatorWeightMessage( + signedWarpMessage, + validationID, + newValidatorWeight, + nonce, + ) + + // Construct a SubnetValidatorWeightUpdateMessage Warp message from the P-Chain + registrationSignedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( + validationID, + nonce, + newValidatorWeight, + subnetAInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = utils.CompleteNativeDelegatorRegistration( + fundedKey, + delegationID, + subnetAInfo, + stakingManagerAddress, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorRegistered, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } + // + // Delist the delegator + // + { + nonce := uint64(2) + receipt := utils.InitializeEndNativeDelegation( + fundedKey, + subnetAInfo, + stakingManager, + delegationID, + ) + delegatorRemovalEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorRemovalInitialized, + ) + Expect(err).Should(BeNil()) + Expect(delegatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(delegatorRemovalEvent.DelegationID[:]).Should(Equal(delegationID[:])) + + // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + Expect(err).Should(BeNil()) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + utils.ValidateSetSubnetValidatorWeightMessage(signedWarpMessage, validationID, validatorWeight, 2) + + // Construct a SubnetValidatorWeightUpdateMessage Warp message from the P-Chain + signedMessage := utils.ConstructSubnetValidatorWeightUpdateMessage( + validationID, + nonce, + validatorWeight, + subnetAInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = utils.CompleteEndNativeDelegation( + fundedKey, + delegationID, + subnetAInfo, + stakingManagerAddress, + signedMessage, + ) + + // Check that the delegator has been delisted from the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegationEnded, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(registrationEvent.DelegationID[:]).Should(Equal(delegationID[:])) + } +} diff --git a/tests/flows/validator-manager/native_token_staking.go b/tests/flows/validator-manager/native_token_staking.go new file mode 100644 index 000000000..9a0974e61 --- /dev/null +++ b/tests/flows/validator-manager/native_token_staking.go @@ -0,0 +1,104 @@ +package staking + +import ( + "context" + "math/big" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ava-labs/teleporter/tests/utils" + . "github.com/onsi/gomega" +) + +/* + * Registers a native token staking validator on a subnet. The steps are as follows: + * - Deploy the NativeTokenStakingManager + * - Initiate validator registration + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the subnet + * - Verify that the validator is registered in the staking contract + * + * Delists the validator from the subnet. The steps are as follows: + * - Initiate validator delisting + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the subnet + * - Verify that the validator is delisted from the staking contract + */ +func NativeTokenStakingManager(network interfaces.LocalNetwork) { + // Get the subnets info + cChainInfo := network.GetPrimaryNetworkInfo() + subnetAInfo, _ := utils.GetTwoSubnets(network) + _, fundedKey := network.GetFundedAccountInfo() + pChainInfo := utils.GetPChainInfo(cChainInfo) + + signatureAggregator := utils.NewSignatureAggregator( + cChainInfo.NodeURIs[0], + []ids.ID{ + subnetAInfo.SubnetID, + ids.Empty, // Primary network subnet ID + }, + ) + ctx := context.Background() + + // Deploy the staking manager contract + stakingManagerContractAddress, stakingManager := utils.DeployAndInitializeNativeTokenStakingManager( + ctx, + fundedKey, + subnetAInfo, + pChainInfo, + ) + + utils.AddNativeMinterAdmin(ctx, subnetAInfo, fundedKey, stakingManagerContractAddress) + + _ = utils.InitializeNativeTokenValidatorSet( + ctx, + fundedKey, + subnetAInfo, + pChainInfo, + stakingManager, + stakingManagerContractAddress, + network, + signatureAggregator, + utils.DefaultMinStakeAmount*10, + ) + + // + // Register a validator + // + stakeAmount := new(big.Int).SetUint64(utils.DefaultMinStakeAmount) + weight, err := stakingManager.ValueToWeight( + &bind.CallOpts{}, + stakeAmount, + ) + Expect(err).Should(BeNil()) + // Iniatiate validator registration + validationID := utils.InitializeAndCompleteNativeValidatorRegistration( + network, + signatureAggregator, + fundedKey, + subnetAInfo, + pChainInfo, + stakingManager, + stakingManagerContractAddress, + stakeAmount, + ) + + // + // Delist the validator + // + utils.InitializeAndCompleteEndNativeValidation( + network, + signatureAggregator, + fundedKey, + subnetAInfo, + pChainInfo, + stakingManager, + stakingManagerContractAddress, + validationID, + weight, + 1, + ) +} diff --git a/tests/flows/validator-manager/poa_to_pos.go b/tests/flows/validator-manager/poa_to_pos.go new file mode 100644 index 000000000..21ab63680 --- /dev/null +++ b/tests/flows/validator-manager/poa_to_pos.go @@ -0,0 +1,233 @@ +package staking + +import ( + "context" + "math/big" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + nativetokenstakingmanager "github.com/ava-labs/teleporter/abi-bindings/go/validator-manager/NativeTokenStakingManager" + poavalidatormanager "github.com/ava-labs/teleporter/abi-bindings/go/validator-manager/PoAValidatorManager" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ava-labs/teleporter/tests/utils" + "github.com/ethereum/go-ethereum/crypto" + + . "github.com/onsi/gomega" +) + +/* + * Register a PoA validator manager on a L1 with a proxy. The steps are as follows: + * - Generate random address to be the owner address + * - Fund native assets to the owner address + * - Deploy the PoAValidatorManager contract + * - Deploy a TransparentUpgradeableProxy contract that points to the PoAValidatorManager + * - Call initialize on the PoAValidatorManager through the proxy + * - Initialize and complete PoA validator registration + * + * Migrates the proxy to a PoS validator manager. The steps are as follows: + * - Deploy the PoSValidatorManager contract + * - Upgrade the TransparentUpgradeableProxy to point to the PoSValidatorManager + * - Call initialize on the PoSValidatorManager through the proxy + * - Check that previous validator is still active + * - Initialize and complete PoS validator registration + * - Attempt to delist previous PoA validator with wrong owner and check that it fails + * - Delist the previous PoA validator properly + * - Delist the PoS validator + */ +func PoAMigrationToPoS(network interfaces.LocalNetwork) { + cChainInfo := network.GetPrimaryNetworkInfo() + subnetAInfo, _ := utils.GetTwoSubnets(network) + _, fundedKey := network.GetFundedAccountInfo() + pChainInfo := utils.GetPChainInfo(cChainInfo) + + signatureAggregator := utils.NewSignatureAggregator( + cChainInfo.NodeURIs[0], + []ids.ID{ + subnetAInfo.SubnetID, + ids.Empty, // Primary network subnet ID + }, + ) + + // Generate random address to be the owner address + ownerKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + ownerAddress := crypto.PubkeyToAddress(ownerKey.PublicKey) + + // Transfer native assets to the owner account + ctx := context.Background() + fundAmount := big.NewInt(1e18) // 1avax + utils.SendNativeTransfer( + ctx, + subnetAInfo, + fundedKey, + ownerAddress, + fundAmount, + ) + + // Deploy PoAValidatorManager contract + implAddress, _ := utils.DeployPoAValidatorManager( + ctx, + fundedKey, + subnetAInfo, + ) + + // Deploy TransparentUpgradeableProxy contract pointing to PoAValidatorManager + proxyAddress, proxyAdmin, poaValidatorManager := utils.DeployTransparentUpgradeableProxy( + ctx, + subnetAInfo, + fundedKey, + implAddress, + poavalidatormanager.NewPoAValidatorManager, + ) + opts, err := bind.NewKeyedTransactorWithChainID( + fundedKey, + subnetAInfo.EVMChainID, + ) + Expect(err).Should(BeNil()) + + tx, err := poaValidatorManager.Initialize( + opts, + poavalidatormanager.ValidatorManagerSettings{ + SubnetID: subnetAInfo.SubnetID, + ChurnPeriodSeconds: uint64(0), + MaximumChurnPercentage: uint8(20), + }, + ownerAddress, + ) + Expect(err).Should(BeNil()) + utils.WaitForTransactionSuccess(context.Background(), subnetAInfo, tx.Hash()) + + _ = utils.InitializePoAValidatorSet( + ctx, + fundedKey, + subnetAInfo, + pChainInfo, + poaValidatorManager, + proxyAddress, + network, + signatureAggregator, + utils.DefaultMinStakeAmount*10, + ) + + // Register a validator + poaWeight := uint64(1) + poaValidationID := utils.InitializeAndCompletePoAValidatorRegistration( + network, + signatureAggregator, + ownerKey, + fundedKey, + subnetAInfo, + pChainInfo, + poaValidatorManager, + proxyAddress, + poaWeight, + ) + poaValidator, err := poaValidatorManager.GetValidator(&bind.CallOpts{}, poaValidationID) + Expect(err).Should(BeNil()) + poaNodeID := poaValidator.NodeID + + /* + ****************** + * Migrate PoAValidatorManager to PoSValidatorManager + ****************** + */ + + // Deploy PoSValidatorManager contract + newImplAddress, _ := utils.DeployNativeTokenStakingManager( + ctx, + fundedKey, + subnetAInfo, + ) + + // Upgrade the TransparentUpgradeableProxy contract to use the new logic contract + tx, err = proxyAdmin.UpgradeAndCall(opts, proxyAddress, newImplAddress, []byte{}) + Expect(err).Should(BeNil()) + utils.WaitForTransactionSuccess(ctx, subnetAInfo, tx.Hash()) + + // Change the proxy contract type to NativeTokenStakingManager and initialize it + posValidatorManager, err := nativetokenstakingmanager.NewNativeTokenStakingManager( + proxyAddress, + subnetAInfo.RPCClient, + ) + Expect(err).Should(BeNil()) + + utils.AddNativeMinterAdmin(ctx, subnetAInfo, fundedKey, proxyAddress) + + rewardCalculatorAddress, _ := utils.DeployExampleRewardCalculator( + ctx, + fundedKey, + subnetAInfo, + uint64(10), + ) + + tx, err = posValidatorManager.Initialize( + opts, + nativetokenstakingmanager.PoSValidatorManagerSettings{ + BaseSettings: nativetokenstakingmanager.ValidatorManagerSettings{ + SubnetID: subnetAInfo.SubnetID, + ChurnPeriodSeconds: utils.DefaultChurnPeriodSeconds, + MaximumChurnPercentage: utils.DefaultMaxChurnPercentage, + }, + MinimumStakeAmount: big.NewInt(0).SetUint64(utils.DefaultMinStakeAmount), + MaximumStakeAmount: big.NewInt(0).SetUint64(utils.DefaultMaxStakeAmount), + MinimumStakeDuration: utils.DefaultMinStakeDurationSeconds, + MinimumDelegationFeeBips: utils.DefaultMinDelegateFeeBips, + MaximumStakeMultiplier: utils.DefaultMaxStakeMultiplier, + RewardCalculator: rewardCalculatorAddress, + }, + ) + Expect(err).Should(BeNil()) + utils.WaitForTransactionSuccess(context.Background(), subnetAInfo, tx.Hash()) + + // Check that previous validator is still registered + validationID, err := posValidatorManager.RegisteredValidators(&bind.CallOpts{}, poaNodeID) + Expect(err).Should(BeNil()) + Expect(validationID[:]).Should(Equal(poaValidationID[:])) + + // Register a PoS validator + stakeAmount := big.NewInt(1e18) + posWeight, err := posValidatorManager.ValueToWeight( + &bind.CallOpts{}, + stakeAmount, + ) + Expect(err).Should(BeNil()) + + posValidationID := utils.InitializeAndCompleteNativeValidatorRegistration( + network, + signatureAggregator, + fundedKey, + subnetAInfo, + pChainInfo, + posValidatorManager, + proxyAddress, + stakeAmount, + ) + + // Delist the previous PoA validator + utils.InitializeAndCompleteEndNativeValidation( + network, + signatureAggregator, + ownerKey, + subnetAInfo, + pChainInfo, + posValidatorManager, + proxyAddress, + poaValidationID, + poaWeight, + 1, + ) + + // Delist the PoS validator + utils.InitializeAndCompleteEndNativeValidation( + network, + signatureAggregator, + fundedKey, + subnetAInfo, + pChainInfo, + posValidatorManager, + proxyAddress, + posValidationID, + posWeight, + 1, + ) +} diff --git a/tests/flows/validator-manager/poa_validator_manager.go b/tests/flows/validator-manager/poa_validator_manager.go new file mode 100644 index 000000000..28866d58d --- /dev/null +++ b/tests/flows/validator-manager/poa_validator_manager.go @@ -0,0 +1,149 @@ +package staking + +import ( + "context" + "math/big" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + poavalidatormanager "github.com/ava-labs/teleporter/abi-bindings/go/validator-manager/PoAValidatorManager" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ava-labs/teleporter/tests/utils" + "github.com/ethereum/go-ethereum/crypto" + . "github.com/onsi/gomega" +) + +/* + * Register a PoA validator manager on a L1. The steps are as follows: + * - Generate random address to be the owner address + * - Fund native assets to the owner address + * - Deploy the PoAValidatorManager contract + * - Attempt to initiate with non owner and check that it fails + * - Initiate validator registration + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the L1 + * - Verify that the validator is registered in the validator manager contract + * + * Delists the validator from the L1. The steps are as follows: + * - Attempt to initiate with non owner and check that it fails + * - Initiate validator delisting + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the L1 + * - Verify that the validator is delisted from the validator manager contract + */ +func PoAValidatorManager(network interfaces.LocalNetwork) { + cChainInfo := network.GetPrimaryNetworkInfo() + subnetAInfo, _ := utils.GetTwoSubnets(network) + _, fundedKey := network.GetFundedAccountInfo() + pChainInfo := utils.GetPChainInfo(cChainInfo) + + signatureAggregator := utils.NewSignatureAggregator( + cChainInfo.NodeURIs[0], + []ids.ID{ + subnetAInfo.SubnetID, + ids.Empty, // Primary network subnet ID + }, + ) + + // Generate random address to be the owner address + ownerKey, err := crypto.GenerateKey() + Expect(err).Should(BeNil()) + ownerAddress := crypto.PubkeyToAddress(ownerKey.PublicKey) + + // Transfer native assets to the owner account + ctx := context.Background() + fundAmount := big.NewInt(1e18) // 1avax + utils.SendNativeTransfer( + ctx, + subnetAInfo, + fundedKey, + ownerAddress, + fundAmount, + ) + + validatorManagerAddress, validatorManager := utils.DeployAndInitializePoAValidatorManager( + ctx, + fundedKey, + subnetAInfo, + pChainInfo, + ownerAddress, + ) + _ = utils.InitializePoAValidatorSet( + ctx, + fundedKey, + subnetAInfo, + pChainInfo, + validatorManager, + validatorManagerAddress, + network, + signatureAggregator, + 5, + ) + + var validationID ids.ID // To be used in the delisting step + weight := uint64(1) + + { + // Try to call with invalid owner + opts, err := bind.NewKeyedTransactorWithChainID(fundedKey, subnetAInfo.EVMChainID) + Expect(err).Should(BeNil()) + + nodeID := ids.GenerateTestID() + blsPublicKey := [bls.PublicKeyLen]byte{} + _, err = validatorManager.InitializeValidatorRegistration( + opts, + poavalidatormanager.ValidatorRegistrationInput{ + NodeID: nodeID, + RegistrationExpiry: uint64(time.Now().Add(24 * time.Hour).Unix()), + BlsPublicKey: blsPublicKey[:], + }, + weight, + ) + Expect(err).ShouldNot(BeNil()) + + // Initiate validator registration + validationID = utils.InitializeAndCompletePoAValidatorRegistration( + network, + signatureAggregator, + ownerKey, + fundedKey, + subnetAInfo, + pChainInfo, + validatorManager, + validatorManagerAddress, + weight, + ) + } + + // + // Delist the validator + // + { + // Try with invalid validator owner + opts, err := bind.NewKeyedTransactorWithChainID(fundedKey, subnetAInfo.EVMChainID) + Expect(err).Should(BeNil()) + _, err = validatorManager.InitializeEndValidation( + opts, + validationID, + ) + Expect(err).ShouldNot(BeNil()) + + utils.InitializeAndCompleteEndPoAValidation( + network, + signatureAggregator, + ownerKey, + fundedKey, + subnetAInfo, + pChainInfo, + validatorManager, + validatorManagerAddress, + validationID, + weight, + 1, + ) + } +} diff --git a/tests/local/e2e_test.go b/tests/local/e2e_test.go index 95d934855..e1795e69b 100644 --- a/tests/local/e2e_test.go +++ b/tests/local/e2e_test.go @@ -7,7 +7,10 @@ import ( "os" "testing" - "github.com/ava-labs/teleporter/tests/flows" + "github.com/ava-labs/teleporter/tests/flows/governance" + "github.com/ava-labs/teleporter/tests/flows/teleporter" + "github.com/ava-labs/teleporter/tests/flows/teleporter/registry" + validatorManager "github.com/ava-labs/teleporter/tests/flows/validator-manager" deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" "github.com/ethereum/go-ethereum/log" "github.com/onsi/ginkgo/v2" @@ -22,6 +25,7 @@ const ( upgradabilityLabel = "upgradability" utilsLabel = "utils" validatorSetSigLabel = "ValidatorSetSig" + validatorManagerLabel = "ValidatorManager" ) var ( @@ -105,91 +109,122 @@ var _ = ginkgo.Describe("[Teleporter integration tests]", func() { ginkgo.It("Send a message from Subnet A to Subnet B, and one from B to A", ginkgo.Label(teleporterMessengerLabel), func() { - flows.BasicSendReceive(LocalNetworkInstance) + teleporter.BasicSendReceive(LocalNetworkInstance) }) ginkgo.It("Deliver to the wrong chain", ginkgo.Label(teleporterMessengerLabel), func() { - flows.DeliverToWrongChain(LocalNetworkInstance) + teleporter.DeliverToWrongChain(LocalNetworkInstance) }) ginkgo.It("Deliver to non-existent contract", ginkgo.Label(teleporterMessengerLabel), func() { - flows.DeliverToNonExistentContract(LocalNetworkInstance) + teleporter.DeliverToNonExistentContract(LocalNetworkInstance) }) ginkgo.It("Retry successful execution", ginkgo.Label(teleporterMessengerLabel), func() { - flows.RetrySuccessfulExecution(LocalNetworkInstance) + teleporter.RetrySuccessfulExecution(LocalNetworkInstance) }) ginkgo.It("Unallowed relayer", ginkgo.Label(teleporterMessengerLabel), func() { - flows.UnallowedRelayer(LocalNetworkInstance) + teleporter.UnallowedRelayer(LocalNetworkInstance) }) ginkgo.It("Relay message twice", ginkgo.Label(teleporterMessengerLabel), func() { - flows.RelayMessageTwice(LocalNetworkInstance) + teleporter.RelayMessageTwice(LocalNetworkInstance) }) ginkgo.It("Add additional fee amount", ginkgo.Label(teleporterMessengerLabel), func() { - flows.AddFeeAmount(LocalNetworkInstance) + teleporter.AddFeeAmount(LocalNetworkInstance) }) ginkgo.It("Send specific receipts", ginkgo.Label(teleporterMessengerLabel), func() { - flows.SendSpecificReceipts(LocalNetworkInstance) + teleporter.SendSpecificReceipts(LocalNetworkInstance) }) ginkgo.It("Insufficient gas", ginkgo.Label(teleporterMessengerLabel), func() { - flows.InsufficientGas(LocalNetworkInstance) + teleporter.InsufficientGas(LocalNetworkInstance) }) ginkgo.It("Resubmit altered message", ginkgo.Label(teleporterMessengerLabel), func() { - flows.ResubmitAlteredMessage(LocalNetworkInstance) + teleporter.ResubmitAlteredMessage(LocalNetworkInstance) + }) + ginkgo.It("Calculate Teleporter message IDs", + ginkgo.Label(utilsLabel), + func() { + teleporter.CalculateMessageID(LocalNetworkInstance) + }) + ginkgo.It("Relayer modifies message", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporter.RelayerModifiesMessage(LocalNetworkInstance) + }) + ginkgo.It("Validator churn", + ginkgo.Label(teleporterMessengerLabel), + func() { + teleporter.ValidatorChurn(LocalNetworkInstance) + }) + + // Teleporter Registry tests + ginkgo.It("Teleporter registry", + ginkgo.Label(upgradabilityLabel), + func() { + registry.TeleporterRegistry(LocalNetworkInstance) }) ginkgo.It("Check upgrade access", ginkgo.Label(upgradabilityLabel), func() { - flows.CheckUpgradeAccess(LocalNetworkInstance) + registry.CheckUpgradeAccess(LocalNetworkInstance) }) ginkgo.It("Pause and Unpause Teleporter", ginkgo.Label(upgradabilityLabel), func() { - flows.PauseTeleporter(LocalNetworkInstance) + registry.PauseTeleporter(LocalNetworkInstance) }) - ginkgo.It("Calculate Teleporter message IDs", - ginkgo.Label(utilsLabel), + + // Governance tests + ginkgo.It("Deliver ValidatorSetSig signed message", + ginkgo.Label(validatorSetSigLabel), func() { - flows.CalculateMessageID(LocalNetworkInstance) + governance.ValidatorSetSig(LocalNetworkInstance) }) - // The following tests require special behavior by the relayer, so we only run them on a local network - ginkgo.It("Relayer modifies message", - ginkgo.Label(teleporterMessengerLabel), + // Validator Manager tests + ginkgo.It("Native token staking manager", + ginkgo.Label(validatorManagerLabel), func() { - flows.RelayerModifiesMessage(LocalNetworkInstance) + validatorManager.NativeTokenStakingManager(LocalNetworkInstance) }) - ginkgo.It("Teleporter registry", - ginkgo.Label(upgradabilityLabel), + ginkgo.It("ERC20 token staking manager", + ginkgo.Label(validatorManagerLabel), func() { - flows.TeleporterRegistry(LocalNetworkInstance) + validatorManager.ERC20TokenStakingManager(LocalNetworkInstance) }) - ginkgo.It("Deliver ValidatorSetSig signed message", - ginkgo.Label(validatorSetSigLabel), + ginkgo.It("PoA validator manager", + ginkgo.Label(validatorManagerLabel), func() { - flows.ValidatorSetSig(LocalNetworkInstance) + validatorManager.PoAValidatorManager(LocalNetworkInstance) }) - ginkgo.It("Validator churn", - ginkgo.Label(teleporterMessengerLabel), + ginkgo.It("ERC20 delegation", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManager.ERC20Delegation(LocalNetworkInstance) + }) + ginkgo.It("Native token delegation", + ginkgo.Label(validatorManagerLabel), + func() { + validatorManager.NativeDelegation(LocalNetworkInstance) + }) + ginkgo.It("PoA migration to PoS", + ginkgo.Label(validatorManagerLabel), func() { - flows.ValidatorChurn(LocalNetworkInstance) + validatorManager.PoAMigrationToPoS(LocalNetworkInstance) }) - // Since the validator churn test modifies the network topology, we put it last for now. - // It should not affect the other tests, but we get some errors if we run it before the other tests. - // TODO: we should fix this so that the order of the tests does not matter. }) diff --git a/tests/local/network.go b/tests/local/network.go index 4472039d0..d2d4ce28b 100644 --- a/tests/local/network.go +++ b/tests/local/network.go @@ -50,21 +50,12 @@ type LocalNetwork struct { globalFundedKey *ecdsa.PrivateKey // Internal vars only used to set up the local network - tmpnet *tmpnet.Network - warpChainConfigPath string + tmpnet *tmpnet.Network } const ( - fundedKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" - warpEnabledChainConfig = `{ - "warp-api-enabled": true, - "eth-apis":["eth","eth-filter","net","admin","web3", - "internal-eth","internal-blockchain","internal-transaction", - "internal-debug","internal-account","internal-personal", - "debug","debug-tracer","debug-file-tracer","debug-handler"] - }` - - timeout = 60 * time.Second + fundedKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" + timeout = 60 * time.Second ) type SubnetSpec struct { @@ -88,12 +79,6 @@ func NewLocalNetwork( // Create extra nodes to be used to add more validators later extraNodes := subnetEvmTestUtils.NewTmpnetNodes(extraNodeCount) - f, err := os.CreateTemp(os.TempDir(), "config.json") - Expect(err).Should(BeNil()) - _, err = f.Write([]byte(warpEnabledChainConfig)) - Expect(err).Should(BeNil()) - warpChainConfigPath := f.Name() - var allNodes []*tmpnet.Node allNodes = append(allNodes, extraNodes...) // to be appended w/ subnet validators @@ -111,7 +96,7 @@ func NewLocalNetwork( subnetSpec.TeleporterDeployedBytecode, subnetSpec.TeleporterDeployerAddress, ), - subnetEvmTestUtils.DefaultChainConfig, + utils.WarpEnabledChainConfig, nodes..., ) subnets = append(subnets, subnet) @@ -149,12 +134,11 @@ func NewLocalNetwork( } localNetwork := &LocalNetwork{ - primaryNetworkInfo: &interfaces.SubnetTestInfo{}, - subnetsInfo: make(map[ids.ID]*interfaces.SubnetTestInfo), - extraNodes: extraNodes, - globalFundedKey: globalFundedKey, - tmpnet: network, - warpChainConfigPath: warpChainConfigPath, + primaryNetworkInfo: &interfaces.SubnetTestInfo{}, + subnetsInfo: make(map[ids.ID]*interfaces.SubnetTestInfo), + extraNodes: extraNodes, + globalFundedKey: globalFundedKey, + tmpnet: network, } for _, subnet := range network.Subnets { localNetwork.setSubnetValues(subnet) @@ -486,7 +470,6 @@ func (n *LocalNetwork) TearDownNetwork() { Expect(n).ShouldNot(BeNil()) Expect(n.tmpnet).ShouldNot(BeNil()) Expect(n.tmpnet.Stop(context.Background())).Should(BeNil()) - Expect(os.Remove(n.warpChainConfigPath)).Should(BeNil()) } func (n *LocalNetwork) AddSubnetValidators(ctx context.Context, subnetID ids.ID, count uint) { diff --git a/tests/testnet/main/run_testnet_flows.go b/tests/testnet/main/run_testnet_flows.go index 440a02711..5721537e1 100644 --- a/tests/testnet/main/run_testnet_flows.go +++ b/tests/testnet/main/run_testnet_flows.go @@ -3,7 +3,9 @@ package main import ( "github.com/ethereum/go-ethereum/log" - "github.com/ava-labs/teleporter/tests/flows" + "github.com/ava-labs/teleporter/tests/flows/teleporter" + "github.com/ava-labs/teleporter/tests/flows/teleporter/registry" + "github.com/ava-labs/teleporter/tests/interfaces" "github.com/ava-labs/teleporter/tests/testnet" "github.com/onsi/gomega" @@ -34,19 +36,19 @@ func main() { // - UnallowedRelayer // - ValidatorSetChrun // - TeleporterRegistry - runFlow("AddFeeAmount", flows.AddFeeAmount, network) - runFlow("BasicSendRecevie", flows.BasicSendReceive, network) - runFlow("DeliverToNonExistentContract", flows.DeliverToNonExistentContract, network) - runFlow("DeliverToWrongChain", flows.DeliverToWrongChain, network) - runFlow("InsufficientGas", flows.InsufficientGas, network) - runFlow("RelayMessageTwice", flows.RelayMessageTwice, network) - runFlow("ResubmitAlteredMessage", flows.ResubmitAlteredMessage, network) - runFlow("RetrySuccessfulExecution", flows.RetrySuccessfulExecution, network) - runFlow("SendSpecificReceipts", flows.SendSpecificReceipts, network) + runFlow("AddFeeAmount", teleporter.AddFeeAmount, network) + runFlow("BasicSendRecevie", teleporter.BasicSendReceive, network) + runFlow("DeliverToNonExistentContract", teleporter.DeliverToNonExistentContract, network) + runFlow("DeliverToWrongChain", teleporter.DeliverToWrongChain, network) + runFlow("InsufficientGas", teleporter.InsufficientGas, network) + runFlow("RelayMessageTwice", teleporter.RelayMessageTwice, network) + runFlow("ResubmitAlteredMessage", teleporter.ResubmitAlteredMessage, network) + runFlow("RetrySuccessfulExecution", teleporter.RetrySuccessfulExecution, network) + runFlow("SendSpecificReceipts", teleporter.SendSpecificReceipts, network) log.Info("Finished Teleporter test flows") // Run the upgradability test flows - runFlow("CheckUpgradeAccess", flows.CheckUpgradeAccess, network) - runFlow("PauseTeleporter", flows.PauseTeleporter, network) + runFlow("CheckUpgradeAccess", registry.CheckUpgradeAccess, network) + runFlow("PauseTeleporter", registry.PauseTeleporter, network) log.Info("Finished upgradability test flows") } diff --git a/tests/utils/chain.go b/tests/utils/chain.go new file mode 100644 index 000000000..ac75d4d02 --- /dev/null +++ b/tests/utils/chain.go @@ -0,0 +1,584 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + "encoding/json" + "errors" + "fmt" + "math/big" + "os" + "strconv" + "strings" + "time" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/message" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/set" + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + relayerConfig "github.com/ava-labs/awm-relayer/config" + "github.com/ava-labs/awm-relayer/peers" + "github.com/ava-labs/awm-relayer/signature-aggregator/aggregator" + sigAggConfig "github.com/ava-labs/awm-relayer/signature-aggregator/config" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/eth/tracers" + "github.com/ava-labs/subnet-evm/ethclient" + subnetEvmInterfaces "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ava-labs/subnet-evm/precompile/contracts/nativeminter" + nativeMinter "github.com/ava-labs/teleporter/abi-bindings/go/INativeMinter" + "github.com/ava-labs/teleporter/tests/interfaces" + gasUtils "github.com/ava-labs/teleporter/utils/gas-utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + . "github.com/onsi/gomega" + "github.com/prometheus/client_golang/prometheus" +) + +const ( + CChainPathSpecifier = "C" +) + +var NativeTransferGas uint64 = 21_000 + +var WarpEnabledChainConfig = tmpnet.FlagsMap{ + "log-level": "debug", + "warp-api-enabled": true, + "local-txs-enabled": true, + "eth-apis": []string{ + "eth", + "eth-filter", + "net", + "admin", + "web3", + "internal-eth", + "internal-blockchain", + "internal-transaction", + "internal-debug", + "internal-account", + "internal-personal", + "debug", + "debug-tracer", + "debug-file-tracer", + "debug-handler", + }, +} + +// +// URL utils +// + +func HttpToWebsocketURI(uri string, blockchainID string) string { + return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) +} + +func HttpToRPCURI(uri string, blockchainID string) string { + return fmt.Sprintf("http://%s/ext/bc/%s/rpc", strings.TrimPrefix(uri, "http://"), blockchainID) +} + +// Get the host and port from a URI. The URI should be in the format http://host:port or https://host:port +func GetURIHostAndPort(uri string) (string, uint32, error) { + // At a minimum uri should have http:// of 7 characters + Expect(len(uri)).Should(BeNumerically(">", 7)) + if uri[:7] == "http://" { + uri = uri[7:] + } else if uri[:8] == "https://" { + uri = uri[8:] + } else { + return "", 0, fmt.Errorf("invalid uri: %s", uri) + } + + // Split the uri into host and port + hostAndPort := strings.Split(uri, ":") + Expect(len(hostAndPort)).Should(Equal(2)) + + // Parse the port + port, err := strconv.ParseUint(hostAndPort[1], 10, 32) + if err != nil { + return "", 0, fmt.Errorf("failed to parse port: %w", err) + } + + return hostAndPort[0], uint32(port), nil +} + +// +// Transaction utils +// + +func CreateNativeTransferTransaction( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + fromKey *ecdsa.PrivateKey, + recipient common.Address, + amount *big.Int, +) *types.Transaction { + fromAddress := crypto.PubkeyToAddress(fromKey.PublicKey) + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, fromAddress) + + tx := types.NewTx(&types.DynamicFeeTx{ + ChainID: subnetInfo.EVMChainID, + Nonce: nonce, + To: &recipient, + Gas: NativeTransferGas, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Value: amount, + }) + + return SignTransaction(tx, fromKey, subnetInfo.EVMChainID) +} + +func SendNativeTransfer( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + fromKey *ecdsa.PrivateKey, + recipient common.Address, + amount *big.Int, +) *types.Receipt { + tx := CreateNativeTransferTransaction(ctx, subnetInfo, fromKey, recipient, amount) + return SendTransactionAndWaitForSuccess(ctx, subnetInfo, tx) +} + +// Sends a tx, and waits for it to be mined. +// Asserts Receipt.status equals success. +func sendAndWaitForTransaction( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + tx *types.Transaction, + success bool, +) *types.Receipt { + err := subnetInfo.RPCClient.SendTransaction(ctx, tx) + Expect(err).Should(BeNil()) + + return waitForTransaction(ctx, subnetInfo, tx.Hash(), success) +} + +// Sends a tx, and waits for it to be mined. +// Asserts Receipt.status equals false. +func SendTransactionAndWaitForFailure( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + tx *types.Transaction, +) *types.Receipt { + return sendAndWaitForTransaction(ctx, subnetInfo, tx, false) +} + +// Sends a tx, and waits for it to be mined. +// Asserts Receipt.status equals true. +func SendTransactionAndWaitForSuccess( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + tx *types.Transaction, +) *types.Receipt { + return sendAndWaitForTransaction(ctx, subnetInfo, tx, true) +} + +// Waits for a transaction to be mined. +// Asserts Receipt.status equals true. +func WaitForTransactionSuccess( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + txHash common.Hash, +) *types.Receipt { + return waitForTransaction(ctx, subnetInfo, txHash, true) +} + +// Waits for a transaction to be mined. +// Asserts Receipt.status equals false. +func WaitForTransactionFailure( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + txHash common.Hash, +) *types.Receipt { + return waitForTransaction(ctx, subnetInfo, txHash, false) +} + +// Waits for a transaction to be mined. +// Asserts Receipt.status equals success. +func waitForTransaction( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + txHash common.Hash, + success bool, +) *types.Receipt { + cctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + + receipt, err := WaitMined(cctx, subnetInfo.RPCClient, txHash) + Expect(err).Should(BeNil()) + + if success { + if receipt.Status == types.ReceiptStatusFailed { + TraceTransactionAndExit(ctx, subnetInfo.RPCClient, receipt.TxHash) + } + } else { + Expect(receipt.Status).Should(Equal(types.ReceiptStatusFailed)) + } + return receipt +} + +// Polls for a transaction receipt of the given txHash on each queryTicker tick until +// either a transaction receipt returned, or the context is cancelled or expired. +func waitForTransactionReceipt( + cctx context.Context, + rpcClient ethclient.Client, + txHash common.Hash, +) (*types.Receipt, error) { + queryTicker := time.NewTicker(200 * time.Millisecond) + defer queryTicker.Stop() + for { + receipt, err := rpcClient.TransactionReceipt(cctx, txHash) + if err == nil { + return receipt, nil + } + + if errors.Is(err, subnetEvmInterfaces.NotFound) { + log.Debug("Transaction not yet mined") + } else { + log.Error("Receipt retrieval failed", "err", err) + return nil, err + } + + // Wait for the next round. + select { + case <-cctx.Done(): + return nil, cctx.Err() + case <-queryTicker.C: + } + } +} + +// Signs a transaction using the provided key for the specified chainID +func SignTransaction(tx *types.Transaction, key *ecdsa.PrivateKey, chainID *big.Int) *types.Transaction { + txSigner := types.LatestSignerForChainID(chainID) + signedTx, err := types.SignTx(tx, txSigner, key) + Expect(err).Should(BeNil()) + + return signedTx +} + +// Returns the gasFeeCap, gasTipCap, and nonce the be used when constructing a transaction from fundedAddress +func CalculateTxParams( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + fundedAddress common.Address, +) (*big.Int, *big.Int, uint64) { + baseFee, err := subnetInfo.RPCClient.EstimateBaseFee(ctx) + Expect(err).Should(BeNil()) + + gasTipCap, err := subnetInfo.RPCClient.SuggestGasTipCap(ctx) + Expect(err).Should(BeNil()) + + nonce, err := subnetInfo.RPCClient.NonceAt(ctx, fundedAddress, nil) + Expect(err).Should(BeNil()) + + gasFeeCap := baseFee.Mul(baseFee, big.NewInt(gasUtils.BaseFeeFactor)) + gasFeeCap.Add(gasFeeCap, big.NewInt(gasUtils.MaxPriorityFeePerGas)) + + return gasFeeCap, gasTipCap, nonce +} + +// Gomega will print the transaction trace and exit +func TraceTransactionAndExit(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) { + Expect(TraceTransaction(ctx, rpcClient, txHash)).Should(Equal("")) +} + +func TraceTransaction(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) string { + var result interface{} + ct := "callTracer" + err := rpcClient.Client().Call(&result, "debug_traceTransaction", txHash.String(), tracers.TraceConfig{Tracer: &ct}) + Expect(err).Should(BeNil()) + + jsonStr, err := json.Marshal(result) + Expect(err).Should(BeNil()) + + return string(jsonStr) +} + +// +// Block utils +// + +// WaitMined waits for tx to be mined on the blockchain. +// It stops waiting when the context is canceled. +// Takes a tx hash instead of the full tx in the subnet-evm version of this function. +// Copied and modified from https://github.com/ava-labs/subnet-evm/blob/v0.6.0-fuji/accounts/abi/bind/util.go#L42 +func WaitMined(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) (*types.Receipt, error) { + cctx, cancel := context.WithTimeout(ctx, 20*time.Second) + defer cancel() + + receipt, err := waitForTransactionReceipt(cctx, rpcClient, txHash) + if err != nil { + return nil, err + } + + // Check that the block height endpoint returns a block height as high as the block number that the transaction was + // included in. This is to workaround the issue where multiple nodes behind a public RPC endpoint see + // transactions/blocks at different points in time. Ideally, all nodes in the network should have seen this block + // and transaction before returning from WaitMined. The block height endpoint of public RPC endpoints is + // configured to return the lowest value currently returned by any node behind the load balancer, so waiting for + // it to be at least as high as the block height specified in the receipt should provide a relatively strong + // indication that the transaction has been seen widely throughout the network. + err = waitForBlockHeight(cctx, rpcClient, receipt.BlockNumber.Uint64()) + if err != nil { + return nil, err + } + + return receipt, nil +} + +// Polls for the eth_blockNumber endpoint for the latest blockheight on each queryTicker tick until +// either the returned height is greater than or equal to the expectedBlockNumber, or the context +// is cancelled or expired. +func waitForBlockHeight( + cctx context.Context, + rpcClient ethclient.Client, + expectedBlockNumber uint64, +) error { + queryTicker := time.NewTicker(2 * time.Second) + defer queryTicker.Stop() + for { + currentBlockNumber, err := rpcClient.BlockNumber(cctx) + if err != nil { + return err + } + + if currentBlockNumber >= expectedBlockNumber { + return nil + } else { + log.Info("Waiting for block height where transaction was included", + "blockNumber", expectedBlockNumber) + } + + // Wait for the next round. + select { + case <-cctx.Done(): + return cctx.Err() + case <-queryTicker.C: + } + } +} + +// +// Log utils +// + +// Returns the first log in 'logs' that is successfully parsed by 'parser' +// Errors and prints a trace of the transaction if no log is found. +func GetEventFromLogsOrTrace[T any]( + ctx context.Context, + receipt *types.Receipt, + subnetInfo interfaces.SubnetTestInfo, + parser func(log types.Log) (T, error), +) T { + log, err := GetEventFromLogs(receipt.Logs, parser) + if err != nil { + TraceTransactionAndExit(ctx, subnetInfo.RPCClient, receipt.TxHash) + } + return log +} + +// Returns the first log in 'logs' that is successfully parsed by 'parser' +func GetEventFromLogs[T any](logs []*types.Log, parser func(log types.Log) (T, error)) (T, error) { + for _, log := range logs { + event, err := parser(*log) + if err == nil { + return event, nil + } + } + return *new(T), fmt.Errorf("failed to find %T event in receipt logs", *new(T)) +} + +// +// Account utils +// + +func PrivateKeyToAddress(k *ecdsa.PrivateKey) common.Address { + return crypto.PubkeyToAddress(k.PublicKey) +} + +// Throws a Gomega error if there is a mismatch +func CheckBalance(ctx context.Context, addr common.Address, expectedBalance *big.Int, rpcClient ethclient.Client) { + bal, err := rpcClient.BalanceAt(ctx, addr, nil) + Expect(err).Should(BeNil()) + ExpectBigEqual(bal, expectedBalance) +} + +// +// Big int utils +// + +func ExpectBigEqual(v1 *big.Int, v2 *big.Int) { + // Compare strings, so gomega will print the numbers if they differ + Expect(v1.String()).Should(Equal(v2.String())) +} + +func BigIntSub(v1 *big.Int, v2 *big.Int) *big.Int { + return big.NewInt(0).Sub(v1, v2) +} + +func BigIntMul(v1 *big.Int, v2 *big.Int) *big.Int { + return big.NewInt(0).Mul(v1, v2) +} + +// +// Network utils +// + +func GetPChainInfo(cChainInfo interfaces.SubnetTestInfo) interfaces.SubnetTestInfo { + pChainBlockchainID, err := info.NewClient(cChainInfo.NodeURIs[0]).GetBlockchainID(context.Background(), "P") + Expect(err).Should(BeNil()) + return interfaces.SubnetTestInfo{ + BlockchainID: pChainBlockchainID, + SubnetID: ids.Empty, + } +} + +func GetTwoSubnets(network interfaces.Network) ( + interfaces.SubnetTestInfo, + interfaces.SubnetTestInfo, +) { + subnets := network.GetSubnetsInfo() + Expect(len(subnets)).Should(BeNumerically(">=", 2)) + return subnets[0], subnets[1] +} + +type ChainConfigMap map[string]string + +// Sets the chain config in customChainConfigs for the specified subnet +func (m ChainConfigMap) Add(subnet interfaces.SubnetTestInfo, chainConfig string) { + if subnet.SubnetID == constants.PrimaryNetworkID { + m[CChainPathSpecifier] = chainConfig + } else { + m[subnet.BlockchainID.String()] = chainConfig + } +} + +func GetChainConfigWithOffChainMessages(offChainMessages []avalancheWarp.UnsignedMessage) string { + // Convert messages to hex + hexOffChainMessages := []string{} + for _, message := range offChainMessages { + hexOffChainMessages = append(hexOffChainMessages, hexutil.Encode(message.Bytes())) + } + + chainConfig := WarpEnabledChainConfig + chainConfig["warp-off-chain-messages"] = hexOffChainMessages + + // Marshal the map to JSON + offChainMessageJson, err := tmpnet.DefaultJSONMarshal(chainConfig) + Expect(err).Should(BeNil()) + + return string(offChainMessageJson) +} + +// read in the template file, make the substitutions declared at the beginning +// of the function, write out the instantiation to a temp file, and then return +// the path to that temp file. +func InstantiateGenesisTemplate( + templateFileName string, + chainID uint64, + teleporterContractAddress common.Address, + teleporterDeployedBytecode string, + teleporterDeployerAddress common.Address, +) string { + substitutions := []struct { + Target string + Value string + }{ + { + "", + strconv.FormatUint(chainID, 10), + }, + { + "", + teleporterContractAddress.Hex(), + }, + { + "", + teleporterDeployedBytecode, + }, + { + "", + teleporterDeployerAddress.Hex(), + }, + } + + templateFileBytes, err := os.ReadFile(templateFileName) + Expect(err).Should(BeNil()) + + subnetGenesisFile, err := os.CreateTemp(os.TempDir(), "") + Expect(err).Should(BeNil()) + + defer subnetGenesisFile.Close() + + var replaced string = string(templateFileBytes[:]) + for _, s := range substitutions { + replaced = strings.ReplaceAll(replaced, s.Target, s.Value) + } + + subnetGenesisFile.WriteString(replaced) + + return subnetGenesisFile.Name() +} + +// +// Aggregator utils +// + +func NewSignatureAggregator(apiUri string, subnets []ids.ID) *aggregator.SignatureAggregator { + logger := logging.NoLog{} + cfg := sigAggConfig.Config{ + PChainAPI: &relayerConfig.APIConfig{ + BaseURL: apiUri, + }, + InfoAPI: &relayerConfig.APIConfig{ + BaseURL: apiUri, + }, + } + trackedSubnets := set.NewSet[ids.ID](len(subnets)) + trackedSubnets.Add(subnets...) + registry := prometheus.NewRegistry() + appRequestNetwork, err := peers.NewNetwork( + logging.Debug, + registry, + trackedSubnets, + &cfg, + ) + Expect(err).Should(BeNil()) + + messageCreator, err := message.NewCreator( + logger, + registry, + constants.DefaultNetworkCompressionType, + constants.DefaultNetworkMaximumInboundTimeout, + ) + Expect(err).Should(BeNil()) + return aggregator.NewSignatureAggregator( + appRequestNetwork, + logger, + messageCreator, + ) +} + +// Funded key must have admin access to set new admin. +func AddNativeMinterAdmin( + ctx context.Context, + subnet interfaces.SubnetTestInfo, + fundedKey *ecdsa.PrivateKey, + address common.Address, +) { + nativeMinterPrecompile, err := nativeMinter.NewINativeMinter(nativeminter.ContractAddress, subnet.RPCClient) + Expect(err).Should(BeNil()) + + opts, err := bind.NewKeyedTransactorWithChainID(fundedKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := nativeMinterPrecompile.SetAdmin(opts, address) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(ctx, subnet, tx.Hash()) +} diff --git a/tests/utils/erc20.go b/tests/utils/erc20.go new file mode 100644 index 000000000..b235dbf6d --- /dev/null +++ b/tests/utils/erc20.go @@ -0,0 +1,61 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + "math/big" + + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + exampleerc20 "github.com/ava-labs/teleporter/abi-bindings/go/mocks/ExampleERC20" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + . "github.com/onsi/gomega" +) + +var ( + ExpectedExampleERC20DeployerBalance = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e10)) +) + +func DeployExampleERC20( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + source interfaces.SubnetTestInfo, +) (common.Address, *exampleerc20.ExampleERC20) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) + Expect(err).Should(BeNil()) + + // Deploy Mock ERC20 contract + address, tx, token, err := exampleerc20.DeployExampleERC20(opts, source.RPCClient) + Expect(err).Should(BeNil()) + log.Info("Deployed Mock ERC20 contract", "address", address.Hex(), "txHash", tx.Hash().Hex()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, source, tx.Hash()) + + // Check that the deployer has the expected initial balance + senderAddress := crypto.PubkeyToAddress(senderKey.PublicKey) + balance, err := token.BalanceOf(&bind.CallOpts{}, senderAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(ExpectedExampleERC20DeployerBalance)) + + return address, token +} + +func ERC20Approve( + ctx context.Context, + token *exampleerc20.ExampleERC20, + spender common.Address, + amount *big.Int, + source interfaces.SubnetTestInfo, + senderKey *ecdsa.PrivateKey, +) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := token.Approve(opts, spender, amount) + Expect(err).Should(BeNil()) + log.Info("Approved ERC20", "spender", spender.Hex(), "txHash", tx.Hash().Hex()) + + WaitForTransactionSuccess(ctx, source, tx.Hash()) +} diff --git a/tests/utils/governance.go b/tests/utils/governance.go new file mode 100644 index 000000000..177d3f017 --- /dev/null +++ b/tests/utils/governance.go @@ -0,0 +1,108 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + validatorsetsig "github.com/ava-labs/teleporter/abi-bindings/go/governance/ValidatorSetSig" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + . "github.com/onsi/gomega" +) + +func DeployValidatorSetSig( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + contractSubnet interfaces.SubnetTestInfo, + validatorSubnet interfaces.SubnetTestInfo, +) (common.Address, *validatorsetsig.ValidatorSetSig) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, contractSubnet.EVMChainID) + Expect(err).Should(BeNil()) + address, tx, validatorSetSig, err := validatorsetsig.DeployValidatorSetSig( + opts, + contractSubnet.RPCClient, + validatorSubnet.BlockchainID, + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, contractSubnet, tx.Hash()) + + return address, validatorSetSig +} + +// Returns Receipt for the transaction unlike TeleporterRegistry version since this is a non-teleporter case +// and we don't want to add the ValidatorSetSig ABI to the subnetInfo +func ExecuteValidatorSetSigCallAndVerify( + ctx context.Context, + network interfaces.Network, + source interfaces.SubnetTestInfo, + destination interfaces.SubnetTestInfo, + validatorSetSigAddress common.Address, + senderKey *ecdsa.PrivateKey, + unsignedMessage *avalancheWarp.UnsignedMessage, + expectSuccess bool, +) *types.Receipt { + signedWarpMsg := network.GetSignedMessage(ctx, source, destination, unsignedMessage.ID()) + log.Info("Got signed warp message", "messageID", signedWarpMsg.ID()) + + signedPredicateTx := CreateExecuteCallPredicateTransaction( + ctx, + signedWarpMsg, + validatorSetSigAddress, + senderKey, + destination, + ) + + // Wait for tx to be accepted and verify events emitted + if expectSuccess { + return SendTransactionAndWaitForSuccess(ctx, destination, signedPredicateTx) + } + return SendTransactionAndWaitForFailure(ctx, destination, signedPredicateTx) +} + +func InitOffChainMessageChainConfigValidatorSetSig( + networkID uint32, + subnet interfaces.SubnetTestInfo, + validatorSetSigAddress common.Address, + validatorSetSigMessages []validatorsetsig.ValidatorSetSigMessage, +) ([]avalancheWarp.UnsignedMessage, string) { + unsignedMessages := []avalancheWarp.UnsignedMessage{} + for _, message := range validatorSetSigMessages { + unsignedMessage := CreateOffChainValidatorSetSigMessage(networkID, subnet, message) + unsignedMessages = append(unsignedMessages, *unsignedMessage) + log.Info("Adding validatorSetSig off-chain message to Warp chain config", + "messageID", unsignedMessage.ID(), + "blockchainID", subnet.BlockchainID.String()) + } + return unsignedMessages, GetChainConfigWithOffChainMessages(unsignedMessages) +} + +// Creates an off-chain Warp message pointing to a function, contract and payload to be executed +// if the validator set signs this message +func CreateOffChainValidatorSetSigMessage( + networkID uint32, + subnet interfaces.SubnetTestInfo, + message validatorsetsig.ValidatorSetSigMessage, +) *avalancheWarp.UnsignedMessage { + sourceAddress := []byte{} + payloadBytes, err := message.Pack() + Expect(err).Should(BeNil()) + + addressedPayload, err := payload.NewAddressedCall(sourceAddress, payloadBytes) + Expect(err).Should(BeNil()) + + unsignedMessage, err := avalancheWarp.NewUnsignedMessage( + networkID, + subnet.BlockchainID, + addressedPayload.Bytes(), + ) + Expect(err).Should(BeNil()) + + return unsignedMessage +} diff --git a/tests/utils/proxy.go b/tests/utils/proxy.go new file mode 100644 index 000000000..36b6413d3 --- /dev/null +++ b/tests/utils/proxy.go @@ -0,0 +1,49 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + proxyadmin "github.com/ava-labs/teleporter/abi-bindings/go/ProxyAdmin" + transparentupgradeableproxy "github.com/ava-labs/teleporter/abi-bindings/go/TransparentUpgradeableProxy" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + . "github.com/onsi/gomega" +) + +func DeployTransparentUpgradeableProxy[T any]( + ctx context.Context, + subnet interfaces.SubnetTestInfo, + senderKey *ecdsa.PrivateKey, + implAddress common.Address, + newInstance func(address common.Address, backend bind.ContractBackend) (*T, error), +) (common.Address, *proxyadmin.ProxyAdmin, *T) { + opts, err := bind.NewKeyedTransactorWithChainID( + senderKey, + subnet.EVMChainID, + ) + Expect(err).Should((BeNil())) + + senderAddress := crypto.PubkeyToAddress(senderKey.PublicKey) + proxyAddress, tx, proxy, err := transparentupgradeableproxy.DeployTransparentUpgradeableProxy( + opts, + subnet.RPCClient, + implAddress, + senderAddress, + []byte{}, + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(ctx, subnet, tx.Hash()) + proxyAdminEvent, err := GetEventFromLogs(receipt.Logs, proxy.ParseAdminChanged) + Expect(err).Should(BeNil()) + + proxyAdmin, err := proxyadmin.NewProxyAdmin(proxyAdminEvent.NewAdmin, subnet.RPCClient) + Expect(err).Should(BeNil()) + + contract, err := newInstance(proxyAddress, subnet.RPCClient) + Expect(err).Should(BeNil()) + + return proxyAddress, proxyAdmin, contract +} diff --git a/tests/utils/utils.go b/tests/utils/teleporter.go similarity index 51% rename from tests/utils/utils.go rename to tests/utils/teleporter.go index a5ec2198a..1647bd0fa 100644 --- a/tests/utils/utils.go +++ b/tests/utils/teleporter.go @@ -1,61 +1,113 @@ -// Copyright (C) 2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - package utils import ( "bytes" "context" "crypto/ecdsa" - "encoding/json" - "errors" - "fmt" "math/big" - "os" - "strconv" - "strings" - "time" - - validatorsetsig "github.com/ava-labs/teleporter/abi-bindings/go/governance/ValidatorSetSig" - exampleerc20 "github.com/ava-labs/teleporter/abi-bindings/go/mocks/ExampleERC20" - teleportermessenger "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/TeleporterMessenger" - teleporterregistry "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/registry/TeleporterRegistry" - testmessenger "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/tests/TestMessenger" - deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" - gasUtils "github.com/ava-labs/teleporter/utils/gas-utils" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" "github.com/ava-labs/subnet-evm/accounts/abi/bind" "github.com/ava-labs/subnet-evm/core/types" - "github.com/ava-labs/subnet-evm/eth/tracers" - "github.com/ava-labs/subnet-evm/ethclient" - subnetEvmInterfaces "github.com/ava-labs/subnet-evm/interfaces" "github.com/ava-labs/subnet-evm/precompile/contracts/warp" predicateutils "github.com/ava-labs/subnet-evm/predicate" + validatorsetsig "github.com/ava-labs/teleporter/abi-bindings/go/governance/ValidatorSetSig" + exampleerc20 "github.com/ava-labs/teleporter/abi-bindings/go/mocks/ExampleERC20" + teleportermessenger "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/TeleporterMessenger" + teleporterregistry "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/registry/TeleporterRegistry" + testmessenger "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/tests/TestMessenger" "github.com/ava-labs/teleporter/tests/interfaces" + deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" + gasUtils "github.com/ava-labs/teleporter/utils/gas-utils" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" . "github.com/onsi/gomega" ) var ( - NativeTransferGas uint64 = 21_000 - DefaultTeleporterTransactionGas uint64 = 300_000 - DefaultTeleporterTransactionValue = common.Big0 - ExpectedExampleERC20DeployerBalance = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e10)) + DefaultTeleporterTransactionGas uint64 = 300_000 + DefaultTeleporterTransactionValue = common.Big0 ) -const ( - CChainPathSpecifier = "C" -) +// +// Deployment utils +// + +// Deploys a new version of Teleporter and returns its address +// Does NOT modify the global Teleporter contract address to provide greater testing flexibility. +func DeployNewTeleporterVersion( + ctx context.Context, + network interfaces.LocalNetwork, + fundedKey *ecdsa.PrivateKey, + teleporterByteCodeFile string, +) common.Address { + contractCreationGasPrice := (&big.Int{}).Add(deploymentUtils.GetDefaultContractCreationGasPrice(), big.NewInt(1)) + teleporterDeployerTransaction, + _, + teleporterDeployerAddress, + teleporterContractAddress, + err := deploymentUtils.ConstructKeylessTransaction( + teleporterByteCodeFile, + false, + contractCreationGasPrice, + ) + Expect(err).Should(BeNil()) + + network.DeployTeleporterContractToAllChains( + teleporterDeployerTransaction, + teleporterDeployerAddress, + teleporterContractAddress, + fundedKey, + ) + return teleporterContractAddress +} + +func DeployTestMessenger( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + teleporterManager common.Address, + subnet interfaces.SubnetTestInfo, +) (common.Address, *testmessenger.TestMessenger) { + opts, err := bind.NewKeyedTransactorWithChainID( + senderKey, + subnet.EVMChainID, + ) + Expect(err).Should(BeNil()) + address, tx, exampleMessenger, err := testmessenger.DeployTestMessenger( + opts, + subnet.RPCClient, + subnet.TeleporterRegistryAddress, + teleporterManager, + big.NewInt(1), + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, subnet, tx.Hash()) + + return address, exampleMessenger +} + +// +// Parsing utils +// + +func ParseTeleporterMessage(unsignedMessage avalancheWarp.UnsignedMessage) *teleportermessenger.TeleporterMessage { + addressedPayload, err := payload.ParseAddressedCall(unsignedMessage.Payload) + Expect(err).Should(BeNil()) + + teleporterMessage := teleportermessenger.TeleporterMessage{} + err = teleporterMessage.Unpack(addressedPayload.Payload) + Expect(err).Should(BeNil()) + + return &teleporterMessage +} // -// Test utility functions +// Function call utils // func SendAddFeeAmountAndWaitForAcceptance( @@ -190,183 +242,6 @@ func SendSpecifiedReceiptsAndWaitForAcceptance( return receipt, event.MessageID } -func HttpToWebsocketURI(uri string, blockchainID string) string { - return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) -} - -func HttpToRPCURI(uri string, blockchainID string) string { - return fmt.Sprintf("http://%s/ext/bc/%s/rpc", strings.TrimPrefix(uri, "http://"), blockchainID) -} - -// Get the host and port from a URI. The URI should be in the format http://host:port or https://host:port -func GetURIHostAndPort(uri string) (string, uint32, error) { - // At a minimum uri should have http:// of 7 characters - Expect(len(uri)).Should(BeNumerically(">", 7)) - if uri[:7] == "http://" { - uri = uri[7:] - } else if uri[:8] == "https://" { - uri = uri[8:] - } else { - return "", 0, fmt.Errorf("invalid uri: %s", uri) - } - - // Split the uri into host and port - hostAndPort := strings.Split(uri, ":") - Expect(len(hostAndPort)).Should(Equal(2)) - - // Parse the port - port, err := strconv.ParseUint(hostAndPort[1], 10, 32) - if err != nil { - return "", 0, fmt.Errorf("failed to parse port: %w", err) - } - - return hostAndPort[0], uint32(port), nil -} - -// -// Transaction creation functions -// - -// Constructs a transaction to call sendCrossChainMessage -// Returns the signed transaction. -func CreateSendCrossChainMessageTransaction( - ctx context.Context, - source interfaces.SubnetTestInfo, - input teleportermessenger.TeleporterMessageInput, - senderKey *ecdsa.PrivateKey, - teleporterContractAddress common.Address, -) *types.Transaction { - data, err := teleportermessenger.PackSendCrossChainMessage(input) - Expect(err).Should(BeNil()) - - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, source, PrivateKeyToAddress(senderKey)) - - // Send a transaction to the Teleporter contract - tx := types.NewTx(&types.DynamicFeeTx{ - ChainID: source.EVMChainID, - Nonce: nonce, - To: &teleporterContractAddress, - Gas: DefaultTeleporterTransactionGas, - GasFeeCap: gasFeeCap, - GasTipCap: gasTipCap, - Value: DefaultTeleporterTransactionValue, - Data: data, - }) - - return SignTransaction(tx, senderKey, source.EVMChainID) -} - -// Constructs a transaction to call receiveCrossChainMessage -// Returns the signed transaction. -func CreateReceiveCrossChainMessageTransaction( - ctx context.Context, - signedMessage *avalancheWarp.Message, - requiredGasLimit *big.Int, - teleporterContractAddress common.Address, - senderKey *ecdsa.PrivateKey, - subnetInfo interfaces.SubnetTestInfo, -) *types.Transaction { - // Construct the transaction to send the Warp message to the destination chain - log.Info("Constructing receiveCrossChainMessage transaction for the destination chain") - numSigners, err := signedMessage.Signature.NumSigners() - Expect(err).Should(BeNil()) - - teleporterMessage := ParseTeleporterMessage(signedMessage.UnsignedMessage) - gasLimit, err := gasUtils.CalculateReceiveMessageGasLimit( - numSigners, - requiredGasLimit, - len(signedMessage.Bytes()), - len(signedMessage.Payload), - len(teleporterMessage.Receipts), - ) - Expect(err).Should(BeNil()) - - callData, err := teleportermessenger.PackReceiveCrossChainMessage(0, PrivateKeyToAddress(senderKey)) - Expect(err).Should(BeNil()) - - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) - - destinationTx := predicateutils.NewPredicateTx( - subnetInfo.EVMChainID, - nonce, - &teleporterContractAddress, - gasLimit, - gasFeeCap, - gasTipCap, - big.NewInt(0), - callData, - types.AccessList{}, - warp.ContractAddress, - signedMessage.Bytes(), - ) - - return SignTransaction(destinationTx, senderKey, subnetInfo.EVMChainID) -} - -// Constructs a transaction to call addProtocolVersion -// Returns the signed transaction. -func CreateAddProtocolVersionTransaction( - ctx context.Context, - signedMessage *avalancheWarp.Message, - teleporterRegistryAddress common.Address, - senderKey *ecdsa.PrivateKey, - subnetInfo interfaces.SubnetTestInfo, -) *types.Transaction { - // Construct the transaction to send the Warp message to the destination chain - log.Info("Constructing addProtocolVersion transaction for the destination chain") - - callData, err := teleporterregistry.PackAddProtocolVersion(0) - Expect(err).Should(BeNil()) - - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) - - destinationTx := predicateutils.NewPredicateTx( - subnetInfo.EVMChainID, - nonce, - &teleporterRegistryAddress, - 500_000, - gasFeeCap, - gasTipCap, - big.NewInt(0), - callData, - types.AccessList{}, - warp.ContractAddress, - signedMessage.Bytes(), - ) - - return SignTransaction(destinationTx, senderKey, subnetInfo.EVMChainID) -} - -func CreateExecuteCallPredicateTransaction( - ctx context.Context, - signedMessage *avalancheWarp.Message, - validatorSetSigAddress common.Address, - senderKey *ecdsa.PrivateKey, - subnetInfo interfaces.SubnetTestInfo, -) *types.Transaction { - log.Info("Constructing executeCall transaction for the destination chain") - - callData, err := validatorsetsig.PackExecuteCall(0) - Expect(err).Should(BeNil()) - - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) - - destinationTx := predicateutils.NewPredicateTx( - subnetInfo.EVMChainID, - nonce, - &validatorSetSigAddress, - 500_000, - gasFeeCap, - gasTipCap, - big.NewInt(0), - callData, - types.AccessList{}, - warp.ContractAddress, - signedMessage.Bytes(), - ) - return SignTransaction(destinationTx, senderKey, subnetInfo.EVMChainID) -} - func AddProtocolVersionAndWaitForAcceptance( ctx context.Context, network interfaces.Network, @@ -404,113 +279,15 @@ func AddProtocolVersionAndWaitForAcceptance( Expect(versionUpdatedEvent.NewVersion.Cmp(expectedLatestVersion)).Should(Equal(0)) } -// Returns Receipt for the transaction unlike TeleporterRegistry version since this is a non-teleporter case -// and we don't want to add the ValidatorSetSig ABI to the subnetInfo -func ExecuteValidatorSetSigCallAndVerify( +func SendCrossChainMessageAndWaitForAcceptance( ctx context.Context, - network interfaces.Network, source interfaces.SubnetTestInfo, destination interfaces.SubnetTestInfo, - validatorSetSigAddress common.Address, + input teleportermessenger.TeleporterMessageInput, senderKey *ecdsa.PrivateKey, - unsignedMessage *avalancheWarp.UnsignedMessage, - expectSuccess bool, -) *types.Receipt { - signedWarpMsg := network.GetSignedMessage(ctx, source, destination, unsignedMessage.ID()) - log.Info("Got signed warp message", "messageID", signedWarpMsg.ID()) - - signedPredicateTx := CreateExecuteCallPredicateTransaction( - ctx, - signedWarpMsg, - validatorSetSigAddress, - senderKey, - destination, - ) - - // Wait for tx to be accepted and verify events emitted - if expectSuccess { - return SendTransactionAndWaitForSuccess(ctx, destination, signedPredicateTx) - } - return SendTransactionAndWaitForFailure(ctx, destination, signedPredicateTx) -} - -func CreateNativeTransferTransaction( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - fromKey *ecdsa.PrivateKey, - recipient common.Address, - amount *big.Int, -) *types.Transaction { - fromAddress := crypto.PubkeyToAddress(fromKey.PublicKey) - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, fromAddress) - - tx := types.NewTx(&types.DynamicFeeTx{ - ChainID: subnetInfo.EVMChainID, - Nonce: nonce, - To: &recipient, - Gas: NativeTransferGas, - GasFeeCap: gasFeeCap, - GasTipCap: gasTipCap, - Value: amount, - }) - - return SignTransaction(tx, fromKey, subnetInfo.EVMChainID) -} - -func SendNativeTransfer( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - fromKey *ecdsa.PrivateKey, - recipient common.Address, - amount *big.Int, -) *types.Receipt { - tx := CreateNativeTransferTransaction(ctx, subnetInfo, fromKey, recipient, amount) - return SendTransactionAndWaitForSuccess(ctx, subnetInfo, tx) -} - -// Sends a tx, and waits for it to be mined. -// Asserts Receipt.status equals success. -func sendAndWaitForTransaction( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - tx *types.Transaction, - success bool, -) *types.Receipt { - err := subnetInfo.RPCClient.SendTransaction(ctx, tx) - Expect(err).Should(BeNil()) - - return waitForTransaction(ctx, subnetInfo, tx.Hash(), success) -} - -// Sends a tx, and waits for it to be mined. -// Asserts Receipt.status equals false. -func SendTransactionAndWaitForFailure( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - tx *types.Transaction, -) *types.Receipt { - return sendAndWaitForTransaction(ctx, subnetInfo, tx, false) -} - -// Sends a tx, and waits for it to be mined. -// Asserts Receipt.status equals true. -func SendTransactionAndWaitForSuccess( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - tx *types.Transaction, -) *types.Receipt { - return sendAndWaitForTransaction(ctx, subnetInfo, tx, true) -} - -func SendCrossChainMessageAndWaitForAcceptance( - ctx context.Context, - source interfaces.SubnetTestInfo, - destination interfaces.SubnetTestInfo, - input teleportermessenger.TeleporterMessageInput, - senderKey *ecdsa.PrivateKey, -) (*types.Receipt, ids.ID) { - opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) - Expect(err).Should(BeNil()) +) (*types.Receipt, ids.ID) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) + Expect(err).Should(BeNil()) // Send a transaction to the Teleporter contract tx, err := source.TeleporterMessenger.SendCrossChainMessage(opts, input) @@ -531,167 +308,6 @@ func SendCrossChainMessageAndWaitForAcceptance( return receipt, event.MessageID } -// Waits for a transaction to be mined. -// Asserts Receipt.status equals true. -func WaitForTransactionSuccess( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - txHash common.Hash, -) *types.Receipt { - return waitForTransaction(ctx, subnetInfo, txHash, true) -} - -// Waits for a transaction to be mined. -// Asserts Receipt.status equals false. -func WaitForTransactionFailure( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - txHash common.Hash, -) *types.Receipt { - return waitForTransaction(ctx, subnetInfo, txHash, false) -} - -// Waits for a transaction to be mined. -// Asserts Receipt.status equals success. -func waitForTransaction( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - txHash common.Hash, - success bool, -) *types.Receipt { - cctx, cancel := context.WithTimeout(ctx, 10*time.Second) - defer cancel() - - receipt, err := WaitMined(cctx, subnetInfo.RPCClient, txHash) - Expect(err).Should(BeNil()) - - if success { - if receipt.Status == types.ReceiptStatusFailed { - TraceTransactionAndExit(ctx, subnetInfo.RPCClient, receipt.TxHash) - } - } else { - Expect(receipt.Status).Should(Equal(types.ReceiptStatusFailed)) - } - return receipt -} - -// Polls for a transaction receipt of the given txHash on each queryTicker tick until -// either a transaction receipt returned, or the context is cancelled or expired. -func waitForTransactionReceipt( - cctx context.Context, - rpcClient ethclient.Client, - txHash common.Hash, -) (*types.Receipt, error) { - queryTicker := time.NewTicker(200 * time.Millisecond) - defer queryTicker.Stop() - for { - receipt, err := rpcClient.TransactionReceipt(cctx, txHash) - if err == nil { - return receipt, nil - } - - if errors.Is(err, subnetEvmInterfaces.NotFound) { - log.Debug("Transaction not yet mined") - } else { - log.Error("Receipt retrieval failed", "err", err) - return nil, err - } - - // Wait for the next round. - select { - case <-cctx.Done(): - return nil, cctx.Err() - case <-queryTicker.C: - } - } -} - -// Polls for the eth_blockNumber endpoint for the latest blockheight on each queryTicker tick until -// either the returned height is greater than or equal to the expectedBlockNumber, or the context -// is cancelled or expired. -func waitForBlockHeight( - cctx context.Context, - rpcClient ethclient.Client, - expectedBlockNumber uint64, -) error { - queryTicker := time.NewTicker(2 * time.Second) - defer queryTicker.Stop() - for { - currentBlockNumber, err := rpcClient.BlockNumber(cctx) - if err != nil { - return err - } - - if currentBlockNumber >= expectedBlockNumber { - return nil - } else { - log.Info("Waiting for block height where transaction was included", - "blockNumber", expectedBlockNumber) - } - - // Wait for the next round. - select { - case <-cctx.Done(): - return cctx.Err() - case <-queryTicker.C: - } - } -} - -// WaitMined waits for tx to be mined on the blockchain. -// It stops waiting when the context is canceled. -// Takes a tx hash instead of the full tx in the subnet-evm version of this function. -// Copied and modified from https://github.com/ava-labs/subnet-evm/blob/v0.6.0-fuji/accounts/abi/bind/util.go#L42 -func WaitMined(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) (*types.Receipt, error) { - cctx, cancel := context.WithTimeout(ctx, 20*time.Second) - defer cancel() - - receipt, err := waitForTransactionReceipt(cctx, rpcClient, txHash) - if err != nil { - return nil, err - } - - // Check that the block height endpoint returns a block height as high as the block number that the transaction was - // included in. This is to workaround the issue where multiple nodes behind a public RPC endpoint see - // transactions/blocks at different points in time. Ideally, all nodes in the network should have seen this block - // and transaction before returning from WaitMined. The block height endpoint of public RPC endpoints is - // configured to return the lowest value currently returned by any node behind the load balancer, so waiting for - // it to be at least as high as the block height specified in the receipt should provide a relatively strong - // indication that the transaction has been seen widely throughout the network. - err = waitForBlockHeight(cctx, rpcClient, receipt.BlockNumber.Uint64()) - if err != nil { - return nil, err - } - - return receipt, nil -} - -// Returns the first log in 'logs' that is successfully parsed by 'parser' -// Errors and prints a trace of the transaction if no log is found. -func GetEventFromLogsOrTrace[T any]( - ctx context.Context, - receipt *types.Receipt, - subnetInfo interfaces.SubnetTestInfo, - parser func(log types.Log) (T, error), -) T { - log, err := GetEventFromLogs(receipt.Logs, parser) - if err != nil { - TraceTransactionAndExit(ctx, subnetInfo.RPCClient, receipt.TxHash) - } - return log -} - -// Returns the first log in 'logs' that is successfully parsed by 'parser' -func GetEventFromLogs[T any](logs []*types.Log, parser func(log types.Log) (T, error)) (T, error) { - for _, log := range logs { - event, err := parser(*log) - if err == nil { - return event, nil - } - } - return *new(T), fmt.Errorf("failed to find %T event in receipt logs", *new(T)) -} - // Returns true if the transaction receipt contains a ReceiptReceived log with the specified messageID func CheckReceiptReceived( receipt *types.Receipt, @@ -751,177 +367,6 @@ func GetOutstandingReceiptCount(source interfaces.SubnetTestInfo, destinationBlo return size } -// Signs a transaction using the provided key for the specified chainID -func SignTransaction(tx *types.Transaction, key *ecdsa.PrivateKey, chainID *big.Int) *types.Transaction { - txSigner := types.LatestSignerForChainID(chainID) - signedTx, err := types.SignTx(tx, txSigner, key) - Expect(err).Should(BeNil()) - - return signedTx -} - -// Returns the gasFeeCap, gasTipCap, and nonce the be used when constructing a transaction from fundedAddress -func CalculateTxParams( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - fundedAddress common.Address, -) (*big.Int, *big.Int, uint64) { - baseFee, err := subnetInfo.RPCClient.EstimateBaseFee(ctx) - Expect(err).Should(BeNil()) - - gasTipCap, err := subnetInfo.RPCClient.SuggestGasTipCap(ctx) - Expect(err).Should(BeNil()) - - nonce, err := subnetInfo.RPCClient.NonceAt(ctx, fundedAddress, nil) - Expect(err).Should(BeNil()) - - gasFeeCap := baseFee.Mul(baseFee, big.NewInt(gasUtils.BaseFeeFactor)) - gasFeeCap.Add(gasFeeCap, big.NewInt(gasUtils.MaxPriorityFeePerGas)) - - return gasFeeCap, gasTipCap, nonce -} - -func PrivateKeyToAddress(k *ecdsa.PrivateKey) common.Address { - return crypto.PubkeyToAddress(k.PublicKey) -} - -// Throws a Gomega error if there is a mismatch -func CheckBalance(ctx context.Context, addr common.Address, expectedBalance *big.Int, rpcClient ethclient.Client) { - bal, err := rpcClient.BalanceAt(ctx, addr, nil) - Expect(err).Should(BeNil()) - ExpectBigEqual(bal, expectedBalance) -} - -// Gomega will print the transaction trace and exit -func TraceTransactionAndExit(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) { - Expect(TraceTransaction(ctx, rpcClient, txHash)).Should(Equal("")) -} - -func TraceTransaction(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) string { - var result interface{} - ct := "callTracer" - err := rpcClient.Client().Call(&result, "debug_traceTransaction", txHash.String(), tracers.TraceConfig{Tracer: &ct}) - Expect(err).Should(BeNil()) - - jsonStr, err := json.Marshal(result) - Expect(err).Should(BeNil()) - - return string(jsonStr) -} - -func ExpectBigEqual(v1 *big.Int, v2 *big.Int) { - // Compare strings, so gomega will print the numbers if they differ - Expect(v1.String()).Should(Equal(v2.String())) -} - -func BigIntSub(v1 *big.Int, v2 *big.Int) *big.Int { - return big.NewInt(0).Sub(v1, v2) -} - -func BigIntMul(v1 *big.Int, v2 *big.Int) *big.Int { - return big.NewInt(0).Mul(v1, v2) -} - -func ERC20Approve( - ctx context.Context, - token *exampleerc20.ExampleERC20, - spender common.Address, - amount *big.Int, - source interfaces.SubnetTestInfo, - senderKey *ecdsa.PrivateKey, -) { - opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) - Expect(err).Should(BeNil()) - tx, err := token.Approve(opts, spender, amount) - Expect(err).Should(BeNil()) - log.Info("Approved ERC20", "spender", spender.Hex(), "txHash", tx.Hash().Hex()) - - WaitForTransactionSuccess(ctx, source, tx.Hash()) -} - -func DeployExampleERC20( - ctx context.Context, - senderKey *ecdsa.PrivateKey, - source interfaces.SubnetTestInfo, -) (common.Address, *exampleerc20.ExampleERC20) { - opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) - Expect(err).Should(BeNil()) - - // Deploy Mock ERC20 contract - address, tx, token, err := exampleerc20.DeployExampleERC20(opts, source.RPCClient) - Expect(err).Should(BeNil()) - log.Info("Deployed Mock ERC20 contract", "address", address.Hex(), "txHash", tx.Hash().Hex()) - - // Wait for the transaction to be mined - WaitForTransactionSuccess(ctx, source, tx.Hash()) - - // Check that the deployer has the expected initial balance - senderAddress := crypto.PubkeyToAddress(senderKey.PublicKey) - balance, err := token.BalanceOf(&bind.CallOpts{}, senderAddress) - Expect(err).Should(BeNil()) - Expect(balance).Should(Equal(ExpectedExampleERC20DeployerBalance)) - - return address, token -} - -func DeployTestMessenger( - ctx context.Context, - senderKey *ecdsa.PrivateKey, - teleporterManager common.Address, - subnet interfaces.SubnetTestInfo, -) (common.Address, *testmessenger.TestMessenger) { - opts, err := bind.NewKeyedTransactorWithChainID( - senderKey, - subnet.EVMChainID, - ) - Expect(err).Should(BeNil()) - minTeleporterVersion, err := subnet.TeleporterRegistry.LatestVersion(&bind.CallOpts{}) - Expect(err).Should(BeNil()) - address, tx, exampleMessenger, err := testmessenger.DeployTestMessenger( - opts, - subnet.RPCClient, - subnet.TeleporterRegistryAddress, - teleporterManager, - minTeleporterVersion, - ) - Expect(err).Should(BeNil()) - - // Wait for the transaction to be mined - WaitForTransactionSuccess(ctx, subnet, tx.Hash()) - - return address, exampleMessenger -} - -func DeployValidatorSetSig( - ctx context.Context, - senderKey *ecdsa.PrivateKey, - contractSubnet interfaces.SubnetTestInfo, - validatorSubnet interfaces.SubnetTestInfo, -) (common.Address, *validatorsetsig.ValidatorSetSig) { - opts, err := bind.NewKeyedTransactorWithChainID(senderKey, contractSubnet.EVMChainID) - Expect(err).Should(BeNil()) - address, tx, validatorSetSig, err := validatorsetsig.DeployValidatorSetSig( - opts, - contractSubnet.RPCClient, - validatorSubnet.BlockchainID, - ) - Expect(err).Should(BeNil()) - - // Wait for the transaction to be mined - WaitForTransactionSuccess(ctx, contractSubnet, tx.Hash()) - - return address, validatorSetSig -} - -func GetTwoSubnets(network interfaces.Network) ( - interfaces.SubnetTestInfo, - interfaces.SubnetTestInfo, -) { - subnets := network.GetSubnetsInfo() - Expect(len(subnets)).Should(BeNumerically(">=", 2)) - return subnets[0], subnets[1] -} - func SendExampleCrossChainMessageAndVerify( ctx context.Context, network interfaces.Network, @@ -998,6 +443,154 @@ func SendExampleCrossChainMessageAndVerify( } } +// +// Transaction utils +// + +// Constructs a transaction to call sendCrossChainMessage +// Returns the signed transaction. +func CreateSendCrossChainMessageTransaction( + ctx context.Context, + source interfaces.SubnetTestInfo, + input teleportermessenger.TeleporterMessageInput, + senderKey *ecdsa.PrivateKey, + teleporterContractAddress common.Address, +) *types.Transaction { + data, err := teleportermessenger.PackSendCrossChainMessage(input) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, source, PrivateKeyToAddress(senderKey)) + + // Send a transaction to the Teleporter contract + tx := types.NewTx(&types.DynamicFeeTx{ + ChainID: source.EVMChainID, + Nonce: nonce, + To: &teleporterContractAddress, + Gas: DefaultTeleporterTransactionGas, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Value: DefaultTeleporterTransactionValue, + Data: data, + }) + + return SignTransaction(tx, senderKey, source.EVMChainID) +} + +// Constructs a transaction to call receiveCrossChainMessage +// Returns the signed transaction. +func CreateReceiveCrossChainMessageTransaction( + ctx context.Context, + signedMessage *avalancheWarp.Message, + requiredGasLimit *big.Int, + teleporterContractAddress common.Address, + senderKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, +) *types.Transaction { + // Construct the transaction to send the Warp message to the destination chain + log.Info("Constructing receiveCrossChainMessage transaction for the destination chain") + numSigners, err := signedMessage.Signature.NumSigners() + Expect(err).Should(BeNil()) + + teleporterMessage := ParseTeleporterMessage(signedMessage.UnsignedMessage) + gasLimit, err := gasUtils.CalculateReceiveMessageGasLimit( + numSigners, + requiredGasLimit, + len(signedMessage.Bytes()), + len(signedMessage.Payload), + len(teleporterMessage.Receipts), + ) + Expect(err).Should(BeNil()) + + callData, err := teleportermessenger.PackReceiveCrossChainMessage(0, PrivateKeyToAddress(senderKey)) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) + + destinationTx := predicateutils.NewPredicateTx( + subnetInfo.EVMChainID, + nonce, + &teleporterContractAddress, + gasLimit, + gasFeeCap, + gasTipCap, + big.NewInt(0), + callData, + types.AccessList{}, + warp.ContractAddress, + signedMessage.Bytes(), + ) + + return SignTransaction(destinationTx, senderKey, subnetInfo.EVMChainID) +} + +// Constructs a transaction to call addProtocolVersion +// Returns the signed transaction. +func CreateAddProtocolVersionTransaction( + ctx context.Context, + signedMessage *avalancheWarp.Message, + teleporterRegistryAddress common.Address, + senderKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, +) *types.Transaction { + // Construct the transaction to send the Warp message to the destination chain + log.Info("Constructing addProtocolVersion transaction for the destination chain") + + callData, err := teleporterregistry.PackAddProtocolVersion(0) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) + + destinationTx := predicateutils.NewPredicateTx( + subnetInfo.EVMChainID, + nonce, + &teleporterRegistryAddress, + 500_000, + gasFeeCap, + gasTipCap, + big.NewInt(0), + callData, + types.AccessList{}, + warp.ContractAddress, + signedMessage.Bytes(), + ) + + return SignTransaction(destinationTx, senderKey, subnetInfo.EVMChainID) +} + +func CreateExecuteCallPredicateTransaction( + ctx context.Context, + signedMessage *avalancheWarp.Message, + validatorSetSigAddress common.Address, + senderKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, +) *types.Transaction { + log.Info("Constructing executeCall transaction for the destination chain") + + callData, err := validatorsetsig.PackExecuteCall(0) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) + + destinationTx := predicateutils.NewPredicateTx( + subnetInfo.EVMChainID, + nonce, + &validatorSetSigAddress, + 500_000, + gasFeeCap, + gasTipCap, + big.NewInt(0), + callData, + types.AccessList{}, + warp.ContractAddress, + signedMessage.Bytes(), + ) + return SignTransaction(destinationTx, senderKey, subnetInfo.EVMChainID) +} + +// +// Off-chain message utils +// + // Creates an Warp message that registers a Teleporter protocol version with TeleporterRegistry. // Returns the Warp message, as well as the chain config adding the message to the list of approved // off-chain Warp messages @@ -1041,209 +634,3 @@ func CreateOffChainRegistryMessage( return unsignedMessage } - -func InitOffChainMessageChainConfigValidatorSetSig( - networkID uint32, - subnet interfaces.SubnetTestInfo, - validatorSetSigAddress common.Address, - validatorSetSigMessages []validatorsetsig.ValidatorSetSigMessage, -) ([]avalancheWarp.UnsignedMessage, string) { - unsignedMessages := []avalancheWarp.UnsignedMessage{} - for _, message := range validatorSetSigMessages { - unsignedMessage := CreateOffChainValidatorSetSigMessage(networkID, subnet, message) - unsignedMessages = append(unsignedMessages, *unsignedMessage) - log.Info("Adding validatorSetSig off-chain message to Warp chain config", - "messageID", unsignedMessage.ID(), - "blockchainID", subnet.BlockchainID.String()) - } - return unsignedMessages, GetChainConfigWithOffChainMessages(unsignedMessages) -} - -// Creates an off-chain Warp message pointing to a function, contract and payload to be executed -// if the validator set signs this message -func CreateOffChainValidatorSetSigMessage( - networkID uint32, - subnet interfaces.SubnetTestInfo, - message validatorsetsig.ValidatorSetSigMessage, -) *avalancheWarp.UnsignedMessage { - sourceAddress := []byte{} - payloadBytes, err := message.Pack() - Expect(err).Should(BeNil()) - - addressedPayload, err := payload.NewAddressedCall(sourceAddress, payloadBytes) - Expect(err).Should(BeNil()) - - unsignedMessage, err := avalancheWarp.NewUnsignedMessage( - networkID, - subnet.BlockchainID, - addressedPayload.Bytes(), - ) - Expect(err).Should(BeNil()) - - return unsignedMessage -} - -// Deploys a new version of Teleporter and returns its address -// Does NOT modify the global Teleporter contract address to provide greater testing flexibility. -func DeployNewTeleporterVersion( - ctx context.Context, - network interfaces.LocalNetwork, - fundedKey *ecdsa.PrivateKey, - teleporterByteCodeFile string, -) common.Address { - contractCreationGasPrice := (&big.Int{}).Add(deploymentUtils.GetDefaultContractCreationGasPrice(), big.NewInt(1)) - teleporterDeployerTransaction, - _, - teleporterDeployerAddress, - teleporterContractAddress, - err := deploymentUtils.ConstructKeylessTransaction( - teleporterByteCodeFile, - false, - contractCreationGasPrice, - ) - Expect(err).Should(BeNil()) - - network.DeployTeleporterContractToAllChains( - teleporterDeployerTransaction, - teleporterDeployerAddress, - teleporterContractAddress, - fundedKey, - ) - return teleporterContractAddress -} - -type ChainConfigMap map[string]string - -// Sets the chain config in customChainConfigs for the specified subnet -func (m ChainConfigMap) Add(subnet interfaces.SubnetTestInfo, chainConfig string) { - if subnet.SubnetID == constants.PrimaryNetworkID { - m[CChainPathSpecifier] = chainConfig - } else { - m[subnet.BlockchainID.String()] = chainConfig - } -} - -func ParseTeleporterMessage(unsignedMessage avalancheWarp.UnsignedMessage) *teleportermessenger.TeleporterMessage { - addressedPayload, err := payload.ParseAddressedCall(unsignedMessage.Payload) - Expect(err).Should(BeNil()) - - teleporterMessage := teleportermessenger.TeleporterMessage{} - err = teleporterMessage.Unpack(addressedPayload.Payload) - Expect(err).Should(BeNil()) - - return &teleporterMessage -} - -func GetChainConfigWithOffChainMessages(offChainMessages []avalancheWarp.UnsignedMessage) string { - // Convert messages to hex - hexOffChainMessages := []string{} - for _, message := range offChainMessages { - hexOffChainMessages = append(hexOffChainMessages, hexutil.Encode(message.Bytes())) - } - - // Create a map to represent the JSON structure - jsonMap := map[string]interface{}{ - "warp-api-enabled": true, - "warp-off-chain-messages": hexOffChainMessages, - "log-level": "debug", - "eth-apis": []string{ - "eth", "eth-filter", "net", "admin", "web3", - "internal-eth", "internal-blockchain", "internal-transaction", - "internal-debug", "internal-account", "internal-personal", - "debug", "debug-tracer", "debug-file-tracer", "debug-handler", - }, - } - - // Marshal the map to JSON - offChainMessageJson, err := json.Marshal(jsonMap) - Expect(err).Should(BeNil()) - - return string(offChainMessageJson) -} - -// read in the template file, make the substitutions declared at the beginning -// of the function, write out the instantiation to a temp file, and then return -// the path to that temp file. -func InstantiateGenesisTemplate( - templateFileName string, - chainID uint64, - teleporterContractAddress common.Address, - teleporterDeployedBytecode string, - teleporterDeployerAddress common.Address, -) string { - substitutions := []struct { - Target string - Value string - }{ - { - "", - strconv.FormatUint(chainID, 10), - }, - { - "", - teleporterContractAddress.Hex(), - }, - { - "", - teleporterDeployedBytecode, - }, - { - "", - teleporterDeployerAddress.Hex(), - }, - } - - templateFileBytes, err := os.ReadFile(templateFileName) - Expect(err).Should(BeNil()) - - subnetGenesisFile, err := os.CreateTemp(os.TempDir(), "") - Expect(err).Should(BeNil()) - - defer subnetGenesisFile.Close() - - var replaced string = string(templateFileBytes[:]) - for _, s := range substitutions { - replaced = strings.ReplaceAll(replaced, s.Target, s.Value) - } - - subnetGenesisFile.WriteString(replaced) - - return subnetGenesisFile.Name() -} - -// -// Teleporter message utils -// - -// Blocks until the given teleporter message is delivered to the specified TeleporterMessenger -// before the timeout, or if an error occurred. -func WaitTeleporterMessageDelivered( - ctx context.Context, - teleporterMessenger *teleportermessenger.TeleporterMessenger, - teleporterMessageID ids.ID, -) error { - cctx, cancel := context.WithTimeout(ctx, 20*time.Second) - defer cancel() - - queryTicker := time.NewTicker(200 * time.Millisecond) - defer queryTicker.Stop() - for { - delivered, err := teleporterMessenger.MessageReceived( - &bind.CallOpts{}, teleporterMessageID, - ) - if err != nil { - return err - } - - if delivered { - return nil - } - - // Wait for the next round. - select { - case <-cctx.Done(): - return cctx.Err() - case <-queryTicker.C: - } - } -} diff --git a/tests/utils/validator_manager.go b/tests/utils/validator_manager.go new file mode 100644 index 000000000..f39c11e24 --- /dev/null +++ b/tests/utils/validator_manager.go @@ -0,0 +1,1635 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + "crypto/sha256" + "encoding/binary" + "fmt" + "math/big" + "reflect" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + warpMessages "github.com/ava-labs/avalanchego/vms/platformvm/warp/messages" + warpPayload "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" + "github.com/ava-labs/awm-relayer/signature-aggregator/aggregator" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/precompile/contracts/warp" + predicateutils "github.com/ava-labs/subnet-evm/predicate" + exampleerc20 "github.com/ava-labs/teleporter/abi-bindings/go/mocks/ExampleERC20" + erc20tokenstakingmanager "github.com/ava-labs/teleporter/abi-bindings/go/validator-manager/ERC20TokenStakingManager" + examplerewardcalculator "github.com/ava-labs/teleporter/abi-bindings/go/validator-manager/ExampleRewardCalculator" + nativetokenstakingmanager "github.com/ava-labs/teleporter/abi-bindings/go/validator-manager/NativeTokenStakingManager" + poavalidatormanager "github.com/ava-labs/teleporter/abi-bindings/go/validator-manager/PoAValidatorManager" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ethereum/go-ethereum/common" + + . "github.com/onsi/gomega" +) + +const ( + DefaultMinDelegateFeeBips uint16 = 1 + DefaultMinStakeDurationSeconds uint64 = 1 + DefaultMinStakeAmount uint64 = 1e18 + DefaultMaxStakeAmount uint64 = 10e18 + DefaultMaxStakeMultiplier uint8 = 4 + DefaultMaxChurnPercentage uint8 = 20 + DefaultChurnPeriodSeconds uint64 = 1 + + initialValidatorPackedLen = 88 +) + +// +// Deployment utils +// + +func DeployNativeTokenStakingManager( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, +) (common.Address, *nativetokenstakingmanager.NativeTokenStakingManager) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + address, tx, stakingManager, err := nativetokenstakingmanager.DeployNativeTokenStakingManager( + opts, + subnet.RPCClient, + 0, // ICMInitializable.Allowed + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, subnet, tx.Hash()) + + return address, stakingManager +} + +func DeployAndInitializeNativeTokenStakingManager( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, +) (common.Address, *nativetokenstakingmanager.NativeTokenStakingManager) { + stakingManagerContractAddress, stakingManager := DeployNativeTokenStakingManager( + ctx, + senderKey, + subnet, + ) + rewardCalculatorAddress, _ := DeployExampleRewardCalculator( + ctx, + senderKey, + subnet, + uint64(10), + ) + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.Initialize( + opts, + nativetokenstakingmanager.PoSValidatorManagerSettings{ + BaseSettings: nativetokenstakingmanager.ValidatorManagerSettings{ + SubnetID: subnet.SubnetID, + ChurnPeriodSeconds: DefaultChurnPeriodSeconds, + MaximumChurnPercentage: DefaultMaxChurnPercentage, + }, + MinimumStakeAmount: big.NewInt(0).SetUint64(DefaultMinStakeAmount), + MaximumStakeAmount: big.NewInt(0).SetUint64(DefaultMaxStakeAmount), + MinimumStakeDuration: DefaultMinStakeDurationSeconds, + MinimumDelegationFeeBips: DefaultMinDelegateFeeBips, + MaximumStakeMultiplier: DefaultMaxStakeMultiplier, + RewardCalculator: rewardCalculatorAddress, + }, + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) + + return stakingManagerContractAddress, stakingManager +} + +func DeployERC20TokenStakingManager( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, +) (common.Address, *erc20tokenstakingmanager.ERC20TokenStakingManager) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + address, tx, stakingManager, err := erc20tokenstakingmanager.DeployERC20TokenStakingManager( + opts, + subnet.RPCClient, + 0, // ICMInitializable.Allowed + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, subnet, tx.Hash()) + + return address, stakingManager +} + +func DeployAndInitializeERC20TokenStakingManager( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, +) ( + common.Address, + *erc20tokenstakingmanager.ERC20TokenStakingManager, + common.Address, + *exampleerc20.ExampleERC20, +) { + stakingManagerContractAddress, stakingManager := DeployERC20TokenStakingManager( + ctx, + senderKey, + subnet, + ) + + erc20Address, erc20 := DeployExampleERC20(ctx, senderKey, subnet) + rewardCalculatorAddress, _ := DeployExampleRewardCalculator( + ctx, + senderKey, + subnet, + uint64(10), + ) + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.Initialize( + opts, + erc20tokenstakingmanager.PoSValidatorManagerSettings{ + BaseSettings: erc20tokenstakingmanager.ValidatorManagerSettings{ + SubnetID: subnet.SubnetID, + ChurnPeriodSeconds: DefaultChurnPeriodSeconds, + MaximumChurnPercentage: DefaultMaxChurnPercentage, + }, + MinimumStakeAmount: big.NewInt(0).SetUint64(DefaultMinStakeAmount), + MaximumStakeAmount: big.NewInt(0).SetUint64(DefaultMaxStakeAmount), + MinimumStakeDuration: DefaultMinStakeDurationSeconds, + MinimumDelegationFeeBips: DefaultMinDelegateFeeBips, + MaximumStakeMultiplier: DefaultMaxStakeMultiplier, + RewardCalculator: rewardCalculatorAddress, + }, + erc20Address, + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) + + return stakingManagerContractAddress, stakingManager, erc20Address, erc20 +} + +func DeployPoAValidatorManager( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, +) (common.Address, *poavalidatormanager.PoAValidatorManager) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + address, tx, validatorManager, err := poavalidatormanager.DeployPoAValidatorManager( + opts, + subnet.RPCClient, + 0, // ICMInitializable.Allowed + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, subnet, tx.Hash()) + + return address, validatorManager +} + +func DeployAndInitializePoAValidatorManager( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + ownerAddress common.Address, +) (common.Address, *poavalidatormanager.PoAValidatorManager) { + validatorManagerAddress, validatorManager := DeployPoAValidatorManager( + ctx, + senderKey, + subnet, + ) + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := validatorManager.Initialize( + opts, + poavalidatormanager.ValidatorManagerSettings{ + SubnetID: subnet.SubnetID, + ChurnPeriodSeconds: uint64(0), + MaximumChurnPercentage: uint8(20), + }, + ownerAddress, + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) + + return validatorManagerAddress, validatorManager +} + +func DeployExampleRewardCalculator( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + rewardBasisPoints uint64, +) (common.Address, *examplerewardcalculator.ExampleRewardCalculator) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + address, tx, calculator, err := examplerewardcalculator.DeployExampleRewardCalculator( + opts, + subnet.RPCClient, + rewardBasisPoints, + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, subnet, tx.Hash()) + + return address, calculator +} + +// +// Validator Set Initialization utils +// + +func InitializeNativeTokenValidatorSet( + ctx context.Context, + sendingKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + validatorManager *nativetokenstakingmanager.NativeTokenStakingManager, + validatorManagerAddress common.Address, + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, + initialValidatorWeight uint64, +) ids.ID { + convertSubnetTxId := ids.GenerateTestID() + blsPublicKey := [bls.PublicKeyLen]byte{} + subnetConversionData := nativetokenstakingmanager.SubnetConversionData{ + ConvertSubnetTxID: convertSubnetTxId, + ValidatorManagerBlockchainID: subnetInfo.BlockchainID, + ValidatorManagerAddress: validatorManagerAddress, + InitialValidators: []nativetokenstakingmanager.InitialValidator{ + { + NodeID: ids.GenerateTestID(), + Weight: initialValidatorWeight, + BlsPublicKey: blsPublicKey[:], + }, + }, + } + subnetConversionDataBytes, err := PackSubnetConversionData(subnetConversionData) + Expect(err).Should(BeNil()) + subnetConversionID := sha256.Sum256(subnetConversionDataBytes) + subnetConversionSignedMessage := ConstructSubnetConversionMessage( + subnetConversionID, + subnetInfo, + pChainInfo, + network, + signatureAggregator, + ) + // Deliver the Warp message to the subnet + receipt := DeliverNativeTokenSubnetConversion( + sendingKey, + subnetInfo, + validatorManagerAddress, + subnetConversionSignedMessage, + subnetConversionData, + ) + initialValidatorCreatedEvent, err := GetEventFromLogs( + receipt.Logs, + validatorManager.ParseInitialValidatorCreated, + ) + Expect(err).Should(BeNil()) + Expect(initialValidatorCreatedEvent.NodeID).Should(Equal(subnetConversionData.InitialValidators[0].NodeID)) + Expect(initialValidatorCreatedEvent.Weight).Should(Equal(new(big.Int).SetUint64(initialValidatorWeight))) + + expectedValidationID := CalculateSubnetConversionValidationId(convertSubnetTxId, 0) + emittedValidationID := ids.ID(initialValidatorCreatedEvent.ValidationID) + Expect(emittedValidationID).Should(Equal(expectedValidationID)) + + return emittedValidationID +} + +func InitializeERC20TokenValidatorSet( + ctx context.Context, + sendingKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + validatorManager *erc20tokenstakingmanager.ERC20TokenStakingManager, + validatorManagerAddress common.Address, + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, + initialValidatorWeight uint64, +) ids.ID { + convertSubnetTxId := ids.GenerateTestID() + blsPublicKey := [bls.PublicKeyLen]byte{} + subnetConversionData := erc20tokenstakingmanager.SubnetConversionData{ + ConvertSubnetTxID: convertSubnetTxId, + ValidatorManagerBlockchainID: subnetInfo.BlockchainID, + ValidatorManagerAddress: validatorManagerAddress, + InitialValidators: []erc20tokenstakingmanager.InitialValidator{ + { + NodeID: ids.GenerateTestID(), + Weight: initialValidatorWeight, + BlsPublicKey: blsPublicKey[:], + }, + }, + } + subnetConversionDataBytes, err := PackSubnetConversionData(subnetConversionData) + Expect(err).Should(BeNil()) + subnetConversionID := sha256.Sum256(subnetConversionDataBytes) + subnetConversionSignedMessage := ConstructSubnetConversionMessage( + subnetConversionID, + subnetInfo, + pChainInfo, + network, + signatureAggregator, + ) + // Deliver the Warp message to the subnet + receipt := DeliverERC20TokenSubnetConversion( + sendingKey, + subnetInfo, + validatorManagerAddress, + subnetConversionSignedMessage, + subnetConversionData, + ) + initialValidatorCreatedEvent, err := GetEventFromLogs( + receipt.Logs, + validatorManager.ParseInitialValidatorCreated, + ) + Expect(err).Should(BeNil()) + Expect(initialValidatorCreatedEvent.NodeID).Should(Equal(subnetConversionData.InitialValidators[0].NodeID)) + Expect(initialValidatorCreatedEvent.Weight).Should(Equal(new(big.Int).SetUint64(initialValidatorWeight))) + + expectedValidationID := CalculateSubnetConversionValidationId(convertSubnetTxId, 0) + emittedValidationID := ids.ID(initialValidatorCreatedEvent.ValidationID) + Expect(emittedValidationID).Should(Equal(expectedValidationID)) + + return emittedValidationID +} + +func InitializePoAValidatorSet( + ctx context.Context, + sendingKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + validatorManager *poavalidatormanager.PoAValidatorManager, + validatorManagerAddress common.Address, + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, + initialValidatorWeight uint64, +) ids.ID { + convertSubnetTxId := ids.GenerateTestID() + blsPublicKey := [bls.PublicKeyLen]byte{} + subnetConversionData := poavalidatormanager.SubnetConversionData{ + ConvertSubnetTxID: convertSubnetTxId, + ValidatorManagerBlockchainID: subnetInfo.BlockchainID, + ValidatorManagerAddress: validatorManagerAddress, + InitialValidators: []poavalidatormanager.InitialValidator{ + { + NodeID: ids.GenerateTestID(), + Weight: initialValidatorWeight, + BlsPublicKey: blsPublicKey[:], + }, + }, + } + + subnetConversionDataBytes, err := PackSubnetConversionData(subnetConversionData) + Expect(err).Should(BeNil()) + subnetConversionID := sha256.Sum256(subnetConversionDataBytes) + subnetConversionSignedMessage := ConstructSubnetConversionMessage( + subnetConversionID, + subnetInfo, + pChainInfo, + network, + signatureAggregator, + ) + // Deliver the Warp message to the subnet + receipt := DeliverPoASubnetConversion( + sendingKey, + subnetInfo, + validatorManagerAddress, + subnetConversionSignedMessage, + subnetConversionData, + ) + initialValidatorCreatedEvent, err := GetEventFromLogs( + receipt.Logs, + validatorManager.ParseInitialValidatorCreated, + ) + Expect(err).Should(BeNil()) + Expect(initialValidatorCreatedEvent.NodeID).Should(Equal(subnetConversionData.InitialValidators[0].NodeID)) + Expect(initialValidatorCreatedEvent.Weight).Should(Equal(new(big.Int).SetUint64(initialValidatorWeight))) + + expectedValidationID := CalculateSubnetConversionValidationId(convertSubnetTxId, 0) + emittedValidationID := ids.ID(initialValidatorCreatedEvent.ValidationID) + Expect(emittedValidationID).Should(Equal(expectedValidationID)) + + return emittedValidationID +} + +func DeliverNativeTokenSubnetConversion( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + validatorManagerAddress common.Address, + subnetConversionSignedMessage *avalancheWarp.Message, + subnetConversionData nativetokenstakingmanager.SubnetConversionData, +) *types.Receipt { + abi, err := nativetokenstakingmanager.NativeTokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("initializeValidatorSet", subnetConversionData, uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + validatorManagerAddress, + subnetConversionSignedMessage, + ) +} + +func DeliverERC20TokenSubnetConversion( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + validatorManagerAddress common.Address, + subnetConversionSignedMessage *avalancheWarp.Message, + subnetConversionData erc20tokenstakingmanager.SubnetConversionData, +) *types.Receipt { + abi, err := erc20tokenstakingmanager.ERC20TokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("initializeValidatorSet", subnetConversionData, uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + validatorManagerAddress, + subnetConversionSignedMessage, + ) +} + +func DeliverPoASubnetConversion( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + validatorManagerAddress common.Address, + subnetConversionSignedMessage *avalancheWarp.Message, + subnetConversionData poavalidatormanager.SubnetConversionData, +) *types.Receipt { + abi, err := poavalidatormanager.PoAValidatorManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("initializeValidatorSet", subnetConversionData, uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + validatorManagerAddress, + subnetConversionSignedMessage, + ) +} + +// +// Function call utils +// + +func InitializeNativeValidatorRegistration( + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakeAmount *big.Int, + nodeID ids.ID, + blsPublicKey [bls.PublicKeyLen]byte, + stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, +) (*types.Receipt, ids.ID) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + opts.Value = stakeAmount + + tx, err := stakingManager.InitializeValidatorRegistration( + opts, + nativetokenstakingmanager.ValidatorRegistrationInput{ + NodeID: nodeID, + RegistrationExpiry: uint64(time.Now().Add(24 * time.Hour).Unix()), + BlsPublicKey: blsPublicKey[:], + }, + DefaultMinDelegateFeeBips, + DefaultMinStakeDurationSeconds, + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) + registrationInitiatedEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodCreated, + ) + Expect(err).Should(BeNil()) + return receipt, ids.ID(registrationInitiatedEvent.ValidationID) +} + +func InitializeERC20ValidatorRegistration( + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakeAmount *big.Int, + token *exampleerc20.ExampleERC20, + stakingManagerAddress common.Address, + nodeID ids.ID, + blsPublicKey [bls.PublicKeyLen]byte, + stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, +) (*types.Receipt, ids.ID) { + ERC20Approve( + context.Background(), + token, + stakingManagerAddress, + stakeAmount, + subnet, + senderKey, + ) + + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + + tx, err := stakingManager.InitializeValidatorRegistration( + opts, + erc20tokenstakingmanager.ValidatorRegistrationInput{ + NodeID: nodeID, + RegistrationExpiry: uint64(time.Now().Add(24 * time.Hour).Unix()), + BlsPublicKey: blsPublicKey[:], + }, + DefaultMinDelegateFeeBips, + DefaultMinStakeDurationSeconds, + stakeAmount, + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) + registrationInitiatedEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodCreated, + ) + Expect(err).Should(BeNil()) + return receipt, ids.ID(registrationInitiatedEvent.ValidationID) +} + +func InitializePoAValidatorRegistration( + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + weight uint64, + nodeID ids.ID, + blsPublicKey [bls.PublicKeyLen]byte, + validatorManager *poavalidatormanager.PoAValidatorManager, +) (*types.Receipt, ids.ID) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + + tx, err := validatorManager.InitializeValidatorRegistration( + opts, + poavalidatormanager.ValidatorRegistrationInput{ + NodeID: nodeID, + RegistrationExpiry: uint64(time.Now().Add(24 * time.Hour).Unix()), + BlsPublicKey: blsPublicKey[:], + }, + weight, + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) + registrationInitiatedEvent, err := GetEventFromLogs( + receipt.Logs, + validatorManager.ParseValidationPeriodCreated, + ) + Expect(err).Should(BeNil()) + return receipt, ids.ID(registrationInitiatedEvent.ValidationID) +} + +func CompleteNativeValidatorRegistration( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := nativetokenstakingmanager.NativeTokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeValidatorRegistration", uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + stakingManagerContractAddress, + registrationSignedMessage, + ) +} + +func CompleteERC20ValidatorRegistration( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := erc20tokenstakingmanager.ERC20TokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeValidatorRegistration", uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + stakingManagerContractAddress, + registrationSignedMessage, + ) +} + +func CompletePoAValidatorRegistration( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + validatorManagerAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := poavalidatormanager.PoAValidatorManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeValidatorRegistration", uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + validatorManagerAddress, + registrationSignedMessage, + ) +} + +// Calls a method that retreived a signed Warp message from the transaction's access list +func CallWarpReceiver( + callData []byte, + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + contract common.Address, + signedMessage *avalancheWarp.Message, +) *types.Receipt { + gasFeeCap, gasTipCap, nonce := CalculateTxParams(context.Background(), subnet, PrivateKeyToAddress(sendingKey)) + registrationTx := predicateutils.NewPredicateTx( + subnet.EVMChainID, + nonce, + &contract, + 2_000_000, + gasFeeCap, + gasTipCap, + big.NewInt(0), + callData, + types.AccessList{}, + warp.ContractAddress, + signedMessage.Bytes(), + ) + signedRegistrationTx := SignTransaction(registrationTx, sendingKey, subnet.EVMChainID) + return SendTransactionAndWaitForSuccess(context.Background(), subnet, signedRegistrationTx) +} + +func InitializeAndCompleteNativeValidatorRegistration( + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, + fundedKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, + stakingManagerContractAddress common.Address, + stakeAmount *big.Int, +) ids.ID { + // Initiate validator registration + nodeID := ids.GenerateTestID() + blsPublicKey := [bls.PublicKeyLen]byte{} + receipt, validationID := InitializeNativeValidatorRegistration( + fundedKey, + subnetInfo, + stakeAmount, + nodeID, + blsPublicKey, + stakingManager, + ) + + // Gather subnet-evm Warp signatures for the RegisterSubnetValidatorMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetInfo, pChainInfo) + + weight, err := stakingManager.ValueToWeight( + &bind.CallOpts{}, + stakeAmount, + ) + Expect(err).Should(BeNil()) + // Validate the Warp message, (this will be done on the P-Chain in the future) + ValidateRegisterSubnetValidatorMessage( + signedWarpMessage, + nodeID, + weight, + subnetInfo.SubnetID, + blsPublicKey, + ) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( + validationID, + true, + subnetInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = CompleteNativeValidatorRegistration( + fundedKey, + subnetInfo, + stakingManagerContractAddress, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + registrationEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodRegistered, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + + return validationID +} + +func InitializeAndCompleteERC20ValidatorRegistration( + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, + fundedKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, + stakingManagerAddress common.Address, + erc20 *exampleerc20.ExampleERC20, + stakeAmount *big.Int, +) ids.ID { + // Initiate validator registration + nodeID := ids.GenerateTestID() + blsPublicKey := [bls.PublicKeyLen]byte{} + var receipt *types.Receipt + receipt, validationID := InitializeERC20ValidatorRegistration( + fundedKey, + subnetInfo, + stakeAmount, + erc20, + stakingManagerAddress, + nodeID, + blsPublicKey, + stakingManager, + ) + + // Gather subnet-evm Warp signatures for the RegisterSubnetValidatorMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetInfo, pChainInfo) + + weight, err := stakingManager.ValueToWeight( + &bind.CallOpts{}, + stakeAmount, + ) + Expect(err).Should(BeNil()) + // Validate the Warp message, (this will be done on the P-Chain in the future) + ValidateRegisterSubnetValidatorMessage( + signedWarpMessage, + nodeID, + weight, + subnetInfo.SubnetID, + blsPublicKey, + ) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( + validationID, + true, + subnetInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = CompleteERC20ValidatorRegistration( + fundedKey, + subnetInfo, + stakingManagerAddress, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + registrationEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodRegistered, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + + return validationID +} + +func InitializeAndCompletePoAValidatorRegistration( + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, + ownerKey *ecdsa.PrivateKey, + fundedKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + validatorManager *poavalidatormanager.PoAValidatorManager, + validatorManagerAddress common.Address, + weight uint64, +) ids.ID { + // Initiate validator registration + nodeID := ids.GenerateTestID() + blsPublicKey := [bls.PublicKeyLen]byte{} + receipt, validationID := InitializePoAValidatorRegistration( + ownerKey, + subnetInfo, + weight, + nodeID, + blsPublicKey, + validatorManager, + ) + + // Gather subnet-evm Warp signatures for the RegisterSubnetValidatorMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetInfo, pChainInfo) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + ValidateRegisterSubnetValidatorMessage( + signedWarpMessage, + nodeID, + weight, + subnetInfo.SubnetID, + blsPublicKey, + ) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( + validationID, + true, + subnetInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = CompletePoAValidatorRegistration( + fundedKey, + subnetInfo, + validatorManagerAddress, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + registrationEvent, err := GetEventFromLogs( + receipt.Logs, + validatorManager.ParseValidationPeriodRegistered, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + + return validationID +} + +func InitializeEndNativeValidation( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, + validationID ids.ID, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(sendingKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.InitializeEndValidation( + opts, + validationID, + false, + 0, + ) + Expect(err).Should(BeNil()) + return WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) +} + +func InitializeEndERC20Validation( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, + validationID ids.ID, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(sendingKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.InitializeEndValidation( + opts, + validationID, + false, + 0, + ) + Expect(err).Should(BeNil()) + return WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) +} + +func InitializeEndPoAValidation( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + validatorManager *poavalidatormanager.PoAValidatorManager, + validationID ids.ID, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(sendingKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := validatorManager.InitializeEndValidation( + opts, + validationID, + ) + Expect(err).Should(BeNil()) + return WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) +} + +func CompleteEndNativeValidation( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := nativetokenstakingmanager.NativeTokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeEndValidation", uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + stakingManagerContractAddress, + registrationSignedMessage, + ) +} + +func CompleteEndERC20Validation( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := erc20tokenstakingmanager.ERC20TokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeEndValidation", uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + stakingManagerContractAddress, + registrationSignedMessage, + ) +} + +func CompleteEndPoAValidation( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + validatorManagerAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := poavalidatormanager.PoAValidatorManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeEndValidation", uint32(0)) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + validatorManagerAddress, + registrationSignedMessage, + ) +} + +func InitializeERC20DelegatorRegistration( + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + validationID ids.ID, + delegationAmount *big.Int, + token *exampleerc20.ExampleERC20, + stakingManagerAddress common.Address, + stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, +) *types.Receipt { + ERC20Approve( + context.Background(), + token, + stakingManagerAddress, + delegationAmount, + subnet, + senderKey, + ) + + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + + tx, err := stakingManager.InitializeDelegatorRegistration( + opts, + validationID, + delegationAmount, + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) + _, err = GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorAdded, + ) + Expect(err).Should(BeNil()) + return receipt +} + +func CompleteERC20DelegatorRegistration( + sendingKey *ecdsa.PrivateKey, + delegationID ids.ID, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + signedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := erc20tokenstakingmanager.ERC20TokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeDelegatorRegistration", uint32(0), delegationID) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + stakingManagerContractAddress, + signedMessage, + ) +} + +func InitializeEndERC20Delegation( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, + delegationID ids.ID, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(sendingKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.InitializeEndDelegation( + opts, + delegationID, + false, + 0, + ) + Expect(err).Should(BeNil()) + return WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) +} + +func CompleteEndERC20Delegation( + sendingKey *ecdsa.PrivateKey, + delegationID ids.ID, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + signedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := erc20tokenstakingmanager.ERC20TokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeEndDelegation", uint32(0), delegationID) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + stakingManagerContractAddress, + signedMessage, + ) +} + +func InitializeNativeDelegatorRegistration(senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + validationID ids.ID, + delegationAmount *big.Int, + stakingManagerAddress common.Address, + stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + opts.Value = delegationAmount + + tx, err := stakingManager.InitializeDelegatorRegistration( + opts, + validationID, + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) + _, err = GetEventFromLogs( + receipt.Logs, + stakingManager.ParseDelegatorAdded, + ) + Expect(err).Should(BeNil()) + return receipt +} + +func CompleteNativeDelegatorRegistration( + sendingKey *ecdsa.PrivateKey, + delegationID ids.ID, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + signedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := nativetokenstakingmanager.NativeTokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeDelegatorRegistration", uint32(0), delegationID) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + stakingManagerContractAddress, + signedMessage, + ) +} + +func InitializeEndNativeDelegation( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, + delegationID ids.ID, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(sendingKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.InitializeEndDelegation( + opts, + delegationID, + false, + 0, + ) + Expect(err).Should(BeNil()) + return WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) +} + +func CompleteEndNativeDelegation( + sendingKey *ecdsa.PrivateKey, + delegationID ids.ID, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + signedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := nativetokenstakingmanager.NativeTokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + callData, err := abi.Pack("completeEndDelegation", uint32(0), delegationID) + Expect(err).Should(BeNil()) + return CallWarpReceiver( + callData, + sendingKey, + subnet, + stakingManagerContractAddress, + signedMessage, + ) +} + +func InitializeAndCompleteEndNativeValidation( + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, + fundedKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, + stakingManagerAddress common.Address, + validationID ids.ID, + weight uint64, + nonce uint64, +) { + WaitMinStakeDuration(subnetInfo, fundedKey) + receipt := InitializeEndNativeValidation( + fundedKey, + subnetInfo, + stakingManager, + validationID, + ) + validatorRemovalEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidatorRemovalInitialized, + ) + Expect(err).Should(BeNil()) + Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validatorRemovalEvent.Weight.Uint64()).Should(Equal(weight)) + + // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetInfo, pChainInfo) + Expect(err).Should(BeNil()) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + ValidateSetSubnetValidatorWeightMessage(signedWarpMessage, validationID, 0, nonce) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( + validationID, + false, + subnetInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = CompleteEndNativeValidation( + fundedKey, + subnetInfo, + stakingManagerAddress, + registrationSignedMessage, + ) + + // Check that the validator is has been delisted from the staking contract + registrationEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodEnded, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) +} + +func InitializeAndCompleteEndERC20Validation( + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, + fundedKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, + stakingManagerAddress common.Address, + validationID ids.ID, + weight uint64, + nonce uint64, +) { + WaitMinStakeDuration(subnetInfo, fundedKey) + receipt := InitializeEndERC20Validation( + fundedKey, + subnetInfo, + stakingManager, + validationID, + ) + validatorRemovalEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidatorRemovalInitialized, + ) + Expect(err).Should(BeNil()) + Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validatorRemovalEvent.Weight.Uint64()).Should(Equal(weight)) + + // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetInfo, pChainInfo) + Expect(err).Should(BeNil()) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + ValidateSetSubnetValidatorWeightMessage(signedWarpMessage, validationID, 0, nonce) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( + validationID, + false, + subnetInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = CompleteEndERC20Validation( + fundedKey, + subnetInfo, + stakingManagerAddress, + registrationSignedMessage, + ) + + // Check that the validator is has been delisted from the staking contract + registrationEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodEnded, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) +} + +func InitializeAndCompleteEndPoAValidation( + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, + ownerKey *ecdsa.PrivateKey, + fundedKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + validatorManager *poavalidatormanager.PoAValidatorManager, + validatorManagerAddress common.Address, + validationID ids.ID, + weight uint64, + nonce uint64, +) { + receipt := InitializeEndPoAValidation( + ownerKey, + subnetInfo, + validatorManager, + validationID, + ) + validatorRemovalEvent, err := GetEventFromLogs( + receipt.Logs, + validatorManager.ParseValidatorRemovalInitialized, + ) + Expect(err).Should(BeNil()) + Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validatorRemovalEvent.Weight.Uint64()).Should(Equal(weight)) + + // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetInfo, pChainInfo) + Expect(err).Should(BeNil()) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + ValidateSetSubnetValidatorWeightMessage(signedWarpMessage, validationID, 0, nonce) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + registrationSignedMessage := ConstructSubnetValidatorRegistrationMessage( + validationID, + false, + subnetInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = CompleteEndPoAValidation( + ownerKey, + subnetInfo, + validatorManagerAddress, + registrationSignedMessage, + ) + + // Check that the validator is has been delisted from the staking contract + registrationEvent, err := GetEventFromLogs( + receipt.Logs, + validatorManager.ParseValidationPeriodEnded, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) +} + +// +// P-Chain utils +// + +func ConstructSubnetValidatorRegistrationMessage( + validationID ids.ID, + valid bool, + subnet interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, +) *avalancheWarp.Message { + registrationPayload, err := warpMessages.NewSubnetValidatorRegistration(validationID, valid) + Expect(err).Should(BeNil()) + registrationAddressedCall, err := warpPayload.NewAddressedCall(common.Address{}.Bytes(), registrationPayload.Bytes()) + Expect(err).Should(BeNil()) + registrationUnsignedMessage, err := avalancheWarp.NewUnsignedMessage( + network.GetNetworkID(), + pChainInfo.BlockchainID, + registrationAddressedCall.Bytes(), + ) + Expect(err).Should(BeNil()) + + registrationSignedMessage, err := signatureAggregator.CreateSignedMessage( + registrationUnsignedMessage, + nil, + subnet.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + return registrationSignedMessage +} + +func ConstructSubnetValidatorWeightUpdateMessage( + validationID ids.ID, + nonce uint64, + weight uint64, + subnet interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, +) *avalancheWarp.Message { + updatePayload, err := warpMessages.NewSubnetValidatorWeightUpdate(validationID, nonce, weight) + Expect(err).Should(BeNil()) + updateAddressedCall, err := warpPayload.NewAddressedCall(common.Address{}.Bytes(), updatePayload.Bytes()) + Expect(err).Should(BeNil()) + updateUnsignedMessage, err := avalancheWarp.NewUnsignedMessage( + network.GetNetworkID(), + pChainInfo.BlockchainID, + updateAddressedCall.Bytes(), + ) + Expect(err).Should(BeNil()) + + updateSignedMessage, err := signatureAggregator.CreateSignedMessage( + updateUnsignedMessage, + nil, + subnet.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + return updateSignedMessage +} + +func ConstructSubnetConversionMessage( + subnetConversionID ids.ID, + subnet interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, +) *avalancheWarp.Message { + subnetConversionPayload, err := warpMessages.NewSubnetConversion(subnetConversionID) + Expect(err).Should(BeNil()) + subnetConversionAddressedCall, err := warpPayload.NewAddressedCall( + common.Address{}.Bytes(), + subnetConversionPayload.Bytes(), + ) + Expect(err).Should(BeNil()) + subnetConversionUnsignedMessage, err := avalancheWarp.NewUnsignedMessage( + network.GetNetworkID(), + pChainInfo.BlockchainID, + subnetConversionAddressedCall.Bytes(), + ) + Expect(err).Should(BeNil()) + + subnetConversionSignedMessage, err := signatureAggregator.CreateSignedMessage( + subnetConversionUnsignedMessage, + nil, + subnet.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + return subnetConversionSignedMessage +} + +// +// Warp message validiation utils +// These will be replaced by the actual implementation on the P-Chain in the future +// + +func ValidateRegisterSubnetValidatorMessage( + signedWarpMessage *avalancheWarp.Message, + nodeID ids.ID, + weight uint64, + subnetID ids.ID, + blsPublicKey [bls.PublicKeyLen]byte, +) { + // Validate the Warp message, (this will be done on the P-Chain in the future) + msg, err := warpPayload.ParseAddressedCall(signedWarpMessage.UnsignedMessage.Payload) + Expect(err).Should(BeNil()) + // Check that the addressed call payload is a registered Warp message type + var payloadInterface warpMessages.Payload + ver, err := warpMessages.Codec.Unmarshal(msg.Payload, &payloadInterface) + Expect(err).Should(BeNil()) + registerValidatorPayload, ok := payloadInterface.(*warpMessages.RegisterSubnetValidator) + Expect(ok).Should(BeTrue()) + + Expect(ver).Should(Equal(uint16(warpMessages.CodecVersion))) + Expect(registerValidatorPayload.NodeID).Should(Equal(nodeID)) + Expect(registerValidatorPayload.Weight).Should(Equal(weight)) + Expect(registerValidatorPayload.SubnetID).Should(Equal(subnetID)) + Expect(registerValidatorPayload.BlsPubKey[:]).Should(Equal(blsPublicKey[:])) +} + +func ValidateSetSubnetValidatorWeightMessage( + signedWarpMessage *avalancheWarp.Message, + validationID ids.ID, + weight uint64, + nonce uint64, +) { + msg, err := warpPayload.ParseAddressedCall(signedWarpMessage.UnsignedMessage.Payload) + Expect(err).Should(BeNil()) + // Check that the addressed call payload is a registered Warp message type + var payloadInterface warpMessages.Payload + ver, err := warpMessages.Codec.Unmarshal(msg.Payload, &payloadInterface) + Expect(err).Should(BeNil()) + registerValidatorPayload, ok := payloadInterface.(*warpMessages.SetSubnetValidatorWeight) + Expect(ok).Should(BeTrue()) + + Expect(ver).Should(Equal(uint16(warpMessages.CodecVersion))) + Expect(registerValidatorPayload.ValidationID).Should(Equal(validationID)) + Expect(registerValidatorPayload.Weight).Should(Equal(weight)) + Expect(registerValidatorPayload.Nonce).Should(Equal(nonce)) +} + +func WaitMinStakeDuration( + subnet interfaces.SubnetTestInfo, + fundedKey *ecdsa.PrivateKey, +) { + // Make sure minimum stake duration has passed + time.Sleep(time.Duration(DefaultMinStakeDurationSeconds) * time.Second) + + // Send a loopback transaction to self to force a block production + // before delisting the validator. + SendNativeTransfer( + context.Background(), + subnet, + fundedKey, + common.Address{}, + big.NewInt(10), + ) +} + +func CalculateSubnetConversionValidationId(convertSubnetTxID ids.ID, validatorIdx uint32) ids.ID { + preImage := make([]byte, 36) + copy(preImage[0:32], convertSubnetTxID[:]) + binary.BigEndian.PutUint32(preImage[32:36], validatorIdx) + return sha256.Sum256(preImage) +} + +// PackSubnetConversionData defines a packing function that works +// over any struct instance of SubnetConversionData since the abi-bindings +// process generates one for each of the different contracts. +func PackSubnetConversionData(data interface{}) ([]byte, error) { + v := reflect.ValueOf(data) + if v.Kind() != reflect.Struct { + return nil, fmt.Errorf("expected struct, got %s", v.Kind()) + } + // Define required fields and their expected types + requiredFields := map[string]reflect.Type{ + "ConvertSubnetTxID": reflect.TypeOf([32]byte{}), + "ValidatorManagerBlockchainID": reflect.TypeOf([32]byte{}), + "ValidatorManagerAddress": reflect.TypeOf(common.Address{}), + // InitialValidators is a slice of structs and handled separately + "InitialValidators": reflect.TypeOf([]struct{}{}), + } + // Check for required fields and types + for fieldName, expectedType := range requiredFields { + field := v.FieldByName(fieldName) + + if !field.IsValid() { + return nil, fmt.Errorf("field %s is missing", fieldName) + } + // Allow flexible types for InitialValidators by checking it contains structs + if fieldName == "InitialValidators" { + if field.Kind() != reflect.Slice || field.Type().Elem().Kind() != reflect.Struct { + return nil, fmt.Errorf("field %s has incorrect type: expected a slice of structs", fieldName) + } + } else { + if field.Type() != expectedType { + return nil, fmt.Errorf("field %s has incorrect type: expected %s, got %s", fieldName, expectedType, field.Type()) + } + } + } + + convertSubnetTxID := v.FieldByName("ConvertSubnetTxID").Interface().([32]byte) + validatorManagerBlockchainID := v.FieldByName("ValidatorManagerBlockchainID").Interface().([32]byte) + validatorManagerAddress := v.FieldByName("ValidatorManagerAddress").Interface().(common.Address) + initialValidators := v.FieldByName("InitialValidators") + + packedLen := 92 + initialValidatorPackedLen*initialValidators.Len() + b := make([]byte, packedLen) + copy(b[0:32], convertSubnetTxID[:]) + copy(b[32:64], validatorManagerBlockchainID[:]) + // These are evm addresses and have lengths of 20 so hardcoding here + binary.BigEndian.PutUint32(b[64:68], uint32(20)) + copy(b[68:88], validatorManagerAddress.Bytes()) + binary.BigEndian.PutUint32(b[88:92], uint32(initialValidators.Len())) + // Pack each InitialValidator struct + for i := 0; i < initialValidators.Len(); i++ { + iv := initialValidators.Index(i).Interface() + ivPacked, err := PackInitialValidator(iv) + if err != nil { + return nil, fmt.Errorf("failed to pack InitialValidator: %w", err) + } + if len(ivPacked) != initialValidatorPackedLen { + return nil, fmt.Errorf( + "expected packed InitialValidator to be %d bytes, got %d", + initialValidatorPackedLen, + len(ivPacked), + ) + } + copy(b[92+i*initialValidatorPackedLen:92+(i+1)*initialValidatorPackedLen], ivPacked) + } + return b, nil +} + +// PackInitialValidator defines a packing function that works +// over any struct instance of InitialValidator since the abi-bindings +// process generates one for each of the different contracts. +func PackInitialValidator(iv interface{}) ([]byte, error) { + v := reflect.ValueOf(iv) + + // Ensure the passed interface is a struct + if v.Kind() != reflect.Struct { + return nil, fmt.Errorf("expected a struct, got %s", v.Kind()) + } + + // Define required fields and their expected types + requiredFields := map[string]reflect.Type{ + "NodeID": reflect.TypeOf([32]byte{}), + "Weight": reflect.TypeOf(uint64(0)), + "BlsPublicKey": reflect.TypeOf([]byte{}), + } + + // Check for required fields and types + for fieldName, expectedType := range requiredFields { + field := v.FieldByName(fieldName) + + if !field.IsValid() { + return nil, fmt.Errorf("field %s is missing", fieldName) + } + + if field.Type() != expectedType { + return nil, fmt.Errorf("field %s has incorrect type: expected %s, got %s", fieldName, expectedType, field.Type()) + } + } + + // At this point, we know the struct has all required fields with correct types + // Use reflection to retrieve field values and perform canonical packing + nodeID := v.FieldByName("NodeID").Interface().([32]byte) + weight := v.FieldByName("Weight").Interface().(uint64) + blsPublicKey := v.FieldByName("BlsPublicKey").Interface().([]byte) + + b := make([]byte, initialValidatorPackedLen) + copy(b[0:32], nodeID[:]) + binary.BigEndian.PutUint64(b[32:40], weight) + copy(b[40:88], blsPublicKey) + return b, nil +} diff --git a/tests/utils/warp-genesis-template.json b/tests/utils/warp-genesis-template.json index 9d221136e..5dab415be 100644 --- a/tests/utils/warp-genesis-template.json +++ b/tests/utils/warp-genesis-template.json @@ -28,7 +28,8 @@ "blockTimestamp": 0, "adminAddresses": [ "0xAcB633F5B00099c7ec187eB00156c5cd9D854b5B", - "0x3405506b3711859c5070949ed9b700c7ba7bf750" + "0x3405506b3711859c5070949ed9b700c7ba7bf750", + "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC" ] } },