diff --git a/.changeset/honest-avocados-heal.md b/.changeset/honest-avocados-heal.md new file mode 100644 index 00000000000..a28c08fde84 --- /dev/null +++ b/.changeset/honest-avocados-heal.md @@ -0,0 +1,5 @@ +--- +"chainlink": patch +--- + +add test for v23 #added diff --git a/contracts/.changeset/green-pigs-reflect.md b/contracts/.changeset/green-pigs-reflect.md new file mode 100644 index 00000000000..cb197a32bcf --- /dev/null +++ b/contracts/.changeset/green-pigs-reflect.md @@ -0,0 +1,5 @@ +--- +"@chainlink/contracts": patch +--- + +add test for v23 #added diff --git a/contracts/scripts/native_solc_compile_all_automation b/contracts/scripts/native_solc_compile_all_automation index 84656917d8f..f144e4f7dc8 100755 --- a/contracts/scripts/native_solc_compile_all_automation +++ b/contracts/scripts/native_solc_compile_all_automation @@ -106,3 +106,6 @@ compileContract automation/v2_3/AutomationRegistryLogicB2_3.sol compileContract automation/v2_3/AutomationRegistryLogicC2_3.sol compileContract automation/v2_3/AutomationUtils2_3.sol compileContract automation/interfaces/v2_3/IAutomationRegistryMaster2_3.sol + +compileContract automation/testhelpers/MockETHUSDAggregator.sol +compileContract automation/test/v2_3/WETH9.sol diff --git a/contracts/src/v0.8/automation/testhelpers/MockETHUSDAggregator.sol b/contracts/src/v0.8/automation/testhelpers/MockETHUSDAggregator.sol new file mode 100644 index 00000000000..10f6732c998 --- /dev/null +++ b/contracts/src/v0.8/automation/testhelpers/MockETHUSDAggregator.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import "../../shared/interfaces/AggregatorV3Interface.sol"; + +contract MockETHUSDAggregator is AggregatorV3Interface { + int256 public answer; + uint256 private blockTimestampDeduction = 0; + + constructor(int256 _answer) { + answer = _answer; + } + + function decimals() external pure override returns (uint8) { + return 8; + } + + function description() external pure override returns (string memory) { + return "MockETHUSDAggregator"; + } + + function version() external pure override returns (uint256) { + return 1; + } + + function getRoundData( + uint80 /*_roundId*/ + ) + external + view + override + returns (uint80 roundId, int256 ans, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) + { + return (1, answer, getDeductedBlockTimestamp(), getDeductedBlockTimestamp(), 1); + } + + function latestRoundData() + external + view + override + returns (uint80 roundId, int256 ans, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) + { + return (1, answer, getDeductedBlockTimestamp(), getDeductedBlockTimestamp(), 1); + } + + function getDeductedBlockTimestamp() internal view returns (uint256) { + return block.timestamp - blockTimestampDeduction; + } + + function setBlockTimestampDeduction(uint256 _blockTimestampDeduction) external { + blockTimestampDeduction = _blockTimestampDeduction; + } +} diff --git a/core/gethwrappers/generated/mock_ethusd_aggregator_wrapper/mock_ethusd_aggregator_wrapper.go b/core/gethwrappers/generated/mock_ethusd_aggregator_wrapper/mock_ethusd_aggregator_wrapper.go new file mode 100644 index 00000000000..c10f916c5e7 --- /dev/null +++ b/core/gethwrappers/generated/mock_ethusd_aggregator_wrapper/mock_ethusd_aggregator_wrapper.go @@ -0,0 +1,377 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package mock_ethusd_aggregator_wrapper + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var MockETHUSDAggregatorMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"_answer\",\"type\":\"int256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"answer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"description\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"}],\"name\":\"getRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"ans\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"ans\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"answeredInRound\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_blockTimestampDeduction\",\"type\":\"uint256\"}],\"name\":\"setBlockTimestampDeduction\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", + Bin: "0x6080604052600060015534801561001557600080fd5b506040516103333803806103338339810160408190526100349161003c565b600055610055565b60006020828403121561004e57600080fd5b5051919050565b6102cf806100646000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c806385bb7d691161005b57806385bb7d69146100e65780639a6fc8f5146100ef578063f0ad37df14610139578063feaf968c1461014e57600080fd5b8063313ce5671461008257806354fd4d50146100965780637284e416146100a7575b600080fd5b604051600881526020015b60405180910390f35b60015b60405190815260200161008d565b604080518082018252601481527f4d6f636b45544855534441676772656761746f720000000000000000000000006020820152905161008d91906101ca565b61009960005481565b6101026100fd366004610236565b610156565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161008d565b61014c610147366004610269565b600155565b005b610102610186565b6000806000806000600160005461016b6101b5565b6101736101b5565b9299919850965090945060019350915050565b6000806000806000600160005461019b6101b5565b6101a36101b5565b92989197509550909350600192509050565b6000600154426101c59190610282565b905090565b600060208083528351808285015260005b818110156101f7578581018301518582016040015282016101db565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561024857600080fd5b813569ffffffffffffffffffff8116811461026257600080fd5b9392505050565b60006020828403121561027b57600080fd5b5035919050565b818103818111156102bc577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9291505056fea164736f6c6343000813000a", +} + +var MockETHUSDAggregatorABI = MockETHUSDAggregatorMetaData.ABI + +var MockETHUSDAggregatorBin = MockETHUSDAggregatorMetaData.Bin + +func DeployMockETHUSDAggregator(auth *bind.TransactOpts, backend bind.ContractBackend, _answer *big.Int) (common.Address, *types.Transaction, *MockETHUSDAggregator, error) { + parsed, err := MockETHUSDAggregatorMetaData.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(MockETHUSDAggregatorBin), backend, _answer) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &MockETHUSDAggregator{address: address, abi: *parsed, MockETHUSDAggregatorCaller: MockETHUSDAggregatorCaller{contract: contract}, MockETHUSDAggregatorTransactor: MockETHUSDAggregatorTransactor{contract: contract}, MockETHUSDAggregatorFilterer: MockETHUSDAggregatorFilterer{contract: contract}}, nil +} + +type MockETHUSDAggregator struct { + address common.Address + abi abi.ABI + MockETHUSDAggregatorCaller + MockETHUSDAggregatorTransactor + MockETHUSDAggregatorFilterer +} + +type MockETHUSDAggregatorCaller struct { + contract *bind.BoundContract +} + +type MockETHUSDAggregatorTransactor struct { + contract *bind.BoundContract +} + +type MockETHUSDAggregatorFilterer struct { + contract *bind.BoundContract +} + +type MockETHUSDAggregatorSession struct { + Contract *MockETHUSDAggregator + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type MockETHUSDAggregatorCallerSession struct { + Contract *MockETHUSDAggregatorCaller + CallOpts bind.CallOpts +} + +type MockETHUSDAggregatorTransactorSession struct { + Contract *MockETHUSDAggregatorTransactor + TransactOpts bind.TransactOpts +} + +type MockETHUSDAggregatorRaw struct { + Contract *MockETHUSDAggregator +} + +type MockETHUSDAggregatorCallerRaw struct { + Contract *MockETHUSDAggregatorCaller +} + +type MockETHUSDAggregatorTransactorRaw struct { + Contract *MockETHUSDAggregatorTransactor +} + +func NewMockETHUSDAggregator(address common.Address, backend bind.ContractBackend) (*MockETHUSDAggregator, error) { + abi, err := abi.JSON(strings.NewReader(MockETHUSDAggregatorABI)) + if err != nil { + return nil, err + } + contract, err := bindMockETHUSDAggregator(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MockETHUSDAggregator{address: address, abi: abi, MockETHUSDAggregatorCaller: MockETHUSDAggregatorCaller{contract: contract}, MockETHUSDAggregatorTransactor: MockETHUSDAggregatorTransactor{contract: contract}, MockETHUSDAggregatorFilterer: MockETHUSDAggregatorFilterer{contract: contract}}, nil +} + +func NewMockETHUSDAggregatorCaller(address common.Address, caller bind.ContractCaller) (*MockETHUSDAggregatorCaller, error) { + contract, err := bindMockETHUSDAggregator(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MockETHUSDAggregatorCaller{contract: contract}, nil +} + +func NewMockETHUSDAggregatorTransactor(address common.Address, transactor bind.ContractTransactor) (*MockETHUSDAggregatorTransactor, error) { + contract, err := bindMockETHUSDAggregator(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MockETHUSDAggregatorTransactor{contract: contract}, nil +} + +func NewMockETHUSDAggregatorFilterer(address common.Address, filterer bind.ContractFilterer) (*MockETHUSDAggregatorFilterer, error) { + contract, err := bindMockETHUSDAggregator(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MockETHUSDAggregatorFilterer{contract: contract}, nil +} + +func bindMockETHUSDAggregator(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MockETHUSDAggregatorMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockETHUSDAggregator.Contract.MockETHUSDAggregatorCaller.contract.Call(opts, result, method, params...) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockETHUSDAggregator.Contract.MockETHUSDAggregatorTransactor.contract.Transfer(opts) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockETHUSDAggregator.Contract.MockETHUSDAggregatorTransactor.contract.Transact(opts, method, params...) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockETHUSDAggregator.Contract.contract.Call(opts, result, method, params...) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockETHUSDAggregator.Contract.contract.Transfer(opts) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockETHUSDAggregator.Contract.contract.Transact(opts, method, params...) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCaller) Answer(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MockETHUSDAggregator.contract.Call(opts, &out, "answer") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorSession) Answer() (*big.Int, error) { + return _MockETHUSDAggregator.Contract.Answer(&_MockETHUSDAggregator.CallOpts) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCallerSession) Answer() (*big.Int, error) { + return _MockETHUSDAggregator.Contract.Answer(&_MockETHUSDAggregator.CallOpts) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _MockETHUSDAggregator.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorSession) Decimals() (uint8, error) { + return _MockETHUSDAggregator.Contract.Decimals(&_MockETHUSDAggregator.CallOpts) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCallerSession) Decimals() (uint8, error) { + return _MockETHUSDAggregator.Contract.Decimals(&_MockETHUSDAggregator.CallOpts) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCaller) Description(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _MockETHUSDAggregator.contract.Call(opts, &out, "description") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorSession) Description() (string, error) { + return _MockETHUSDAggregator.Contract.Description(&_MockETHUSDAggregator.CallOpts) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCallerSession) Description() (string, error) { + return _MockETHUSDAggregator.Contract.Description(&_MockETHUSDAggregator.CallOpts) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCaller) GetRoundData(opts *bind.CallOpts, arg0 *big.Int) (GetRoundData, + + error) { + var out []interface{} + err := _MockETHUSDAggregator.contract.Call(opts, &out, "getRoundData", arg0) + + outstruct := new(GetRoundData) + if err != nil { + return *outstruct, err + } + + outstruct.RoundId = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Ans = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.StartedAt = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.UpdatedAt = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.AnsweredInRound = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorSession) GetRoundData(arg0 *big.Int) (GetRoundData, + + error) { + return _MockETHUSDAggregator.Contract.GetRoundData(&_MockETHUSDAggregator.CallOpts, arg0) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCallerSession) GetRoundData(arg0 *big.Int) (GetRoundData, + + error) { + return _MockETHUSDAggregator.Contract.GetRoundData(&_MockETHUSDAggregator.CallOpts, arg0) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCaller) LatestRoundData(opts *bind.CallOpts) (LatestRoundData, + + error) { + var out []interface{} + err := _MockETHUSDAggregator.contract.Call(opts, &out, "latestRoundData") + + outstruct := new(LatestRoundData) + if err != nil { + return *outstruct, err + } + + outstruct.RoundId = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Ans = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.StartedAt = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.UpdatedAt = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.AnsweredInRound = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorSession) LatestRoundData() (LatestRoundData, + + error) { + return _MockETHUSDAggregator.Contract.LatestRoundData(&_MockETHUSDAggregator.CallOpts) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCallerSession) LatestRoundData() (LatestRoundData, + + error) { + return _MockETHUSDAggregator.Contract.LatestRoundData(&_MockETHUSDAggregator.CallOpts) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCaller) Version(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MockETHUSDAggregator.contract.Call(opts, &out, "version") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorSession) Version() (*big.Int, error) { + return _MockETHUSDAggregator.Contract.Version(&_MockETHUSDAggregator.CallOpts) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorCallerSession) Version() (*big.Int, error) { + return _MockETHUSDAggregator.Contract.Version(&_MockETHUSDAggregator.CallOpts) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorTransactor) SetBlockTimestampDeduction(opts *bind.TransactOpts, _blockTimestampDeduction *big.Int) (*types.Transaction, error) { + return _MockETHUSDAggregator.contract.Transact(opts, "setBlockTimestampDeduction", _blockTimestampDeduction) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorSession) SetBlockTimestampDeduction(_blockTimestampDeduction *big.Int) (*types.Transaction, error) { + return _MockETHUSDAggregator.Contract.SetBlockTimestampDeduction(&_MockETHUSDAggregator.TransactOpts, _blockTimestampDeduction) +} + +func (_MockETHUSDAggregator *MockETHUSDAggregatorTransactorSession) SetBlockTimestampDeduction(_blockTimestampDeduction *big.Int) (*types.Transaction, error) { + return _MockETHUSDAggregator.Contract.SetBlockTimestampDeduction(&_MockETHUSDAggregator.TransactOpts, _blockTimestampDeduction) +} + +type GetRoundData struct { + RoundId *big.Int + Ans *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int +} +type LatestRoundData struct { + RoundId *big.Int + Ans *big.Int + StartedAt *big.Int + UpdatedAt *big.Int + AnsweredInRound *big.Int +} + +func (_MockETHUSDAggregator *MockETHUSDAggregator) Address() common.Address { + return _MockETHUSDAggregator.address +} + +type MockETHUSDAggregatorInterface interface { + Answer(opts *bind.CallOpts) (*big.Int, error) + + Decimals(opts *bind.CallOpts) (uint8, error) + + Description(opts *bind.CallOpts) (string, error) + + GetRoundData(opts *bind.CallOpts, arg0 *big.Int) (GetRoundData, + + error) + + LatestRoundData(opts *bind.CallOpts) (LatestRoundData, + + error) + + Version(opts *bind.CallOpts) (*big.Int, error) + + SetBlockTimestampDeduction(opts *bind.TransactOpts, _blockTimestampDeduction *big.Int) (*types.Transaction, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/weth9_wrapper/weth9_wrapper.go b/core/gethwrappers/generated/weth9_wrapper/weth9_wrapper.go new file mode 100644 index 00000000000..f38435143b9 --- /dev/null +++ b/core/gethwrappers/generated/weth9_wrapper/weth9_wrapper.go @@ -0,0 +1,1010 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package weth9_wrapper + +import ( + "errors" + "fmt" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" +) + +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +var WETH9MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"guy\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"src\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dst\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60c0604052600d60809081526c2bb930b83832b21022ba3432b960991b60a05260009061002c9082610114565b506040805180820190915260048152630ae8aa8960e31b60208201526001906100559082610114565b506002805460ff1916601217905534801561006f57600080fd5b506101d3565b634e487b7160e01b600052604160045260246000fd5b600181811c9082168061009f57607f821691505b6020821081036100bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561010f57600081815260208120601f850160051c810160208610156100ec5750805b601f850160051c820191505b8181101561010b578281556001016100f8565b5050505b505050565b81516001600160401b0381111561012d5761012d610075565b6101418161013b845461008b565b846100c5565b602080601f831160018114610176576000841561015e5750858301515b600019600386901b1c1916600185901b17855561010b565b600085815260208120601f198616915b828110156101a557888601518255948401946001909101908401610186565b50858210156101c35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61099c80620001e36000396000f3fe6080604052600436106100cb5760003560e01c806340c10f1911610074578063a9059cbb1161004e578063a9059cbb14610225578063d0e30db014610245578063dd62ed3e1461024d57600080fd5b806340c10f19146101c357806370a08231146101e357806395d89b411461021057600080fd5b806323b872dd116100a557806323b872dd146101575780632e1a7d4d14610177578063313ce5671461019757600080fd5b806306fdde03146100df578063095ea7b31461010a57806318160ddd1461013a57600080fd5b366100da576100d8610285565b005b600080fd5b3480156100eb57600080fd5b506100f46102e0565b6040516101019190610785565b60405180910390f35b34801561011657600080fd5b5061012a61012536600461081a565b61036e565b6040519015158152602001610101565b34801561014657600080fd5b50475b604051908152602001610101565b34801561016357600080fd5b5061012a610172366004610844565b6103e8565b34801561018357600080fd5b506100d8610192366004610880565b610649565b3480156101a357600080fd5b506002546101b19060ff1681565b60405160ff9091168152602001610101565b3480156101cf57600080fd5b506100d86101de36600461081a565b61071c565b3480156101ef57600080fd5b506101496101fe366004610899565b60036020526000908152604090205481565b34801561021c57600080fd5b506100f461075a565b34801561023157600080fd5b5061012a61024036600461081a565b610767565b6100d861077b565b34801561025957600080fd5b506101496102683660046108b4565b600460209081526000928352604080842090915290825290205481565b33600090815260036020526040812080543492906102a4908490610916565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b600080546102ed90610929565b80601f016020809104026020016040519081016040528092919081815260200182805461031990610929565b80156103665780601f1061033b57610100808354040283529160200191610366565b820191906000526020600020905b81548152906001019060200180831161034957829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103d69086815260200190565b60405180910390a35060015b92915050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812054821115610447576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff841633148015906104ad575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020546fffffffffffffffffffffffffffffffff14155b156105625773ffffffffffffffffffffffffffffffffffffffff8416600090815260046020908152604080832033845290915290205482111561051c576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091528120805484929061055c90849061097c565b90915550505b73ffffffffffffffffffffffffffffffffffffffff84166000908152600360205260408120805484929061059790849061097c565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600090815260036020526040812080548492906105d1908490610916565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161063791815260200190565b60405180910390a35060019392505050565b33600090815260036020526040902054811115610692576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260036020526040812080548392906106b190849061097c565b9091555050604051339082156108fc029083906000818181858888f193505050501580156106e3573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054839290610751908490610916565b90915550505050565b600180546102ed90610929565b60006107743384846103e8565b9392505050565b610783610285565b565b600060208083528351808285015260005b818110156107b257858101830151858201604001528201610796565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461081557600080fd5b919050565b6000806040838503121561082d57600080fd5b610836836107f1565b946020939093013593505050565b60008060006060848603121561085957600080fd5b610862846107f1565b9250610870602085016107f1565b9150604084013590509250925092565b60006020828403121561089257600080fd5b5035919050565b6000602082840312156108ab57600080fd5b610774826107f1565b600080604083850312156108c757600080fd5b6108d0836107f1565b91506108de602084016107f1565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156103e2576103e26108e7565b600181811c9082168061093d57607f821691505b602082108103610976577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b818103818111156103e2576103e26108e756fea164736f6c6343000813000a", +} + +var WETH9ABI = WETH9MetaData.ABI + +var WETH9Bin = WETH9MetaData.Bin + +func DeployWETH9(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *WETH9, error) { + parsed, err := WETH9MetaData.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(WETH9Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &WETH9{address: address, abi: *parsed, WETH9Caller: WETH9Caller{contract: contract}, WETH9Transactor: WETH9Transactor{contract: contract}, WETH9Filterer: WETH9Filterer{contract: contract}}, nil +} + +type WETH9 struct { + address common.Address + abi abi.ABI + WETH9Caller + WETH9Transactor + WETH9Filterer +} + +type WETH9Caller struct { + contract *bind.BoundContract +} + +type WETH9Transactor struct { + contract *bind.BoundContract +} + +type WETH9Filterer struct { + contract *bind.BoundContract +} + +type WETH9Session struct { + Contract *WETH9 + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type WETH9CallerSession struct { + Contract *WETH9Caller + CallOpts bind.CallOpts +} + +type WETH9TransactorSession struct { + Contract *WETH9Transactor + TransactOpts bind.TransactOpts +} + +type WETH9Raw struct { + Contract *WETH9 +} + +type WETH9CallerRaw struct { + Contract *WETH9Caller +} + +type WETH9TransactorRaw struct { + Contract *WETH9Transactor +} + +func NewWETH9(address common.Address, backend bind.ContractBackend) (*WETH9, error) { + abi, err := abi.JSON(strings.NewReader(WETH9ABI)) + if err != nil { + return nil, err + } + contract, err := bindWETH9(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &WETH9{address: address, abi: abi, WETH9Caller: WETH9Caller{contract: contract}, WETH9Transactor: WETH9Transactor{contract: contract}, WETH9Filterer: WETH9Filterer{contract: contract}}, nil +} + +func NewWETH9Caller(address common.Address, caller bind.ContractCaller) (*WETH9Caller, error) { + contract, err := bindWETH9(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &WETH9Caller{contract: contract}, nil +} + +func NewWETH9Transactor(address common.Address, transactor bind.ContractTransactor) (*WETH9Transactor, error) { + contract, err := bindWETH9(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &WETH9Transactor{contract: contract}, nil +} + +func NewWETH9Filterer(address common.Address, filterer bind.ContractFilterer) (*WETH9Filterer, error) { + contract, err := bindWETH9(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &WETH9Filterer{contract: contract}, nil +} + +func bindWETH9(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := WETH9MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_WETH9 *WETH9Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _WETH9.Contract.WETH9Caller.contract.Call(opts, result, method, params...) +} + +func (_WETH9 *WETH9Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WETH9.Contract.WETH9Transactor.contract.Transfer(opts) +} + +func (_WETH9 *WETH9Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _WETH9.Contract.WETH9Transactor.contract.Transact(opts, method, params...) +} + +func (_WETH9 *WETH9CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _WETH9.Contract.contract.Call(opts, result, method, params...) +} + +func (_WETH9 *WETH9TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WETH9.Contract.contract.Transfer(opts) +} + +func (_WETH9 *WETH9TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _WETH9.Contract.contract.Transact(opts, method, params...) +} + +func (_WETH9 *WETH9Caller) Allowance(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (*big.Int, error) { + var out []interface{} + err := _WETH9.contract.Call(opts, &out, "allowance", arg0, arg1) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_WETH9 *WETH9Session) Allowance(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _WETH9.Contract.Allowance(&_WETH9.CallOpts, arg0, arg1) +} + +func (_WETH9 *WETH9CallerSession) Allowance(arg0 common.Address, arg1 common.Address) (*big.Int, error) { + return _WETH9.Contract.Allowance(&_WETH9.CallOpts, arg0, arg1) +} + +func (_WETH9 *WETH9Caller) BalanceOf(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { + var out []interface{} + err := _WETH9.contract.Call(opts, &out, "balanceOf", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_WETH9 *WETH9Session) BalanceOf(arg0 common.Address) (*big.Int, error) { + return _WETH9.Contract.BalanceOf(&_WETH9.CallOpts, arg0) +} + +func (_WETH9 *WETH9CallerSession) BalanceOf(arg0 common.Address) (*big.Int, error) { + return _WETH9.Contract.BalanceOf(&_WETH9.CallOpts, arg0) +} + +func (_WETH9 *WETH9Caller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _WETH9.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_WETH9 *WETH9Session) Decimals() (uint8, error) { + return _WETH9.Contract.Decimals(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9CallerSession) Decimals() (uint8, error) { + return _WETH9.Contract.Decimals(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9Caller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _WETH9.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_WETH9 *WETH9Session) Name() (string, error) { + return _WETH9.Contract.Name(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9CallerSession) Name() (string, error) { + return _WETH9.Contract.Name(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9Caller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _WETH9.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_WETH9 *WETH9Session) Symbol() (string, error) { + return _WETH9.Contract.Symbol(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9CallerSession) Symbol() (string, error) { + return _WETH9.Contract.Symbol(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _WETH9.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_WETH9 *WETH9Session) TotalSupply() (*big.Int, error) { + return _WETH9.Contract.TotalSupply(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9CallerSession) TotalSupply() (*big.Int, error) { + return _WETH9.Contract.TotalSupply(&_WETH9.CallOpts) +} + +func (_WETH9 *WETH9Transactor) Approve(opts *bind.TransactOpts, guy common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.contract.Transact(opts, "approve", guy, wad) +} + +func (_WETH9 *WETH9Session) Approve(guy common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Approve(&_WETH9.TransactOpts, guy, wad) +} + +func (_WETH9 *WETH9TransactorSession) Approve(guy common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Approve(&_WETH9.TransactOpts, guy, wad) +} + +func (_WETH9 *WETH9Transactor) Deposit(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WETH9.contract.Transact(opts, "deposit") +} + +func (_WETH9 *WETH9Session) Deposit() (*types.Transaction, error) { + return _WETH9.Contract.Deposit(&_WETH9.TransactOpts) +} + +func (_WETH9 *WETH9TransactorSession) Deposit() (*types.Transaction, error) { + return _WETH9.Contract.Deposit(&_WETH9.TransactOpts) +} + +func (_WETH9 *WETH9Transactor) Mint(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _WETH9.contract.Transact(opts, "mint", account, amount) +} + +func (_WETH9 *WETH9Session) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Mint(&_WETH9.TransactOpts, account, amount) +} + +func (_WETH9 *WETH9TransactorSession) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Mint(&_WETH9.TransactOpts, account, amount) +} + +func (_WETH9 *WETH9Transactor) Transfer(opts *bind.TransactOpts, dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.contract.Transact(opts, "transfer", dst, wad) +} + +func (_WETH9 *WETH9Session) Transfer(dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Transfer(&_WETH9.TransactOpts, dst, wad) +} + +func (_WETH9 *WETH9TransactorSession) Transfer(dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Transfer(&_WETH9.TransactOpts, dst, wad) +} + +func (_WETH9 *WETH9Transactor) TransferFrom(opts *bind.TransactOpts, src common.Address, dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.contract.Transact(opts, "transferFrom", src, dst, wad) +} + +func (_WETH9 *WETH9Session) TransferFrom(src common.Address, dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.TransferFrom(&_WETH9.TransactOpts, src, dst, wad) +} + +func (_WETH9 *WETH9TransactorSession) TransferFrom(src common.Address, dst common.Address, wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.TransferFrom(&_WETH9.TransactOpts, src, dst, wad) +} + +func (_WETH9 *WETH9Transactor) Withdraw(opts *bind.TransactOpts, wad *big.Int) (*types.Transaction, error) { + return _WETH9.contract.Transact(opts, "withdraw", wad) +} + +func (_WETH9 *WETH9Session) Withdraw(wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Withdraw(&_WETH9.TransactOpts, wad) +} + +func (_WETH9 *WETH9TransactorSession) Withdraw(wad *big.Int) (*types.Transaction, error) { + return _WETH9.Contract.Withdraw(&_WETH9.TransactOpts, wad) +} + +func (_WETH9 *WETH9Transactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WETH9.contract.RawTransact(opts, nil) +} + +func (_WETH9 *WETH9Session) Receive() (*types.Transaction, error) { + return _WETH9.Contract.Receive(&_WETH9.TransactOpts) +} + +func (_WETH9 *WETH9TransactorSession) Receive() (*types.Transaction, error) { + return _WETH9.Contract.Receive(&_WETH9.TransactOpts) +} + +type WETH9ApprovalIterator struct { + Event *WETH9Approval + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *WETH9ApprovalIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(WETH9Approval) + 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 + } + } + + select { + case log := <-it.logs: + it.Event = new(WETH9Approval) + 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() + } +} + +func (it *WETH9ApprovalIterator) Error() error { + return it.fail +} + +func (it *WETH9ApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type WETH9Approval struct { + Src common.Address + Guy common.Address + Wad *big.Int + Raw types.Log +} + +func (_WETH9 *WETH9Filterer) FilterApproval(opts *bind.FilterOpts, src []common.Address, guy []common.Address) (*WETH9ApprovalIterator, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + var guyRule []interface{} + for _, guyItem := range guy { + guyRule = append(guyRule, guyItem) + } + + logs, sub, err := _WETH9.contract.FilterLogs(opts, "Approval", srcRule, guyRule) + if err != nil { + return nil, err + } + return &WETH9ApprovalIterator{contract: _WETH9.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +func (_WETH9 *WETH9Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *WETH9Approval, src []common.Address, guy []common.Address) (event.Subscription, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + var guyRule []interface{} + for _, guyItem := range guy { + guyRule = append(guyRule, guyItem) + } + + logs, sub, err := _WETH9.contract.WatchLogs(opts, "Approval", srcRule, guyRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(WETH9Approval) + if err := _WETH9.contract.UnpackLog(event, "Approval", 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 +} + +func (_WETH9 *WETH9Filterer) ParseApproval(log types.Log) (*WETH9Approval, error) { + event := new(WETH9Approval) + if err := _WETH9.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type WETH9DepositIterator struct { + Event *WETH9Deposit + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *WETH9DepositIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(WETH9Deposit) + 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 + } + } + + select { + case log := <-it.logs: + it.Event = new(WETH9Deposit) + 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() + } +} + +func (it *WETH9DepositIterator) Error() error { + return it.fail +} + +func (it *WETH9DepositIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type WETH9Deposit struct { + Dst common.Address + Wad *big.Int + Raw types.Log +} + +func (_WETH9 *WETH9Filterer) FilterDeposit(opts *bind.FilterOpts, dst []common.Address) (*WETH9DepositIterator, error) { + + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _WETH9.contract.FilterLogs(opts, "Deposit", dstRule) + if err != nil { + return nil, err + } + return &WETH9DepositIterator{contract: _WETH9.contract, event: "Deposit", logs: logs, sub: sub}, nil +} + +func (_WETH9 *WETH9Filterer) WatchDeposit(opts *bind.WatchOpts, sink chan<- *WETH9Deposit, dst []common.Address) (event.Subscription, error) { + + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _WETH9.contract.WatchLogs(opts, "Deposit", dstRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(WETH9Deposit) + if err := _WETH9.contract.UnpackLog(event, "Deposit", 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 +} + +func (_WETH9 *WETH9Filterer) ParseDeposit(log types.Log) (*WETH9Deposit, error) { + event := new(WETH9Deposit) + if err := _WETH9.contract.UnpackLog(event, "Deposit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type WETH9TransferIterator struct { + Event *WETH9Transfer + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *WETH9TransferIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(WETH9Transfer) + 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 + } + } + + select { + case log := <-it.logs: + it.Event = new(WETH9Transfer) + 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() + } +} + +func (it *WETH9TransferIterator) Error() error { + return it.fail +} + +func (it *WETH9TransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type WETH9Transfer struct { + Src common.Address + Dst common.Address + Wad *big.Int + Raw types.Log +} + +func (_WETH9 *WETH9Filterer) FilterTransfer(opts *bind.FilterOpts, src []common.Address, dst []common.Address) (*WETH9TransferIterator, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _WETH9.contract.FilterLogs(opts, "Transfer", srcRule, dstRule) + if err != nil { + return nil, err + } + return &WETH9TransferIterator{contract: _WETH9.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +func (_WETH9 *WETH9Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *WETH9Transfer, src []common.Address, dst []common.Address) (event.Subscription, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _WETH9.contract.WatchLogs(opts, "Transfer", srcRule, dstRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(WETH9Transfer) + if err := _WETH9.contract.UnpackLog(event, "Transfer", 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 +} + +func (_WETH9 *WETH9Filterer) ParseTransfer(log types.Log) (*WETH9Transfer, error) { + event := new(WETH9Transfer) + if err := _WETH9.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type WETH9WithdrawalIterator struct { + Event *WETH9Withdrawal + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *WETH9WithdrawalIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(WETH9Withdrawal) + 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 + } + } + + select { + case log := <-it.logs: + it.Event = new(WETH9Withdrawal) + 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() + } +} + +func (it *WETH9WithdrawalIterator) Error() error { + return it.fail +} + +func (it *WETH9WithdrawalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type WETH9Withdrawal struct { + Src common.Address + Wad *big.Int + Raw types.Log +} + +func (_WETH9 *WETH9Filterer) FilterWithdrawal(opts *bind.FilterOpts, src []common.Address) (*WETH9WithdrawalIterator, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + + logs, sub, err := _WETH9.contract.FilterLogs(opts, "Withdrawal", srcRule) + if err != nil { + return nil, err + } + return &WETH9WithdrawalIterator{contract: _WETH9.contract, event: "Withdrawal", logs: logs, sub: sub}, nil +} + +func (_WETH9 *WETH9Filterer) WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *WETH9Withdrawal, src []common.Address) (event.Subscription, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + + logs, sub, err := _WETH9.contract.WatchLogs(opts, "Withdrawal", srcRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(WETH9Withdrawal) + if err := _WETH9.contract.UnpackLog(event, "Withdrawal", 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 +} + +func (_WETH9 *WETH9Filterer) ParseWithdrawal(log types.Log) (*WETH9Withdrawal, error) { + event := new(WETH9Withdrawal) + if err := _WETH9.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_WETH9 *WETH9) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _WETH9.abi.Events["Approval"].ID: + return _WETH9.ParseApproval(log) + case _WETH9.abi.Events["Deposit"].ID: + return _WETH9.ParseDeposit(log) + case _WETH9.abi.Events["Transfer"].ID: + return _WETH9.ParseTransfer(log) + case _WETH9.abi.Events["Withdrawal"].ID: + return _WETH9.ParseWithdrawal(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (WETH9Approval) Topic() common.Hash { + return common.HexToHash("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925") +} + +func (WETH9Deposit) Topic() common.Hash { + return common.HexToHash("0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c") +} + +func (WETH9Transfer) Topic() common.Hash { + return common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") +} + +func (WETH9Withdrawal) Topic() common.Hash { + return common.HexToHash("0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65") +} + +func (_WETH9 *WETH9) Address() common.Address { + return _WETH9.address +} + +type WETH9Interface interface { + Allowance(opts *bind.CallOpts, arg0 common.Address, arg1 common.Address) (*big.Int, error) + + BalanceOf(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) + + Decimals(opts *bind.CallOpts) (uint8, error) + + Name(opts *bind.CallOpts) (string, error) + + Symbol(opts *bind.CallOpts) (string, error) + + TotalSupply(opts *bind.CallOpts) (*big.Int, error) + + Approve(opts *bind.TransactOpts, guy common.Address, wad *big.Int) (*types.Transaction, error) + + Deposit(opts *bind.TransactOpts) (*types.Transaction, error) + + Mint(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) + + Transfer(opts *bind.TransactOpts, dst common.Address, wad *big.Int) (*types.Transaction, error) + + TransferFrom(opts *bind.TransactOpts, src common.Address, dst common.Address, wad *big.Int) (*types.Transaction, error) + + Withdraw(opts *bind.TransactOpts, wad *big.Int) (*types.Transaction, error) + + Receive(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterApproval(opts *bind.FilterOpts, src []common.Address, guy []common.Address) (*WETH9ApprovalIterator, error) + + WatchApproval(opts *bind.WatchOpts, sink chan<- *WETH9Approval, src []common.Address, guy []common.Address) (event.Subscription, error) + + ParseApproval(log types.Log) (*WETH9Approval, error) + + FilterDeposit(opts *bind.FilterOpts, dst []common.Address) (*WETH9DepositIterator, error) + + WatchDeposit(opts *bind.WatchOpts, sink chan<- *WETH9Deposit, dst []common.Address) (event.Subscription, error) + + ParseDeposit(log types.Log) (*WETH9Deposit, error) + + FilterTransfer(opts *bind.FilterOpts, src []common.Address, dst []common.Address) (*WETH9TransferIterator, error) + + WatchTransfer(opts *bind.WatchOpts, sink chan<- *WETH9Transfer, src []common.Address, dst []common.Address) (event.Subscription, error) + + ParseTransfer(log types.Log) (*WETH9Transfer, error) + + FilterWithdrawal(opts *bind.FilterOpts, src []common.Address) (*WETH9WithdrawalIterator, error) + + WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *WETH9Withdrawal, src []common.Address) (event.Subscription, error) + + ParseWithdrawal(log types.Log) (*WETH9Withdrawal, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index e46f86ba591..e3cf0db7dfa 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -55,6 +55,7 @@ log_emitter: ../../contracts/solc/v0.8.19/LogEmitter/LogEmitter.abi ../../contra log_triggered_streams_lookup_wrapper: ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup/LogTriggeredStreamsLookup.abi ../../contracts/solc/v0.8.16/LogTriggeredStreamsLookup/LogTriggeredStreamsLookup.bin 920fff3b662909f12ed11b47d168036ffa74ad52070a94e2fa26cdad5e428b4e log_upkeep_counter_wrapper: ../../contracts/solc/v0.8.6/LogUpkeepCounter/LogUpkeepCounter.abi ../../contracts/solc/v0.8.6/LogUpkeepCounter/LogUpkeepCounter.bin 42426bbb83f96dfbe55fc576d6c65020eaeed690e2289cf99b0c4aa810a5f4ec mock_aggregator_proxy: ../../contracts/solc/v0.8.6/MockAggregatorProxy/MockAggregatorProxy.abi ../../contracts/solc/v0.8.6/MockAggregatorProxy/MockAggregatorProxy.bin b16c108f3dd384c342ddff5e94da7c0a8d39d1be5e3d8f2cf61ecc7f0e50ff42 +mock_ethusd_aggregator_wrapper: ../../contracts/solc/v0.8.19/MockETHUSDAggregator/MockETHUSDAggregator.abi ../../contracts/solc/v0.8.19/MockETHUSDAggregator/MockETHUSDAggregator.bin b9b361f502d2aad32311c60ca86b071de93a024ac488bcfa19725d368cd05d61 offchain_aggregator_wrapper: OffchainAggregator/OffchainAggregator.abi - 5c8d6562e94166d4790f1ee6e4321d359d9f7262e6c5452a712b1f1c896f45cf operator_factory: ../../contracts/solc/v0.8.19/OperatorFactory/OperatorFactory.abi ../../contracts/solc/v0.8.19/OperatorFactory/OperatorFactory.bin 88e6baa5d9b255eea02616fbcb2cbe21a25ab46adeb6395f6289d169dec949ae operator_wrapper: ../../contracts/solc/v0.8.19/Operator/Operator.abi ../../contracts/solc/v0.8.19/Operator/Operator.bin 23c3888eaa7259e6adf2153d09abae8f4b1987dc44200363faab1e65483f32d5 @@ -115,3 +116,4 @@ vrfv2plus_reverting_example: ../../contracts/solc/v0.8.19/VRFV2PlusRevertingExam vrfv2plus_wrapper: ../../contracts/solc/v0.8.19/VRFV2PlusWrapper/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapper/VRFV2PlusWrapper.bin 004733665a250081153e8878c0621461fea65a2d3b4905269cbd79a0966f211e vrfv2plus_wrapper_consumer_example: ../../contracts/solc/v0.8.19/VRFV2PlusWrapperConsumerExample/VRFV2PlusWrapperConsumerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapperConsumerExample/VRFV2PlusWrapperConsumerExample.bin aeb0c681fa264f90971f65cba1e8d41064948070b217c8204a80ac95e1fa2294 vrfv2plus_wrapper_load_test_consumer: ../../contracts/solc/v0.8.19/VRFV2PlusWrapperLoadTestConsumer/VRFV2PlusWrapperLoadTestConsumer.abi ../../contracts/solc/v0.8.19/VRFV2PlusWrapperLoadTestConsumer/VRFV2PlusWrapperLoadTestConsumer.bin 5ca0223d3f6f6073ddfee4f9ddca13ea5f87297eb5f800359d7a1c41d04b6776 +weth9_wrapper: ../../contracts/solc/v0.8.19/WETH9/WETH9.abi ../../contracts/solc/v0.8.19/WETH9/WETH9.bin 7f600a1de0c02a071cb13bcf9eb1dbf11c3e3eccd1e78ed4b4ecb2960f2bb020 diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index 1ab61563bf7..25afd446484 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -57,6 +57,8 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.abi ../../contracts/solc/v0.8.19/ScrollModule/ScrollModule.bin ScrollModule scroll_module //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/IChainModule/IChainModule.abi ../../contracts/solc/v0.8.19/IChainModule/IChainModule.bin IChainModule i_chain_module //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.abi ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.bin IAutomationV21PlusCommon i_automation_v21_plus_common +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/MockETHUSDAggregator/MockETHUSDAggregator.abi ../../contracts/solc/v0.8.19/MockETHUSDAggregator/MockETHUSDAggregator.bin MockETHUSDAggregator mock_ethusd_aggregator_wrapper +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.19/WETH9/WETH9.abi ../../contracts/solc/v0.8.19/WETH9/WETH9.bin WETH9 weth9_wrapper //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.abi ../../contracts/solc/v0.8.16/ILogAutomation/ILogAutomation.bin ILogAutomation i_log_automation //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.abi ../../contracts/solc/v0.8.16/AutomationForwarderLogic/AutomationForwarderLogic.bin AutomationForwarderLogic automation_forwarder_logic diff --git a/integration-tests/actions/automationv2/actions.go b/integration-tests/actions/automationv2/actions.go index ced41dfb427..1ed4bef1414 100644 --- a/integration-tests/actions/automationv2/actions.go +++ b/integration-tests/actions/automationv2/actions.go @@ -25,6 +25,8 @@ import ( "golang.org/x/sync/errgroup" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3" + ocr2keepers20config "github.com/smartcontractkit/chainlink-automation/pkg/v2/config" ocr2keepers30config "github.com/smartcontractkit/chainlink-automation/pkg/v3/config" @@ -61,6 +63,8 @@ type AutomationTest struct { LinkToken contracts.LinkToken Transcoder contracts.UpkeepTranscoder EthLinkFeed contracts.MockETHLINKFeed + EthUSDFeed contracts.MockETHUSDFeed + WETHToken contracts.WETHToken GasFeed contracts.MockGasFeed Registry contracts.KeeperRegistry Registrar contracts.KeeperRegistrar @@ -213,6 +217,43 @@ func (a *AutomationTest) LoadEthLinkFeed(address string) error { return nil } +func (a *AutomationTest) DeployEthUSDFeed() error { + // FallbackLinkPrice and FallbackETHPrice are the same + ethUSDFeed, err := contracts.DeployMockETHUSDFeed(a.ChainClient, a.RegistrySettings.FallbackLinkPrice) + if err != nil { + return err + } + a.EthUSDFeed = ethUSDFeed + return nil +} + +func (a *AutomationTest) LoadEthUSDFeed(address string) error { + ethUSDFeed, err := contracts.LoadMockETHUSDFeed(a.ChainClient, common.HexToAddress(address)) + if err != nil { + return err + } + a.EthUSDFeed = ethUSDFeed + return nil +} + +func (a *AutomationTest) DeployWETH() error { + wethToken, err := contracts.DeployWETHTokenContract(a.Logger, a.ChainClient) + if err != nil { + return err + } + a.WETHToken = wethToken + return nil +} + +func (a *AutomationTest) LoadWETH(address string) error { + wethToken, err := contracts.LoadWETHTokenContract(a.Logger, a.ChainClient, common.HexToAddress(address)) + if err != nil { + return err + } + a.WETHToken = wethToken + return nil +} + func (a *AutomationTest) DeployGasFeed() error { gasFeed, err := contracts.DeployMockGASFeed(a.ChainClient, a.RegistrySettings.FallbackGasPrice) if err != nil { @@ -233,13 +274,16 @@ func (a *AutomationTest) LoadEthGasFeed(address string) error { func (a *AutomationTest) DeployRegistry() error { registryOpts := &contracts.KeeperRegistryOpts{ - RegistryVersion: a.RegistrySettings.RegistryVersion, - LinkAddr: a.LinkToken.Address(), - ETHFeedAddr: a.EthLinkFeed.Address(), - GasFeedAddr: a.GasFeed.Address(), - TranscoderAddr: a.Transcoder.Address(), - RegistrarAddr: utils.ZeroAddress.Hex(), - Settings: a.RegistrySettings, + RegistryVersion: a.RegistrySettings.RegistryVersion, + LinkAddr: a.LinkToken.Address(), + ETHFeedAddr: a.EthLinkFeed.Address(), + GasFeedAddr: a.GasFeed.Address(), + TranscoderAddr: a.Transcoder.Address(), + RegistrarAddr: utils.ZeroAddress.Hex(), + Settings: a.RegistrySettings, + LinkUSDFeedAddr: a.EthUSDFeed.Address(), + NativeUSDFeedAddr: a.EthUSDFeed.Address(), + WrappedNativeAddr: a.WETHToken.Address(), } registry, err := contracts.DeployKeeperRegistry(a.ChainClient, registryOpts) if err != nil { @@ -263,6 +307,7 @@ func (a *AutomationTest) DeployRegistrar() error { return fmt.Errorf("registry must be deployed or loaded before registrar") } a.RegistrarSettings.RegistryAddr = a.Registry.Address() + a.RegistrarSettings.WETHTokenAddr = a.WETHToken.Address() registrar, err := contracts.DeployKeeperRegistrar(a.ChainClient, a.RegistrySettings.RegistryVersion, a.LinkToken.Address(), a.RegistrarSettings) if err != nil { return err @@ -361,14 +406,14 @@ func (a *AutomationTest) AddBootstrapJob() error { func (a *AutomationTest) AddAutomationJobs() error { var contractVersion string - if a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_2 { + if a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_2 || a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_3 { contractVersion = "v2.1+" } else if a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_1 { contractVersion = "v2.1" } else if a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_0 { contractVersion = "v2.0" } else { - return fmt.Errorf("v2.0, v2.1, and v2.2 are the only supported versions") + return fmt.Errorf("v2.0, v2.1, v2.2 and v2.3 are the only supported versions") } pluginCfg := map[string]interface{}{ "contractVersion": "\"" + contractVersion + "\"", @@ -473,13 +518,13 @@ func (a *AutomationTest) SetConfigOnRegistry() error { if err != nil { return errors.Join(err, fmt.Errorf("failed to build config args")) } - case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2: + case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2, ethereum.RegistryVersion_2_3: signerOnchainPublicKeys, transmitterAccounts, f, _, offchainConfigVersion, offchainConfig, err = calculateOCR3ConfigArgs(a, S, oracleIdentities) if err != nil { return errors.Join(err, fmt.Errorf("failed to build config args")) } default: - return fmt.Errorf("v2.0, v2.1, and v2.2 are the only supported versions") + return fmt.Errorf("v2.0, v2.1, v2.2 and v2.3 are the only supported versions") } var signers []common.Address @@ -517,6 +562,22 @@ func (a *AutomationTest) SetConfigOnRegistry() error { ocrConfig.TypedOnchainConfig21 = a.RegistrySettings.Create21OnchainConfig(a.Registrar.Address(), a.UpkeepPrivilegeManager) } else if a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_2 { ocrConfig.TypedOnchainConfig22 = a.RegistrySettings.Create22OnchainConfig(a.Registrar.Address(), a.UpkeepPrivilegeManager, a.Registry.ChainModuleAddress(), a.Registry.ReorgProtectionEnabled()) + } else if a.RegistrySettings.RegistryVersion == ethereum.RegistryVersion_2_3 { + ocrConfig.TypedOnchainConfig23 = a.RegistrySettings.Create23OnchainConfig(a.Registrar.Address(), a.UpkeepPrivilegeManager, a.Registry.ChainModuleAddress(), a.Registry.ReorgProtectionEnabled()) + ocrConfig.BillingTokens = []common.Address{ + common.HexToAddress(a.LinkToken.Address()), // TODO add more billing tokens + } + + ocrConfig.BillingConfigs = []i_automation_registry_master_wrapper_2_3.AutomationRegistryBase23BillingConfig{ + { + GasFeePPB: 100, + FlatFeeMilliCents: big.NewInt(500), + PriceFeed: common.HexToAddress(a.EthUSDFeed.Address()), // ETH/USD feed and LINK/USD feed are the same + Decimals: 18, + FallbackPrice: big.NewInt(1000), + MinSpend: big.NewInt(200), + }, + } } err = a.Registry.SetConfigTypeSafe(ocrConfig) if err != nil { @@ -790,11 +851,17 @@ func (a *AutomationTest) SetupAutomationDeployment(t *testing.T) { err = a.DeployLINK() require.NoError(t, err, "Error deploying link token contract") + err = a.DeployWETH() + require.NoError(t, err, "Error deploying weth token contract") + err = a.DeployEthLinkFeed() require.NoError(t, err, "Error deploying eth link feed contract") err = a.DeployGasFeed() require.NoError(t, err, "Error deploying gas feed contract") + err = a.DeployEthUSDFeed() + require.NoError(t, err, "Error deploying eth usd feed contract") + err = a.DeployTranscoder() require.NoError(t, err, "Error deploying transcoder contract") diff --git a/integration-tests/actions/keeper_helpers.go b/integration-tests/actions/keeper_helpers.go index 882544e858a..7f02f54c751 100644 --- a/integration-tests/actions/keeper_helpers.go +++ b/integration-tests/actions/keeper_helpers.go @@ -313,6 +313,7 @@ func RegisterUpkeepContractsWithCheckData(t *testing.T, client *seth.Client, lin client.Addresses[keyNum].Hex(), isLogTrigger, isMercury, + linkToken.Address(), ) if err != nil { diff --git a/integration-tests/contracts/contract_models.go b/integration-tests/contracts/contract_models.go index b548ec1427a..e221f3effb0 100644 --- a/integration-tests/contracts/contract_models.go +++ b/integration-tests/contracts/contract_models.go @@ -81,6 +81,16 @@ type LinkToken interface { TransferAndCall(to string, amount *big.Int, data []byte) (*types.Transaction, error) TransferAndCallFromKey(to string, amount *big.Int, data []byte, keyNum int) (*types.Transaction, error) Name(context.Context) (string, error) + Decimals() uint +} + +type WETHToken interface { + Address() string + Approve(to string, amount *big.Int) error + Transfer(to string, amount *big.Int) error + BalanceOf(ctx context.Context, addr string) (*big.Int, error) + Name(context.Context) (string, error) + Decimals() uint } type OffchainOptions struct { @@ -220,6 +230,13 @@ type MockETHLINKFeed interface { LatestRoundDataUpdatedAt() (*big.Int, error) } +type MockETHUSDFeed interface { + Address() string + LatestRoundData() (*big.Int, error) + LatestRoundDataUpdatedAt() (*big.Int, error) + Decimals() uint +} + type MockGasFeed interface { Address() string } diff --git a/integration-tests/contracts/ethereum/KeeperRegistryVersions.go b/integration-tests/contracts/ethereum/KeeperRegistryVersions.go index 4aee8d75d21..d5d0c2edeae 100644 --- a/integration-tests/contracts/ethereum/KeeperRegistryVersions.go +++ b/integration-tests/contracts/ethereum/KeeperRegistryVersions.go @@ -19,4 +19,5 @@ const ( RegistryVersion_2_0 RegistryVersion_2_1 RegistryVersion_2_2 + RegistryVersion_2_3 ) diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index 6d6c9108a4f..ebe99da2d92 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -20,6 +20,10 @@ import ( ocrTypes "github.com/smartcontractkit/libocr/offchainreporting/types" "github.com/smartcontractkit/seth" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/mock_ethusd_aggregator_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/weth9_wrapper" + contractsethereum "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_coordinator" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_load_test_client" @@ -56,8 +60,11 @@ type OCRv2Config struct { OnchainConfig []byte TypedOnchainConfig21 i_keeper_registry_master_wrapper_2_1.IAutomationV21PlusCommonOnchainConfigLegacy TypedOnchainConfig22 i_automation_registry_master_wrapper_2_2.AutomationRegistryBase22OnchainConfig + TypedOnchainConfig23 i_automation_registry_master_wrapper_2_3.AutomationRegistryBase23OnchainConfig OffchainConfigVersion uint64 OffchainConfig []byte + BillingTokens []common.Address + BillingConfigs []i_automation_registry_master_wrapper_2_3.AutomationRegistryBase23BillingConfig } type EthereumFunctionsLoadStats struct { @@ -739,6 +746,10 @@ type EthereumLinkToken struct { l zerolog.Logger } +func (l *EthereumLinkToken) Decimals() uint { + return 18 +} + func DeployLinkTokenContract(l zerolog.Logger, client *seth.Client) (*EthereumLinkToken, error) { linkTokenAbi, err := link_token_interface.LinkTokenMetaData.GetAbi() if err != nil { @@ -1483,3 +1494,185 @@ func (e *EthereumFunctionsLoadTestClient) SendRequestWithDONHostedSecrets(times _, err := e.client.Decode(e.instance.SendRequestWithDONHostedSecrets(e.client.NewTXOpts(), times, source, slotID, slotVersion, args, subscriptionId, donID)) return err } + +// EthereumWETHToken represents a WETH address +type EthereumWETHToken struct { + client *seth.Client + instance *weth9_wrapper.WETH9 + address common.Address + l zerolog.Logger +} + +func DeployWETHTokenContract(l zerolog.Logger, client *seth.Client) (*EthereumWETHToken, error) { + wethTokenAbi, err := weth9_wrapper.WETH9MetaData.GetAbi() + if err != nil { + return &EthereumWETHToken{}, fmt.Errorf("failed to get WETH token ABI: %w", err) + } + wethDeploymentData, err := client.DeployContract(client.NewTXOpts(), "WETHToken", *wethTokenAbi, common.FromHex(weth9_wrapper.WETH9MetaData.Bin)) + if err != nil { + return &EthereumWETHToken{}, fmt.Errorf("WETH token instance deployment failed: %w", err) + } + + wethToken, err := weth9_wrapper.NewWETH9(wethDeploymentData.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumWETHToken{}, fmt.Errorf("failed to instantiate WETHToken instance: %w", err) + } + + return &EthereumWETHToken{ + client: client, + instance: wethToken, + address: wethDeploymentData.Address, + l: l, + }, nil +} + +func LoadWETHTokenContract(l zerolog.Logger, client *seth.Client, address common.Address) (*EthereumWETHToken, error) { + abi, err := weth9_wrapper.WETH9MetaData.GetAbi() + if err != nil { + return &EthereumWETHToken{}, fmt.Errorf("failed to get WETH token ABI: %w", err) + } + + client.ContractStore.AddABI("WETHToken", *abi) + client.ContractStore.AddBIN("WETHToken", common.FromHex(weth9_wrapper.WETH9MetaData.Bin)) + + wethToken, err := weth9_wrapper.NewWETH9(address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumWETHToken{}, fmt.Errorf("failed to instantiate WETHToken instance: %w", err) + } + + return &EthereumWETHToken{ + client: client, + instance: wethToken, + address: address, + l: l, + }, nil +} + +// Fund the WETH Token contract with ETH to distribute the token +func (l *EthereumWETHToken) Fund(_ *big.Float) error { + panic("do not use this function, use actions_seth.SendFunds instead") +} + +func (l *EthereumWETHToken) Decimals() uint { + return 18 +} + +func (l *EthereumWETHToken) BalanceOf(ctx context.Context, addr string) (*big.Int, error) { + return l.instance.BalanceOf(&bind.CallOpts{ + From: l.client.Addresses[0], + Context: ctx, + }, common.HexToAddress(addr)) + +} + +// Name returns the name of the weth token +func (l *EthereumWETHToken) Name(ctx context.Context) (string, error) { + return l.instance.Name(&bind.CallOpts{ + From: l.client.Addresses[0], + Context: ctx, + }) +} + +func (l *EthereumWETHToken) Address() string { + return l.address.Hex() +} + +func (l *EthereumWETHToken) Approve(to string, amount *big.Int) error { + l.l.Info(). + Str("From", l.client.Addresses[0].Hex()). + Str("To", to). + Str("Amount", amount.String()). + Msg("Approving WETH Transfer") + _, err := l.client.Decode(l.instance.Approve(l.client.NewTXOpts(), common.HexToAddress(to), amount)) + return err +} + +func (l *EthereumWETHToken) Transfer(to string, amount *big.Int) error { + l.l.Info(). + Str("From", l.client.Addresses[0].Hex()). + Str("To", to). + Str("Amount", amount.String()). + Msg("Transferring WETH") + _, err := l.client.Decode(l.instance.Transfer(l.client.NewTXOpts(), common.HexToAddress(to), amount)) + return err +} + +// EthereumMockETHUSDFeed represents mocked ETH/USD feed contract +// For the integration tests, we also use this ETH/USD feed for LINK/USD feed since they have the same structure +type EthereumMockETHUSDFeed struct { + client *seth.Client + feed *mock_ethusd_aggregator_wrapper.MockETHUSDAggregator + address *common.Address +} + +func (l *EthereumMockETHUSDFeed) Decimals() uint { + return 8 +} + +func (l *EthereumMockETHUSDFeed) Address() string { + return l.address.Hex() +} + +func (l *EthereumMockETHUSDFeed) LatestRoundData() (*big.Int, error) { + data, err := l.feed.LatestRoundData(&bind.CallOpts{ + From: l.client.Addresses[0], + Context: context.Background(), + }) + if err != nil { + return nil, err + } + return data.Ans, nil +} + +func (l *EthereumMockETHUSDFeed) LatestRoundDataUpdatedAt() (*big.Int, error) { + data, err := l.feed.LatestRoundData(&bind.CallOpts{ + From: l.client.Addresses[0], + Context: context.Background(), + }) + if err != nil { + return nil, err + } + return data.UpdatedAt, nil +} + +func DeployMockETHUSDFeed(client *seth.Client, answer *big.Int) (MockETHUSDFeed, error) { + abi, err := mock_ethusd_aggregator_wrapper.MockETHUSDAggregatorMetaData.GetAbi() + if err != nil { + return &EthereumMockETHUSDFeed{}, fmt.Errorf("failed to get MockETHUSDFeed ABI: %w", err) + } + data, err := client.DeployContract(client.NewTXOpts(), "MockETHUSDFeed", *abi, common.FromHex(mock_ethusd_aggregator_wrapper.MockETHUSDAggregatorMetaData.Bin), answer) + if err != nil { + return &EthereumMockETHUSDFeed{}, fmt.Errorf("MockETHUSDFeed instance deployment have failed: %w", err) + } + + instance, err := mock_ethusd_aggregator_wrapper.NewMockETHUSDAggregator(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumMockETHUSDFeed{}, fmt.Errorf("failed to instantiate MockETHUSDFeed instance: %w", err) + } + + return &EthereumMockETHUSDFeed{ + address: &data.Address, + client: client, + feed: instance, + }, nil +} + +func LoadMockETHUSDFeed(client *seth.Client, address common.Address) (MockETHUSDFeed, error) { + abi, err := mock_ethusd_aggregator_wrapper.MockETHUSDAggregatorMetaData.GetAbi() + if err != nil { + return &EthereumMockETHUSDFeed{}, fmt.Errorf("failed to get MockETHUSDFeed ABI: %w", err) + } + client.ContractStore.AddABI("MockETHUSDFeed", *abi) + client.ContractStore.AddBIN("MockETHUSDFeed", common.FromHex(mock_ethusd_aggregator_wrapper.MockETHUSDAggregatorMetaData.Bin)) + + instance, err := mock_ethusd_aggregator_wrapper.NewMockETHUSDAggregator(address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumMockETHUSDFeed{}, fmt.Errorf("failed to instantiate MockETHUSDFeed instance: %w", err) + } + + return &EthereumMockETHUSDFeed{ + address: &address, + client: client, + feed: instance, + }, nil +} diff --git a/integration-tests/contracts/ethereum_contracts_automation.go b/integration-tests/contracts/ethereum_contracts_automation.go index 13cad7ffefb..c2c7576e0f0 100644 --- a/integration-tests/contracts/ethereum_contracts_automation.go +++ b/integration-tests/contracts/ethereum_contracts_automation.go @@ -16,6 +16,9 @@ import ( "github.com/rs/zerolog" "github.com/smartcontractkit/seth" + cltypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" + registrylogicc23 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_logic_c_wrapper_2_3" + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/networks" "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" @@ -28,12 +31,20 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_consumer_benchmark" automationForwarderLogic "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_forwarder_logic" registrar21 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registrar_wrapper2_1" + registrar23 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registrar_wrapper2_3" registrylogica22 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_2" registrylogicb22 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_2" registry22 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_wrapper_2_2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/chain_module_base" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_2" iregistry22 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_2" + + registrylogica23 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_logic_a_wrapper_2_3" + registrylogicb23 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_logic_b_wrapper_2_3" + registry23 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_registry_wrapper_2_3" + iregistry23 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3" ac "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_v21_plus_common" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_chain_module" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" @@ -127,6 +138,7 @@ type EthereumKeeperRegistry struct { registry2_0 *keeper_registry_wrapper2_0.KeeperRegistry registry2_1 *i_keeper_registry_master_wrapper_2_1.IKeeperRegistryMaster registry2_2 *i_automation_registry_master_wrapper_2_2.IAutomationRegistryMaster + registry2_3 *i_automation_registry_master_wrapper_2_3.IAutomationRegistryMaster23 chainModule *i_chain_module.IChainModule address *common.Address l zerolog.Logger @@ -139,7 +151,7 @@ func (v *EthereumKeeperRegistry) ReorgProtectionEnabled() bool { } func (v *EthereumKeeperRegistry) ChainModuleAddress() common.Address { - if v.version == ethereum.RegistryVersion_2_2 { + if v.version >= ethereum.RegistryVersion_2_2 { return v.chainModule.Address() } return common.Address{} @@ -159,6 +171,9 @@ func (v *EthereumKeeperRegistry) RegistryOwnerAddress() common.Address { } switch v.version { + case ethereum.RegistryVersion_2_3: + ownerAddress, _ := v.registry2_3.Owner(callOpts) + return ownerAddress case ethereum.RegistryVersion_2_2: ownerAddress, _ := v.registry2_2.Owner(callOpts) return ownerAddress @@ -198,6 +213,17 @@ func (v *EthereumKeeperRegistry) SetConfigTypeSafe(ocrConfig OCRv2Config) error ocrConfig.OffchainConfigVersion, ocrConfig.OffchainConfig, )) + case ethereum.RegistryVersion_2_3: + _, err = v.client.Decode(v.registry2_3.SetConfigTypeSafe(txOpts, + ocrConfig.Signers, + ocrConfig.Transmitters, + ocrConfig.F, + ocrConfig.TypedOnchainConfig23, + ocrConfig.OffchainConfigVersion, + ocrConfig.OffchainConfig, + ocrConfig.BillingTokens, + ocrConfig.BillingConfigs, + )) default: return fmt.Errorf("SetConfigTypeSafe is not supported in keeper registry version %d", v.version) } @@ -280,8 +306,8 @@ func (v *EthereumKeeperRegistry) SetConfig(config KeeperRegistrySettings, ocrCon ocrConfig.OffchainConfig, )) return err - case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2: - return fmt.Errorf("registry version 2.1 and 2.2 must use setConfigTypeSafe function") + case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2, ethereum.RegistryVersion_2_3: + return fmt.Errorf("registry version 2.1 2.2 and 2.3 must use setConfigTypeSafe function") default: return fmt.Errorf("keeper registry version %d is not supported", v.version) } @@ -298,6 +324,9 @@ func (v *EthereumKeeperRegistry) SetUpkeepOffchainConfig(id *big.Int, offchainCo case ethereum.RegistryVersion_2_2: _, err := v.client.Decode(v.registry2_2.SetUpkeepOffchainConfig(v.client.NewTXOpts(), id, offchainConfig)) return err + case ethereum.RegistryVersion_2_3: + _, err := v.client.Decode(v.registry2_3.SetUpkeepOffchainConfig(v.client.NewTXOpts(), id, offchainConfig)) + return err default: return fmt.Errorf("SetUpkeepOffchainConfig is not supported by keeper registry version %d", v.version) } @@ -321,6 +350,8 @@ func (v *EthereumKeeperRegistry) Pause() error { _, err = v.client.Decode(v.registry2_1.Pause(txOpts)) case ethereum.RegistryVersion_2_2: _, err = v.client.Decode(v.registry2_2.Pause(txOpts)) + case ethereum.RegistryVersion_2_3: + _, err = v.client.Decode(v.registry2_3.Pause(txOpts)) default: return fmt.Errorf("keeper registry version %d is not supported", v.version) } @@ -405,6 +436,8 @@ func (v *EthereumKeeperRegistry) AddUpkeepFundsFromKey(id *big.Int, amount *big. _, err = v.client.Decode(v.registry2_1.AddFunds(opts, id, amount)) case ethereum.RegistryVersion_2_2: _, err = v.client.Decode(v.registry2_2.AddFunds(opts, id, amount)) + case ethereum.RegistryVersion_2_3: + _, err = v.client.Decode(v.registry2_3.AddFunds(opts, id, amount)) } return err @@ -501,6 +534,8 @@ func (v *EthereumKeeperRegistry) GetUpkeepInfo(ctx context.Context, id *big.Int) }, nil case ethereum.RegistryVersion_2_2: return v.getUpkeepInfo22(opts, id) + case ethereum.RegistryVersion_2_3: + return v.getUpkeepInfo23(opts, id) } return nil, fmt.Errorf("keeper registry version %d is not supported", v.version) @@ -525,6 +560,25 @@ func (v *EthereumKeeperRegistry) getUpkeepInfo22(opts *bind.CallOpts, id *big.In }, nil } +func (v *EthereumKeeperRegistry) getUpkeepInfo23(opts *bind.CallOpts, id *big.Int) (*UpkeepInfo, error) { + uk, err := v.registry2_3.GetUpkeep(opts, id) + if err != nil { + return nil, err + } + return &UpkeepInfo{ + Target: uk.Target.Hex(), + ExecuteGas: uk.PerformGas, + CheckData: uk.CheckData, + Balance: uk.Balance, + Admin: uk.Admin.Hex(), + MaxValidBlocknumber: uk.MaxValidBlocknumber, + LastPerformBlockNumber: uk.LastPerformedBlockNumber, + AmountSpent: uk.AmountSpent, + Paused: uk.Paused, + OffchainConfig: uk.OffchainConfig, + }, nil +} + func (v *EthereumKeeperRegistry) GetKeeperInfo(ctx context.Context, keeperAddr string) (*KeeperInfo, error) { opts := &bind.CallOpts{ From: v.client.MustGetRootKeyAddress(), @@ -544,7 +598,7 @@ func (v *EthereumKeeperRegistry) GetKeeperInfo(ctx context.Context, keeperAddr s info, err = v.registry1_2.GetKeeperInfo(opts, common.HexToAddress(keeperAddr)) case ethereum.RegistryVersion_1_3: info, err = v.registry1_3.GetKeeperInfo(opts, common.HexToAddress(keeperAddr)) - case ethereum.RegistryVersion_2_0, ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2: + case ethereum.RegistryVersion_2_0, ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2, ethereum.RegistryVersion_2_3: // this is not used anywhere return nil, fmt.Errorf("not supported") } @@ -588,7 +642,7 @@ func (v *EthereumKeeperRegistry) SetKeepers(keepers []string, payees []string, o ocrConfig.OffchainConfigVersion, ocrConfig.OffchainConfig, )) - case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2: + case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2, ethereum.RegistryVersion_2_3: return fmt.Errorf("not supported") } @@ -634,7 +688,7 @@ func (v *EthereumKeeperRegistry) RegisterUpkeep(target string, gasLimit uint32, checkData, nil, //offchain config )) - case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2: + case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2, ethereum.RegistryVersion_2_3: return fmt.Errorf("not supported") } @@ -660,6 +714,8 @@ func (v *EthereumKeeperRegistry) CancelUpkeep(id *big.Int) error { tx, err = v.client.Decode(v.registry2_1.CancelUpkeep(opts, id)) case ethereum.RegistryVersion_2_2: tx, err = v.client.Decode(v.registry2_2.CancelUpkeep(opts, id)) + case ethereum.RegistryVersion_2_3: + tx, err = v.client.Decode(v.registry2_3.CancelUpkeep(opts, id)) } txHash := "none" @@ -692,6 +748,8 @@ func (v *EthereumKeeperRegistry) SetUpkeepGasLimit(id *big.Int, gas uint32) erro _, err = v.client.Decode(v.registry2_1.SetUpkeepGasLimit(opts, id, gas)) case ethereum.RegistryVersion_2_2: _, err = v.client.Decode(v.registry2_2.SetUpkeepGasLimit(opts, id, gas)) + case ethereum.RegistryVersion_2_3: + _, err = v.client.Decode(v.registry2_3.SetUpkeepGasLimit(opts, id, gas)) default: return fmt.Errorf("keeper registry version %d is not supported for SetUpkeepGasLimit", v.version) } @@ -729,7 +787,7 @@ func (v *EthereumKeeperRegistry) GetKeeperList(ctx context.Context) ([]string, e return []string{}, err } list = state.Transmitters - case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2: + case ethereum.RegistryVersion_2_1, ethereum.RegistryVersion_2_2, ethereum.RegistryVersion_2_3: return nil, fmt.Errorf("not supported") } @@ -757,6 +815,8 @@ func (v *EthereumKeeperRegistry) UpdateCheckData(id *big.Int, newCheckData []byt _, err = v.client.Decode(v.registry2_1.SetUpkeepCheckData(opts, id, newCheckData)) case ethereum.RegistryVersion_2_2: _, err = v.client.Decode(v.registry2_2.SetUpkeepCheckData(opts, id, newCheckData)) + case ethereum.RegistryVersion_2_3: + _, err = v.client.Decode(v.registry2_3.SetUpkeepCheckData(opts, id, newCheckData)) default: return fmt.Errorf("UpdateCheckData is not supported by keeper registry version %d", v.version) } @@ -774,6 +834,8 @@ func (v *EthereumKeeperRegistry) SetUpkeepTriggerConfig(id *big.Int, triggerConf _, err = v.client.Decode(v.registry2_1.SetUpkeepTriggerConfig(opts, id, triggerConfig)) case ethereum.RegistryVersion_2_2: _, err = v.client.Decode(v.registry2_2.SetUpkeepTriggerConfig(opts, id, triggerConfig)) + case ethereum.RegistryVersion_2_3: + _, err = v.client.Decode(v.registry2_3.SetUpkeepTriggerConfig(opts, id, triggerConfig)) default: return fmt.Errorf("SetUpkeepTriggerConfig is not supported by keeper registry version %d", v.version) } @@ -791,6 +853,8 @@ func (v *EthereumKeeperRegistry) SetUpkeepPrivilegeConfig(id *big.Int, privilege _, err = v.client.Decode(v.registry2_1.SetUpkeepPrivilegeConfig(opts, id, privilegeConfig)) case ethereum.RegistryVersion_2_2: _, err = v.client.Decode(v.registry2_2.SetUpkeepPrivilegeConfig(opts, id, privilegeConfig)) + case ethereum.RegistryVersion_2_3: + _, err = v.client.Decode(v.registry2_3.SetUpkeepPrivilegeConfig(opts, id, privilegeConfig)) default: return fmt.Errorf("SetUpkeepPrivilegeConfig is not supported by keeper registry version %d", v.version) } @@ -812,6 +876,8 @@ func (v *EthereumKeeperRegistry) PauseUpkeep(id *big.Int) error { _, err = v.client.Decode(v.registry2_1.PauseUpkeep(opts, id)) case ethereum.RegistryVersion_2_2: _, err = v.client.Decode(v.registry2_2.PauseUpkeep(opts, id)) + case ethereum.RegistryVersion_2_3: + _, err = v.client.Decode(v.registry2_3.PauseUpkeep(opts, id)) default: return fmt.Errorf("PauseUpkeep is not supported by keeper registry version %d", v.version) } @@ -833,6 +899,8 @@ func (v *EthereumKeeperRegistry) UnpauseUpkeep(id *big.Int) error { _, err = v.client.Decode(v.registry2_1.UnpauseUpkeep(opts, id)) case ethereum.RegistryVersion_2_2: _, err = v.client.Decode(v.registry2_2.UnpauseUpkeep(opts, id)) + case ethereum.RegistryVersion_2_3: + _, err = v.client.Decode(v.registry2_3.UnpauseUpkeep(opts, id)) default: return fmt.Errorf("UnpauseUpkeep is not supported by keeper registry version %d", v.version) } @@ -903,6 +971,16 @@ func (v *EthereumKeeperRegistry) ParseUpkeepPerformedLog(log *types.Log) (*Upkee Success: parsedLog.Success, From: utils.ZeroAddress, }, nil + case ethereum.RegistryVersion_2_3: + parsedLog, err := v.registry2_3.ParseUpkeepPerformed(*log) + if err != nil { + return nil, err + } + return &UpkeepPerformedLog{ + Id: parsedLog.Id, + Success: parsedLog.Success, + From: utils.ZeroAddress, + }, nil } return nil, fmt.Errorf("keeper registry version %d is not supported", v.version) } @@ -935,6 +1013,14 @@ func (v *EthereumKeeperRegistry) ParseStaleUpkeepReportLog(log *types.Log) (*Sta return &StaleUpkeepReportLog{ Id: parsedLog.Id, }, nil + case ethereum.RegistryVersion_2_3: + parsedLog, err := v.registry2_3.ParseStaleUpkeepReport(*log) + if err != nil { + return nil, err + } + return &StaleUpkeepReportLog{ + Id: parsedLog.Id, + }, nil } return nil, fmt.Errorf("keeper registry version %d is not supported", v.version) } @@ -978,6 +1064,12 @@ func (v *EthereumKeeperRegistry) ParseUpkeepIdFromRegisteredLog(log *types.Log) return nil, err } return parsedLog.Id, nil + case ethereum.RegistryVersion_2_3: + parsedLog, err := v.registry2_3.ParseUpkeepRegistered(*log) + if err != nil { + return nil, err + } + return parsedLog.Id, nil } return nil, fmt.Errorf("keeper registry version %d is not supported", v.version) @@ -1015,6 +1107,8 @@ func DeployKeeperRegistry( return deployRegistry21(client, opts, mode) case eth_contracts.RegistryVersion_2_2: return deployRegistry22(client, opts) + case eth_contracts.RegistryVersion_2_3: + return deployRegistry23(client, opts) default: return nil, fmt.Errorf("keeper registry version %d is not supported", opts.RegistryVersion) } @@ -1339,6 +1433,109 @@ func deployRegistry22(client *seth.Client, opts *KeeperRegistryOpts) (KeeperRegi }, err } +func deployRegistry23(client *seth.Client, opts *KeeperRegistryOpts) (KeeperRegistry, error) { + var chainModuleAddr common.Address + var err error + chainId := client.ChainID + + if chainId == networks.ScrollMainnet.ChainID || chainId == networks.ScrollSepolia.ChainID { + chainModuleAddr, err = deployScrollModule(client) + } else if chainId == networks.ArbitrumMainnet.ChainID || chainId == networks.ArbitrumSepolia.ChainID { + chainModuleAddr, err = deployArbitrumModule(client) + } else if chainId == networks.OptimismMainnet.ChainID || chainId == networks.OptimismSepolia.ChainID { + chainModuleAddr, err = deployOptimismModule(client) + } else { + chainModuleAddr, err = deployBaseModule(client) + } + if err != nil { + return nil, err + } + + automationForwarderLogicAddr, err := deployAutomationForwarderLogicSeth(client) + if err != nil { + return nil, err + } + + var allowedReadOnlyAddress common.Address + if chainId == networks.PolygonZkEvmMainnet.ChainID || chainId == networks.PolygonZkEvmCardona.ChainID { + allowedReadOnlyAddress = common.HexToAddress("0x1111111111111111111111111111111111111111") + } else { + allowedReadOnlyAddress = common.HexToAddress("0x0000000000000000000000000000000000000000") + } + + logicCAbi, err := registrylogicc23.AutomationRegistryLogicCMetaData.GetAbi() + if err != nil { + return &EthereumKeeperRegistry{}, fmt.Errorf("failed to get AutomationRegistryLogicC2_3 ABI: %w", err) + } + + logicCData, err := client.DeployContract(client.NewTXOpts(), "AutomationRegistryLogicC2_3", *logicCAbi, common.FromHex(registrylogicc23.AutomationRegistryLogicCMetaData.Bin), + common.HexToAddress(opts.LinkAddr), + common.HexToAddress(opts.LinkUSDFeedAddr), + common.HexToAddress(opts.NativeUSDFeedAddr), + common.HexToAddress(opts.GasFeedAddr), + automationForwarderLogicAddr, + allowedReadOnlyAddress, + uint8(0), // onchain payout mode + common.HexToAddress(opts.WrappedNativeAddr), + ) + if err != nil { + return &EthereumKeeperRegistry{}, fmt.Errorf("AutomationRegistryLogicC2_3 instance deployment have failed: %w", err) + } + + logicBAbi, err := registrylogicb23.AutomationRegistryLogicBMetaData.GetAbi() + if err != nil { + return &EthereumKeeperRegistry{}, fmt.Errorf("failed to get AutomationRegistryLogicB2_3 ABI: %w", err) + } + + logicBData, err := client.DeployContract(client.NewTXOpts(), "AutomationRegistryLogicB2_3", *logicBAbi, common.FromHex(registrylogicb23.AutomationRegistryLogicBMetaData.Bin), + logicCData.Address, + ) + if err != nil { + return &EthereumKeeperRegistry{}, fmt.Errorf("AutomationRegistryLogicB2_3 instance deployment have failed: %w", err) + } + + logicAAbi, err := registrylogica23.AutomationRegistryLogicAMetaData.GetAbi() + if err != nil { + return &EthereumKeeperRegistry{}, fmt.Errorf("failed to get AutomationRegistryLogicA2_3 ABI: %w", err) + } + logicAData, err := client.DeployContract(client.NewTXOpts(), "AutomationRegistryLogicA2_3", *logicAAbi, common.FromHex(registrylogica23.AutomationRegistryLogicAMetaData.Bin), + logicBData.Address, + ) + if err != nil { + return &EthereumKeeperRegistry{}, fmt.Errorf("AutomationRegistryLogicA2_3 instance deployment have failed: %w", err) + } + + abi, err := registry23.AutomationRegistryMetaData.GetAbi() + if err != nil { + return &EthereumKeeperRegistry{}, fmt.Errorf("failed to get AutomationRegistry2_3 ABI: %w", err) + } + + data, err := client.DeployContract(client.NewTXOpts(), "AutomationRegistry2_3", *abi, common.FromHex(registry23.AutomationRegistryMetaData.Bin), + logicAData.Address, + ) + if err != nil { + return &EthereumKeeperRegistry{}, fmt.Errorf("AutomationRegistry2_3 instance deployment have failed: %w", err) + } + + instance, err := iregistry23.NewIAutomationRegistryMaster23(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumKeeperRegistry{}, fmt.Errorf("failed to instantiate AutomationRegistry2_3 instance: %w", err) + } + + chainModule, err := i_chain_module.NewIChainModule( + chainModuleAddr, + wrappers.MustNewWrappedContractBackend(nil, client), + ) + + return &EthereumKeeperRegistry{ + client: client, + version: eth_contracts.RegistryVersion_2_3, + registry2_3: instance, + chainModule: chainModule, + address: &data.Address, + }, err +} + // LoadKeeperRegistry returns deployed on given address EthereumKeeperRegistry func LoadKeeperRegistry(l zerolog.Logger, client *seth.Client, address common.Address, registryVersion eth_contracts.KeeperRegistryVersion) (KeeperRegistry, error) { var keeper *EthereumKeeperRegistry @@ -1356,6 +1553,8 @@ func LoadKeeperRegistry(l zerolog.Logger, client *seth.Client, address common.Ad keeper, err = loadRegistry2_1(client, address) case eth_contracts.RegistryVersion_2_2: // why the contract name is not the same as the actual contract name? keeper, err = loadRegistry2_2(client, address) + case eth_contracts.RegistryVersion_2_3: + keeper, err = loadRegistry2_3(client, address) default: return nil, fmt.Errorf("keeper registry version %d is not supported", registryVersion) } @@ -1495,6 +1694,27 @@ func loadRegistry2_2(client *seth.Client, address common.Address) (*EthereumKeep }, nil } +func loadRegistry2_3(client *seth.Client, address common.Address) (*EthereumKeeperRegistry, error) { + abi, err := iregistry23.IAutomationRegistryMaster23MetaData.GetAbi() + if err != nil { + return &EthereumKeeperRegistry{}, fmt.Errorf("failed to get AutomationRegistry2_3 ABI: %w", err) + } + + client.ContractStore.AddABI("AutomationRegistry2_3", *abi) + client.ContractStore.AddBIN("AutomationRegistry2_3", common.FromHex(iregistry23.IAutomationRegistryMaster23MetaData.Bin)) + + instance, err := iregistry23.NewIAutomationRegistryMaster23(address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumKeeperRegistry{}, fmt.Errorf("failed to instantiate AutomationRegistry2_3 instance: %w", err) + } + + return &EthereumKeeperRegistry{ + address: &address, + client: client, + registry2_3: instance, + }, nil +} + func deployAutomationForwarderLogicSeth(client *seth.Client) (common.Address, error) { abi, err := automationForwarderLogic.AutomationForwarderLogicMetaData.GetAbi() if err != nil { @@ -1567,6 +1787,7 @@ type EthereumKeeperRegistrar struct { registrar *keeper_registrar_wrapper1_2.KeeperRegistrar registrar20 *keeper_registrar_wrapper2_0.KeeperRegistrar registrar21 *registrar21.AutomationRegistrar + registrar23 *registrar23.AutomationRegistrar address *common.Address } @@ -1579,7 +1800,7 @@ func (v *EthereumKeeperRegistrar) Fund(_ *big.Float) error { } // EncodeRegisterRequest encodes register request to call it through link token TransferAndCall -func (v *EthereumKeeperRegistrar) EncodeRegisterRequest(name string, email []byte, upkeepAddr string, gasLimit uint32, adminAddr string, checkData []byte, amount *big.Int, source uint8, senderAddr string, isLogTrigger bool, isMercury bool) ([]byte, error) { +func (v *EthereumKeeperRegistrar) EncodeRegisterRequest(name string, email []byte, upkeepAddr string, gasLimit uint32, adminAddr string, checkData []byte, amount *big.Int, source uint8, senderAddr string, isLogTrigger bool, isMercury bool, linkTokenAddr string) ([]byte, error) { if v.registrar20 != nil { registryABI, err := abi.JSON(strings.NewReader(keeper_registrar_wrapper2_0.KeeperRegistrarMetaData.ABI)) if err != nil { @@ -1667,6 +1888,76 @@ func (v *EthereumKeeperRegistrar) EncodeRegisterRequest(name string, email []byt common.HexToAddress(senderAddr), ) return req, err + } else if v.registrar23 != nil { + registrarABI = cltypes.MustGetABI(registrar23.AutomationRegistrarABI) + + if isLogTrigger { + var topic0InBytes [32]byte + // bytes representation of 0x0000000000000000000000000000000000000000000000000000000000000000 + bytes0 := [32]byte{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + } + if isMercury { + // bytes representation of 0xd1ffe9e45581c11d7d9f2ed5f75217cd4be9f8b7eee6af0f6d03f46de53956cd + topic0InBytes = [32]byte{209, 255, 233, 228, 85, 129, 193, 29, 125, 159, 46, 213, 247, 82, 23, 205, 75, 233, 248, 183, 238, 230, 175, 15, 109, 3, 244, 109, 229, 57, 86, 205} + } else { + // bytes representation of 0x3d53a39550e04688065827f3bb86584cb007ab9ebca7ebd528e7301c9c31eb5d + topic0InBytes = [32]byte{ + 61, 83, 163, 149, 80, 224, 70, 136, + 6, 88, 39, 243, 187, 134, 88, 76, + 176, 7, 171, 158, 188, 167, 235, + 213, 40, 231, 48, 28, 156, 49, 235, 93, + } + } + + logTriggerConfigStruct := acutils.IAutomationV21PlusCommonLogTriggerConfig{ + ContractAddress: common.HexToAddress(upkeepAddr), + FilterSelector: 0, + Topic0: topic0InBytes, + Topic1: bytes0, + Topic2: bytes0, + Topic3: bytes0, + } + encodedLogTriggerConfig, err := compatibleUtils.Methods["_logTriggerConfig"].Inputs.Pack(&logTriggerConfigStruct) + if err != nil { + return nil, err + } + + params := registrar23.AutomationRegistrar23RegistrationParams{ + UpkeepContract: common.HexToAddress(upkeepAddr), + Amount: amount, + AdminAddress: common.HexToAddress(adminAddr), + GasLimit: gasLimit, + TriggerType: uint8(1), // trigger type + BillingToken: common.HexToAddress(linkTokenAddr), + Name: name, + EncryptedEmail: email, + CheckData: checkData, + TriggerConfig: encodedLogTriggerConfig, + OffchainConfig: []byte{}, + } + + req, err := registrarABI.Methods["registerUpkeep"].Inputs.Pack(¶ms) + return req, err + } + + params := registrar23.AutomationRegistrar23RegistrationParams{ + UpkeepContract: common.HexToAddress(upkeepAddr), + Amount: amount, + AdminAddress: common.HexToAddress(adminAddr), + GasLimit: gasLimit, + TriggerType: uint8(0), // trigger type + BillingToken: common.HexToAddress(linkTokenAddr), + Name: name, + EncryptedEmail: email, + CheckData: checkData, + TriggerConfig: []byte{}, + OffchainConfig: []byte{}, + } + + encodedRegistrationParamsStruct, err := registrarABI.Methods["registerUpkeep"].Inputs.Pack(¶ms) + + return encodedRegistrationParamsStruct, err } registryABI, err := abi.JSON(strings.NewReader(keeper_registrar_wrapper1_2.KeeperRegistrarMetaData.ABI)) if err != nil { @@ -1750,6 +2041,48 @@ func DeployKeeperRegistrar(client *seth.Client, registryVersion eth_contracts.Ke registrar21: instance, address: &data.Address, }, nil + } else if registryVersion == eth_contracts.RegistryVersion_2_3 { + abi, err := registrar23.AutomationRegistrarMetaData.GetAbi() + if err != nil { + return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to get KeeperRegistrar2_3 ABI: %w", err) + } + // set default TriggerType to 0(conditional), AutoApproveConfigType to 2(auto approve enabled), AutoApproveMaxAllowed to 1000 + triggerConfigs := []registrar23.AutomationRegistrar23InitialTriggerConfig{ + {TriggerType: 0, AutoApproveType: registrarSettings.AutoApproveConfigType, + AutoApproveMaxAllowed: uint32(registrarSettings.AutoApproveMaxAllowed)}, + {TriggerType: 1, AutoApproveType: registrarSettings.AutoApproveConfigType, + AutoApproveMaxAllowed: uint32(registrarSettings.AutoApproveMaxAllowed)}, + } + + billingTokens := []common.Address{ + common.HexToAddress(linkAddr), + } + minRegistrationFees := []*big.Int{ + big.NewInt(10), + } + + data, err := client.DeployContract(client.NewTXOpts(), "KeeperRegistrar2_3", *abi, common.FromHex(registrar23.AutomationRegistrarMetaData.Bin), + common.HexToAddress(linkAddr), + common.HexToAddress(registrarSettings.RegistryAddr), + triggerConfigs, + billingTokens, + minRegistrationFees, + common.HexToAddress(registrarSettings.WETHTokenAddr), + ) + if err != nil { + return &EthereumKeeperRegistrar{}, fmt.Errorf("KeeperRegistrar2_3 instance deployment have failed: %w", err) + } + + instance, err := registrar23.NewAutomationRegistrar(data.Address, wrappers.MustNewWrappedContractBackend(nil, client)) + if err != nil { + return &EthereumKeeperRegistrar{}, fmt.Errorf("failed to instantiate KeeperRegistrar2_3 instance: %w", err) + } + + return &EthereumKeeperRegistrar{ + client: client, + registrar23: instance, + address: &data.Address, + }, nil } // non OCR registrar diff --git a/integration-tests/contracts/ethereum_keeper_contracts.go b/integration-tests/contracts/ethereum_keeper_contracts.go index b933c18df0c..84543627d49 100644 --- a/integration-tests/contracts/ethereum_keeper_contracts.go +++ b/integration-tests/contracts/ethereum_keeper_contracts.go @@ -4,13 +4,14 @@ import ( "context" "math/big" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_2" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" goabi "github.com/umbracle/ethgo/abi" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_2" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_automation_registry_master_wrapper_2_3" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/i_keeper_registry_master_wrapper_2_1" + "github.com/smartcontractkit/chainlink/integration-tests/contracts/ethereum" cltypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" ac "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/automation_compatible_utils" @@ -23,7 +24,7 @@ var registrarABI = cltypes.MustGetABI(registrar21.AutomationRegistrarABI) type KeeperRegistrar interface { Address() string - EncodeRegisterRequest(name string, email []byte, upkeepAddr string, gasLimit uint32, adminAddr string, checkData []byte, amount *big.Int, source uint8, senderAddr string, isLogTrigger bool, isMercury bool) ([]byte, error) + EncodeRegisterRequest(name string, email []byte, upkeepAddr string, gasLimit uint32, adminAddr string, checkData []byte, amount *big.Int, source uint8, senderAddr string, isLogTrigger bool, isMercury bool, linkTokenAddr string) ([]byte, error) Fund(ethAmount *big.Float) error } @@ -123,13 +124,16 @@ type StaleUpkeepReportLog struct { // KeeperRegistryOpts opts to deploy keeper registry version type KeeperRegistryOpts struct { - RegistryVersion ethereum.KeeperRegistryVersion - LinkAddr string - ETHFeedAddr string - GasFeedAddr string - TranscoderAddr string - RegistrarAddr string - Settings KeeperRegistrySettings + RegistryVersion ethereum.KeeperRegistryVersion + LinkAddr string + ETHFeedAddr string + GasFeedAddr string + TranscoderAddr string + RegistrarAddr string + Settings KeeperRegistrySettings + LinkUSDFeedAddr string + NativeUSDFeedAddr string + WrappedNativeAddr string } // KeeperRegistrySettings represents the settings to fine tune keeper registry @@ -150,6 +154,27 @@ type KeeperRegistrySettings struct { RegistryVersion ethereum.KeeperRegistryVersion } +func (rcs *KeeperRegistrySettings) Create23OnchainConfig(registrar string, registryOwnerAddress, chainModuleAddress common.Address, reorgProtectionEnabled bool) i_automation_registry_master_wrapper_2_3.AutomationRegistryBase23OnchainConfig { + return i_automation_registry_master_wrapper_2_3.AutomationRegistryBase23OnchainConfig{ + CheckGasLimit: rcs.CheckGasLimit, + StalenessSeconds: rcs.StalenessSeconds, + GasCeilingMultiplier: rcs.GasCeilingMultiplier, + MaxPerformGas: rcs.MaxPerformGas, + MaxCheckDataSize: rcs.MaxCheckDataSize, + MaxPerformDataSize: rcs.MaxPerformDataSize, + MaxRevertDataSize: rcs.MaxRevertDataSize, + FallbackGasPrice: rcs.FallbackGasPrice, + FallbackLinkPrice: rcs.FallbackLinkPrice, + Transcoder: common.Address{}, + Registrars: []common.Address{common.HexToAddress(registrar)}, + UpkeepPrivilegeManager: registryOwnerAddress, + ChainModule: chainModuleAddress, + ReorgProtectionEnabled: reorgProtectionEnabled, + FinanceAdmin: registryOwnerAddress, + FallbackNativePrice: big.NewInt(1), + } +} + func (rcs *KeeperRegistrySettings) Encode20OnchainConfig(registrar string) []byte { configType := goabi.MustNewType("tuple(uint32 paymentPremiumPPB,uint32 flatFeeMicroLink,uint32 checkGasLimit,uint24 stalenessSeconds,uint16 gasCeilingMultiplier,uint96 minUpkeepSpend,uint32 maxPerformGas,uint32 maxCheckDataSize,uint32 maxPerformDataSize,uint256 fallbackGasPrice,uint256 fallbackLinkPrice,address transcoder,address registrar)") onchainConfig, _ := goabi.Encode(map[string]interface{}{ @@ -218,6 +243,7 @@ type KeeperRegistrarSettings struct { AutoApproveMaxAllowed uint16 RegistryAddr string MinLinkJuels *big.Int + WETHTokenAddr string } // KeeperInfo keeper status and balance info diff --git a/integration-tests/go.mod b/integration-tests/go.mod index a700e20d88c..c4a064ce75b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -208,7 +208,6 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.15.5 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect - github.com/go-test/deep v1.0.8 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect github.com/goccy/go-json v0.10.2 // indirect @@ -416,7 +415,6 @@ require ( github.com/uber/jaeger-lib v2.4.1+incompatible // indirect github.com/ugorji/go/codec v1.2.12 // indirect github.com/umbracle/fastrlp v0.0.0-20220527094140-59d5dd30e722 // indirect - github.com/urfave/cli/v2 v2.27.1 // indirect github.com/valyala/fastjson v1.4.1 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/x448/float16 v0.8.4 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 97813f85ea1..187167f5da1 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -652,9 +652,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6lpIc2g= github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= @@ -1673,8 +1672,8 @@ github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFs github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= -github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= -github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index e3e9254d67c..4fea8817ce8 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -646,9 +646,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6lpIc2g= github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= @@ -1659,8 +1658,8 @@ github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFs github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA= -github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= -github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 50b5fb96230..46abccae565 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -110,6 +110,7 @@ func SetupAutomationBasic(t *testing.T, nodeUpgrade bool) { "registry_2_2_with_mercury_v02": ethereum.RegistryVersion_2_2, "registry_2_2_with_mercury_v03": ethereum.RegistryVersion_2_2, "registry_2_2_with_logtrigger_and_mercury_v02": ethereum.RegistryVersion_2_2, + "registry_2_3_conditional": ethereum.RegistryVersion_2_3, } for n, rv := range registryVersions { diff --git a/integration-tests/smoke/automation_test.go_test_list.json b/integration-tests/smoke/automation_test.go_test_list.json index e8f0f838dfd..f0b8a1cb603 100644 --- a/integration-tests/smoke/automation_test.go_test_list.json +++ b/integration-tests/smoke/automation_test.go_test_list.json @@ -35,6 +35,13 @@ {"name":"registry_2_2_with_logtrigger_and_mercury_v02"} ] }, + { + "name": "TestAutomationBasic", + "nodes": 1, + "run":[ + {"name":"registry_2_3_conditional"} + ] + }, { "name": "TestSetUpkeepTriggerConfig", "nodes": 2