From 16fe6b3f41973e4d3f8f146e7b44f10f01be1137 Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Fri, 10 Nov 2023 17:31:32 +0100 Subject: [PATCH] Add basic fee currency test --- contracts/celo/abigen/MockSortedOracles.go | 484 ++++++++++++++++++ contracts/celo/celo.go | 4 + contracts/celo/compiled/MockSortedOracles.abi | 226 ++++++++ .../compiled/MockSortedOracles.bin-runtime | 1 + .../celo/compiled/SortedOracles.bin-runtime | 2 +- contracts/celo/compiled/update.sh | 2 +- core/blockchain_celo_test.go | 129 +++++ core/celo_genesis.go | 43 +- core/genesis.go | 2 +- 9 files changed, 868 insertions(+), 25 deletions(-) create mode 100644 contracts/celo/abigen/MockSortedOracles.go create mode 100644 contracts/celo/compiled/MockSortedOracles.abi create mode 100644 contracts/celo/compiled/MockSortedOracles.bin-runtime create mode 100644 core/blockchain_celo_test.go diff --git a/contracts/celo/abigen/MockSortedOracles.go b/contracts/celo/abigen/MockSortedOracles.go new file mode 100644 index 0000000000..edb35523e7 --- /dev/null +++ b/contracts/celo/abigen/MockSortedOracles.go @@ -0,0 +1,484 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package abigen + +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" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// MockSortedOraclesMetaData contains all meta data concerning the MockSortedOracles contract. +var MockSortedOraclesMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"addOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isOldestReportExpired\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"medianRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"medianTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"numRates\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"numTimestamps\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"numerators\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"removeExpiredReports\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"removeOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +// MockSortedOraclesABI is the input ABI used to generate the binding from. +// Deprecated: Use MockSortedOraclesMetaData.ABI instead. +var MockSortedOraclesABI = MockSortedOraclesMetaData.ABI + +// MockSortedOracles is an auto generated Go binding around an Ethereum contract. +type MockSortedOracles struct { + MockSortedOraclesCaller // Read-only binding to the contract + MockSortedOraclesTransactor // Write-only binding to the contract + MockSortedOraclesFilterer // Log filterer for contract events +} + +// MockSortedOraclesCaller is an auto generated read-only Go binding around an Ethereum contract. +type MockSortedOraclesCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MockSortedOraclesTransactor is an auto generated write-only Go binding around an Ethereum contract. +type MockSortedOraclesTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MockSortedOraclesFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MockSortedOraclesFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MockSortedOraclesSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type MockSortedOraclesSession struct { + Contract *MockSortedOracles // 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 +} + +// MockSortedOraclesCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type MockSortedOraclesCallerSession struct { + Contract *MockSortedOraclesCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// MockSortedOraclesTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type MockSortedOraclesTransactorSession struct { + Contract *MockSortedOraclesTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MockSortedOraclesRaw is an auto generated low-level Go binding around an Ethereum contract. +type MockSortedOraclesRaw struct { + Contract *MockSortedOracles // Generic contract binding to access the raw methods on +} + +// MockSortedOraclesCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MockSortedOraclesCallerRaw struct { + Contract *MockSortedOraclesCaller // Generic read-only contract binding to access the raw methods on +} + +// MockSortedOraclesTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MockSortedOraclesTransactorRaw struct { + Contract *MockSortedOraclesTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewMockSortedOracles creates a new instance of MockSortedOracles, bound to a specific deployed contract. +func NewMockSortedOracles(address common.Address, backend bind.ContractBackend) (*MockSortedOracles, error) { + contract, err := bindMockSortedOracles(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &MockSortedOracles{MockSortedOraclesCaller: MockSortedOraclesCaller{contract: contract}, MockSortedOraclesTransactor: MockSortedOraclesTransactor{contract: contract}, MockSortedOraclesFilterer: MockSortedOraclesFilterer{contract: contract}}, nil +} + +// NewMockSortedOraclesCaller creates a new read-only instance of MockSortedOracles, bound to a specific deployed contract. +func NewMockSortedOraclesCaller(address common.Address, caller bind.ContractCaller) (*MockSortedOraclesCaller, error) { + contract, err := bindMockSortedOracles(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MockSortedOraclesCaller{contract: contract}, nil +} + +// NewMockSortedOraclesTransactor creates a new write-only instance of MockSortedOracles, bound to a specific deployed contract. +func NewMockSortedOraclesTransactor(address common.Address, transactor bind.ContractTransactor) (*MockSortedOraclesTransactor, error) { + contract, err := bindMockSortedOracles(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MockSortedOraclesTransactor{contract: contract}, nil +} + +// NewMockSortedOraclesFilterer creates a new log filterer instance of MockSortedOracles, bound to a specific deployed contract. +func NewMockSortedOraclesFilterer(address common.Address, filterer bind.ContractFilterer) (*MockSortedOraclesFilterer, error) { + contract, err := bindMockSortedOracles(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MockSortedOraclesFilterer{contract: contract}, nil +} + +// bindMockSortedOracles binds a generic wrapper to an already deployed contract. +func bindMockSortedOracles(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MockSortedOraclesMetaData.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 (_MockSortedOracles *MockSortedOraclesRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockSortedOracles.Contract.MockSortedOraclesCaller.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 (_MockSortedOracles *MockSortedOraclesRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockSortedOracles.Contract.MockSortedOraclesTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MockSortedOracles *MockSortedOraclesRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockSortedOracles.Contract.MockSortedOraclesTransactor.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 (_MockSortedOracles *MockSortedOraclesCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _MockSortedOracles.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 (_MockSortedOracles *MockSortedOraclesTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _MockSortedOracles.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_MockSortedOracles *MockSortedOraclesTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _MockSortedOracles.Contract.contract.Transact(opts, method, params...) +} + +// DENOMINATOR is a free data retrieval call binding the contract method 0x918f8674. +// +// Solidity: function DENOMINATOR() view returns(uint256) +func (_MockSortedOracles *MockSortedOraclesCaller) DENOMINATOR(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _MockSortedOracles.contract.Call(opts, &out, "DENOMINATOR") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// DENOMINATOR is a free data retrieval call binding the contract method 0x918f8674. +// +// Solidity: function DENOMINATOR() view returns(uint256) +func (_MockSortedOracles *MockSortedOraclesSession) DENOMINATOR() (*big.Int, error) { + return _MockSortedOracles.Contract.DENOMINATOR(&_MockSortedOracles.CallOpts) +} + +// DENOMINATOR is a free data retrieval call binding the contract method 0x918f8674. +// +// Solidity: function DENOMINATOR() view returns(uint256) +func (_MockSortedOracles *MockSortedOraclesCallerSession) DENOMINATOR() (*big.Int, error) { + return _MockSortedOracles.Contract.DENOMINATOR(&_MockSortedOracles.CallOpts) +} + +// IsOldestReportExpired is a free data retrieval call binding the contract method 0xffe736bf. +// +// Solidity: function isOldestReportExpired(address ) pure returns(bool, address) +func (_MockSortedOracles *MockSortedOraclesCaller) IsOldestReportExpired(opts *bind.CallOpts, arg0 common.Address) (bool, common.Address, error) { + var out []interface{} + err := _MockSortedOracles.contract.Call(opts, &out, "isOldestReportExpired", arg0) + + if err != nil { + return *new(bool), *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + out1 := *abi.ConvertType(out[1], new(common.Address)).(*common.Address) + + return out0, out1, err + +} + +// IsOldestReportExpired is a free data retrieval call binding the contract method 0xffe736bf. +// +// Solidity: function isOldestReportExpired(address ) pure returns(bool, address) +func (_MockSortedOracles *MockSortedOraclesSession) IsOldestReportExpired(arg0 common.Address) (bool, common.Address, error) { + return _MockSortedOracles.Contract.IsOldestReportExpired(&_MockSortedOracles.CallOpts, arg0) +} + +// IsOldestReportExpired is a free data retrieval call binding the contract method 0xffe736bf. +// +// Solidity: function isOldestReportExpired(address ) pure returns(bool, address) +func (_MockSortedOracles *MockSortedOraclesCallerSession) IsOldestReportExpired(arg0 common.Address) (bool, common.Address, error) { + return _MockSortedOracles.Contract.IsOldestReportExpired(&_MockSortedOracles.CallOpts, arg0) +} + +// MedianRate is a free data retrieval call binding the contract method 0xef90e1b0. +// +// Solidity: function medianRate(address token) pure returns(uint256, uint256) +func (_MockSortedOracles *MockSortedOraclesCaller) MedianRate(opts *bind.CallOpts, token common.Address) (*big.Int, *big.Int, error) { + var out []interface{} + err := _MockSortedOracles.contract.Call(opts, &out, "medianRate", token) + + if err != nil { + return *new(*big.Int), *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out1 := *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return out0, out1, err + +} + +// MedianRate is a free data retrieval call binding the contract method 0xef90e1b0. +// +// Solidity: function medianRate(address token) pure returns(uint256, uint256) +func (_MockSortedOracles *MockSortedOraclesSession) MedianRate(token common.Address) (*big.Int, *big.Int, error) { + return _MockSortedOracles.Contract.MedianRate(&_MockSortedOracles.CallOpts, token) +} + +// MedianRate is a free data retrieval call binding the contract method 0xef90e1b0. +// +// Solidity: function medianRate(address token) pure returns(uint256, uint256) +func (_MockSortedOracles *MockSortedOraclesCallerSession) MedianRate(token common.Address) (*big.Int, *big.Int, error) { + return _MockSortedOracles.Contract.MedianRate(&_MockSortedOracles.CallOpts, token) +} + +// MedianTimestamp is a free data retrieval call binding the contract method 0x071b48fc. +// +// Solidity: function medianTimestamp(address ) pure returns(uint256) +func (_MockSortedOracles *MockSortedOraclesCaller) MedianTimestamp(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { + var out []interface{} + err := _MockSortedOracles.contract.Call(opts, &out, "medianTimestamp", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MedianTimestamp is a free data retrieval call binding the contract method 0x071b48fc. +// +// Solidity: function medianTimestamp(address ) pure returns(uint256) +func (_MockSortedOracles *MockSortedOraclesSession) MedianTimestamp(arg0 common.Address) (*big.Int, error) { + return _MockSortedOracles.Contract.MedianTimestamp(&_MockSortedOracles.CallOpts, arg0) +} + +// MedianTimestamp is a free data retrieval call binding the contract method 0x071b48fc. +// +// Solidity: function medianTimestamp(address ) pure returns(uint256) +func (_MockSortedOracles *MockSortedOraclesCallerSession) MedianTimestamp(arg0 common.Address) (*big.Int, error) { + return _MockSortedOracles.Contract.MedianTimestamp(&_MockSortedOracles.CallOpts, arg0) +} + +// NumRates is a free data retrieval call binding the contract method 0xbbc66a94. +// +// Solidity: function numRates(address ) pure returns(uint256) +func (_MockSortedOracles *MockSortedOraclesCaller) NumRates(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { + var out []interface{} + err := _MockSortedOracles.contract.Call(opts, &out, "numRates", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// NumRates is a free data retrieval call binding the contract method 0xbbc66a94. +// +// Solidity: function numRates(address ) pure returns(uint256) +func (_MockSortedOracles *MockSortedOraclesSession) NumRates(arg0 common.Address) (*big.Int, error) { + return _MockSortedOracles.Contract.NumRates(&_MockSortedOracles.CallOpts, arg0) +} + +// NumRates is a free data retrieval call binding the contract method 0xbbc66a94. +// +// Solidity: function numRates(address ) pure returns(uint256) +func (_MockSortedOracles *MockSortedOraclesCallerSession) NumRates(arg0 common.Address) (*big.Int, error) { + return _MockSortedOracles.Contract.NumRates(&_MockSortedOracles.CallOpts, arg0) +} + +// NumTimestamps is a free data retrieval call binding the contract method 0x6dd6ef0c. +// +// Solidity: function numTimestamps(address ) pure returns(uint256) +func (_MockSortedOracles *MockSortedOraclesCaller) NumTimestamps(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { + var out []interface{} + err := _MockSortedOracles.contract.Call(opts, &out, "numTimestamps", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// NumTimestamps is a free data retrieval call binding the contract method 0x6dd6ef0c. +// +// Solidity: function numTimestamps(address ) pure returns(uint256) +func (_MockSortedOracles *MockSortedOraclesSession) NumTimestamps(arg0 common.Address) (*big.Int, error) { + return _MockSortedOracles.Contract.NumTimestamps(&_MockSortedOracles.CallOpts, arg0) +} + +// NumTimestamps is a free data retrieval call binding the contract method 0x6dd6ef0c. +// +// Solidity: function numTimestamps(address ) pure returns(uint256) +func (_MockSortedOracles *MockSortedOraclesCallerSession) NumTimestamps(arg0 common.Address) (*big.Int, error) { + return _MockSortedOracles.Contract.NumTimestamps(&_MockSortedOracles.CallOpts, arg0) +} + +// Numerators is a free data retrieval call binding the contract method 0xf7ca6963. +// +// Solidity: function numerators(address ) view returns(uint256) +func (_MockSortedOracles *MockSortedOraclesCaller) Numerators(opts *bind.CallOpts, arg0 common.Address) (*big.Int, error) { + var out []interface{} + err := _MockSortedOracles.contract.Call(opts, &out, "numerators", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Numerators is a free data retrieval call binding the contract method 0xf7ca6963. +// +// Solidity: function numerators(address ) view returns(uint256) +func (_MockSortedOracles *MockSortedOraclesSession) Numerators(arg0 common.Address) (*big.Int, error) { + return _MockSortedOracles.Contract.Numerators(&_MockSortedOracles.CallOpts, arg0) +} + +// Numerators is a free data retrieval call binding the contract method 0xf7ca6963. +// +// Solidity: function numerators(address ) view returns(uint256) +func (_MockSortedOracles *MockSortedOraclesCallerSession) Numerators(arg0 common.Address) (*big.Int, error) { + return _MockSortedOracles.Contract.Numerators(&_MockSortedOracles.CallOpts, arg0) +} + +// AddOracle is a paid mutator transaction binding the contract method 0xf0ca4adb. +// +// Solidity: function addOracle(address , address ) returns() +func (_MockSortedOracles *MockSortedOraclesTransactor) AddOracle(opts *bind.TransactOpts, arg0 common.Address, arg1 common.Address) (*types.Transaction, error) { + return _MockSortedOracles.contract.Transact(opts, "addOracle", arg0, arg1) +} + +// AddOracle is a paid mutator transaction binding the contract method 0xf0ca4adb. +// +// Solidity: function addOracle(address , address ) returns() +func (_MockSortedOracles *MockSortedOraclesSession) AddOracle(arg0 common.Address, arg1 common.Address) (*types.Transaction, error) { + return _MockSortedOracles.Contract.AddOracle(&_MockSortedOracles.TransactOpts, arg0, arg1) +} + +// AddOracle is a paid mutator transaction binding the contract method 0xf0ca4adb. +// +// Solidity: function addOracle(address , address ) returns() +func (_MockSortedOracles *MockSortedOraclesTransactorSession) AddOracle(arg0 common.Address, arg1 common.Address) (*types.Transaction, error) { + return _MockSortedOracles.Contract.AddOracle(&_MockSortedOracles.TransactOpts, arg0, arg1) +} + +// RemoveExpiredReports is a paid mutator transaction binding the contract method 0xdd34ca3b. +// +// Solidity: function removeExpiredReports(address , uint256 ) returns() +func (_MockSortedOracles *MockSortedOraclesTransactor) RemoveExpiredReports(opts *bind.TransactOpts, arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { + return _MockSortedOracles.contract.Transact(opts, "removeExpiredReports", arg0, arg1) +} + +// RemoveExpiredReports is a paid mutator transaction binding the contract method 0xdd34ca3b. +// +// Solidity: function removeExpiredReports(address , uint256 ) returns() +func (_MockSortedOracles *MockSortedOraclesSession) RemoveExpiredReports(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { + return _MockSortedOracles.Contract.RemoveExpiredReports(&_MockSortedOracles.TransactOpts, arg0, arg1) +} + +// RemoveExpiredReports is a paid mutator transaction binding the contract method 0xdd34ca3b. +// +// Solidity: function removeExpiredReports(address , uint256 ) returns() +func (_MockSortedOracles *MockSortedOraclesTransactorSession) RemoveExpiredReports(arg0 common.Address, arg1 *big.Int) (*types.Transaction, error) { + return _MockSortedOracles.Contract.RemoveExpiredReports(&_MockSortedOracles.TransactOpts, arg0, arg1) +} + +// RemoveOracle is a paid mutator transaction binding the contract method 0x53a57297. +// +// Solidity: function removeOracle(address , address , uint256 ) returns() +func (_MockSortedOracles *MockSortedOraclesTransactor) RemoveOracle(opts *bind.TransactOpts, arg0 common.Address, arg1 common.Address, arg2 *big.Int) (*types.Transaction, error) { + return _MockSortedOracles.contract.Transact(opts, "removeOracle", arg0, arg1, arg2) +} + +// RemoveOracle is a paid mutator transaction binding the contract method 0x53a57297. +// +// Solidity: function removeOracle(address , address , uint256 ) returns() +func (_MockSortedOracles *MockSortedOraclesSession) RemoveOracle(arg0 common.Address, arg1 common.Address, arg2 *big.Int) (*types.Transaction, error) { + return _MockSortedOracles.Contract.RemoveOracle(&_MockSortedOracles.TransactOpts, arg0, arg1, arg2) +} + +// RemoveOracle is a paid mutator transaction binding the contract method 0x53a57297. +// +// Solidity: function removeOracle(address , address , uint256 ) returns() +func (_MockSortedOracles *MockSortedOraclesTransactorSession) RemoveOracle(arg0 common.Address, arg1 common.Address, arg2 *big.Int) (*types.Transaction, error) { + return _MockSortedOracles.Contract.RemoveOracle(&_MockSortedOracles.TransactOpts, arg0, arg1, arg2) +} + +// Report is a paid mutator transaction binding the contract method 0x80e50744. +// +// Solidity: function report(address , uint256 , address , address ) returns() +func (_MockSortedOracles *MockSortedOraclesTransactor) Report(opts *bind.TransactOpts, arg0 common.Address, arg1 *big.Int, arg2 common.Address, arg3 common.Address) (*types.Transaction, error) { + return _MockSortedOracles.contract.Transact(opts, "report", arg0, arg1, arg2, arg3) +} + +// Report is a paid mutator transaction binding the contract method 0x80e50744. +// +// Solidity: function report(address , uint256 , address , address ) returns() +func (_MockSortedOracles *MockSortedOraclesSession) Report(arg0 common.Address, arg1 *big.Int, arg2 common.Address, arg3 common.Address) (*types.Transaction, error) { + return _MockSortedOracles.Contract.Report(&_MockSortedOracles.TransactOpts, arg0, arg1, arg2, arg3) +} + +// Report is a paid mutator transaction binding the contract method 0x80e50744. +// +// Solidity: function report(address , uint256 , address , address ) returns() +func (_MockSortedOracles *MockSortedOraclesTransactorSession) Report(arg0 common.Address, arg1 *big.Int, arg2 common.Address, arg3 common.Address) (*types.Transaction, error) { + return _MockSortedOracles.Contract.Report(&_MockSortedOracles.TransactOpts, arg0, arg1, arg2, arg3) +} diff --git a/contracts/celo/celo.go b/contracts/celo/celo.go index 39b572822d..db9b6d0171 100644 --- a/contracts/celo/celo.go +++ b/contracts/celo/celo.go @@ -7,6 +7,7 @@ import _ "embed" //go:generate go run ../../cmd/abigen --pkg abigen --out abigen/SortedOracles.go --abi compiled/SortedOracles.abi --type SortedOracles //go:generate go run ../../cmd/abigen --pkg abigen --out abigen/FeeCurrencyWhitelist.go --abi compiled/FeeCurrencyWhitelist.abi --type FeeCurrencyWhitelist //go:generate go run ../../cmd/abigen --pkg abigen --out abigen/FeeCurrency.go --abi compiled/FeeCurrency.abi --type FeeCurrency +//go:generate go run ../../cmd/abigen --pkg abigen --out abigen/MockSortedOracles.go --abi compiled/MockSortedOracles.abi --type MockSortedOracles //go:embed compiled/CeloRegistry.bin-runtime var RegistryBytecodeRaw []byte @@ -20,6 +21,9 @@ var ProxyBytecodeRaw []byte //go:embed compiled/SortedOracles.bin-runtime var SortedOraclesBytecodeRaw []byte +//go:embed compiled/MockSortedOracles.bin-runtime +var MockSortedOraclesBytecodeRaw []byte + //go:embed compiled/FeeCurrencyWhitelist.bin-runtime var FeeCurrencyWhitelistBytecodeRaw []byte diff --git a/contracts/celo/compiled/MockSortedOracles.abi b/contracts/celo/compiled/MockSortedOracles.abi new file mode 100644 index 0000000000..6b1fb86be1 --- /dev/null +++ b/contracts/celo/compiled/MockSortedOracles.abi @@ -0,0 +1,226 @@ +[ + { + "inputs": [], + "name": "DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "addOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isOldestReportExpired", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "medianRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "medianTimestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "numRates", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "numTimestamps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "numerators", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "removeExpiredReports", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "removeOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "report", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/contracts/celo/compiled/MockSortedOracles.bin-runtime b/contracts/celo/compiled/MockSortedOracles.bin-runtime new file mode 100644 index 0000000000..d255d5cd61 --- /dev/null +++ b/contracts/celo/compiled/MockSortedOracles.bin-runtime @@ -0,0 +1 @@ +0x608060405234801561001057600080fd5b50600436106100c95760003560e01c8063bbc66a9411610081578063f0ca4adb1161005b578063f0ca4adb1461017d578063f7ca69631461018b578063ffe736bf146101ab57600080fd5b8063bbc66a941461012f578063dd34ca3b14610143578063ef90e1b01461015557600080fd5b80636dd6ef0c116100b25780636dd6ef0c146100ce57806380e507441461010a578063918f86741461011e57600080fd5b8063071b48fc146100ce57806353a57297146100f5575b600080fd5b6100e26100dc366004610277565b50600090565b6040519081526020015b60405180910390f35b610108610103366004610299565b505050565b005b6101086101183660046102d5565b50505050565b6100e269d3c21bcecceda100000081565b6100e261013d366004610277565b50600190565b610108610151366004610322565b5050565b610168610163366004610277565b6101ef565b604080519283526020830191909152016100ec565b61010861015136600461034c565b6100e2610199366004610277565b60006020819052908152604090205481565b6101c36101b9366004610277565b5060009061ce1090565b60408051921515835273ffffffffffffffffffffffffffffffffffffffff9091166020830152016100ec565b6000807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff31ea73ffffffffffffffffffffffffffffffffffffffff841601610243575069d3c21bcecceda1000000928392509050565b506000928392509050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461027257600080fd5b919050565b60006020828403121561028957600080fd5b6102928261024e565b9392505050565b6000806000606084860312156102ae57600080fd5b6102b78461024e565b92506102c56020850161024e565b9150604084013590509250925092565b600080600080608085870312156102eb57600080fd5b6102f48561024e565b9350602085013592506103096040860161024e565b91506103176060860161024e565b905092959194509250565b6000806040838503121561033557600080fd5b61033e8361024e565b946020939093013593505050565b6000806040838503121561035f57600080fd5b6103688361024e565b91506103766020840161024e565b9050925092905056fea164736f6c6343000813000a diff --git a/contracts/celo/compiled/SortedOracles.bin-runtime b/contracts/celo/compiled/SortedOracles.bin-runtime index d60982c4fc..bf2fe78ee1 100644 --- a/contracts/celo/compiled/SortedOracles.bin-runtime +++ b/contracts/celo/compiled/SortedOracles.bin-runtime @@ -1 +1 @@ -0x608060405234801561001057600080fd5b50600436106101a35760003560e01c80638da5cb5b116100ee578063ebc1d6bb11610097578063f2fde38b11610071578063f2fde38b146103f5578063fc20935d14610408578063fe4b84df1461041b578063ffe736bf1461042e57600080fd5b8063ebc1d6bb146103a7578063ef90e1b0146103ba578063f0ca4adb146103e257600080fd5b8063b9292158116100c8578063b92921581461036e578063bbc66a9414610381578063dd34ca3b1461039457600080fd5b80638da5cb5b146102fc5780638e7492811461033b578063a00a8b2c1461035b57600080fd5b806353a57297116101505780636deb67991161012a5780636deb6799146102ce578063715018a6146102e157806380e50744146102e957600080fd5b806353a572971461028057806354255be0146102955780636dd6ef0c146102bb57600080fd5b80632e86bc01116101815780632e86bc0114610229578063370c998e14610249578063493a353c1461027757600080fd5b806302f55b61146101a8578063071b48fc146101d3578063158ef93e146101f4575b600080fd5b6101bb6101b636600461255a565b61046d565b6040516101ca939291906125c8565b60405180910390f35b6101e66101e136600461255a565b61055c565b6040519081526020016101ca565b6000546102199074010000000000000000000000000000000000000000900460ff1681565b60405190151581526020016101ca565b6101e661023736600461255a565b60066020526000908152604090205481565b61021961025736600461268f565b600360209081526000928352604080842090915290825290205460ff1681565b6101e660055481565b61029361028e3660046126c8565b610616565b005b6001806002806040805194855260208501939093529183015260608201526080016101ca565b6101e66102c936600461255a565b6109ab565b6101e66102dc36600461255a565b610a22565b610293610a7f565b6102936102f7366004612709565b610a93565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ca565b61034e61034936600461255a565b6111bc565b6040516101ca919061275c565b61031661036936600461276f565b61124c565b6101bb61037c36600461255a565b611291565b6101e661038f36600461255a565b611310565b6102936103a236600461276f565b611387565b6102936103b536600461279b565b61153b565b6103cd6103c836600461255a565b61169f565b604080519283526020830191909152016101ca565b6102936103f036600461268f565b611783565b61029361040336600461255a565b611981565b61029361041636600461276f565b611a38565b61029361042936600461279b565b611be9565b61044161043c36600461255a565b611cbf565b60408051921515835273ffffffffffffffffffffffffffffffffffffffff9091166020830152016101ca565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600160205260409081902090517f6cfa38730000000000000000000000000000000000000000000000000000000081526060918291829173__$c0b499b413513d0c67e2a6a17d90846cb3$__91636cfa3873916104ec9160040190815260200190565b600060405180830381865af4158015610509573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261054f919081019061292a565b9250925092509193909250565b73ffffffffffffffffffffffffffffffffffffffff811660009081526002602052604080822090517f59d556a8000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__906359d556a8906024015b602060405180830381865af41580156105ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106109190612a13565b92915050565b61061e611ee3565b73ffffffffffffffffffffffffffffffffffffffff831615801590610658575073ffffffffffffffffffffffffffffffffffffffff821615155b8015610688575073ffffffffffffffffffffffffffffffffffffffff831660009081526004602052604090205481105b80156106ef575073ffffffffffffffffffffffffffffffffffffffff8381166000908152600460205260409020805491841691839081106106cb576106cb612a2c565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16145b6107a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605660248201527f746f6b656e2061646472206e756c6c206f72206f7261636c652061646472206e60448201527f756c6c206f7220696e646578206f6620746f6b656e206f7261636c65206e6f7460648201527f206d617070656420746f206f7261636c65206164647200000000000000000000608482015260a4015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000818152600360209081526040808320948716835293815283822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055918152600490915220805461081790600190612a8a565b8154811061082757610827612a2c565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff86811684526004909252604090922080549190921691908390811061087157610871612a2c565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94851617905591851681526004909152604090208054806108db576108db612a9d565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905561093d8383611f64565b1561094c5761094c8383612105565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f6dc84b66cc948d847632b9d829f7cb1cb904fbf2c084554a9bc22ad9d845334060405160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526002602052604080822090517f6eafa6c3000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__90636eafa6c3906024016105cf565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600660205260408120548103610a5657505060055490565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604090205490565b610a87611ee3565b610a9160006124c3565b565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600360209081526040808320338452909152902054849060ff16610b55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f73656e64657220776173206e6f7420616e206f7261636c6520666f7220746f6b60448201527f656e206164647200000000000000000000000000000000000000000000000000606482015260840161079d565b73ffffffffffffffffffffffffffffffffffffffff851660009081526001602052604080822090517f59d556a8000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__906359d556a890602401602060405180830381865af4158015610be4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c089190612a13565b73ffffffffffffffffffffffffffffffffffffffff87166000908152600160205260409081902090517f95073a79000000000000000000000000000000000000000000000000000000008152600481019190915233602482015290915073__$c0b499b413513d0c67e2a6a17d90846cb3$__906395073a7990604401602060405180830381865af4158015610ca1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc59190612acc565b15610e395773ffffffffffffffffffffffffffffffffffffffff8681166000908152600160205260409081902090517f832a21470000000000000000000000000000000000000000000000000000000081526004810191909152336024820152604481018790528582166064820152908416608482015273__$c0b499b413513d0c67e2a6a17d90846cb3$__9063832a21479060a40160006040518083038186803b158015610d7357600080fd5b505af4158015610d87573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff86166000908152600260205260409081902090517fc1e728e9000000000000000000000000000000000000000000000000000000008152600481019190915233602482015273__$c0b499b413513d0c67e2a6a17d90846cb3$__9063c1e728e99060440160006040518083038186803b158015610e1c57600080fd5b505af4158015610e30573d6000803e3d6000fd5b50505050610efb565b73ffffffffffffffffffffffffffffffffffffffff8681166000908152600160205260409081902090517fd4a092720000000000000000000000000000000000000000000000000000000081526004810191909152336024820152604481018790528582166064820152908416608482015273__$c0b499b413513d0c67e2a6a17d90846cb3$__9063d4a092729060a40160006040518083038186803b158015610ee257600080fd5b505af4158015610ef6573d6000803e3d6000fd5b505050505b73ffffffffffffffffffffffffffffffffffffffff86166000908152600260205260409081902090517f0944c5940000000000000000000000000000000000000000000000000000000081526004810182905273__$c0b499b413513d0c67e2a6a17d90846cb3$__9163d4a0927291339042908590630944c59490602401602060405180830381865af4158015610f96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fba9190612aee565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b168152600481019490945273ffffffffffffffffffffffffffffffffffffffff928316602485015260448401919091521660648201526000608482015260a40160006040518083038186803b15801561103b57600080fd5b505af415801561104f573d6000803e3d6000fd5b5050604080514281526020810189905233935073ffffffffffffffffffffffffffffffffffffffff8a1692507f7cebb17173a9ed273d2b7538f64395c0ebf352ff743f1cf8ce66b437a6144213910160405180910390a373ffffffffffffffffffffffffffffffffffffffff861660009081526001602052604080822090517f59d556a8000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__906359d556a890602401602060405180830381865af4158015611135573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111599190612a13565b90508181146111b3578673ffffffffffffffffffffffffffffffffffffffff167fa9981ebfc3b766a742486e898f54959b050a66006dbce1a4155c1f84a08bcf41826040516111aa91815260200190565b60405180910390a25b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815260409182902080548351818402810184019094528084526060939283018282801561124057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611215575b50505050509050919050565b6004602052816000526040600020818154811061126857600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600260205260409081902090517f6cfa38730000000000000000000000000000000000000000000000000000000081526060918291829173__$c0b499b413513d0c67e2a6a17d90846cb3$__91636cfa3873916104ec9160040190815260200190565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604080822090517f6eafa6c3000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__90636eafa6c3906024016105cf565b73ffffffffffffffffffffffffffffffffffffffff82161580159061145e575073ffffffffffffffffffffffffffffffffffffffff82166000908152600260205260409081902090517f6eafa6c3000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__90636eafa6c390602401602060405180830381865af4158015611437573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145b9190612a13565b81105b6114ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f746f6b656e2061646472206e756c6c206f7220747279696e6720746f2072656d60448201527f6f766520746f6f206d616e79207265706f727473000000000000000000000000606482015260840161079d565b60005b818110156115365760008061150185611cbf565b91509150811561151a576115158582612105565b611521565b5050505050565b5050808061152e90612b0b565b9150506114ed565b505050565b611543611ee3565b600081116115d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f7265706f727420657870697279207365636f6e6473206d757374206265203e2060448201527f3000000000000000000000000000000000000000000000000000000000000000606482015260840161079d565b6005548103611664576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f7265706f72744578706972795365636f6e6473206861736e2774206368616e6760448201527f6564000000000000000000000000000000000000000000000000000000000000606482015260840161079d565b60058190556040518181527fc68a9b88effd8a11611ff410efbc83569f0031b7bc70dd455b61344c7f0a042f9060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604080822090517f59d556a8000000000000000000000000000000000000000000000000000000008152829173__$c0b499b413513d0c67e2a6a17d90846cb3$__916359d556a8916117189160040190815260200190565b602060405180830381865af4158015611735573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117599190612a13565b61176284611310565b156117775769d3c21bcecceda100000061177a565b60005b91509150915091565b61178b611ee3565b73ffffffffffffffffffffffffffffffffffffffff8216158015906117c5575073ffffffffffffffffffffffffffffffffffffffff811615155b8015611804575073ffffffffffffffffffffffffffffffffffffffff80831660009081526003602090815260408083209385168352929052205460ff16155b6118b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605a60248201527f746f6b656e206164647220776173206e756c6c206f72206f7261636c6520616460448201527f647220776173206e756c6c206f72206f7261636c652061646472206973206e6f60648201527f7420616e206f7261636c6520666f7220746f6b656e2061646472000000000000608482015260a40161079d565b73ffffffffffffffffffffffffffffffffffffffff808316600081815260036020908152604080832094861680845294825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484526004835281842080549182018155845291832090910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001685179055517f828d2be040dede7698182e08dfa8bfbd663c879aee772509c4a2bd961d0ed43f9190a35050565b611989611ee3565b73ffffffffffffffffffffffffffffffffffffffff8116611a2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161079d565b611a35816124c3565b50565b611a40611ee3565b60008111611ad0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f7265706f727420657870697279207365636f6e6473206d757374206265203e2060448201527f3000000000000000000000000000000000000000000000000000000000000000606482015260840161079d565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600660205260409020548103611b84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f746f6b656e207265706f72744578706972795365636f6e6473206861736e277460448201527f206368616e676564000000000000000000000000000000000000000000000000606482015260840161079d565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260066020908152604091829020849055815192835282018390527ff8324c8592dfd9991ee3e717351afe0a964605257959e3d99b0eb3d45bff9422910160405180910390a15050565b60005474010000000000000000000000000000000000000000900460ff1615611c6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f636f6e747261637420616c726561647920696e697469616c697a656400000000604482015260640161079d565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055611cb6336124c3565b611a358161153b565b60008073ffffffffffffffffffffffffffffffffffffffff8316611d3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f746f6b656e20616464726573732063616e6e6f74206265206e756c6c00000000604482015260640161079d565b73ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604080822090517fd938ec7b000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__9063d938ec7b90602401602060405180830381865af4158015611dce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df29190612aee565b73ffffffffffffffffffffffffffffffffffffffff85811660009081526002602052604080822090517f7c6bb8620000000000000000000000000000000000000000000000000000000081526004810191909152918316602483015291925073__$c0b499b413513d0c67e2a6a17d90846cb3$__90637c6bb86290604401602060405180830381865af4158015611e8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eb19190612a13565b9050611ebc85610a22565b611ec68242612a8a565b10611ed75750600194909350915050565b50600094909350915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161079d565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604080822090517f95073a7900000000000000000000000000000000000000000000000000000000815273__$c0b499b413513d0c67e2a6a17d90846cb3$__916395073a7991611ff99190869060040191825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b602060405180830381865af4158015612016573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203a9190612acc565b80156120fe575073ffffffffffffffffffffffffffffffffffffffff8381166000908152600260205260409081902090517f95073a790000000000000000000000000000000000000000000000000000000081526004810191909152908316602482015273__$c0b499b413513d0c67e2a6a17d90846cb3$__906395073a7990604401602060405180830381865af41580156120da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120fe9190612acc565b9392505050565b61210e826109ab565b600114801561212257506121228282611f64565b1561212b575050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604080822090517f59d556a8000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__906359d556a890602401602060405180830381865af41580156121ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121de9190612a13565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600160205260409081902090517fc1e728e900000000000000000000000000000000000000000000000000000000815291925073__$c0b499b413513d0c67e2a6a17d90846cb3$__9163c1e728e99161227691869060040191825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60006040518083038186803b15801561228e57600080fd5b505af41580156122a2573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff84166000908152600260205260409081902090517fc1e728e900000000000000000000000000000000000000000000000000000000815273__$c0b499b413513d0c67e2a6a17d90846cb3$__925063c1e728e99161233b91869060040191825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60006040518083038186803b15801561235357600080fd5b505af4158015612367573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff8086169350861691507fe21a44017b6fa1658d84e937d56ff408501facdb4ff7427c479ac460d76f789390600090a373ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604080822090517f59d556a8000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__906359d556a890602401602060405180830381865af415801561243f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124639190612a13565b90508181146124bd578373ffffffffffffffffffffffffffffffffffffffff167fa9981ebfc3b766a742486e898f54959b050a66006dbce1a4155c1f84a08bcf41826040516124b491815260200190565b60405180910390a25b50505050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a3557600080fd5b60006020828403121561256c57600080fd5b81356120fe81612538565b600081518084526020808501945080840160005b838110156125bd57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161258b565b509495945050505050565b6060815260006125db6060830186612577565b82810360208481019190915285518083528682019282019060005b81811015612612578451835293830193918301916001016125f6565b50508481036040860152855180825290820192508186019060005b81811015612681578251600480821061266e577f4e487b71000000000000000000000000000000000000000000000000000000006000526021815260246000fd5b508552938301939183019160010161262d565b509298975050505050505050565b600080604083850312156126a257600080fd5b82356126ad81612538565b915060208301356126bd81612538565b809150509250929050565b6000806000606084860312156126dd57600080fd5b83356126e881612538565b925060208401356126f881612538565b929592945050506040919091013590565b6000806000806080858703121561271f57600080fd5b843561272a81612538565b935060208501359250604085013561274181612538565b9150606085013561275181612538565b939692955090935050565b6020815260006120fe6020830184612577565b6000806040838503121561278257600080fd5b823561278d81612538565b946020939093013593505050565b6000602082840312156127ad57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561282a5761282a6127b4565b604052919050565b600067ffffffffffffffff82111561284c5761284c6127b4565b5060051b60200190565b600082601f83011261286757600080fd5b8151602061287c61287783612832565b6127e3565b82815260059290921b8401810191818101908684111561289b57600080fd5b8286015b848110156128b6578051835291830191830161289f565b509695505050505050565b600082601f8301126128d257600080fd5b815160206128e261287783612832565b82815260059290921b8401810191818101908684111561290157600080fd5b8286015b848110156128b65780516004811061291d5760008081fd5b8352918301918301612905565b60008060006060848603121561293f57600080fd5b835167ffffffffffffffff8082111561295757600080fd5b818601915086601f83011261296b57600080fd5b8151602061297b61287783612832565b82815260059290921b8401810191818101908a84111561299a57600080fd5b948201945b838610156129c15785516129b281612538565b8252948201949082019061299f565b918901519197509093505050808211156129da57600080fd5b6129e687838801612856565b935060408601519150808211156129fc57600080fd5b50612a09868287016128c1565b9150509250925092565b600060208284031215612a2557600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561061057610610612a5b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060208284031215612ade57600080fd5b815180151581146120fe57600080fd5b600060208284031215612b0057600080fd5b81516120fe81612538565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612b3c57612b3c612a5b565b506001019056fea164736f6c6343000814000a +0x608060405234801561001057600080fd5b50600436106101a35760003560e01c80638da5cb5b116100ee578063ebc1d6bb11610097578063f2fde38b11610071578063f2fde38b146103f5578063fc20935d14610408578063fe4b84df1461041b578063ffe736bf1461042e57600080fd5b8063ebc1d6bb146103a7578063ef90e1b0146103ba578063f0ca4adb146103e257600080fd5b8063b9292158116100c8578063b92921581461036e578063bbc66a9414610381578063dd34ca3b1461039457600080fd5b80638da5cb5b146102fc5780638e7492811461033b578063a00a8b2c1461035b57600080fd5b806353a57297116101505780636deb67991161012a5780636deb6799146102ce578063715018a6146102e157806380e50744146102e957600080fd5b806353a572971461028057806354255be0146102955780636dd6ef0c146102bb57600080fd5b80632e86bc01116101815780632e86bc0114610229578063370c998e14610249578063493a353c1461027757600080fd5b806302f55b61146101a8578063071b48fc146101d3578063158ef93e146101f4575b600080fd5b6101bb6101b636600461255a565b61046d565b6040516101ca939291906125c8565b60405180910390f35b6101e66101e136600461255a565b61055c565b6040519081526020016101ca565b6000546102199074010000000000000000000000000000000000000000900460ff1681565b60405190151581526020016101ca565b6101e661023736600461255a565b60066020526000908152604090205481565b61021961025736600461268f565b600360209081526000928352604080842090915290825290205460ff1681565b6101e660055481565b61029361028e3660046126c8565b610616565b005b6001806002806040805194855260208501939093529183015260608201526080016101ca565b6101e66102c936600461255a565b6109ab565b6101e66102dc36600461255a565b610a22565b610293610a7f565b6102936102f7366004612709565b610a93565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ca565b61034e61034936600461255a565b6111bc565b6040516101ca919061275c565b61031661036936600461276f565b61124c565b6101bb61037c36600461255a565b611291565b6101e661038f36600461255a565b611310565b6102936103a236600461276f565b611387565b6102936103b536600461279b565b61153b565b6103cd6103c836600461255a565b61169f565b604080519283526020830191909152016101ca565b6102936103f036600461268f565b611783565b61029361040336600461255a565b611981565b61029361041636600461276f565b611a38565b61029361042936600461279b565b611be9565b61044161043c36600461255a565b611cbf565b60408051921515835273ffffffffffffffffffffffffffffffffffffffff9091166020830152016101ca565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600160205260409081902090517f6cfa38730000000000000000000000000000000000000000000000000000000081526060918291829173__$c0b499b413513d0c67e2a6a17d90846cb3$__91636cfa3873916104ec9160040190815260200190565b600060405180830381865af4158015610509573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261054f919081019061292a565b9250925092509193909250565b73ffffffffffffffffffffffffffffffffffffffff811660009081526002602052604080822090517f59d556a8000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__906359d556a8906024015b602060405180830381865af41580156105ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106109190612a13565b92915050565b61061e611ee3565b73ffffffffffffffffffffffffffffffffffffffff831615801590610658575073ffffffffffffffffffffffffffffffffffffffff821615155b8015610688575073ffffffffffffffffffffffffffffffffffffffff831660009081526004602052604090205481105b80156106ef575073ffffffffffffffffffffffffffffffffffffffff8381166000908152600460205260409020805491841691839081106106cb576106cb612a2c565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16145b6107a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605660248201527f746f6b656e2061646472206e756c6c206f72206f7261636c652061646472206e60448201527f756c6c206f7220696e646578206f6620746f6b656e206f7261636c65206e6f7460648201527f206d617070656420746f206f7261636c65206164647200000000000000000000608482015260a4015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000818152600360209081526040808320948716835293815283822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055918152600490915220805461081790600190612a8a565b8154811061082757610827612a2c565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff86811684526004909252604090922080549190921691908390811061087157610871612a2c565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94851617905591851681526004909152604090208054806108db576108db612a9d565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905561093d8383611f64565b1561094c5761094c8383612105565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f6dc84b66cc948d847632b9d829f7cb1cb904fbf2c084554a9bc22ad9d845334060405160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526002602052604080822090517f6eafa6c3000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__90636eafa6c3906024016105cf565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600660205260408120548103610a5657505060055490565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604090205490565b610a87611ee3565b610a9160006124c3565b565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600360209081526040808320338452909152902054849060ff16610b55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f73656e64657220776173206e6f7420616e206f7261636c6520666f7220746f6b60448201527f656e206164647200000000000000000000000000000000000000000000000000606482015260840161079d565b73ffffffffffffffffffffffffffffffffffffffff851660009081526001602052604080822090517f59d556a8000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__906359d556a890602401602060405180830381865af4158015610be4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c089190612a13565b73ffffffffffffffffffffffffffffffffffffffff87166000908152600160205260409081902090517f95073a79000000000000000000000000000000000000000000000000000000008152600481019190915233602482015290915073__$c0b499b413513d0c67e2a6a17d90846cb3$__906395073a7990604401602060405180830381865af4158015610ca1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc59190612acc565b15610e395773ffffffffffffffffffffffffffffffffffffffff8681166000908152600160205260409081902090517f832a21470000000000000000000000000000000000000000000000000000000081526004810191909152336024820152604481018790528582166064820152908416608482015273__$c0b499b413513d0c67e2a6a17d90846cb3$__9063832a21479060a40160006040518083038186803b158015610d7357600080fd5b505af4158015610d87573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff86166000908152600260205260409081902090517fc1e728e9000000000000000000000000000000000000000000000000000000008152600481019190915233602482015273__$c0b499b413513d0c67e2a6a17d90846cb3$__9063c1e728e99060440160006040518083038186803b158015610e1c57600080fd5b505af4158015610e30573d6000803e3d6000fd5b50505050610efb565b73ffffffffffffffffffffffffffffffffffffffff8681166000908152600160205260409081902090517fd4a092720000000000000000000000000000000000000000000000000000000081526004810191909152336024820152604481018790528582166064820152908416608482015273__$c0b499b413513d0c67e2a6a17d90846cb3$__9063d4a092729060a40160006040518083038186803b158015610ee257600080fd5b505af4158015610ef6573d6000803e3d6000fd5b505050505b73ffffffffffffffffffffffffffffffffffffffff86166000908152600260205260409081902090517f0944c5940000000000000000000000000000000000000000000000000000000081526004810182905273__$c0b499b413513d0c67e2a6a17d90846cb3$__9163d4a0927291339042908590630944c59490602401602060405180830381865af4158015610f96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fba9190612aee565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b168152600481019490945273ffffffffffffffffffffffffffffffffffffffff928316602485015260448401919091521660648201526000608482015260a40160006040518083038186803b15801561103b57600080fd5b505af415801561104f573d6000803e3d6000fd5b5050604080514281526020810189905233935073ffffffffffffffffffffffffffffffffffffffff8a1692507f7cebb17173a9ed273d2b7538f64395c0ebf352ff743f1cf8ce66b437a6144213910160405180910390a373ffffffffffffffffffffffffffffffffffffffff861660009081526001602052604080822090517f59d556a8000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__906359d556a890602401602060405180830381865af4158015611135573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111599190612a13565b90508181146111b3578673ffffffffffffffffffffffffffffffffffffffff167fa9981ebfc3b766a742486e898f54959b050a66006dbce1a4155c1f84a08bcf41826040516111aa91815260200190565b60405180910390a25b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815260409182902080548351818402810184019094528084526060939283018282801561124057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611215575b50505050509050919050565b6004602052816000526040600020818154811061126857600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600260205260409081902090517f6cfa38730000000000000000000000000000000000000000000000000000000081526060918291829173__$c0b499b413513d0c67e2a6a17d90846cb3$__91636cfa3873916104ec9160040190815260200190565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604080822090517f6eafa6c3000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__90636eafa6c3906024016105cf565b73ffffffffffffffffffffffffffffffffffffffff82161580159061145e575073ffffffffffffffffffffffffffffffffffffffff82166000908152600260205260409081902090517f6eafa6c3000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__90636eafa6c390602401602060405180830381865af4158015611437573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061145b9190612a13565b81105b6114ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603460248201527f746f6b656e2061646472206e756c6c206f7220747279696e6720746f2072656d60448201527f6f766520746f6f206d616e79207265706f727473000000000000000000000000606482015260840161079d565b60005b818110156115365760008061150185611cbf565b91509150811561151a576115158582612105565b611521565b5050505050565b5050808061152e90612b0b565b9150506114ed565b505050565b611543611ee3565b600081116115d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f7265706f727420657870697279207365636f6e6473206d757374206265203e2060448201527f3000000000000000000000000000000000000000000000000000000000000000606482015260840161079d565b6005548103611664576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f7265706f72744578706972795365636f6e6473206861736e2774206368616e6760448201527f6564000000000000000000000000000000000000000000000000000000000000606482015260840161079d565b60058190556040518181527fc68a9b88effd8a11611ff410efbc83569f0031b7bc70dd455b61344c7f0a042f9060200160405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001602052604080822090517f59d556a8000000000000000000000000000000000000000000000000000000008152829173__$c0b499b413513d0c67e2a6a17d90846cb3$__916359d556a8916117189160040190815260200190565b602060405180830381865af4158015611735573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117599190612a13565b61176284611310565b156117775769d3c21bcecceda100000061177a565b60005b91509150915091565b61178b611ee3565b73ffffffffffffffffffffffffffffffffffffffff8216158015906117c5575073ffffffffffffffffffffffffffffffffffffffff811615155b8015611804575073ffffffffffffffffffffffffffffffffffffffff80831660009081526003602090815260408083209385168352929052205460ff16155b6118b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605a60248201527f746f6b656e206164647220776173206e756c6c206f72206f7261636c6520616460448201527f647220776173206e756c6c206f72206f7261636c652061646472206973206e6f60648201527f7420616e206f7261636c6520666f7220746f6b656e2061646472000000000000608482015260a40161079d565b73ffffffffffffffffffffffffffffffffffffffff808316600081815260036020908152604080832094861680845294825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091558484526004835281842080549182018155845291832090910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001685179055517f828d2be040dede7698182e08dfa8bfbd663c879aee772509c4a2bd961d0ed43f9190a35050565b611989611ee3565b73ffffffffffffffffffffffffffffffffffffffff8116611a2c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161079d565b611a35816124c3565b50565b611a40611ee3565b60008111611ad0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f7265706f727420657870697279207365636f6e6473206d757374206265203e2060448201527f3000000000000000000000000000000000000000000000000000000000000000606482015260840161079d565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600660205260409020548103611b84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f746f6b656e207265706f72744578706972795365636f6e6473206861736e277460448201527f206368616e676564000000000000000000000000000000000000000000000000606482015260840161079d565b73ffffffffffffffffffffffffffffffffffffffff8216600081815260066020908152604091829020849055815192835282018390527ff8324c8592dfd9991ee3e717351afe0a964605257959e3d99b0eb3d45bff9422910160405180910390a15050565b60005474010000000000000000000000000000000000000000900460ff1615611c6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f636f6e747261637420616c726561647920696e697469616c697a656400000000604482015260640161079d565b600080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055611cb6336124c3565b611a358161153b565b60008073ffffffffffffffffffffffffffffffffffffffff8316611d3f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f746f6b656e20616464726573732063616e6e6f74206265206e756c6c00000000604482015260640161079d565b73ffffffffffffffffffffffffffffffffffffffff831660009081526002602052604080822090517fd938ec7b000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__9063d938ec7b90602401602060405180830381865af4158015611dce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df29190612aee565b73ffffffffffffffffffffffffffffffffffffffff85811660009081526002602052604080822090517f7c6bb8620000000000000000000000000000000000000000000000000000000081526004810191909152918316602483015291925073__$c0b499b413513d0c67e2a6a17d90846cb3$__90637c6bb86290604401602060405180830381865af4158015611e8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eb19190612a13565b9050611ebc85610a22565b611ec68242612a8a565b10611ed75750600194909350915050565b50600094909350915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161079d565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604080822090517f95073a7900000000000000000000000000000000000000000000000000000000815273__$c0b499b413513d0c67e2a6a17d90846cb3$__916395073a7991611ff99190869060040191825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b602060405180830381865af4158015612016573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203a9190612acc565b80156120fe575073ffffffffffffffffffffffffffffffffffffffff8381166000908152600260205260409081902090517f95073a790000000000000000000000000000000000000000000000000000000081526004810191909152908316602482015273__$c0b499b413513d0c67e2a6a17d90846cb3$__906395073a7990604401602060405180830381865af41580156120da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120fe9190612acc565b9392505050565b61210e826109ab565b600114801561212257506121228282611f64565b1561212b575050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604080822090517f59d556a8000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__906359d556a890602401602060405180830381865af41580156121ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121de9190612a13565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600160205260409081902090517fc1e728e900000000000000000000000000000000000000000000000000000000815291925073__$c0b499b413513d0c67e2a6a17d90846cb3$__9163c1e728e99161227691869060040191825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60006040518083038186803b15801561228e57600080fd5b505af41580156122a2573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff84166000908152600260205260409081902090517fc1e728e900000000000000000000000000000000000000000000000000000000815273__$c0b499b413513d0c67e2a6a17d90846cb3$__925063c1e728e99161233b91869060040191825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b60006040518083038186803b15801561235357600080fd5b505af4158015612367573d6000803e3d6000fd5b505060405173ffffffffffffffffffffffffffffffffffffffff8086169350861691507fe21a44017b6fa1658d84e937d56ff408501facdb4ff7427c479ac460d76f789390600090a373ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604080822090517f59d556a8000000000000000000000000000000000000000000000000000000008152600481019190915273__$c0b499b413513d0c67e2a6a17d90846cb3$__906359d556a890602401602060405180830381865af415801561243f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124639190612a13565b90508181146124bd578373ffffffffffffffffffffffffffffffffffffffff167fa9981ebfc3b766a742486e898f54959b050a66006dbce1a4155c1f84a08bcf41826040516124b491815260200190565b60405180910390a25b50505050565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a3557600080fd5b60006020828403121561256c57600080fd5b81356120fe81612538565b600081518084526020808501945080840160005b838110156125bd57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161258b565b509495945050505050565b6060815260006125db6060830186612577565b82810360208481019190915285518083528682019282019060005b81811015612612578451835293830193918301916001016125f6565b50508481036040860152855180825290820192508186019060005b81811015612681578251600480821061266e577f4e487b71000000000000000000000000000000000000000000000000000000006000526021815260246000fd5b508552938301939183019160010161262d565b509298975050505050505050565b600080604083850312156126a257600080fd5b82356126ad81612538565b915060208301356126bd81612538565b809150509250929050565b6000806000606084860312156126dd57600080fd5b83356126e881612538565b925060208401356126f881612538565b929592945050506040919091013590565b6000806000806080858703121561271f57600080fd5b843561272a81612538565b935060208501359250604085013561274181612538565b9150606085013561275181612538565b939692955090935050565b6020815260006120fe6020830184612577565b6000806040838503121561278257600080fd5b823561278d81612538565b946020939093013593505050565b6000602082840312156127ad57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561282a5761282a6127b4565b604052919050565b600067ffffffffffffffff82111561284c5761284c6127b4565b5060051b60200190565b600082601f83011261286757600080fd5b8151602061287c61287783612832565b6127e3565b82815260059290921b8401810191818101908684111561289b57600080fd5b8286015b848110156128b6578051835291830191830161289f565b509695505050505050565b600082601f8301126128d257600080fd5b815160206128e261287783612832565b82815260059290921b8401810191818101908684111561290157600080fd5b8286015b848110156128b65780516004811061291d5760008081fd5b8352918301918301612905565b60008060006060848603121561293f57600080fd5b835167ffffffffffffffff8082111561295757600080fd5b818601915086601f83011261296b57600080fd5b8151602061297b61287783612832565b82815260059290921b8401810191818101908a84111561299a57600080fd5b948201945b838610156129c15785516129b281612538565b8252948201949082019061299f565b918901519197509093505050808211156129da57600080fd5b6129e687838801612856565b935060408601519150808211156129fc57600080fd5b50612a09868287016128c1565b9150509250925092565b600060208284031215612a2557600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561061057610610612a5b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600060208284031215612ade57600080fd5b815180151581146120fe57600080fd5b600060208284031215612b0057600080fd5b81516120fe81612538565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612b3c57612b3c612a5b565b506001019056fea164736f6c6343000813000a diff --git a/contracts/celo/compiled/update.sh b/contracts/celo/compiled/update.sh index 4a468d0d72..564a1f8c0f 100755 --- a/contracts/celo/compiled/update.sh +++ b/contracts/celo/compiled/update.sh @@ -5,7 +5,7 @@ CONTRACTS_DIR=${CELO_OPTIMISM_REPO:-~/optimism}/packages/contracts-bedrock (cd "$CONTRACTS_DIR" && forge build) -for contract in GoldToken CeloRegistry SortedOracles FeeCurrencyWhitelist FeeCurrency Proxy AddressSortedLinkedListWithMedian +for contract in GoldToken CeloRegistry SortedOracles FeeCurrencyWhitelist FeeCurrency Proxy AddressSortedLinkedListWithMedian MockSortedOracles do contract_json="$CONTRACTS_DIR/forge-artifacts/$contract.sol/$contract.json" jq .abi "$contract_json" > "$SCRIPT_DIR/$contract.abi" diff --git a/core/blockchain_celo_test.go b/core/blockchain_celo_test.go new file mode 100644 index 0000000000..e982e08d97 --- /dev/null +++ b/core/blockchain_celo_test.go @@ -0,0 +1,129 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/ethash" + fee_currencies "github.com/ethereum/go-ethereum/contracts" + contracts "github.com/ethereum/go-ethereum/contracts/celo" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" +) + +// TestNativeTransferWithFeeCurrency tests the following: +// +// 1. A transaction whose gasFeeCap is greater than the baseFee is valid. +// 2. Gas accounting for celo fee currency transactions is correct. +// 3. Only the transaction's tip will be received by the coinbase. +// 4. The transaction sender pays for both the tip and baseFee. +// 5. The base fee goes to the fee handler. +func TestNativeTransferWithFeeCurrency(t *testing.T) { + testNativeTransferWithFeeCurrency(t, rawdb.HashScheme) + testNativeTransferWithFeeCurrency(t, rawdb.PathScheme) +} + +func testNativeTransferWithFeeCurrency(t *testing.T, scheme string) { + var ( + aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") + engine = ethash.NewFaker() + + // A sender who makes transactions, has some funds + key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + config = *params.AllEthashProtocolChanges + funds = DevBalance + gspec = &Genesis{ + Config: &config, + Alloc: celoGenesisAccounts(addr1), + } + ) + gspec.Config.Cel2Time = uint64ptr(0) + + signer := types.LatestSigner(gspec.Config) + + _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { + b.SetCoinbase(common.Address{1}) + + txdata := &types.CeloDynamicFeeTx{ + ChainID: gspec.Config.ChainID, + Nonce: 0, + To: &aa, + Gas: 100000, + GasFeeCap: newGwei(5), + GasTipCap: big.NewInt(2), + Data: []byte{}, + FeeCurrency: &FeeCurrencyAddr, + } + tx := types.NewTx(txdata) + tx, _ = types.SignTx(tx, signer, key1) + + b.AddTx(tx) + }) + chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, engine, vm.Config{}, nil, nil) + if err != nil { + t.Fatalf("failed to create tester chain: %v", err) + } + defer chain.Stop() + + if n, err := chain.InsertChain(blocks); err != nil { + t.Fatalf("block %d: failed to insert into chain: %v", n, err) + } + + block := chain.GetBlockByNumber(1) + + // 1+2: Ensure correct gas amount is deducted + expectedGas := uint64(71000) + if block.GasUsed() != expectedGas { + t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed()) + } + + state, _ := chain.State() + + backend := CeloBackend{ + chainConfig: chain.chainConfig, + state: state, + } + actual, _ := fee_currencies.GetBalanceOf(&backend, block.Coinbase(), FeeCurrencyAddr) + + // 3: Ensure that miner received only the tx's tip. + expected := new(big.Int).SetUint64(block.GasUsed() * block.Transactions()[0].GasTipCap().Uint64()) + if actual.Cmp(expected) != 0 { + t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual) + } + + // 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee). + actual, _ = fee_currencies.GetBalanceOf(&backend, addr1, FeeCurrencyAddr) + actual = new(big.Int).Sub(funds, actual) + expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64())) + if actual.Cmp(expected) != 0 { + t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual) + } + + // 5; Check that base fee has been moved to fee handler. + actual, _ = fee_currencies.GetBalanceOf(&backend, contracts.FeeHandlerAddress, FeeCurrencyAddr) + expected = new(big.Int).SetUint64(block.GasUsed() * block.BaseFee().Uint64()) + if actual.Cmp(expected) != 0 { + t.Fatalf("fee handler balance incorrect: expected %d, got %d", expected, actual) + } +} diff --git a/core/celo_genesis.go b/core/celo_genesis.go index 8f4cde860c..79dfa9e3dc 100644 --- a/core/celo_genesis.go +++ b/core/celo_genesis.go @@ -1,7 +1,6 @@ package core import ( - "bytes" "encoding/hex" "fmt" "math/big" @@ -31,11 +30,16 @@ func CalcMapAddr(slot common.Hash, key common.Hash) common.Hash { return crypto.Keccak256Hash(append(key.Bytes(), slot.Bytes()...)) } -var DevPrivateKey, _ = crypto.HexToECDSA("2771aff413cac48d9f8c114fabddd9195a2129f3c2c436caa07e27bb7f58ead5") -var DevAddr = common.BytesToAddress(DevAddr32.Bytes()) -var DevAddr32 = common.HexToHash("0x42cf1bbc38BaAA3c4898ce8790e21eD2738c6A4a") +var ( + DevPrivateKey, _ = crypto.HexToECDSA("2771aff413cac48d9f8c114fabddd9195a2129f3c2c436caa07e27bb7f58ead5") + DevAddr = common.BytesToAddress(DevAddr32.Bytes()) + DevAddr32 = common.HexToHash("0x42cf1bbc38BaAA3c4898ce8790e21eD2738c6A4a") -func celoGenesisAccounts() map[common.Address]GenesisAccount { + FeeCurrencyAddr = common.HexToAddress("0xce16") + DevBalance, _ = new(big.Int).SetString("100000000000000000000", 10) +) + +func celoGenesisAccounts(fundedAddr common.Address) GenesisAlloc { // As defined in ERC-1967: Proxy Storage Slots (https://eips.ethereum.org/EIPS/eip-1967) var ( proxy_owner_slot = common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103") @@ -55,8 +59,8 @@ func celoGenesisAccounts() map[common.Address]GenesisAccount { if err != nil { panic(err) } - sortedOraclesBytecodeLinked := bytes.Replace(contracts.SortedOraclesBytecodeRaw, []byte("__$c0b499b413513d0c67e2a6a17d90846cb3$__"), []byte("000000000000000000000000000000000000ce17"), -1) - sortedOraclesBytecode, err := DecodeHex(sortedOraclesBytecodeLinked) + // sortedOraclesBytecodeLinked := bytes.Replace(contracts.SortedOraclesBytecodeRaw, []byte("__$c0b499b413513d0c67e2a6a17d90846cb3$__"), []byte("000000000000000000000000000000000000ce17"), -1) + sortedOraclesBytecode, err := DecodeHex(contracts.MockSortedOraclesBytecodeRaw) if err != nil { panic(err) } @@ -73,12 +77,9 @@ func celoGenesisAccounts() map[common.Address]GenesisAccount { panic(err) } - devBalance, ok := new(big.Int).SetString("100000000000000000000", 10) var devBalance32 common.Hash - devBalance.FillBytes(devBalance32[:]) - if !ok { - panic("Could not set devBalance!") - } + DevBalance.FillBytes(devBalance32[:]) + return map[common.Address]GenesisAccount{ contracts.RegistryAddress: { // Registry Proxy Code: proxyBytecode, @@ -109,23 +110,21 @@ func celoGenesisAccounts() map[common.Address]GenesisAccount { Code: feeCurrencyWhitelistBytecode, Balance: big.NewInt(0), Storage: map[common.Hash]common.Hash{ - common.HexToHash("0x1"): common.HexToHash("0x1"), // array length 1 - crypto.Keccak256Hash(common.HexToHash("0x1").Bytes()): common.HexToHash("0xce16"), // FeeCurrency + common.HexToHash("0x1"): common.HexToHash("0x1"), // array length 1 + crypto.Keccak256Hash(common.HexToHash("0x1").Bytes()): common.BytesToHash(FeeCurrencyAddr[:]), // FeeCurrency }, }, contracts.SortedOraclesAddress: { - Code: sortedOraclesBytecode, - Storage: map[common.Hash]common.Hash{ - common.HexToHash("0x0"): DevAddr32, // _owner - }, + Code: sortedOraclesBytecode, Balance: big.NewInt(0), }, - common.HexToAddress("0xce16"): { + FeeCurrencyAddr: { Code: feeCurrencyBytecode, Balance: big.NewInt(0), Storage: map[common.Hash]common.Hash{ - CalcMapAddr(common.HexToHash("0x0"), DevAddr32): devBalance32, // _balances[DevAddr] - common.HexToHash("0x2"): devBalance32, // _totalSupply + CalcMapAddr(common.HexToHash("0x0"), DevAddr32): devBalance32, // _balances[DevAddr] + CalcMapAddr(common.HexToHash("0x0"), common.BytesToHash(fundedAddr[:])): devBalance32, // _balances[fund] + common.HexToHash("0x2"): devBalance32, // _totalSupply }, }, common.HexToAddress("0xce17"): { @@ -133,7 +132,7 @@ func celoGenesisAccounts() map[common.Address]GenesisAccount { Balance: big.NewInt(0), }, DevAddr: { - Balance: devBalance, + Balance: DevBalance, }, } } diff --git a/core/genesis.go b/core/genesis.go index d2d9edfa4d..25e27bf326 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -641,7 +641,7 @@ func DeveloperGenesisBlock(gasLimit uint64, faucet common.Address) *Genesis { } // Add state from celoGenesisAccounts - for addr, data := range celoGenesisAccounts() { + for addr, data := range celoGenesisAccounts(common.HexToAddress("0x2")) { genesis.Alloc[addr] = data }