diff --git a/Makefile b/Makefile
index e0bb2030f..a378eaab7 100644
--- a/Makefile
+++ b/Makefile
@@ -20,9 +20,12 @@ core/test_segment.go:
 	core/test_segment.sh core/test_segment.go
 
 eth/contracts/chainlink/AggregatorInterface.go eth/contracts/chainlink/AggregatorV2V3Interface.go eth/contracts/chainlink/AggregatorV3Interface.go:
-	@for sol_file in eth/contracts/chainlink/*.sol; do \
+	@set -ex; \
+	solc --version | grep 0.8.9+commit.e5eed63a; \
+	for sol_file in eth/contracts/chainlink/*.sol; do \
+		contract_name=$$(basename "$$sol_file" .sol); \
 		solc --abi --optimize --overwrite -o $$(dirname "$$sol_file") $$sol_file; \
-		$(ABIGEN) --abi=$$abi_file --pkg=chainlink --out=$${sol_file%.sol}.go; \
+		$(ABIGEN) --abi=$${sol_file%.sol}.abi --pkg=chainlink --type=$$contract_name --out=$${sol_file%.sol}.go; \
 	done
 
 version=$(shell cat VERSION)
diff --git a/eth/contracts/chainlink/AggregatorInterface.go b/eth/contracts/chainlink/AggregatorInterface.go
index 7657cc536..01b79f25e 100644
--- a/eth/contracts/chainlink/AggregatorInterface.go
+++ b/eth/contracts/chainlink/AggregatorInterface.go
@@ -28,3 +28,617 @@ var (
 	_ = event.NewSubscription
 	_ = abi.ConvertType
 )
+
+// AggregatorInterfaceMetaData contains all meta data concerning the AggregatorInterface contract.
+var AggregatorInterfaceMetaData = &bind.MetaData{
+	ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int256\",\"name\":\"current\",\"type\":\"int256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"}],\"name\":\"AnswerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"startedBy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"}],\"name\":\"NewRound\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"}],\"name\":\"getAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"}],\"name\":\"getTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRound\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
+}
+
+// AggregatorInterfaceABI is the input ABI used to generate the binding from.
+// Deprecated: Use AggregatorInterfaceMetaData.ABI instead.
+var AggregatorInterfaceABI = AggregatorInterfaceMetaData.ABI
+
+// AggregatorInterface is an auto generated Go binding around an Ethereum contract.
+type AggregatorInterface struct {
+	AggregatorInterfaceCaller     // Read-only binding to the contract
+	AggregatorInterfaceTransactor // Write-only binding to the contract
+	AggregatorInterfaceFilterer   // Log filterer for contract events
+}
+
+// AggregatorInterfaceCaller is an auto generated read-only Go binding around an Ethereum contract.
+type AggregatorInterfaceCaller struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AggregatorInterfaceTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type AggregatorInterfaceTransactor struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AggregatorInterfaceFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type AggregatorInterfaceFilterer struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AggregatorInterfaceSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type AggregatorInterfaceSession struct {
+	Contract     *AggregatorInterface // Generic contract binding to set the session for
+	CallOpts     bind.CallOpts        // Call options to use throughout this session
+	TransactOpts bind.TransactOpts    // Transaction auth options to use throughout this session
+}
+
+// AggregatorInterfaceCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type AggregatorInterfaceCallerSession struct {
+	Contract *AggregatorInterfaceCaller // Generic contract caller binding to set the session for
+	CallOpts bind.CallOpts              // Call options to use throughout this session
+}
+
+// AggregatorInterfaceTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type AggregatorInterfaceTransactorSession struct {
+	Contract     *AggregatorInterfaceTransactor // Generic contract transactor binding to set the session for
+	TransactOpts bind.TransactOpts              // Transaction auth options to use throughout this session
+}
+
+// AggregatorInterfaceRaw is an auto generated low-level Go binding around an Ethereum contract.
+type AggregatorInterfaceRaw struct {
+	Contract *AggregatorInterface // Generic contract binding to access the raw methods on
+}
+
+// AggregatorInterfaceCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type AggregatorInterfaceCallerRaw struct {
+	Contract *AggregatorInterfaceCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// AggregatorInterfaceTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type AggregatorInterfaceTransactorRaw struct {
+	Contract *AggregatorInterfaceTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewAggregatorInterface creates a new instance of AggregatorInterface, bound to a specific deployed contract.
+func NewAggregatorInterface(address common.Address, backend bind.ContractBackend) (*AggregatorInterface, error) {
+	contract, err := bindAggregatorInterface(address, backend, backend, backend)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorInterface{AggregatorInterfaceCaller: AggregatorInterfaceCaller{contract: contract}, AggregatorInterfaceTransactor: AggregatorInterfaceTransactor{contract: contract}, AggregatorInterfaceFilterer: AggregatorInterfaceFilterer{contract: contract}}, nil
+}
+
+// NewAggregatorInterfaceCaller creates a new read-only instance of AggregatorInterface, bound to a specific deployed contract.
+func NewAggregatorInterfaceCaller(address common.Address, caller bind.ContractCaller) (*AggregatorInterfaceCaller, error) {
+	contract, err := bindAggregatorInterface(address, caller, nil, nil)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorInterfaceCaller{contract: contract}, nil
+}
+
+// NewAggregatorInterfaceTransactor creates a new write-only instance of AggregatorInterface, bound to a specific deployed contract.
+func NewAggregatorInterfaceTransactor(address common.Address, transactor bind.ContractTransactor) (*AggregatorInterfaceTransactor, error) {
+	contract, err := bindAggregatorInterface(address, nil, transactor, nil)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorInterfaceTransactor{contract: contract}, nil
+}
+
+// NewAggregatorInterfaceFilterer creates a new log filterer instance of AggregatorInterface, bound to a specific deployed contract.
+func NewAggregatorInterfaceFilterer(address common.Address, filterer bind.ContractFilterer) (*AggregatorInterfaceFilterer, error) {
+	contract, err := bindAggregatorInterface(address, nil, nil, filterer)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorInterfaceFilterer{contract: contract}, nil
+}
+
+// bindAggregatorInterface binds a generic wrapper to an already deployed contract.
+func bindAggregatorInterface(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+	parsed, err := AggregatorInterfaceMetaData.GetAbi()
+	if err != nil {
+		return nil, err
+	}
+	return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_AggregatorInterface *AggregatorInterfaceRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+	return _AggregatorInterface.Contract.AggregatorInterfaceCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_AggregatorInterface *AggregatorInterfaceRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _AggregatorInterface.Contract.AggregatorInterfaceTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_AggregatorInterface *AggregatorInterfaceRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+	return _AggregatorInterface.Contract.AggregatorInterfaceTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_AggregatorInterface *AggregatorInterfaceCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+	return _AggregatorInterface.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_AggregatorInterface *AggregatorInterfaceTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _AggregatorInterface.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_AggregatorInterface *AggregatorInterfaceTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+	return _AggregatorInterface.Contract.contract.Transact(opts, method, params...)
+}
+
+// GetAnswer is a free data retrieval call binding the contract method 0xb5ab58dc.
+//
+// Solidity: function getAnswer(uint256 roundId) view returns(int256)
+func (_AggregatorInterface *AggregatorInterfaceCaller) GetAnswer(opts *bind.CallOpts, roundId *big.Int) (*big.Int, error) {
+	var out []interface{}
+	err := _AggregatorInterface.contract.Call(opts, &out, "getAnswer", roundId)
+
+	if err != nil {
+		return *new(*big.Int), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+	return out0, err
+
+}
+
+// GetAnswer is a free data retrieval call binding the contract method 0xb5ab58dc.
+//
+// Solidity: function getAnswer(uint256 roundId) view returns(int256)
+func (_AggregatorInterface *AggregatorInterfaceSession) GetAnswer(roundId *big.Int) (*big.Int, error) {
+	return _AggregatorInterface.Contract.GetAnswer(&_AggregatorInterface.CallOpts, roundId)
+}
+
+// GetAnswer is a free data retrieval call binding the contract method 0xb5ab58dc.
+//
+// Solidity: function getAnswer(uint256 roundId) view returns(int256)
+func (_AggregatorInterface *AggregatorInterfaceCallerSession) GetAnswer(roundId *big.Int) (*big.Int, error) {
+	return _AggregatorInterface.Contract.GetAnswer(&_AggregatorInterface.CallOpts, roundId)
+}
+
+// GetTimestamp is a free data retrieval call binding the contract method 0xb633620c.
+//
+// Solidity: function getTimestamp(uint256 roundId) view returns(uint256)
+func (_AggregatorInterface *AggregatorInterfaceCaller) GetTimestamp(opts *bind.CallOpts, roundId *big.Int) (*big.Int, error) {
+	var out []interface{}
+	err := _AggregatorInterface.contract.Call(opts, &out, "getTimestamp", roundId)
+
+	if err != nil {
+		return *new(*big.Int), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+	return out0, err
+
+}
+
+// GetTimestamp is a free data retrieval call binding the contract method 0xb633620c.
+//
+// Solidity: function getTimestamp(uint256 roundId) view returns(uint256)
+func (_AggregatorInterface *AggregatorInterfaceSession) GetTimestamp(roundId *big.Int) (*big.Int, error) {
+	return _AggregatorInterface.Contract.GetTimestamp(&_AggregatorInterface.CallOpts, roundId)
+}
+
+// GetTimestamp is a free data retrieval call binding the contract method 0xb633620c.
+//
+// Solidity: function getTimestamp(uint256 roundId) view returns(uint256)
+func (_AggregatorInterface *AggregatorInterfaceCallerSession) GetTimestamp(roundId *big.Int) (*big.Int, error) {
+	return _AggregatorInterface.Contract.GetTimestamp(&_AggregatorInterface.CallOpts, roundId)
+}
+
+// LatestAnswer is a free data retrieval call binding the contract method 0x50d25bcd.
+//
+// Solidity: function latestAnswer() view returns(int256)
+func (_AggregatorInterface *AggregatorInterfaceCaller) LatestAnswer(opts *bind.CallOpts) (*big.Int, error) {
+	var out []interface{}
+	err := _AggregatorInterface.contract.Call(opts, &out, "latestAnswer")
+
+	if err != nil {
+		return *new(*big.Int), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+	return out0, err
+
+}
+
+// LatestAnswer is a free data retrieval call binding the contract method 0x50d25bcd.
+//
+// Solidity: function latestAnswer() view returns(int256)
+func (_AggregatorInterface *AggregatorInterfaceSession) LatestAnswer() (*big.Int, error) {
+	return _AggregatorInterface.Contract.LatestAnswer(&_AggregatorInterface.CallOpts)
+}
+
+// LatestAnswer is a free data retrieval call binding the contract method 0x50d25bcd.
+//
+// Solidity: function latestAnswer() view returns(int256)
+func (_AggregatorInterface *AggregatorInterfaceCallerSession) LatestAnswer() (*big.Int, error) {
+	return _AggregatorInterface.Contract.LatestAnswer(&_AggregatorInterface.CallOpts)
+}
+
+// LatestRound is a free data retrieval call binding the contract method 0x668a0f02.
+//
+// Solidity: function latestRound() view returns(uint256)
+func (_AggregatorInterface *AggregatorInterfaceCaller) LatestRound(opts *bind.CallOpts) (*big.Int, error) {
+	var out []interface{}
+	err := _AggregatorInterface.contract.Call(opts, &out, "latestRound")
+
+	if err != nil {
+		return *new(*big.Int), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+	return out0, err
+
+}
+
+// LatestRound is a free data retrieval call binding the contract method 0x668a0f02.
+//
+// Solidity: function latestRound() view returns(uint256)
+func (_AggregatorInterface *AggregatorInterfaceSession) LatestRound() (*big.Int, error) {
+	return _AggregatorInterface.Contract.LatestRound(&_AggregatorInterface.CallOpts)
+}
+
+// LatestRound is a free data retrieval call binding the contract method 0x668a0f02.
+//
+// Solidity: function latestRound() view returns(uint256)
+func (_AggregatorInterface *AggregatorInterfaceCallerSession) LatestRound() (*big.Int, error) {
+	return _AggregatorInterface.Contract.LatestRound(&_AggregatorInterface.CallOpts)
+}
+
+// LatestTimestamp is a free data retrieval call binding the contract method 0x8205bf6a.
+//
+// Solidity: function latestTimestamp() view returns(uint256)
+func (_AggregatorInterface *AggregatorInterfaceCaller) LatestTimestamp(opts *bind.CallOpts) (*big.Int, error) {
+	var out []interface{}
+	err := _AggregatorInterface.contract.Call(opts, &out, "latestTimestamp")
+
+	if err != nil {
+		return *new(*big.Int), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+	return out0, err
+
+}
+
+// LatestTimestamp is a free data retrieval call binding the contract method 0x8205bf6a.
+//
+// Solidity: function latestTimestamp() view returns(uint256)
+func (_AggregatorInterface *AggregatorInterfaceSession) LatestTimestamp() (*big.Int, error) {
+	return _AggregatorInterface.Contract.LatestTimestamp(&_AggregatorInterface.CallOpts)
+}
+
+// LatestTimestamp is a free data retrieval call binding the contract method 0x8205bf6a.
+//
+// Solidity: function latestTimestamp() view returns(uint256)
+func (_AggregatorInterface *AggregatorInterfaceCallerSession) LatestTimestamp() (*big.Int, error) {
+	return _AggregatorInterface.Contract.LatestTimestamp(&_AggregatorInterface.CallOpts)
+}
+
+// AggregatorInterfaceAnswerUpdatedIterator is returned from FilterAnswerUpdated and is used to iterate over the raw logs and unpacked data for AnswerUpdated events raised by the AggregatorInterface contract.
+type AggregatorInterfaceAnswerUpdatedIterator struct {
+	Event *AggregatorInterfaceAnswerUpdated // Event containing the contract specifics and raw log
+
+	contract *bind.BoundContract // Generic contract to use for unpacking event data
+	event    string              // Event name to use for unpacking event data
+
+	logs chan types.Log        // Log channel receiving the found contract events
+	sub  ethereum.Subscription // Subscription for errors, completion and termination
+	done bool                  // Whether the subscription completed delivering logs
+	fail error                 // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *AggregatorInterfaceAnswerUpdatedIterator) Next() bool {
+	// If the iterator failed, stop iterating
+	if it.fail != nil {
+		return false
+	}
+	// If the iterator completed, deliver directly whatever's available
+	if it.done {
+		select {
+		case log := <-it.logs:
+			it.Event = new(AggregatorInterfaceAnswerUpdated)
+			if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+				it.fail = err
+				return false
+			}
+			it.Event.Raw = log
+			return true
+
+		default:
+			return false
+		}
+	}
+	// Iterator still in progress, wait for either a data or an error event
+	select {
+	case log := <-it.logs:
+		it.Event = new(AggregatorInterfaceAnswerUpdated)
+		if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+			it.fail = err
+			return false
+		}
+		it.Event.Raw = log
+		return true
+
+	case err := <-it.sub.Err():
+		it.done = true
+		it.fail = err
+		return it.Next()
+	}
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *AggregatorInterfaceAnswerUpdatedIterator) Error() error {
+	return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *AggregatorInterfaceAnswerUpdatedIterator) Close() error {
+	it.sub.Unsubscribe()
+	return nil
+}
+
+// AggregatorInterfaceAnswerUpdated represents a AnswerUpdated event raised by the AggregatorInterface contract.
+type AggregatorInterfaceAnswerUpdated struct {
+	Current   *big.Int
+	RoundId   *big.Int
+	UpdatedAt *big.Int
+	Raw       types.Log // Blockchain specific contextual infos
+}
+
+// FilterAnswerUpdated is a free log retrieval operation binding the contract event 0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f.
+//
+// Solidity: event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt)
+func (_AggregatorInterface *AggregatorInterfaceFilterer) FilterAnswerUpdated(opts *bind.FilterOpts, current []*big.Int, roundId []*big.Int) (*AggregatorInterfaceAnswerUpdatedIterator, error) {
+
+	var currentRule []interface{}
+	for _, currentItem := range current {
+		currentRule = append(currentRule, currentItem)
+	}
+	var roundIdRule []interface{}
+	for _, roundIdItem := range roundId {
+		roundIdRule = append(roundIdRule, roundIdItem)
+	}
+
+	logs, sub, err := _AggregatorInterface.contract.FilterLogs(opts, "AnswerUpdated", currentRule, roundIdRule)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorInterfaceAnswerUpdatedIterator{contract: _AggregatorInterface.contract, event: "AnswerUpdated", logs: logs, sub: sub}, nil
+}
+
+// WatchAnswerUpdated is a free log subscription operation binding the contract event 0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f.
+//
+// Solidity: event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt)
+func (_AggregatorInterface *AggregatorInterfaceFilterer) WatchAnswerUpdated(opts *bind.WatchOpts, sink chan<- *AggregatorInterfaceAnswerUpdated, current []*big.Int, roundId []*big.Int) (event.Subscription, error) {
+
+	var currentRule []interface{}
+	for _, currentItem := range current {
+		currentRule = append(currentRule, currentItem)
+	}
+	var roundIdRule []interface{}
+	for _, roundIdItem := range roundId {
+		roundIdRule = append(roundIdRule, roundIdItem)
+	}
+
+	logs, sub, err := _AggregatorInterface.contract.WatchLogs(opts, "AnswerUpdated", currentRule, roundIdRule)
+	if err != nil {
+		return nil, err
+	}
+	return event.NewSubscription(func(quit <-chan struct{}) error {
+		defer sub.Unsubscribe()
+		for {
+			select {
+			case log := <-logs:
+				// New log arrived, parse the event and forward to the user
+				event := new(AggregatorInterfaceAnswerUpdated)
+				if err := _AggregatorInterface.contract.UnpackLog(event, "AnswerUpdated", 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
+}
+
+// ParseAnswerUpdated is a log parse operation binding the contract event 0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f.
+//
+// Solidity: event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt)
+func (_AggregatorInterface *AggregatorInterfaceFilterer) ParseAnswerUpdated(log types.Log) (*AggregatorInterfaceAnswerUpdated, error) {
+	event := new(AggregatorInterfaceAnswerUpdated)
+	if err := _AggregatorInterface.contract.UnpackLog(event, "AnswerUpdated", log); err != nil {
+		return nil, err
+	}
+	event.Raw = log
+	return event, nil
+}
+
+// AggregatorInterfaceNewRoundIterator is returned from FilterNewRound and is used to iterate over the raw logs and unpacked data for NewRound events raised by the AggregatorInterface contract.
+type AggregatorInterfaceNewRoundIterator struct {
+	Event *AggregatorInterfaceNewRound // Event containing the contract specifics and raw log
+
+	contract *bind.BoundContract // Generic contract to use for unpacking event data
+	event    string              // Event name to use for unpacking event data
+
+	logs chan types.Log        // Log channel receiving the found contract events
+	sub  ethereum.Subscription // Subscription for errors, completion and termination
+	done bool                  // Whether the subscription completed delivering logs
+	fail error                 // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *AggregatorInterfaceNewRoundIterator) Next() bool {
+	// If the iterator failed, stop iterating
+	if it.fail != nil {
+		return false
+	}
+	// If the iterator completed, deliver directly whatever's available
+	if it.done {
+		select {
+		case log := <-it.logs:
+			it.Event = new(AggregatorInterfaceNewRound)
+			if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+				it.fail = err
+				return false
+			}
+			it.Event.Raw = log
+			return true
+
+		default:
+			return false
+		}
+	}
+	// Iterator still in progress, wait for either a data or an error event
+	select {
+	case log := <-it.logs:
+		it.Event = new(AggregatorInterfaceNewRound)
+		if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+			it.fail = err
+			return false
+		}
+		it.Event.Raw = log
+		return true
+
+	case err := <-it.sub.Err():
+		it.done = true
+		it.fail = err
+		return it.Next()
+	}
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *AggregatorInterfaceNewRoundIterator) Error() error {
+	return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *AggregatorInterfaceNewRoundIterator) Close() error {
+	it.sub.Unsubscribe()
+	return nil
+}
+
+// AggregatorInterfaceNewRound represents a NewRound event raised by the AggregatorInterface contract.
+type AggregatorInterfaceNewRound struct {
+	RoundId   *big.Int
+	StartedBy common.Address
+	StartedAt *big.Int
+	Raw       types.Log // Blockchain specific contextual infos
+}
+
+// FilterNewRound is a free log retrieval operation binding the contract event 0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271.
+//
+// Solidity: event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt)
+func (_AggregatorInterface *AggregatorInterfaceFilterer) FilterNewRound(opts *bind.FilterOpts, roundId []*big.Int, startedBy []common.Address) (*AggregatorInterfaceNewRoundIterator, error) {
+
+	var roundIdRule []interface{}
+	for _, roundIdItem := range roundId {
+		roundIdRule = append(roundIdRule, roundIdItem)
+	}
+	var startedByRule []interface{}
+	for _, startedByItem := range startedBy {
+		startedByRule = append(startedByRule, startedByItem)
+	}
+
+	logs, sub, err := _AggregatorInterface.contract.FilterLogs(opts, "NewRound", roundIdRule, startedByRule)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorInterfaceNewRoundIterator{contract: _AggregatorInterface.contract, event: "NewRound", logs: logs, sub: sub}, nil
+}
+
+// WatchNewRound is a free log subscription operation binding the contract event 0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271.
+//
+// Solidity: event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt)
+func (_AggregatorInterface *AggregatorInterfaceFilterer) WatchNewRound(opts *bind.WatchOpts, sink chan<- *AggregatorInterfaceNewRound, roundId []*big.Int, startedBy []common.Address) (event.Subscription, error) {
+
+	var roundIdRule []interface{}
+	for _, roundIdItem := range roundId {
+		roundIdRule = append(roundIdRule, roundIdItem)
+	}
+	var startedByRule []interface{}
+	for _, startedByItem := range startedBy {
+		startedByRule = append(startedByRule, startedByItem)
+	}
+
+	logs, sub, err := _AggregatorInterface.contract.WatchLogs(opts, "NewRound", roundIdRule, startedByRule)
+	if err != nil {
+		return nil, err
+	}
+	return event.NewSubscription(func(quit <-chan struct{}) error {
+		defer sub.Unsubscribe()
+		for {
+			select {
+			case log := <-logs:
+				// New log arrived, parse the event and forward to the user
+				event := new(AggregatorInterfaceNewRound)
+				if err := _AggregatorInterface.contract.UnpackLog(event, "NewRound", 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
+}
+
+// ParseNewRound is a log parse operation binding the contract event 0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271.
+//
+// Solidity: event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt)
+func (_AggregatorInterface *AggregatorInterfaceFilterer) ParseNewRound(log types.Log) (*AggregatorInterfaceNewRound, error) {
+	event := new(AggregatorInterfaceNewRound)
+	if err := _AggregatorInterface.contract.UnpackLog(event, "NewRound", log); err != nil {
+		return nil, err
+	}
+	event.Raw = log
+	return event, nil
+}
diff --git a/eth/contracts/chainlink/AggregatorV2V3Interface.go b/eth/contracts/chainlink/AggregatorV2V3Interface.go
index 7657cc536..e426c6f35 100644
--- a/eth/contracts/chainlink/AggregatorV2V3Interface.go
+++ b/eth/contracts/chainlink/AggregatorV2V3Interface.go
@@ -28,3 +28,830 @@ var (
 	_ = event.NewSubscription
 	_ = abi.ConvertType
 )
+
+// AggregatorV2V3InterfaceMetaData contains all meta data concerning the AggregatorV2V3Interface contract.
+var AggregatorV2V3InterfaceMetaData = &bind.MetaData{
+	ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"int256\",\"name\":\"current\",\"type\":\"int256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"}],\"name\":\"AnswerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"startedBy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"startedAt\",\"type\":\"uint256\"}],\"name\":\"NewRound\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"description\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"roundId\",\"type\":\"uint256\"}],\"name\":\"getAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint80\",\"name\":\"_roundId\",\"type\":\"uint80\"}],\"name\":\"getRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"answer\",\"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\":\"roundId\",\"type\":\"uint256\"}],\"name\":\"getTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRound\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"answer\",\"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\":\"latestTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
+}
+
+// AggregatorV2V3InterfaceABI is the input ABI used to generate the binding from.
+// Deprecated: Use AggregatorV2V3InterfaceMetaData.ABI instead.
+var AggregatorV2V3InterfaceABI = AggregatorV2V3InterfaceMetaData.ABI
+
+// AggregatorV2V3Interface is an auto generated Go binding around an Ethereum contract.
+type AggregatorV2V3Interface struct {
+	AggregatorV2V3InterfaceCaller     // Read-only binding to the contract
+	AggregatorV2V3InterfaceTransactor // Write-only binding to the contract
+	AggregatorV2V3InterfaceFilterer   // Log filterer for contract events
+}
+
+// AggregatorV2V3InterfaceCaller is an auto generated read-only Go binding around an Ethereum contract.
+type AggregatorV2V3InterfaceCaller struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AggregatorV2V3InterfaceTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type AggregatorV2V3InterfaceTransactor struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AggregatorV2V3InterfaceFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type AggregatorV2V3InterfaceFilterer struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AggregatorV2V3InterfaceSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type AggregatorV2V3InterfaceSession struct {
+	Contract     *AggregatorV2V3Interface // Generic contract binding to set the session for
+	CallOpts     bind.CallOpts            // Call options to use throughout this session
+	TransactOpts bind.TransactOpts        // Transaction auth options to use throughout this session
+}
+
+// AggregatorV2V3InterfaceCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type AggregatorV2V3InterfaceCallerSession struct {
+	Contract *AggregatorV2V3InterfaceCaller // Generic contract caller binding to set the session for
+	CallOpts bind.CallOpts                  // Call options to use throughout this session
+}
+
+// AggregatorV2V3InterfaceTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type AggregatorV2V3InterfaceTransactorSession struct {
+	Contract     *AggregatorV2V3InterfaceTransactor // Generic contract transactor binding to set the session for
+	TransactOpts bind.TransactOpts                  // Transaction auth options to use throughout this session
+}
+
+// AggregatorV2V3InterfaceRaw is an auto generated low-level Go binding around an Ethereum contract.
+type AggregatorV2V3InterfaceRaw struct {
+	Contract *AggregatorV2V3Interface // Generic contract binding to access the raw methods on
+}
+
+// AggregatorV2V3InterfaceCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type AggregatorV2V3InterfaceCallerRaw struct {
+	Contract *AggregatorV2V3InterfaceCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// AggregatorV2V3InterfaceTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type AggregatorV2V3InterfaceTransactorRaw struct {
+	Contract *AggregatorV2V3InterfaceTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewAggregatorV2V3Interface creates a new instance of AggregatorV2V3Interface, bound to a specific deployed contract.
+func NewAggregatorV2V3Interface(address common.Address, backend bind.ContractBackend) (*AggregatorV2V3Interface, error) {
+	contract, err := bindAggregatorV2V3Interface(address, backend, backend, backend)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorV2V3Interface{AggregatorV2V3InterfaceCaller: AggregatorV2V3InterfaceCaller{contract: contract}, AggregatorV2V3InterfaceTransactor: AggregatorV2V3InterfaceTransactor{contract: contract}, AggregatorV2V3InterfaceFilterer: AggregatorV2V3InterfaceFilterer{contract: contract}}, nil
+}
+
+// NewAggregatorV2V3InterfaceCaller creates a new read-only instance of AggregatorV2V3Interface, bound to a specific deployed contract.
+func NewAggregatorV2V3InterfaceCaller(address common.Address, caller bind.ContractCaller) (*AggregatorV2V3InterfaceCaller, error) {
+	contract, err := bindAggregatorV2V3Interface(address, caller, nil, nil)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorV2V3InterfaceCaller{contract: contract}, nil
+}
+
+// NewAggregatorV2V3InterfaceTransactor creates a new write-only instance of AggregatorV2V3Interface, bound to a specific deployed contract.
+func NewAggregatorV2V3InterfaceTransactor(address common.Address, transactor bind.ContractTransactor) (*AggregatorV2V3InterfaceTransactor, error) {
+	contract, err := bindAggregatorV2V3Interface(address, nil, transactor, nil)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorV2V3InterfaceTransactor{contract: contract}, nil
+}
+
+// NewAggregatorV2V3InterfaceFilterer creates a new log filterer instance of AggregatorV2V3Interface, bound to a specific deployed contract.
+func NewAggregatorV2V3InterfaceFilterer(address common.Address, filterer bind.ContractFilterer) (*AggregatorV2V3InterfaceFilterer, error) {
+	contract, err := bindAggregatorV2V3Interface(address, nil, nil, filterer)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorV2V3InterfaceFilterer{contract: contract}, nil
+}
+
+// bindAggregatorV2V3Interface binds a generic wrapper to an already deployed contract.
+func bindAggregatorV2V3Interface(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+	parsed, err := AggregatorV2V3InterfaceMetaData.GetAbi()
+	if err != nil {
+		return nil, err
+	}
+	return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+	return _AggregatorV2V3Interface.Contract.AggregatorV2V3InterfaceCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _AggregatorV2V3Interface.Contract.AggregatorV2V3InterfaceTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+	return _AggregatorV2V3Interface.Contract.AggregatorV2V3InterfaceTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+	return _AggregatorV2V3Interface.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _AggregatorV2V3Interface.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+	return _AggregatorV2V3Interface.Contract.contract.Transact(opts, method, params...)
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() view returns(uint8)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCaller) Decimals(opts *bind.CallOpts) (uint8, error) {
+	var out []interface{}
+	err := _AggregatorV2V3Interface.contract.Call(opts, &out, "decimals")
+
+	if err != nil {
+		return *new(uint8), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
+
+	return out0, err
+
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() view returns(uint8)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceSession) Decimals() (uint8, error) {
+	return _AggregatorV2V3Interface.Contract.Decimals(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() view returns(uint8)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCallerSession) Decimals() (uint8, error) {
+	return _AggregatorV2V3Interface.Contract.Decimals(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// Description is a free data retrieval call binding the contract method 0x7284e416.
+//
+// Solidity: function description() view returns(string)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCaller) Description(opts *bind.CallOpts) (string, error) {
+	var out []interface{}
+	err := _AggregatorV2V3Interface.contract.Call(opts, &out, "description")
+
+	if err != nil {
+		return *new(string), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+	return out0, err
+
+}
+
+// Description is a free data retrieval call binding the contract method 0x7284e416.
+//
+// Solidity: function description() view returns(string)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceSession) Description() (string, error) {
+	return _AggregatorV2V3Interface.Contract.Description(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// Description is a free data retrieval call binding the contract method 0x7284e416.
+//
+// Solidity: function description() view returns(string)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCallerSession) Description() (string, error) {
+	return _AggregatorV2V3Interface.Contract.Description(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// GetAnswer is a free data retrieval call binding the contract method 0xb5ab58dc.
+//
+// Solidity: function getAnswer(uint256 roundId) view returns(int256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCaller) GetAnswer(opts *bind.CallOpts, roundId *big.Int) (*big.Int, error) {
+	var out []interface{}
+	err := _AggregatorV2V3Interface.contract.Call(opts, &out, "getAnswer", roundId)
+
+	if err != nil {
+		return *new(*big.Int), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+	return out0, err
+
+}
+
+// GetAnswer is a free data retrieval call binding the contract method 0xb5ab58dc.
+//
+// Solidity: function getAnswer(uint256 roundId) view returns(int256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceSession) GetAnswer(roundId *big.Int) (*big.Int, error) {
+	return _AggregatorV2V3Interface.Contract.GetAnswer(&_AggregatorV2V3Interface.CallOpts, roundId)
+}
+
+// GetAnswer is a free data retrieval call binding the contract method 0xb5ab58dc.
+//
+// Solidity: function getAnswer(uint256 roundId) view returns(int256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCallerSession) GetAnswer(roundId *big.Int) (*big.Int, error) {
+	return _AggregatorV2V3Interface.Contract.GetAnswer(&_AggregatorV2V3Interface.CallOpts, roundId)
+}
+
+// GetRoundData is a free data retrieval call binding the contract method 0x9a6fc8f5.
+//
+// Solidity: function getRoundData(uint80 _roundId) view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCaller) GetRoundData(opts *bind.CallOpts, _roundId *big.Int) (struct {
+	RoundId         *big.Int
+	Answer          *big.Int
+	StartedAt       *big.Int
+	UpdatedAt       *big.Int
+	AnsweredInRound *big.Int
+}, error) {
+	var out []interface{}
+	err := _AggregatorV2V3Interface.contract.Call(opts, &out, "getRoundData", _roundId)
+
+	outstruct := new(struct {
+		RoundId         *big.Int
+		Answer          *big.Int
+		StartedAt       *big.Int
+		UpdatedAt       *big.Int
+		AnsweredInRound *big.Int
+	})
+	if err != nil {
+		return *outstruct, err
+	}
+
+	outstruct.RoundId = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+	outstruct.Answer = *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
+
+}
+
+// GetRoundData is a free data retrieval call binding the contract method 0x9a6fc8f5.
+//
+// Solidity: function getRoundData(uint80 _roundId) view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceSession) GetRoundData(_roundId *big.Int) (struct {
+	RoundId         *big.Int
+	Answer          *big.Int
+	StartedAt       *big.Int
+	UpdatedAt       *big.Int
+	AnsweredInRound *big.Int
+}, error) {
+	return _AggregatorV2V3Interface.Contract.GetRoundData(&_AggregatorV2V3Interface.CallOpts, _roundId)
+}
+
+// GetRoundData is a free data retrieval call binding the contract method 0x9a6fc8f5.
+//
+// Solidity: function getRoundData(uint80 _roundId) view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCallerSession) GetRoundData(_roundId *big.Int) (struct {
+	RoundId         *big.Int
+	Answer          *big.Int
+	StartedAt       *big.Int
+	UpdatedAt       *big.Int
+	AnsweredInRound *big.Int
+}, error) {
+	return _AggregatorV2V3Interface.Contract.GetRoundData(&_AggregatorV2V3Interface.CallOpts, _roundId)
+}
+
+// GetTimestamp is a free data retrieval call binding the contract method 0xb633620c.
+//
+// Solidity: function getTimestamp(uint256 roundId) view returns(uint256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCaller) GetTimestamp(opts *bind.CallOpts, roundId *big.Int) (*big.Int, error) {
+	var out []interface{}
+	err := _AggregatorV2V3Interface.contract.Call(opts, &out, "getTimestamp", roundId)
+
+	if err != nil {
+		return *new(*big.Int), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+	return out0, err
+
+}
+
+// GetTimestamp is a free data retrieval call binding the contract method 0xb633620c.
+//
+// Solidity: function getTimestamp(uint256 roundId) view returns(uint256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceSession) GetTimestamp(roundId *big.Int) (*big.Int, error) {
+	return _AggregatorV2V3Interface.Contract.GetTimestamp(&_AggregatorV2V3Interface.CallOpts, roundId)
+}
+
+// GetTimestamp is a free data retrieval call binding the contract method 0xb633620c.
+//
+// Solidity: function getTimestamp(uint256 roundId) view returns(uint256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCallerSession) GetTimestamp(roundId *big.Int) (*big.Int, error) {
+	return _AggregatorV2V3Interface.Contract.GetTimestamp(&_AggregatorV2V3Interface.CallOpts, roundId)
+}
+
+// LatestAnswer is a free data retrieval call binding the contract method 0x50d25bcd.
+//
+// Solidity: function latestAnswer() view returns(int256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCaller) LatestAnswer(opts *bind.CallOpts) (*big.Int, error) {
+	var out []interface{}
+	err := _AggregatorV2V3Interface.contract.Call(opts, &out, "latestAnswer")
+
+	if err != nil {
+		return *new(*big.Int), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+	return out0, err
+
+}
+
+// LatestAnswer is a free data retrieval call binding the contract method 0x50d25bcd.
+//
+// Solidity: function latestAnswer() view returns(int256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceSession) LatestAnswer() (*big.Int, error) {
+	return _AggregatorV2V3Interface.Contract.LatestAnswer(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// LatestAnswer is a free data retrieval call binding the contract method 0x50d25bcd.
+//
+// Solidity: function latestAnswer() view returns(int256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCallerSession) LatestAnswer() (*big.Int, error) {
+	return _AggregatorV2V3Interface.Contract.LatestAnswer(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// LatestRound is a free data retrieval call binding the contract method 0x668a0f02.
+//
+// Solidity: function latestRound() view returns(uint256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCaller) LatestRound(opts *bind.CallOpts) (*big.Int, error) {
+	var out []interface{}
+	err := _AggregatorV2V3Interface.contract.Call(opts, &out, "latestRound")
+
+	if err != nil {
+		return *new(*big.Int), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+	return out0, err
+
+}
+
+// LatestRound is a free data retrieval call binding the contract method 0x668a0f02.
+//
+// Solidity: function latestRound() view returns(uint256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceSession) LatestRound() (*big.Int, error) {
+	return _AggregatorV2V3Interface.Contract.LatestRound(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// LatestRound is a free data retrieval call binding the contract method 0x668a0f02.
+//
+// Solidity: function latestRound() view returns(uint256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCallerSession) LatestRound() (*big.Int, error) {
+	return _AggregatorV2V3Interface.Contract.LatestRound(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// LatestRoundData is a free data retrieval call binding the contract method 0xfeaf968c.
+//
+// Solidity: function latestRoundData() view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCaller) LatestRoundData(opts *bind.CallOpts) (struct {
+	RoundId         *big.Int
+	Answer          *big.Int
+	StartedAt       *big.Int
+	UpdatedAt       *big.Int
+	AnsweredInRound *big.Int
+}, error) {
+	var out []interface{}
+	err := _AggregatorV2V3Interface.contract.Call(opts, &out, "latestRoundData")
+
+	outstruct := new(struct {
+		RoundId         *big.Int
+		Answer          *big.Int
+		StartedAt       *big.Int
+		UpdatedAt       *big.Int
+		AnsweredInRound *big.Int
+	})
+	if err != nil {
+		return *outstruct, err
+	}
+
+	outstruct.RoundId = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+	outstruct.Answer = *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
+
+}
+
+// LatestRoundData is a free data retrieval call binding the contract method 0xfeaf968c.
+//
+// Solidity: function latestRoundData() view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceSession) LatestRoundData() (struct {
+	RoundId         *big.Int
+	Answer          *big.Int
+	StartedAt       *big.Int
+	UpdatedAt       *big.Int
+	AnsweredInRound *big.Int
+}, error) {
+	return _AggregatorV2V3Interface.Contract.LatestRoundData(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// LatestRoundData is a free data retrieval call binding the contract method 0xfeaf968c.
+//
+// Solidity: function latestRoundData() view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCallerSession) LatestRoundData() (struct {
+	RoundId         *big.Int
+	Answer          *big.Int
+	StartedAt       *big.Int
+	UpdatedAt       *big.Int
+	AnsweredInRound *big.Int
+}, error) {
+	return _AggregatorV2V3Interface.Contract.LatestRoundData(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// LatestTimestamp is a free data retrieval call binding the contract method 0x8205bf6a.
+//
+// Solidity: function latestTimestamp() view returns(uint256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCaller) LatestTimestamp(opts *bind.CallOpts) (*big.Int, error) {
+	var out []interface{}
+	err := _AggregatorV2V3Interface.contract.Call(opts, &out, "latestTimestamp")
+
+	if err != nil {
+		return *new(*big.Int), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+
+	return out0, err
+
+}
+
+// LatestTimestamp is a free data retrieval call binding the contract method 0x8205bf6a.
+//
+// Solidity: function latestTimestamp() view returns(uint256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceSession) LatestTimestamp() (*big.Int, error) {
+	return _AggregatorV2V3Interface.Contract.LatestTimestamp(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// LatestTimestamp is a free data retrieval call binding the contract method 0x8205bf6a.
+//
+// Solidity: function latestTimestamp() view returns(uint256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCallerSession) LatestTimestamp() (*big.Int, error) {
+	return _AggregatorV2V3Interface.Contract.LatestTimestamp(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// Version is a free data retrieval call binding the contract method 0x54fd4d50.
+//
+// Solidity: function version() view returns(uint256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCaller) Version(opts *bind.CallOpts) (*big.Int, error) {
+	var out []interface{}
+	err := _AggregatorV2V3Interface.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
+
+}
+
+// Version is a free data retrieval call binding the contract method 0x54fd4d50.
+//
+// Solidity: function version() view returns(uint256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceSession) Version() (*big.Int, error) {
+	return _AggregatorV2V3Interface.Contract.Version(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// Version is a free data retrieval call binding the contract method 0x54fd4d50.
+//
+// Solidity: function version() view returns(uint256)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceCallerSession) Version() (*big.Int, error) {
+	return _AggregatorV2V3Interface.Contract.Version(&_AggregatorV2V3Interface.CallOpts)
+}
+
+// AggregatorV2V3InterfaceAnswerUpdatedIterator is returned from FilterAnswerUpdated and is used to iterate over the raw logs and unpacked data for AnswerUpdated events raised by the AggregatorV2V3Interface contract.
+type AggregatorV2V3InterfaceAnswerUpdatedIterator struct {
+	Event *AggregatorV2V3InterfaceAnswerUpdated // Event containing the contract specifics and raw log
+
+	contract *bind.BoundContract // Generic contract to use for unpacking event data
+	event    string              // Event name to use for unpacking event data
+
+	logs chan types.Log        // Log channel receiving the found contract events
+	sub  ethereum.Subscription // Subscription for errors, completion and termination
+	done bool                  // Whether the subscription completed delivering logs
+	fail error                 // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *AggregatorV2V3InterfaceAnswerUpdatedIterator) Next() bool {
+	// If the iterator failed, stop iterating
+	if it.fail != nil {
+		return false
+	}
+	// If the iterator completed, deliver directly whatever's available
+	if it.done {
+		select {
+		case log := <-it.logs:
+			it.Event = new(AggregatorV2V3InterfaceAnswerUpdated)
+			if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+				it.fail = err
+				return false
+			}
+			it.Event.Raw = log
+			return true
+
+		default:
+			return false
+		}
+	}
+	// Iterator still in progress, wait for either a data or an error event
+	select {
+	case log := <-it.logs:
+		it.Event = new(AggregatorV2V3InterfaceAnswerUpdated)
+		if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+			it.fail = err
+			return false
+		}
+		it.Event.Raw = log
+		return true
+
+	case err := <-it.sub.Err():
+		it.done = true
+		it.fail = err
+		return it.Next()
+	}
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *AggregatorV2V3InterfaceAnswerUpdatedIterator) Error() error {
+	return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *AggregatorV2V3InterfaceAnswerUpdatedIterator) Close() error {
+	it.sub.Unsubscribe()
+	return nil
+}
+
+// AggregatorV2V3InterfaceAnswerUpdated represents a AnswerUpdated event raised by the AggregatorV2V3Interface contract.
+type AggregatorV2V3InterfaceAnswerUpdated struct {
+	Current   *big.Int
+	RoundId   *big.Int
+	UpdatedAt *big.Int
+	Raw       types.Log // Blockchain specific contextual infos
+}
+
+// FilterAnswerUpdated is a free log retrieval operation binding the contract event 0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f.
+//
+// Solidity: event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceFilterer) FilterAnswerUpdated(opts *bind.FilterOpts, current []*big.Int, roundId []*big.Int) (*AggregatorV2V3InterfaceAnswerUpdatedIterator, error) {
+
+	var currentRule []interface{}
+	for _, currentItem := range current {
+		currentRule = append(currentRule, currentItem)
+	}
+	var roundIdRule []interface{}
+	for _, roundIdItem := range roundId {
+		roundIdRule = append(roundIdRule, roundIdItem)
+	}
+
+	logs, sub, err := _AggregatorV2V3Interface.contract.FilterLogs(opts, "AnswerUpdated", currentRule, roundIdRule)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorV2V3InterfaceAnswerUpdatedIterator{contract: _AggregatorV2V3Interface.contract, event: "AnswerUpdated", logs: logs, sub: sub}, nil
+}
+
+// WatchAnswerUpdated is a free log subscription operation binding the contract event 0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f.
+//
+// Solidity: event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceFilterer) WatchAnswerUpdated(opts *bind.WatchOpts, sink chan<- *AggregatorV2V3InterfaceAnswerUpdated, current []*big.Int, roundId []*big.Int) (event.Subscription, error) {
+
+	var currentRule []interface{}
+	for _, currentItem := range current {
+		currentRule = append(currentRule, currentItem)
+	}
+	var roundIdRule []interface{}
+	for _, roundIdItem := range roundId {
+		roundIdRule = append(roundIdRule, roundIdItem)
+	}
+
+	logs, sub, err := _AggregatorV2V3Interface.contract.WatchLogs(opts, "AnswerUpdated", currentRule, roundIdRule)
+	if err != nil {
+		return nil, err
+	}
+	return event.NewSubscription(func(quit <-chan struct{}) error {
+		defer sub.Unsubscribe()
+		for {
+			select {
+			case log := <-logs:
+				// New log arrived, parse the event and forward to the user
+				event := new(AggregatorV2V3InterfaceAnswerUpdated)
+				if err := _AggregatorV2V3Interface.contract.UnpackLog(event, "AnswerUpdated", 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
+}
+
+// ParseAnswerUpdated is a log parse operation binding the contract event 0x0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f.
+//
+// Solidity: event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceFilterer) ParseAnswerUpdated(log types.Log) (*AggregatorV2V3InterfaceAnswerUpdated, error) {
+	event := new(AggregatorV2V3InterfaceAnswerUpdated)
+	if err := _AggregatorV2V3Interface.contract.UnpackLog(event, "AnswerUpdated", log); err != nil {
+		return nil, err
+	}
+	event.Raw = log
+	return event, nil
+}
+
+// AggregatorV2V3InterfaceNewRoundIterator is returned from FilterNewRound and is used to iterate over the raw logs and unpacked data for NewRound events raised by the AggregatorV2V3Interface contract.
+type AggregatorV2V3InterfaceNewRoundIterator struct {
+	Event *AggregatorV2V3InterfaceNewRound // Event containing the contract specifics and raw log
+
+	contract *bind.BoundContract // Generic contract to use for unpacking event data
+	event    string              // Event name to use for unpacking event data
+
+	logs chan types.Log        // Log channel receiving the found contract events
+	sub  ethereum.Subscription // Subscription for errors, completion and termination
+	done bool                  // Whether the subscription completed delivering logs
+	fail error                 // Occurred error to stop iteration
+}
+
+// Next advances the iterator to the subsequent event, returning whether there
+// are any more events found. In case of a retrieval or parsing error, false is
+// returned and Error() can be queried for the exact failure.
+func (it *AggregatorV2V3InterfaceNewRoundIterator) Next() bool {
+	// If the iterator failed, stop iterating
+	if it.fail != nil {
+		return false
+	}
+	// If the iterator completed, deliver directly whatever's available
+	if it.done {
+		select {
+		case log := <-it.logs:
+			it.Event = new(AggregatorV2V3InterfaceNewRound)
+			if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+				it.fail = err
+				return false
+			}
+			it.Event.Raw = log
+			return true
+
+		default:
+			return false
+		}
+	}
+	// Iterator still in progress, wait for either a data or an error event
+	select {
+	case log := <-it.logs:
+		it.Event = new(AggregatorV2V3InterfaceNewRound)
+		if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
+			it.fail = err
+			return false
+		}
+		it.Event.Raw = log
+		return true
+
+	case err := <-it.sub.Err():
+		it.done = true
+		it.fail = err
+		return it.Next()
+	}
+}
+
+// Error returns any retrieval or parsing error occurred during filtering.
+func (it *AggregatorV2V3InterfaceNewRoundIterator) Error() error {
+	return it.fail
+}
+
+// Close terminates the iteration process, releasing any pending underlying
+// resources.
+func (it *AggregatorV2V3InterfaceNewRoundIterator) Close() error {
+	it.sub.Unsubscribe()
+	return nil
+}
+
+// AggregatorV2V3InterfaceNewRound represents a NewRound event raised by the AggregatorV2V3Interface contract.
+type AggregatorV2V3InterfaceNewRound struct {
+	RoundId   *big.Int
+	StartedBy common.Address
+	StartedAt *big.Int
+	Raw       types.Log // Blockchain specific contextual infos
+}
+
+// FilterNewRound is a free log retrieval operation binding the contract event 0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271.
+//
+// Solidity: event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceFilterer) FilterNewRound(opts *bind.FilterOpts, roundId []*big.Int, startedBy []common.Address) (*AggregatorV2V3InterfaceNewRoundIterator, error) {
+
+	var roundIdRule []interface{}
+	for _, roundIdItem := range roundId {
+		roundIdRule = append(roundIdRule, roundIdItem)
+	}
+	var startedByRule []interface{}
+	for _, startedByItem := range startedBy {
+		startedByRule = append(startedByRule, startedByItem)
+	}
+
+	logs, sub, err := _AggregatorV2V3Interface.contract.FilterLogs(opts, "NewRound", roundIdRule, startedByRule)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorV2V3InterfaceNewRoundIterator{contract: _AggregatorV2V3Interface.contract, event: "NewRound", logs: logs, sub: sub}, nil
+}
+
+// WatchNewRound is a free log subscription operation binding the contract event 0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271.
+//
+// Solidity: event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceFilterer) WatchNewRound(opts *bind.WatchOpts, sink chan<- *AggregatorV2V3InterfaceNewRound, roundId []*big.Int, startedBy []common.Address) (event.Subscription, error) {
+
+	var roundIdRule []interface{}
+	for _, roundIdItem := range roundId {
+		roundIdRule = append(roundIdRule, roundIdItem)
+	}
+	var startedByRule []interface{}
+	for _, startedByItem := range startedBy {
+		startedByRule = append(startedByRule, startedByItem)
+	}
+
+	logs, sub, err := _AggregatorV2V3Interface.contract.WatchLogs(opts, "NewRound", roundIdRule, startedByRule)
+	if err != nil {
+		return nil, err
+	}
+	return event.NewSubscription(func(quit <-chan struct{}) error {
+		defer sub.Unsubscribe()
+		for {
+			select {
+			case log := <-logs:
+				// New log arrived, parse the event and forward to the user
+				event := new(AggregatorV2V3InterfaceNewRound)
+				if err := _AggregatorV2V3Interface.contract.UnpackLog(event, "NewRound", 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
+}
+
+// ParseNewRound is a log parse operation binding the contract event 0x0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271.
+//
+// Solidity: event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt)
+func (_AggregatorV2V3Interface *AggregatorV2V3InterfaceFilterer) ParseNewRound(log types.Log) (*AggregatorV2V3InterfaceNewRound, error) {
+	event := new(AggregatorV2V3InterfaceNewRound)
+	if err := _AggregatorV2V3Interface.contract.UnpackLog(event, "NewRound", log); err != nil {
+		return nil, err
+	}
+	event.Raw = log
+	return event, nil
+}
diff --git a/eth/contracts/chainlink/AggregatorV3Interface.go b/eth/contracts/chainlink/AggregatorV3Interface.go
index 7657cc536..2b0c1c958 100644
--- a/eth/contracts/chainlink/AggregatorV3Interface.go
+++ b/eth/contracts/chainlink/AggregatorV3Interface.go
@@ -28,3 +28,367 @@ var (
 	_ = event.NewSubscription
 	_ = abi.ConvertType
 )
+
+// AggregatorV3InterfaceMetaData contains all meta data concerning the AggregatorV3Interface contract.
+var AggregatorV3InterfaceMetaData = &bind.MetaData{
+	ABI: "[{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"description\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint80\",\"name\":\"_roundId\",\"type\":\"uint80\"}],\"name\":\"getRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"roundId\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"answer\",\"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\":\"answer\",\"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\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
+}
+
+// AggregatorV3InterfaceABI is the input ABI used to generate the binding from.
+// Deprecated: Use AggregatorV3InterfaceMetaData.ABI instead.
+var AggregatorV3InterfaceABI = AggregatorV3InterfaceMetaData.ABI
+
+// AggregatorV3Interface is an auto generated Go binding around an Ethereum contract.
+type AggregatorV3Interface struct {
+	AggregatorV3InterfaceCaller     // Read-only binding to the contract
+	AggregatorV3InterfaceTransactor // Write-only binding to the contract
+	AggregatorV3InterfaceFilterer   // Log filterer for contract events
+}
+
+// AggregatorV3InterfaceCaller is an auto generated read-only Go binding around an Ethereum contract.
+type AggregatorV3InterfaceCaller struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AggregatorV3InterfaceTransactor is an auto generated write-only Go binding around an Ethereum contract.
+type AggregatorV3InterfaceTransactor struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AggregatorV3InterfaceFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
+type AggregatorV3InterfaceFilterer struct {
+	contract *bind.BoundContract // Generic contract wrapper for the low level calls
+}
+
+// AggregatorV3InterfaceSession is an auto generated Go binding around an Ethereum contract,
+// with pre-set call and transact options.
+type AggregatorV3InterfaceSession struct {
+	Contract     *AggregatorV3Interface // Generic contract binding to set the session for
+	CallOpts     bind.CallOpts          // Call options to use throughout this session
+	TransactOpts bind.TransactOpts      // Transaction auth options to use throughout this session
+}
+
+// AggregatorV3InterfaceCallerSession is an auto generated read-only Go binding around an Ethereum contract,
+// with pre-set call options.
+type AggregatorV3InterfaceCallerSession struct {
+	Contract *AggregatorV3InterfaceCaller // Generic contract caller binding to set the session for
+	CallOpts bind.CallOpts                // Call options to use throughout this session
+}
+
+// AggregatorV3InterfaceTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
+// with pre-set transact options.
+type AggregatorV3InterfaceTransactorSession struct {
+	Contract     *AggregatorV3InterfaceTransactor // Generic contract transactor binding to set the session for
+	TransactOpts bind.TransactOpts                // Transaction auth options to use throughout this session
+}
+
+// AggregatorV3InterfaceRaw is an auto generated low-level Go binding around an Ethereum contract.
+type AggregatorV3InterfaceRaw struct {
+	Contract *AggregatorV3Interface // Generic contract binding to access the raw methods on
+}
+
+// AggregatorV3InterfaceCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
+type AggregatorV3InterfaceCallerRaw struct {
+	Contract *AggregatorV3InterfaceCaller // Generic read-only contract binding to access the raw methods on
+}
+
+// AggregatorV3InterfaceTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
+type AggregatorV3InterfaceTransactorRaw struct {
+	Contract *AggregatorV3InterfaceTransactor // Generic write-only contract binding to access the raw methods on
+}
+
+// NewAggregatorV3Interface creates a new instance of AggregatorV3Interface, bound to a specific deployed contract.
+func NewAggregatorV3Interface(address common.Address, backend bind.ContractBackend) (*AggregatorV3Interface, error) {
+	contract, err := bindAggregatorV3Interface(address, backend, backend, backend)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorV3Interface{AggregatorV3InterfaceCaller: AggregatorV3InterfaceCaller{contract: contract}, AggregatorV3InterfaceTransactor: AggregatorV3InterfaceTransactor{contract: contract}, AggregatorV3InterfaceFilterer: AggregatorV3InterfaceFilterer{contract: contract}}, nil
+}
+
+// NewAggregatorV3InterfaceCaller creates a new read-only instance of AggregatorV3Interface, bound to a specific deployed contract.
+func NewAggregatorV3InterfaceCaller(address common.Address, caller bind.ContractCaller) (*AggregatorV3InterfaceCaller, error) {
+	contract, err := bindAggregatorV3Interface(address, caller, nil, nil)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorV3InterfaceCaller{contract: contract}, nil
+}
+
+// NewAggregatorV3InterfaceTransactor creates a new write-only instance of AggregatorV3Interface, bound to a specific deployed contract.
+func NewAggregatorV3InterfaceTransactor(address common.Address, transactor bind.ContractTransactor) (*AggregatorV3InterfaceTransactor, error) {
+	contract, err := bindAggregatorV3Interface(address, nil, transactor, nil)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorV3InterfaceTransactor{contract: contract}, nil
+}
+
+// NewAggregatorV3InterfaceFilterer creates a new log filterer instance of AggregatorV3Interface, bound to a specific deployed contract.
+func NewAggregatorV3InterfaceFilterer(address common.Address, filterer bind.ContractFilterer) (*AggregatorV3InterfaceFilterer, error) {
+	contract, err := bindAggregatorV3Interface(address, nil, nil, filterer)
+	if err != nil {
+		return nil, err
+	}
+	return &AggregatorV3InterfaceFilterer{contract: contract}, nil
+}
+
+// bindAggregatorV3Interface binds a generic wrapper to an already deployed contract.
+func bindAggregatorV3Interface(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
+	parsed, err := AggregatorV3InterfaceMetaData.GetAbi()
+	if err != nil {
+		return nil, err
+	}
+	return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_AggregatorV3Interface *AggregatorV3InterfaceRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+	return _AggregatorV3Interface.Contract.AggregatorV3InterfaceCaller.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_AggregatorV3Interface *AggregatorV3InterfaceRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _AggregatorV3Interface.Contract.AggregatorV3InterfaceTransactor.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_AggregatorV3Interface *AggregatorV3InterfaceRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+	return _AggregatorV3Interface.Contract.AggregatorV3InterfaceTransactor.contract.Transact(opts, method, params...)
+}
+
+// Call invokes the (constant) contract method with params as input values and
+// sets the output to result. The result type might be a single field for simple
+// returns, a slice of interfaces for anonymous returns and a struct for named
+// returns.
+func (_AggregatorV3Interface *AggregatorV3InterfaceCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
+	return _AggregatorV3Interface.Contract.contract.Call(opts, result, method, params...)
+}
+
+// Transfer initiates a plain transaction to move funds to the contract, calling
+// its default method if one is available.
+func (_AggregatorV3Interface *AggregatorV3InterfaceTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
+	return _AggregatorV3Interface.Contract.contract.Transfer(opts)
+}
+
+// Transact invokes the (paid) contract method with params as input values.
+func (_AggregatorV3Interface *AggregatorV3InterfaceTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+	return _AggregatorV3Interface.Contract.contract.Transact(opts, method, params...)
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() view returns(uint8)
+func (_AggregatorV3Interface *AggregatorV3InterfaceCaller) Decimals(opts *bind.CallOpts) (uint8, error) {
+	var out []interface{}
+	err := _AggregatorV3Interface.contract.Call(opts, &out, "decimals")
+
+	if err != nil {
+		return *new(uint8), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
+
+	return out0, err
+
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() view returns(uint8)
+func (_AggregatorV3Interface *AggregatorV3InterfaceSession) Decimals() (uint8, error) {
+	return _AggregatorV3Interface.Contract.Decimals(&_AggregatorV3Interface.CallOpts)
+}
+
+// Decimals is a free data retrieval call binding the contract method 0x313ce567.
+//
+// Solidity: function decimals() view returns(uint8)
+func (_AggregatorV3Interface *AggregatorV3InterfaceCallerSession) Decimals() (uint8, error) {
+	return _AggregatorV3Interface.Contract.Decimals(&_AggregatorV3Interface.CallOpts)
+}
+
+// Description is a free data retrieval call binding the contract method 0x7284e416.
+//
+// Solidity: function description() view returns(string)
+func (_AggregatorV3Interface *AggregatorV3InterfaceCaller) Description(opts *bind.CallOpts) (string, error) {
+	var out []interface{}
+	err := _AggregatorV3Interface.contract.Call(opts, &out, "description")
+
+	if err != nil {
+		return *new(string), err
+	}
+
+	out0 := *abi.ConvertType(out[0], new(string)).(*string)
+
+	return out0, err
+
+}
+
+// Description is a free data retrieval call binding the contract method 0x7284e416.
+//
+// Solidity: function description() view returns(string)
+func (_AggregatorV3Interface *AggregatorV3InterfaceSession) Description() (string, error) {
+	return _AggregatorV3Interface.Contract.Description(&_AggregatorV3Interface.CallOpts)
+}
+
+// Description is a free data retrieval call binding the contract method 0x7284e416.
+//
+// Solidity: function description() view returns(string)
+func (_AggregatorV3Interface *AggregatorV3InterfaceCallerSession) Description() (string, error) {
+	return _AggregatorV3Interface.Contract.Description(&_AggregatorV3Interface.CallOpts)
+}
+
+// GetRoundData is a free data retrieval call binding the contract method 0x9a6fc8f5.
+//
+// Solidity: function getRoundData(uint80 _roundId) view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+func (_AggregatorV3Interface *AggregatorV3InterfaceCaller) GetRoundData(opts *bind.CallOpts, _roundId *big.Int) (struct {
+	RoundId         *big.Int
+	Answer          *big.Int
+	StartedAt       *big.Int
+	UpdatedAt       *big.Int
+	AnsweredInRound *big.Int
+}, error) {
+	var out []interface{}
+	err := _AggregatorV3Interface.contract.Call(opts, &out, "getRoundData", _roundId)
+
+	outstruct := new(struct {
+		RoundId         *big.Int
+		Answer          *big.Int
+		StartedAt       *big.Int
+		UpdatedAt       *big.Int
+		AnsweredInRound *big.Int
+	})
+	if err != nil {
+		return *outstruct, err
+	}
+
+	outstruct.RoundId = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+	outstruct.Answer = *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
+
+}
+
+// GetRoundData is a free data retrieval call binding the contract method 0x9a6fc8f5.
+//
+// Solidity: function getRoundData(uint80 _roundId) view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+func (_AggregatorV3Interface *AggregatorV3InterfaceSession) GetRoundData(_roundId *big.Int) (struct {
+	RoundId         *big.Int
+	Answer          *big.Int
+	StartedAt       *big.Int
+	UpdatedAt       *big.Int
+	AnsweredInRound *big.Int
+}, error) {
+	return _AggregatorV3Interface.Contract.GetRoundData(&_AggregatorV3Interface.CallOpts, _roundId)
+}
+
+// GetRoundData is a free data retrieval call binding the contract method 0x9a6fc8f5.
+//
+// Solidity: function getRoundData(uint80 _roundId) view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+func (_AggregatorV3Interface *AggregatorV3InterfaceCallerSession) GetRoundData(_roundId *big.Int) (struct {
+	RoundId         *big.Int
+	Answer          *big.Int
+	StartedAt       *big.Int
+	UpdatedAt       *big.Int
+	AnsweredInRound *big.Int
+}, error) {
+	return _AggregatorV3Interface.Contract.GetRoundData(&_AggregatorV3Interface.CallOpts, _roundId)
+}
+
+// LatestRoundData is a free data retrieval call binding the contract method 0xfeaf968c.
+//
+// Solidity: function latestRoundData() view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+func (_AggregatorV3Interface *AggregatorV3InterfaceCaller) LatestRoundData(opts *bind.CallOpts) (struct {
+	RoundId         *big.Int
+	Answer          *big.Int
+	StartedAt       *big.Int
+	UpdatedAt       *big.Int
+	AnsweredInRound *big.Int
+}, error) {
+	var out []interface{}
+	err := _AggregatorV3Interface.contract.Call(opts, &out, "latestRoundData")
+
+	outstruct := new(struct {
+		RoundId         *big.Int
+		Answer          *big.Int
+		StartedAt       *big.Int
+		UpdatedAt       *big.Int
+		AnsweredInRound *big.Int
+	})
+	if err != nil {
+		return *outstruct, err
+	}
+
+	outstruct.RoundId = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
+	outstruct.Answer = *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
+
+}
+
+// LatestRoundData is a free data retrieval call binding the contract method 0xfeaf968c.
+//
+// Solidity: function latestRoundData() view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+func (_AggregatorV3Interface *AggregatorV3InterfaceSession) LatestRoundData() (struct {
+	RoundId         *big.Int
+	Answer          *big.Int
+	StartedAt       *big.Int
+	UpdatedAt       *big.Int
+	AnsweredInRound *big.Int
+}, error) {
+	return _AggregatorV3Interface.Contract.LatestRoundData(&_AggregatorV3Interface.CallOpts)
+}
+
+// LatestRoundData is a free data retrieval call binding the contract method 0xfeaf968c.
+//
+// Solidity: function latestRoundData() view returns(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
+func (_AggregatorV3Interface *AggregatorV3InterfaceCallerSession) LatestRoundData() (struct {
+	RoundId         *big.Int
+	Answer          *big.Int
+	StartedAt       *big.Int
+	UpdatedAt       *big.Int
+	AnsweredInRound *big.Int
+}, error) {
+	return _AggregatorV3Interface.Contract.LatestRoundData(&_AggregatorV3Interface.CallOpts)
+}
+
+// Version is a free data retrieval call binding the contract method 0x54fd4d50.
+//
+// Solidity: function version() view returns(uint256)
+func (_AggregatorV3Interface *AggregatorV3InterfaceCaller) Version(opts *bind.CallOpts) (*big.Int, error) {
+	var out []interface{}
+	err := _AggregatorV3Interface.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
+
+}
+
+// Version is a free data retrieval call binding the contract method 0x54fd4d50.
+//
+// Solidity: function version() view returns(uint256)
+func (_AggregatorV3Interface *AggregatorV3InterfaceSession) Version() (*big.Int, error) {
+	return _AggregatorV3Interface.Contract.Version(&_AggregatorV3Interface.CallOpts)
+}
+
+// Version is a free data retrieval call binding the contract method 0x54fd4d50.
+//
+// Solidity: function version() view returns(uint256)
+func (_AggregatorV3Interface *AggregatorV3InterfaceCallerSession) Version() (*big.Int, error) {
+	return _AggregatorV3Interface.Contract.Version(&_AggregatorV3Interface.CallOpts)
+}