From 0e9a294d9ef45c52ec9d9960f305aed7540980a8 Mon Sep 17 00:00:00 2001 From: Franfran <51274081+iFrostizz@users.noreply.github.com> Date: Thu, 12 Sep 2024 13:02:34 +0200 Subject: [PATCH] Add price feed rounds (#64) * add price feed rounds * remove unused state var * fmt and lint * add round unit tests * fix tests * lint * update bindings * pass oracle info for bindings * update bindings * update bin * remove unused constants --- .gitmodules | 3 + .../go/PriceFeedImporter/PriceFeedImporter.go | 201 ++++++++++++++---- .../MockPriceFeedAggregator.go | 2 +- contracts/lib/chainlink | 1 + contracts/remappings.txt | 1 + contracts/src/PriceFeedImporter.sol | 58 +++-- contracts/src/RLPUtils.sol | 1 - contracts/test/EventImporterTests.sol | 82 +++++++ contracts/test/PriceFeedImporterTests.sol | 116 +++++----- tests/flows/import_price_feed.go | 3 + tests/utils/utils.go | 6 + 11 files changed, 366 insertions(+), 108 deletions(-) create mode 160000 contracts/lib/chainlink create mode 100644 contracts/test/EventImporterTests.sol diff --git a/.gitmodules b/.gitmodules index 4075a17..49c7d0f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "contracts/lib/solidity-merkle-trees"] path = contracts/lib/solidity-merkle-trees url = git@github.com:michaelkaplan13/solidity-merkle-trees.git +[submodule "contracts/lib/chainlink"] + path = contracts/lib/chainlink + url = https://github.com/smartcontractkit/chainlink diff --git a/abi-bindings/go/PriceFeedImporter/PriceFeedImporter.go b/abi-bindings/go/PriceFeedImporter/PriceFeedImporter.go index ee83aa7..f3f30d3 100644 --- a/abi-bindings/go/PriceFeedImporter/PriceFeedImporter.go +++ b/abi-bindings/go/PriceFeedImporter/PriceFeedImporter.go @@ -31,8 +31,8 @@ var ( // PriceFeedImporterMetaData contains all meta data concerning the PriceFeedImporter contract. var PriceFeedImporterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID_\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"sourceOracleAggregator_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"currentAnswer\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint80\",\"name\":\"roundID\",\"type\":\"uint80\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"}],\"name\":\"AnswerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"loggerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"logIndex\",\"type\":\"uint256\"}],\"name\":\"EventImported\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ANSWER_UPDATED_EVENT_SIGNATURE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"blockHeader\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"receiptProof\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256\",\"name\":\"logIndex\",\"type\":\"uint256\"}],\"name\":\"importEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestSourceBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestSourceLogIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestSourceTxIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"roundID\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sourceBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sourceOracleAggregator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updatedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"warpMessenger\",\"outputs\":[{\"internalType\":\"contractIWarpMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60c06040523480156200001157600080fd5b5060405162002da438038062002da4833981016040819052620000349162000072565b600080546001600160a01b0319167302000000000000000000000000000000000000051790556080919091526001600160a01b031660a052620000b1565b600080604083850312156200008657600080fd5b825160208401519092506001600160a01b0381168114620000a657600080fd5b809150509250929050565b60805160a051612cbf620000e5600039600081816101b70152610fda0152600081816101410152610f740152612cbf6000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80637519ab50116100715780637519ab501461016c5780637e1b4cb0146101755780638716cde51461017e578063c9572e1414610187578063ce2723fc146101b2578063feaf968c146101d957600080fd5b8063042a7c97146100b957806308fd4323146100f35780630a8bfac9146100fc57806314f8b4241461011157806329b7b3fd1461013c5780634af37a1114610163575b600080fd5b6100e07f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f81565b6040519081526020015b60405180910390f35b6100e060065481565b61010f61010a366004612807565b610215565b005b600254610124906001600160501b031681565b6040516001600160501b0390911681526020016100ea565b6100e07f000000000000000000000000000000000000000000000000000000000000000081565b6100e060055481565b6100e060035481565b6100e060015481565b6100e060045481565b60005461019a906001600160a01b031681565b6040516001600160a01b0390911681526020016100ea565b61019a7f000000000000000000000000000000000000000000000000000000000000000081565b6101e1610604565b604080516001600160501b03968716815260208101959095528401929092526060830152909116608082015260a0016100ea565b6000805460405163ce7f592960e01b81526004810183905282916001600160a01b03169063ce7f592990602401606060405180830381865afa15801561025f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102839190612906565b91509150806102d15760405162461bcd60e51b8152602060048201526015602482015274092dcecc2d8d2c840aec2e4e084d8dec6d690c2e6d605b1b60448201526064015b60405180910390fd5b816020015188886040516102e692919061297d565b6040518091039020146103315760405162461bcd60e51b815260206004820152601360248201527224b73b30b634b210313637b1b5a432b0b232b960691b60448201526064016102c8565b6000806103738a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061066c92505050565b60408051600180825281830190925292945090925060009190816020015b60608152602001906001900390816103915790505090506103b18961074f565b816000815181106103c4576103c461298d565b602090810291909101015260006103e5836103df8a8c6129a3565b846107ea565b9050805160011461044b5760405162461bcd60e51b815260206004820152602a60248201527f496e76616c6964206e756d626572206f6620726573756c747320696e2072656360448201526932b4b83a10383937b7b360b11b60648201526084016102c8565b6000816000815181106104605761046061298d565b60200260200101516020015151116104b25760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103932b1b2b4b83a10383937b7b360591b60448201526064016102c8565b60006104e36104de836000815181106104cd576104cd61298d565b602002602001015160200151610c7b565b610ca8565b9050806080015151881061052d5760405162461bcd60e51b8152602060048201526011602482015270092dcecc2d8d2c840d8dece40d2dcc8caf607b1b60448201526064016102c8565b61057d6040518060a00160405280896000015181526020018781526020018d81526020018a815260200183608001518b8151811061056d5761056d61298d565b6020026020010151815250610f6e565b806080015188815181106105935761059361298d565b6020026020010151600001516001600160a01b0316876020015188600001517ffdb2f8239033f2b8c1122b2a4b6af55bb0b0b05e4050b5ecd9eafa153d3cd41d8e8c6040516105ec929190918252602082015260400190565b60405180910390a45050505050505050505050505050565b60008060008060006003546000036106485760405162461bcd60e51b81526020600482015260076024820152664e6f206461746160c81b60448201526064016102c8565b50506002546001546003546001600160501b03909216959094509092508291508490565b600080600061068261067d85610c7b565b611314565b9050600f815110156106ed5760405162461bcd60e51b815260206004820152602e60248201527f496e76616c6964206e756d626572206f6620524c5020656c656d656e7473206960448201526d3710313637b1b5903432b0b232b960911b60648201526084016102c8565b6000610712826008815181106107055761070561298d565b6020026020010151611429565b905060006107398360058151811061072c5761072c61298d565b6020026020010151611477565b61074290612a77565b9196919550909350505050565b6060816000036107765750506040805180820190915260018152600160ff1b602082015290565b607f8211156107ba5760405162461bcd60e51b815260206004820152601060248201526f092dcecc2d8d2c840e8f040d2dcc8caf60831b60448201526064016102c8565b6040516001600160f81b031960f884901b1660208201526021016040516020818303038152906040529050919050565b6060600082516001600160401b03811115610807576108076128c0565b60405190808252806020026020018201604052801561084c57816020015b60408051808201909152606080825260208201528152602001906001900390816108255790505b509050600084516001600160401b0381111561086a5761086a6128c0565b6040519080825280602002602001820160405280156108b057816020015b6040805180820190915260008152606060208201528152602001906001900390816108885790505b50905060005b855181101561093d5760405180604001604052808783815181106108dc576108dc61298d565b60200260200101518051906020012081526020018783815181106109025761090261298d565b602002602001015181525082828151811061091f5761091f61298d565b6020026020010181905250808061093590612ab1565b9150506108b6565b5060005b8451811015610c705784818151811061095c5761095c61298d565b60200260200101518382815181106109765761097661298d565b602002602001015160000181905250600060405180604001604052808784815181106109a4576109a461298d565b602002602001015181526020016000815250905060006109cc6109c7858b6114f4565b6115a1565b905060015b8015610c5a576040805160808101825260008082526020820181905291810191909152606080820152610a03836116f6565b15610ad1576000610a138461170b565b9050600060028660200151610a289190612ae0565b15610a4e5760028660200151610a3e9190612af4565b610a49906001612b08565b610a5f565b60028660200151610a5f9190612af4565b90506040518060400160405280610a7a8860000151846117b5565b815260200160008152509550610a9482600001518761187f565b15610ac957610aa78883602001516118ac565b898881518110610ab957610ab961298d565b6020026020010151602001819052505b505050610c5a565b60c083015115610b6f576000610ae6846118f5565b9050610af6858260000151611a19565b15610b62576000610b0a8260000151611a36565b8660200151610b199190612b08565b90506040518060400160405280610b408860000151600285610b3b9190612af4565b6117b5565b8152602001610b50600284612ae0565b81525095508160200151925050610b69565b5050610c5a565b50610c37565b60e083015115610c2a576000610b8484611a59565b9050610b8f85611c61565b15610bda578051511515600103610b6257610bb2878260000151602001516118ac565b888781518110610bc457610bc461298d565b6020026020010151602001819052505050610c5a565b60008160200151610bec876000611c73565b60108110610bfc57610bfc61298d565b602002015180519091501515600103610ac957610c1a866001611cfd565b9550806020015192505050610c37565b825115610c375750610c5a565b610c446109c787836118ac565b9250508080610c5290612ab1565b9150506109d1565b5050508080610c6890612ab1565b915050610941565b509095945050505050565b60408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b6040805160a08101825260008082526060602083018190529282015281810182905260808101919091526000610cdd83611d40565b610d8d57506020820151805160001a906001821480610cff57508160ff166002145b610d555760405162461bcd60e51b815260206004820152602160248201527f496e76616c6964207478207479706520666f72206e6f6e2d6c656761637920746044820152600f60fb1b60648201526084016102c8565b604051806040016040528060018660000151610d719190612b1b565b815260200185602001516001610d879190612b08565b90529350505b6000610d9884611314565b90508051600414610dfd5760405162461bcd60e51b815260206004820152602960248201527f496e76616c6964206e756d626572206f6620524c5020656c656d656e747320696044820152681b881c9958d95a5c1d60ba1b60648201526084016102c8565b6040805160a0810182526060602082018190526000928201839052808201819052608082015260ff8416815282519091610e409184919061072c5761072c61298d565b8160200181905250610e5e826001815181106107055761070561298d565b6001600160401b031660408201528151610e85908390600290811061072c5761072c61298d565b81606001819052506000610eb283600381518110610ea557610ea561298d565b6020026020010151611314565b905080516001600160401b03811115610ecd57610ecd6128c0565b604051908082528060200260200182016040528015610f0657816020015b610ef3612654565b815260200190600190039081610eeb5790505b50608083015260005b8151811015610c7057610f3a828281518110610f2d57610f2d61298d565b6020026020010151611d7b565b83608001518281518110610f5057610f5061298d565b60200260200101819052508080610f6690612ab1565b915050610f0f565b805181907f000000000000000000000000000000000000000000000000000000000000000014610fd85760405162461bcd60e51b8152602060048201526015602482015274125b9d985b1a5908189b1bd8dad8da185a5b881251605a1b60448201526064016102c8565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168160800151600001516001600160a01b03161461105a5760405162461bcd60e51b8152602060048201526016602482015275496e76616c6964206c6f67676572206164647265737360501b60448201526064016102c8565b81806080015160200151516003146110a95760405162461bcd60e51b8152602060048201526012602482015271496e76616c6964206c6f6720746f7069637360701b60448201526064016102c8565b806080015160400151516020146110f55760405162461bcd60e51b815260206004820152601060248201526f496e76616c6964206c6f67206461746160801b60448201526064016102c8565b7f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f8160800151602001516000815181106111315761113161298d565b6020026020010151146111865760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206576656e74207369676e617475726500000000000000000060448201526064016102c8565b826004548160200151101580156111b15750600454816020015111806111b157506005548160400151115b80156111e15750600454816020015111806111d157506005548160400151115b806111e157506006548160600151115b61121b5760405162461bcd60e51b815260206004820152600b60248201526a14dd185b1948195d995b9d60aa1b60448201526064016102c8565b8360800151602001516001815181106112365761123661298d565b602002602001015160001c6001819055508360800151602001516002815181106112625761126261298d565b60209081029190910101516002805469ffffffffffffffffffff19166001600160501b039092169190911790556080840151604001516112a190612a77565b600381905560208581015160045560408087015160055560608088015160065560015460025483519182526001600160501b031693810193909352908201929092527f5b196ccf306f345de8745dffeaf185f4cafe74a334e2b2466d04c880071533b9910160405180910390a150505050565b606061131f82611d40565b61132857600080fd5b600061133383611f0c565b90506000816001600160401b0381111561134f5761134f6128c0565b60405190808252806020026020018201604052801561139457816020015b604080518082019091526000808252602082015281526020019060019003908161136d5790505b50905060006113a68560200151611f91565b85602001516113b59190612b08565b90506000805b8481101561141e576113cc83612012565b91506040518060400160405280838152602001848152508482815181106113f5576113f561298d565b602090810291909101015261140a8284612b08565b92508061141681612ab1565b9150506113bb565b509195945050505050565b80516000901580159061143e57508151602110155b61144757600080fd5b600080611453846120bb565b81519193509150602082101561146f5760208290036101000a90045b949350505050565b805160609061148557600080fd5b600080611491846120bb565b915091506000816001600160401b038111156114af576114af6128c0565b6040519080825280601f01601f1916602001820160405280156114d9576020820181803683370190505b509050602081016114eb8482856120f5565b50949350505050565b606060005b835181101561155e57828482815181106115155761151561298d565b6020026020010151600001510361154c578381815181106115385761153861298d565b60200260200101516020015191505061159b565b8061155681612ab1565b9150506114f9565b5060405162461bcd60e51b8152602060048201526011602482015270496e636f6d706c6574652050726f6f662160781b60448201526064016102c8565b92915050565b6115a961267e565b6115b161267e565b600060405180604001604052808581526020016000815250905061160a846040518060400160405280602081526020017f56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421815250612178565b1561161a57506001815292915050565b600061162861067d86610c7b565b80519091506000819003611643575050600182525092915050565b8060020361169d5760006116638360008151811061072c5761072c61298d565b602081015190915060fc1c600281148061167d5750806003145b1561168e5760016020870152611696565b600160c08701525b50506116e8565b806011036116b157600160e08501526116e8565b60405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964206461746160a01b60448201526064016102c8565b505061012082015292915050565b600081602001518061159b5750506040015190565b6117136126e4565b61171b6126e4565b600061173261067d85610120015160000151610c7b565b9050600061174c8260018151811061072c5761072c61298d565b905060405180604001604052806117796117728560008151811061072c5761072c61298d565b60016121a8565b81526000602091820181905291855260408051608081018252838152808301939093526001908301526060820192909252908301525092915050565b815160609060006117c68483612b1b565b90508382101561180c5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b60448201526064016102c8565b60608115801561182b5760405191506000825260208201604052611875565b6040519150601f8316801560200281840101848101888315602002848c0101015b8183101561186457805183526020928301920161184c565b5050848452601f01601f1916604052505b5095945050505050565b600061188a82611a36565b61189384611a36565b1480156118a557506118a58383611a19565b9392505050565b60608160400151156118c35750606081015161159b565b8151156118df576118d88383602001516114f4565b905061159b565b5060408051602081019091526000815292915050565b6118fd6126e4565b6119056126e4565b600061191c61067d85610120015160000151610c7b565b905060006119368260018151811061072c5761072c61298d565b9050600060046119528460008151811061072c5761072c61298d565b6000815181106119645761196461298d565b602001015160f81c60f81b6001600160f81b031916901c60f81c600116905060405180604001604052806119c66119a78660008151811061072c5761072c61298d565b60026119b4866001612b2e565b6119be9190612b47565b60ff166121a8565b815260ff83166020918201529085526040805160808101909152600181529081016119f0846121e0565b815260006020808301829052604080519283528282018152909201528501525091949350505050565b6000611a2482611a36565b611a2e8484612248565b149392505050565b600081602001516002836000015151611a4f9190612b69565b61159b9190612b1b565b611a61612735565b611a69612735565b6000611a8061067d85610120015160000151610c7b565b9050611a8a612751565b60005b6010811015611b92576000611aad84838151811061072c5761072c61298d565b90508051602014611b15576040805180820182526000808252825160808101845281815260208082018390528185018390528451928352828101909452606081019190915291810191909152838360108110611b0b57611b0b61298d565b6020020152611b7f565b6000611b20826121e0565b60408051808201825260018082528251608081018452908152602080820185905260008285018190528451908152808201909452606082019390935291810191909152909150848460108110611b7857611b7861298d565b6020020152505b5080611b8a81612ab1565b915050611a8d565b50611bb1611bac8360108151811061072c5761072c61298d565b6123c6565b15611bfe5760408051808201825260008082528251608081018452818152602080820183905281850183905284519283528281019094526060810191909152918101919091528352611c55565b604051806040016040528060011515815260200160405180608001604052806000151581526020016000801b8152602001600115158152602001611c4e8660108151811061072c5761072c61298d565b9052905283525b60208301525092915050565b6000611c6c82611a36565b1592915050565b6000806002838560200151611c889190612b08565b611c929190612af4565b905060006002848660200151611ca89190612b08565b611cb29190612ae0565b9050600085600001518381518110611ccc57611ccc61298d565b016020015160f81c905060018214611ceb5760048160ff16901c611cf0565b80600f165b60ff169695505050505050565b604080518082019091526060815260006020820152604051806040016040528084600001518152602001838560200151611d379190612b08565b90529392505050565b80516000908103611d5357506000919050565b6020820151805160001a9060c0821015611d71575060009392505050565b5060019392505050565b611d83612654565b6000611d8e83611314565b90508051600314611def5760405162461bcd60e51b815260206004820152602560248201527f496e76616c6964206e756d626572206f6620524c5020656c656d656e747320696044820152646e206c6f6760d81b60648201526084016102c8565b611df7612654565b611e1a82600081518110611e0d57611e0d61298d565b6020026020010151612431565b6001600160a01b031681528151600090611e419084906001908110610ea557610ea561298d565b905080516001600160401b03811115611e5c57611e5c6128c0565b604051908082528060200260200182016040528015611e85578160200160208202803683370190505b50602083015260005b8151811015611ee857611eac82828151811061072c5761072c61298d565b611eb590612a77565b83602001518281518110611ecb57611ecb61298d565b602090810291909101015280611ee081612ab1565b915050611e8e565b50611eff8360028151811061072c5761072c61298d565b6040830152509392505050565b80516000908103611f1f57506000919050565b600080611f2f8460200151611f91565b8460200151611f3e9190612b08565b9050600084600001518560200151611f569190612b08565b90505b80821015611f8857611f6a82612012565b611f749083612b08565b915082611f8081612ab1565b935050611f59565b50909392505050565b8051600090811a6080811015611faa5750600092915050565b60b8811080611fc5575060c08110801590611fc5575060f881105b15611fd35750600192915050565b60c081101561200057611fe8600160b8612b80565b611ff59060ff1682612b1b565b6118a5906001612b08565b611fe8600160f8612b80565b50919050565b80516000908190811a608081101561202d57600191506120b4565b60b881101561205357612041608082612b1b565b61204c906001612b08565b91506120b4565b60c08110156120805760b78103600185019450806020036101000a855104600182018101935050506120b4565b60f88110156120945761204160c082612b1b565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b60008060006120cd8460200151611f91565b905060008185602001516120e19190612b08565b905060008286600001516107429190612b1b565b8060000361210257505050565b6020811061213a5782518252612119602084612b08565b9250612126602083612b08565b9150612133602082612b1b565b9050612102565b8015612173576000600161214f836020612b1b565b61215b90610100612c7d565b6121659190612b1b565b845184518216911916178352505b505050565b6000815183511461218b5750600061159b565b825160208381018281209186019283209091145b95945050505050565b606082518211156121b857600080fd5b60008284516121c79190612b1b565b90506020840161219f6121da8583612b08565b8361244b565b60006020825110156122405760405162461bcd60e51b8152602060048201526024808201527f42797465733a3a20746f427974657333323a206461746120697320746f20736860448201526337b93a1760e11b60648201526084016102c8565b506020015190565b6000806002846020015161225c9190612ae0565b90506000600284602001516122719190612ae0565b90508082036123695760006002866020015161228d9190612af4565b90506000600286602001516122a29190612af4565b9050600084156123225786518051839081106122c0576122c061298d565b016020015188518051600f60f81b90921691859081106122e2576122e261298d565b0160200151600f60f81b16146123005760009550505050505061159b565b61230983612ab1565b925061231482612ab1565b915061231f81612ab1565b90505b60006123328960000151856117b5565b905060006123448960000151856117b5565b90508261235183836124a1565b61235b9190612b08565b97505050505050505061159b565b600061238561237787611a36565b61238087611a36565b612589565b905060005b818110156123bb5761239c8682611c73565b6123a68883611c73565b036123bb576123b481612ab1565b905061238a565b935061159b92505050565b600080825111801561159b5750816000815181106123e6576123e661298d565b6020910101516001600160f81b031916600360fe1b148061159b5750816000815181106124155761241561298d565b6020910101516001600160f81b031916600160ff1b1492915050565b805160009060151461244257600080fd5b61159b82611429565b6060816001600160401b03811115612465576124656128c0565b6040519080825280601f01601f19166020018201604052801561248f576020820181803683370190505b509050602081016120b484828561259f565b6000806124b084518451612589565b905060005b8181101561257e578381815181106124cf576124cf61298d565b602001015160f81c60f81b6001600160f81b0319168582815181106124f6576124f661298d565b01602001516001600160f81b0319161461256e5761255085828151811061251f5761251f61298d565b602001015160f81c60f81b85838151811061253c5761253c61298d565b01602001516001600160f81b03191661260d565b61255b600283612b69565b6125659190612b08565b9250505061159b565b61257781612ab1565b90506124b5565b61219f600282612b69565b600081831061259857816118a5565b5090919050565b602081106125d757825182526125b6602083612b08565b91506125c3602084612b08565b92506125d0602082612b1b565b905061259f565b600081156126075760016125ec836020612b1b565b6125f890610100612c7d565b6126029190612b1b565b612165565b50505050565b60006001600160f81b03198083169084160361262b5750600261159b565b8160f81c60f01660ff168360f81c60f01660ff160361264c5750600161159b565b50600061159b565b604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b60408051610140810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905260c0840183905260e084018390526101008401839052845180860190955284528301529061012082015290565b905290565b604051806040016040528061270c604051806040016040528060608152602001600081525090565b815260408051608081018252600080825260208281018290529282015260608082015291015290565b604051806040016040528061274861277f565b81526020016126df5b6040518061020001604052806010905b61276961277f565b8152602001906001900390816127615790505090565b60405180604001604052806000151581526020016126df604080516080810182526000808252602082018190529181019190915260608082015290565b60008083601f8401126127ce57600080fd5b5081356001600160401b038111156127e557600080fd5b6020830191508360208260051b850101111561280057600080fd5b9250929050565b600080600080600080600060a0888a03121561282257600080fd5b8735965060208801356001600160401b038082111561284057600080fd5b818a0191508a601f83011261285457600080fd5b81358181111561286357600080fd5b8b602082850101111561287557600080fd5b6020830198508097505060408a0135955060608a013591508082111561289a57600080fd5b506128a78a828b016127bc565b989b979a50959894979596608090950135949350505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156128fe576128fe6128c0565b604052919050565b600080828403606081121561291a57600080fd5b604081121561292857600080fd5b50604051604081018181106001600160401b038211171561294b5761294b6128c0565b60409081528451825260208086015190830152840151909250801515811461297257600080fd5b809150509250929050565b8183823760009101908152919050565b634e487b7160e01b600052603260045260246000fd5b60006001600160401b03808411156129bd576129bd6128c0565b8360051b60206129ce8183016128d6565b8681529185019181810190368411156129e657600080fd5b865b84811015612a6b57803586811115612a005760008081fd5b8801601f3681830112612a135760008081fd5b813588811115612a2557612a256128c0565b612a36818301601f191688016128d6565b91508082523687828501011115612a4d5760008081fd5b808784018884013760009082018701528452509183019183016129e8565b50979650505050505050565b8051602080830151919081101561200c5760001960209190910360031b1b16919050565b634e487b7160e01b600052601160045260246000fd5b600060018201612ac357612ac3612a9b565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082612aef57612aef612aca565b500690565b600082612b0357612b03612aca565b500490565b8082018082111561159b5761159b612a9b565b8181038181111561159b5761159b612a9b565b60ff818116838216019081111561159b5761159b612a9b565b600060ff831680612b5a57612b5a612aca565b8060ff84160691505092915050565b808202811582820484141761159b5761159b612a9b565b60ff828116828216039081111561159b5761159b612a9b565b600181815b80851115612bd4578160001904821115612bba57612bba612a9b565b80851615612bc757918102915b93841c9390800290612b9e565b509250929050565b600082612beb5750600161159b565b81612bf85750600061159b565b8160018114612c0e5760028114612c1857612c34565b600191505061159b565b60ff841115612c2957612c29612a9b565b50506001821b61159b565b5060208310610133831016604e8410600b8410161715612c57575081810a61159b565b612c618383612b99565b8060001904821115612c7557612c75612a9b565b029392505050565b60006118a58383612bdc56fea26469706673582212203df60811a03d8fb800928ecd4ed94b7eb8aadfd17718decd761001eee182303264736f6c63430008120033", + ABI: "[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID_\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"sourceOracleAggregator_\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"decimals_\",\"type\":\"uint8\"},{\"internalType\":\"string\",\"name\":\"description_\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"version_\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"currentAnswer\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint80\",\"name\":\"roundID\",\"type\":\"uint80\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"}],\"name\":\"AnswerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockchainID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"sourceBlockHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"loggerAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"logIndex\",\"type\":\"uint256\"}],\"name\":\"EventImported\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"ANSWER_UPDATED_EVENT_SIGNATURE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"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\":\"\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"blockHeader\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"txIndex\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"receiptProof\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256\",\"name\":\"logIndex\",\"type\":\"uint256\"}],\"name\":\"importEvent\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundID\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestSourceBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestSourceLogIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestSourceTxIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"}],\"name\":\"rounds\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"answer\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sourceBlockchainID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"sourceOracleAggregator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"warpMessenger\",\"outputs\":[{\"internalType\":\"contractIWarpMessenger\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b5060405162003357380380620033578339810160408190526200003591620000a7565b600080546001600160a01b03191673020000000000000000000000000000000000000517905560c08590526001600160a01b03841660e05260ff831660805260016200008283826200025b565b5060a052506200032792505050565b634e487b7160e01b600052604160045260246000fd5b600080600080600060a08688031215620000c057600080fd5b8551602080880151919650906001600160a01b0381168114620000e257600080fd5b604088015190955060ff81168114620000fa57600080fd5b60608801519094506001600160401b03808211156200011857600080fd5b818901915089601f8301126200012d57600080fd5b81518181111562000142576200014262000091565b604051601f8201601f19908116603f011681019083821181831017156200016d576200016d62000091565b816040528281528c868487010111156200018657600080fd5b600093505b82841015620001aa57848401860151818501870152928501926200018b565b6000868483010152809750505050505050608086015190509295509295909350565b600181811c90821680620001e157607f821691505b6020821081036200020257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200025657600081815260208120601f850160051c81016020861015620002315750805b601f850160051c820191505b8181101562000252578281556001016200023d565b5050505b505050565b81516001600160401b0381111562000277576200027762000091565b6200028f81620002888454620001cc565b8462000208565b602080601f831160018114620002c75760008415620002ae5750858301515b600019600386901b1c1916600185901b17855562000252565b600085815260208120601f198616915b82811015620002f857888601518255948401946001909101908401620002d7565b5085821015620003175787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e051612fe86200036f600039600081816102b301526111af0152600081816101570152611149015260006101fc015260006101ba0152612fe86000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806354fd4d5011610097578063c9572e1411610066578063c9572e1414610283578063ce2723fc146102ae578063f76339dc146102d5578063feaf968c1461030057600080fd5b806354fd4d50146101f75780637284e4161461021e5780638716cde5146102335780639a6fc8f51461023c57600080fd5b806329b7b3fd116100d357806329b7b3fd146101525780632ede662f14610179578063313ce567146101b55780634af37a11146101ee57600080fd5b8063042a7c97146100fa57806308fd4323146101345780630a8bfac91461013d575b600080fd5b6101217f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f81565b6040519081526020015b60405180910390f35b61012160065481565b61015061014b366004612a85565b610308565b005b6101217f000000000000000000000000000000000000000000000000000000000000000081565b6101a0610187366004612b3e565b6003602052600090815260409020805460019091015482565b6040805192835260208301919091520161012b565b6101dc7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161012b565b61012160055481565b6101217f000000000000000000000000000000000000000000000000000000000000000081565b6102266106f7565b60405161012b9190612b67565b61012160045481565b61024f61024a366004612b3e565b610785565b604080516001600160501b03968716815260208101959095528401929092526060830152909116608082015260a00161012b565b600054610296906001600160a01b031681565b6040516001600160a01b03909116815260200161012b565b6102967f000000000000000000000000000000000000000000000000000000000000000081565b6002546102e8906001600160501b031681565b6040516001600160501b03909116815260200161012b565b61024f610810565b6000805460405163ce7f592960e01b81526004810183905282916001600160a01b03169063ce7f592990602401606060405180830381865afa158015610352573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103769190612bfb565b91509150806103c45760405162461bcd60e51b8152602060048201526015602482015274092dcecc2d8d2c840aec2e4e084d8dec6d690c2e6d605b1b60448201526064015b60405180910390fd5b816020015188886040516103d9929190612c72565b6040518091039020146104245760405162461bcd60e51b815260206004820152601360248201527224b73b30b634b210313637b1b5a432b0b232b960691b60448201526064016103bb565b6000806104668a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061084192505050565b60408051600180825281830190925292945090925060009190816020015b60608152602001906001900390816104845790505090506104a489610924565b816000815181106104b7576104b7612c82565b602090810291909101015260006104d8836104d28a8c612c98565b846109bf565b9050805160011461053e5760405162461bcd60e51b815260206004820152602a60248201527f496e76616c6964206e756d626572206f6620726573756c747320696e2072656360448201526932b4b83a10383937b7b360b11b60648201526084016103bb565b60008160008151811061055357610553612c82565b60200260200101516020015151116105a55760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103932b1b2b4b83a10383937b7b360591b60448201526064016103bb565b60006105d66105d1836000815181106105c0576105c0612c82565b602002602001015160200151610e50565b610e7d565b905080608001515188106106205760405162461bcd60e51b8152602060048201526011602482015270092dcecc2d8d2c840d8dece40d2dcc8caf607b1b60448201526064016103bb565b6106706040518060a00160405280896000015181526020018781526020018d81526020018a815260200183608001518b8151811061066057610660612c82565b6020026020010151815250611143565b8060800151888151811061068657610686612c82565b6020026020010151600001516001600160a01b0316876020015188600001517ffdb2f8239033f2b8c1122b2a4b6af55bb0b0b05e4050b5ecd9eafa153d3cd41d8e8c6040516106df929190918252602082015260400190565b60405180910390a45050505050505050505050505050565b6001805461070490612d6c565b80601f016020809104026020016040519081016040528092919081815260200182805461073090612d6c565b801561077d5780601f106107525761010080835404028352916020019161077d565b820191906000526020600020905b81548152906001019060200180831161076057829003601f168201915b505050505081565b6001600160501b03811660009081526003602090815260408083208151808301909252805482526001015491810182905282918291829182919082036107f75760405162461bcd60e51b81526020600482015260076024820152664e6f206461746160c81b60448201526064016103bb565b8051602090910151969790969550859450879350915050565b6002546000908190819081908190610830906001600160501b0316610785565b945094509450945094509091929394565b600080600061085761085285610e50565b611592565b9050600f815110156108c25760405162461bcd60e51b815260206004820152602e60248201527f496e76616c6964206e756d626572206f6620524c5020656c656d656e7473206960448201526d3710313637b1b5903432b0b232b960911b60648201526084016103bb565b60006108e7826008815181106108da576108da612c82565b60200260200101516116a7565b9050600061090e8360058151811061090157610901612c82565b60200260200101516116f5565b61091790612da0565b9196919550909350505050565b60608160000361094b5750506040805180820190915260018152600160ff1b602082015290565b607f82111561098f5760405162461bcd60e51b815260206004820152601060248201526f092dcecc2d8d2c840e8f040d2dcc8caf60831b60448201526064016103bb565b6040516001600160f81b031960f884901b1660208201526021016040516020818303038152906040529050919050565b6060600082516001600160401b038111156109dc576109dc612bb5565b604051908082528060200260200182016040528015610a2157816020015b60408051808201909152606080825260208201528152602001906001900390816109fa5790505b509050600084516001600160401b03811115610a3f57610a3f612bb5565b604051908082528060200260200182016040528015610a8557816020015b604080518082019091526000815260606020820152815260200190600190039081610a5d5790505b50905060005b8551811015610b12576040518060400160405280878381518110610ab157610ab1612c82565b6020026020010151805190602001208152602001878381518110610ad757610ad7612c82565b6020026020010151815250828281518110610af457610af4612c82565b60200260200101819052508080610b0a90612dda565b915050610a8b565b5060005b8451811015610e4557848181518110610b3157610b31612c82565b6020026020010151838281518110610b4b57610b4b612c82565b60200260200101516000018190525060006040518060400160405280878481518110610b7957610b79612c82565b60200260200101518152602001600081525090506000610ba1610b9c858b611772565b61181f565b905060015b8015610e2f576040805160808101825260008082526020820181905291810191909152606080820152610bd883611974565b15610ca6576000610be884611989565b9050600060028660200151610bfd9190612e09565b15610c235760028660200151610c139190612e1d565b610c1e906001612e31565b610c34565b60028660200151610c349190612e1d565b90506040518060400160405280610c4f886000015184611a33565b815260200160008152509550610c69826000015187611afd565b15610c9e57610c7c888360200151611b2a565b898881518110610c8e57610c8e612c82565b6020026020010151602001819052505b505050610e2f565b60c083015115610d44576000610cbb84611b73565b9050610ccb858260000151611c97565b15610d37576000610cdf8260000151611cb4565b8660200151610cee9190612e31565b90506040518060400160405280610d158860000151600285610d109190612e1d565b611a33565b8152602001610d25600284612e09565b81525095508160200151925050610d3e565b5050610e2f565b50610e0c565b60e083015115610dff576000610d5984611cd7565b9050610d6485611edf565b15610daf578051511515600103610d3757610d8787826000015160200151611b2a565b888781518110610d9957610d99612c82565b6020026020010151602001819052505050610e2f565b60008160200151610dc1876000611ef1565b60108110610dd157610dd1612c82565b602002015180519091501515600103610c9e57610def866001611f7b565b9550806020015192505050610e0c565b825115610e0c5750610e2f565b610e19610b9c8783611b2a565b9250508080610e2790612dda565b915050610ba6565b5050508080610e3d90612dda565b915050610b16565b509095945050505050565b60408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b6040805160a08101825260008082526060602083018190529282015281810182905260808101919091526000610eb283611fbe565b610f6257506020820151805160001a906001821480610ed457508160ff166002145b610f2a5760405162461bcd60e51b815260206004820152602160248201527f496e76616c6964207478207479706520666f72206e6f6e2d6c656761637920746044820152600f60fb1b60648201526084016103bb565b604051806040016040528060018660000151610f469190612e44565b815260200185602001516001610f5c9190612e31565b90529350505b6000610f6d84611592565b90508051600414610fd25760405162461bcd60e51b815260206004820152602960248201527f496e76616c6964206e756d626572206f6620524c5020656c656d656e747320696044820152681b881c9958d95a5c1d60ba1b60648201526084016103bb565b6040805160a0810182526060602082018190526000928201839052808201819052608082015260ff84168152825190916110159184919061090157610901612c82565b8160200181905250611033826001815181106108da576108da612c82565b6001600160401b03166040820152815161105a908390600290811061090157610901612c82565b816060018190525060006110878360038151811061107a5761107a612c82565b6020026020010151611592565b905080516001600160401b038111156110a2576110a2612bb5565b6040519080825280602002602001820160405280156110db57816020015b6110c86128d2565b8152602001906001900390816110c05790505b50608083015260005b8151811015610e455761110f82828151811061110257611102612c82565b6020026020010151611ff9565b8360800151828151811061112557611125612c82565b6020026020010181905250808061113b90612dda565b9150506110e4565b805181907f0000000000000000000000000000000000000000000000000000000000000000146111ad5760405162461bcd60e51b8152602060048201526015602482015274125b9d985b1a5908189b1bd8dad8da185a5b881251605a1b60448201526064016103bb565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168160800151600001516001600160a01b03161461122f5760405162461bcd60e51b8152602060048201526016602482015275496e76616c6964206c6f67676572206164647265737360501b60448201526064016103bb565b818060800151602001515160031461127e5760405162461bcd60e51b8152602060048201526012602482015271496e76616c6964206c6f6720746f7069637360701b60448201526064016103bb565b806080015160400151516020146112ca5760405162461bcd60e51b815260206004820152601060248201526f496e76616c6964206c6f67206461746160801b60448201526064016103bb565b7f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f81608001516020015160008151811061130657611306612c82565b60200260200101511461135b5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206576656e74207369676e617475726500000000000000000060448201526064016103bb565b8260045481602001511015801561138657506004548160200151118061138657506005548160400151115b80156113b65750600454816020015111806113a657506005548160400151115b806113b657506006548160600151115b6113f05760405162461bcd60e51b815260206004820152600b60248201526a14dd185b1948195d995b9d60aa1b60448201526064016103bb565b600084608001516020015160028151811061140d5761140d612c82565b60209081029190910101516002549091506001600160501b039081169082161180159061144457506002546001600160501b031615155b156114a45760405162461bcd60e51b815260206004820152602a60248201527f726f756e6449442073686f756c64206265206d6f6e6f746f6e6963616c6c7920604482015269696e6372656173696e6760b01b60648201526084016103bb565b60008560800151602001516001815181106114c1576114c1612c82565b602002602001015160001c905060008660800151604001516114e290612da0565b60408051808201825284815260208082018481526001600160501b0388166000818152600384528590208451815591516001909201919091556002805469ffffffffffffffffffff1916821790558b8201516004558b8401516005556060808d0151600655845188815292830191909152928101849052929350917f5b196ccf306f345de8745dffeaf185f4cafe74a334e2b2466d04c880071533b9910160405180910390a15050505050505050565b606061159d82611fbe565b6115a657600080fd5b60006115b18361218a565b90506000816001600160401b038111156115cd576115cd612bb5565b60405190808252806020026020018201604052801561161257816020015b60408051808201909152600080825260208201528152602001906001900390816115eb5790505b5090506000611624856020015161220f565b85602001516116339190612e31565b90506000805b8481101561169c5761164a83612290565b915060405180604001604052808381526020018481525084828151811061167357611673612c82565b60209081029190910101526116888284612e31565b92508061169481612dda565b915050611639565b509195945050505050565b8051600090158015906116bc57508151602110155b6116c557600080fd5b6000806116d184612339565b8151919350915060208210156116ed5760208290036101000a90045b949350505050565b805160609061170357600080fd5b60008061170f84612339565b915091506000816001600160401b0381111561172d5761172d612bb5565b6040519080825280601f01601f191660200182016040528015611757576020820181803683370190505b50905060208101611769848285612373565b50949350505050565b606060005b83518110156117dc578284828151811061179357611793612c82565b602002602001015160000151036117ca578381815181106117b6576117b6612c82565b602002602001015160200151915050611819565b806117d481612dda565b915050611777565b5060405162461bcd60e51b8152602060048201526011602482015270496e636f6d706c6574652050726f6f662160781b60448201526064016103bb565b92915050565b6118276128fc565b61182f6128fc565b6000604051806040016040528085815260200160008152509050611888846040518060400160405280602081526020017f56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218152506123f6565b1561189857506001815292915050565b60006118a661085286610e50565b805190915060008190036118c1575050600182525092915050565b8060020361191b5760006118e18360008151811061090157610901612c82565b602081015190915060fc1c60028114806118fb5750806003145b1561190c5760016020870152611914565b600160c08701525b5050611966565b8060110361192f57600160e0850152611966565b60405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964206461746160a01b60448201526064016103bb565b505061012082015292915050565b60008160200151806118195750506040015190565b611991612962565b611999612962565b60006119b061085285610120015160000151610e50565b905060006119ca8260018151811061090157610901612c82565b905060405180604001604052806119f76119f08560008151811061090157610901612c82565b6001612426565b81526000602091820181905291855260408051608081018252838152808301939093526001908301526060820192909252908301525092915050565b81516060906000611a448483612e44565b905083821015611a8a5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b60448201526064016103bb565b606081158015611aa95760405191506000825260208201604052611af3565b6040519150601f8316801560200281840101848101888315602002848c0101015b81831015611ae2578051835260209283019201611aca565b5050848452601f01601f1916604052505b5095945050505050565b6000611b0882611cb4565b611b1184611cb4565b148015611b235750611b238383611c97565b9392505050565b6060816040015115611b4157506060810151611819565b815115611b5d57611b56838360200151611772565b9050611819565b5060408051602081019091526000815292915050565b611b7b612962565b611b83612962565b6000611b9a61085285610120015160000151610e50565b90506000611bb48260018151811061090157610901612c82565b905060006004611bd08460008151811061090157610901612c82565b600081518110611be257611be2612c82565b602001015160f81c60f81b6001600160f81b031916901c60f81c60011690506040518060400160405280611c44611c258660008151811061090157610901612c82565b6002611c32866001612e57565b611c3c9190612e70565b60ff16612426565b815260ff8316602091820152908552604080516080810190915260018152908101611c6e8461245e565b815260006020808301829052604080519283528282018152909201528501525091949350505050565b6000611ca282611cb4565b611cac84846124c6565b149392505050565b600081602001516002836000015151611ccd9190612e92565b6118199190612e44565b611cdf6129b3565b611ce76129b3565b6000611cfe61085285610120015160000151610e50565b9050611d086129cf565b60005b6010811015611e10576000611d2b84838151811061090157610901612c82565b90508051602014611d93576040805180820182526000808252825160808101845281815260208082018390528185018390528451928352828101909452606081019190915291810191909152838360108110611d8957611d89612c82565b6020020152611dfd565b6000611d9e8261245e565b60408051808201825260018082528251608081018452908152602080820185905260008285018190528451908152808201909452606082019390935291810191909152909150848460108110611df657611df6612c82565b6020020152505b5080611e0881612dda565b915050611d0b565b50611e2f611e2a8360108151811061090157610901612c82565b612644565b15611e7c5760408051808201825260008082528251608081018452818152602080820183905281850183905284519283528281019094526060810191909152918101919091528352611ed3565b604051806040016040528060011515815260200160405180608001604052806000151581526020016000801b8152602001600115158152602001611ecc8660108151811061090157610901612c82565b9052905283525b60208301525092915050565b6000611eea82611cb4565b1592915050565b6000806002838560200151611f069190612e31565b611f109190612e1d565b905060006002848660200151611f269190612e31565b611f309190612e09565b9050600085600001518381518110611f4a57611f4a612c82565b016020015160f81c905060018214611f695760048160ff16901c611f6e565b80600f165b60ff169695505050505050565b604080518082019091526060815260006020820152604051806040016040528084600001518152602001838560200151611fb59190612e31565b90529392505050565b80516000908103611fd157506000919050565b6020820151805160001a9060c0821015611fef575060009392505050565b5060019392505050565b6120016128d2565b600061200c83611592565b9050805160031461206d5760405162461bcd60e51b815260206004820152602560248201527f496e76616c6964206e756d626572206f6620524c5020656c656d656e747320696044820152646e206c6f6760d81b60648201526084016103bb565b6120756128d2565b6120988260008151811061208b5761208b612c82565b60200260200101516126af565b6001600160a01b0316815281516000906120bf908490600190811061107a5761107a612c82565b905080516001600160401b038111156120da576120da612bb5565b604051908082528060200260200182016040528015612103578160200160208202803683370190505b50602083015260005b81518110156121665761212a82828151811061090157610901612c82565b61213390612da0565b8360200151828151811061214957612149612c82565b60209081029190910101528061215e81612dda565b91505061210c565b5061217d8360028151811061090157610901612c82565b6040830152509392505050565b8051600090810361219d57506000919050565b6000806121ad846020015161220f565b84602001516121bc9190612e31565b90506000846000015185602001516121d49190612e31565b90505b80821015612206576121e882612290565b6121f29083612e31565b9150826121fe81612dda565b9350506121d7565b50909392505050565b8051600090811a60808110156122285750600092915050565b60b8811080612243575060c08110801590612243575060f881105b156122515750600192915050565b60c081101561227e57612266600160b8612ea9565b6122739060ff1682612e44565b611b23906001612e31565b612266600160f8612ea9565b50919050565b80516000908190811a60808110156122ab5760019150612332565b60b88110156122d1576122bf608082612e44565b6122ca906001612e31565b9150612332565b60c08110156122fe5760b78103600185019450806020036101000a85510460018201810193505050612332565b60f8811015612312576122bf60c082612e44565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b600080600061234b846020015161220f565b9050600081856020015161235f9190612e31565b905060008286600001516109179190612e44565b8060000361238057505050565b602081106123b85782518252612397602084612e31565b92506123a4602083612e31565b91506123b1602082612e44565b9050612380565b80156123f157600060016123cd836020612e44565b6123d990610100612fa6565b6123e39190612e44565b845184518216911916178352505b505050565b6000815183511461240957506000611819565b825160208381018281209186019283209091145b95945050505050565b6060825182111561243657600080fd5b60008284516124459190612e44565b90506020840161241d6124588583612e31565b836126c9565b60006020825110156124be5760405162461bcd60e51b8152602060048201526024808201527f42797465733a3a20746f427974657333323a206461746120697320746f20736860448201526337b93a1760e11b60648201526084016103bb565b506020015190565b600080600284602001516124da9190612e09565b90506000600284602001516124ef9190612e09565b90508082036125e75760006002866020015161250b9190612e1d565b90506000600286602001516125209190612e1d565b9050600084156125a057865180518390811061253e5761253e612c82565b016020015188518051600f60f81b909216918590811061256057612560612c82565b0160200151600f60f81b161461257e57600095505050505050611819565b61258783612dda565b925061259282612dda565b915061259d81612dda565b90505b60006125b0896000015185611a33565b905060006125c2896000015185611a33565b9050826125cf838361271f565b6125d99190612e31565b975050505050505050611819565b60006126036125f587611cb4565b6125fe87611cb4565b612807565b905060005b818110156126395761261a8682611ef1565b6126248883611ef1565b036126395761263281612dda565b9050612608565b935061181992505050565b600080825111801561181957508160008151811061266457612664612c82565b6020910101516001600160f81b031916600360fe1b148061181957508160008151811061269357612693612c82565b6020910101516001600160f81b031916600160ff1b1492915050565b80516000906015146126c057600080fd5b611819826116a7565b6060816001600160401b038111156126e3576126e3612bb5565b6040519080825280601f01601f19166020018201604052801561270d576020820181803683370190505b5090506020810161233284828561281d565b60008061272e84518451612807565b905060005b818110156127fc5783818151811061274d5761274d612c82565b602001015160f81c60f81b6001600160f81b03191685828151811061277457612774612c82565b01602001516001600160f81b031916146127ec576127ce85828151811061279d5761279d612c82565b602001015160f81c60f81b8583815181106127ba576127ba612c82565b01602001516001600160f81b03191661288b565b6127d9600283612e92565b6127e39190612e31565b92505050611819565b6127f581612dda565b9050612733565b61241d600282612e92565b60008183106128165781611b23565b5090919050565b602081106128555782518252612834602083612e31565b9150612841602084612e31565b925061284e602082612e44565b905061281d565b6000811561288557600161286a836020612e44565b61287690610100612fa6565b6128809190612e44565b6123e3565b50505050565b60006001600160f81b0319808316908416036128a957506002611819565b8160f81c60f01660ff168360f81c60f01660ff16036128ca57506001611819565b506000611819565b604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b60408051610140810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905260c0840183905260e084018390526101008401839052845180860190955284528301529061012082015290565b905290565b604051806040016040528061298a604051806040016040528060608152602001600081525090565b815260408051608081018252600080825260208281018290529282015260608082015291015290565b60405180604001604052806129c66129fd565b815260200161295d5b6040518061020001604052806010905b6129e76129fd565b8152602001906001900390816129df5790505090565b604051806040016040528060001515815260200161295d604080516080810182526000808252602082018190529181019190915260608082015290565b60008083601f840112612a4c57600080fd5b5081356001600160401b03811115612a6357600080fd5b6020830191508360208260051b8501011115612a7e57600080fd5b9250929050565b600080600080600080600060a0888a031215612aa057600080fd5b8735965060208801356001600160401b0380821115612abe57600080fd5b818a0191508a601f830112612ad257600080fd5b813581811115612ae157600080fd5b8b6020828501011115612af357600080fd5b6020830198508097505060408a0135955060608a0135915080821115612b1857600080fd5b50612b258a828b01612a3a565b989b979a50959894979596608090950135949350505050565b600060208284031215612b5057600080fd5b81356001600160501b0381168114611b2357600080fd5b600060208083528351808285015260005b81811015612b9457858101830151858201604001528201612b78565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612bf357612bf3612bb5565b604052919050565b6000808284036060811215612c0f57600080fd5b6040811215612c1d57600080fd5b50604051604081018181106001600160401b0382111715612c4057612c40612bb5565b604090815284518252602080860151908301528401519092508015158114612c6757600080fd5b809150509250929050565b8183823760009101908152919050565b634e487b7160e01b600052603260045260246000fd5b60006001600160401b0380841115612cb257612cb2612bb5565b8360051b6020612cc3818301612bcb565b868152918501918181019036841115612cdb57600080fd5b865b84811015612d6057803586811115612cf55760008081fd5b8801601f3681830112612d085760008081fd5b813588811115612d1a57612d1a612bb5565b612d2b818301601f19168801612bcb565b91508082523687828501011115612d425760008081fd5b80878401888401376000908201870152845250918301918301612cdd565b50979650505050505050565b600181811c90821680612d8057607f821691505b60208210810361228a57634e487b7160e01b600052602260045260246000fd5b8051602080830151919081101561228a5760001960209190910360031b1b16919050565b634e487b7160e01b600052601160045260246000fd5b600060018201612dec57612dec612dc4565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082612e1857612e18612df3565b500690565b600082612e2c57612e2c612df3565b500490565b8082018082111561181957611819612dc4565b8181038181111561181957611819612dc4565b60ff818116838216019081111561181957611819612dc4565b600060ff831680612e8357612e83612df3565b8060ff84160691505092915050565b808202811582820484141761181957611819612dc4565b60ff828116828216039081111561181957611819612dc4565b600181815b80851115612efd578160001904821115612ee357612ee3612dc4565b80851615612ef057918102915b93841c9390800290612ec7565b509250929050565b600082612f1457506001611819565b81612f2157506000611819565b8160018114612f375760028114612f4157612f5d565b6001915050611819565b60ff841115612f5257612f52612dc4565b50506001821b611819565b5060208310610133831016604e8410600b8410161715612f80575081810a611819565b612f8a8383612ec2565b8060001904821115612f9e57612f9e612dc4565b029392505050565b6000611b238383612f0556fea26469706673582212205a569bd8657b55afcc0ac3b9d12c2aafb09e0bdb35153bf2661dbefbe7d215ba64736f6c63430008120033", } // PriceFeedImporterABI is the input ABI used to generate the binding from. @@ -44,7 +44,7 @@ var PriceFeedImporterABI = PriceFeedImporterMetaData.ABI var PriceFeedImporterBin = PriceFeedImporterMetaData.Bin // DeployPriceFeedImporter deploys a new Ethereum contract, binding an instance of PriceFeedImporter to it. -func DeployPriceFeedImporter(auth *bind.TransactOpts, backend bind.ContractBackend, sourceBlockchainID_ [32]byte, sourceOracleAggregator_ common.Address) (common.Address, *types.Transaction, *PriceFeedImporter, error) { +func DeployPriceFeedImporter(auth *bind.TransactOpts, backend bind.ContractBackend, sourceBlockchainID_ [32]byte, sourceOracleAggregator_ common.Address, decimals_ uint8, description_ string, version_ *big.Int) (common.Address, *types.Transaction, *PriceFeedImporter, error) { parsed, err := PriceFeedImporterMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -53,7 +53,7 @@ func DeployPriceFeedImporter(auth *bind.TransactOpts, backend bind.ContractBacke return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PriceFeedImporterBin), backend, sourceBlockchainID_, sourceOracleAggregator_) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(PriceFeedImporterBin), backend, sourceBlockchainID_, sourceOracleAggregator_, decimals_, description_, version_) if err != nil { return common.Address{}, nil, nil, err } @@ -233,35 +233,101 @@ func (_PriceFeedImporter *PriceFeedImporterCallerSession) ANSWERUPDATEDEVENTSIGN return _PriceFeedImporter.Contract.ANSWERUPDATEDEVENTSIGNATURE(&_PriceFeedImporter.CallOpts) } -// CurrentAnswer is a free data retrieval call binding the contract method 0x7e1b4cb0. +// Decimals is a free data retrieval call binding the contract method 0x313ce567. // -// Solidity: function currentAnswer() view returns(int256) -func (_PriceFeedImporter *PriceFeedImporterCaller) CurrentAnswer(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function decimals() view returns(uint8) +func (_PriceFeedImporter *PriceFeedImporterCaller) Decimals(opts *bind.CallOpts) (uint8, error) { var out []interface{} - err := _PriceFeedImporter.contract.Call(opts, &out, "currentAnswer") + err := _PriceFeedImporter.contract.Call(opts, &out, "decimals") if err != nil { - return *new(*big.Int), err + return *new(uint8), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + 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 (_PriceFeedImporter *PriceFeedImporterSession) Decimals() (uint8, error) { + return _PriceFeedImporter.Contract.Decimals(&_PriceFeedImporter.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_PriceFeedImporter *PriceFeedImporterCallerSession) Decimals() (uint8, error) { + return _PriceFeedImporter.Contract.Decimals(&_PriceFeedImporter.CallOpts) +} + +// Description is a free data retrieval call binding the contract method 0x7284e416. +// +// Solidity: function description() view returns(string) +func (_PriceFeedImporter *PriceFeedImporterCaller) Description(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _PriceFeedImporter.contract.Call(opts, &out, "description") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) return out0, err } -// CurrentAnswer is a free data retrieval call binding the contract method 0x7e1b4cb0. +// Description is a free data retrieval call binding the contract method 0x7284e416. +// +// Solidity: function description() view returns(string) +func (_PriceFeedImporter *PriceFeedImporterSession) Description() (string, error) { + return _PriceFeedImporter.Contract.Description(&_PriceFeedImporter.CallOpts) +} + +// Description is a free data retrieval call binding the contract method 0x7284e416. +// +// Solidity: function description() view returns(string) +func (_PriceFeedImporter *PriceFeedImporterCallerSession) Description() (string, error) { + return _PriceFeedImporter.Contract.Description(&_PriceFeedImporter.CallOpts) +} + +// GetRoundData is a free data retrieval call binding the contract method 0x9a6fc8f5. +// +// Solidity: function getRoundData(uint80 _roundID) view returns(uint80, int256, uint256, uint256, uint80) +func (_PriceFeedImporter *PriceFeedImporterCaller) GetRoundData(opts *bind.CallOpts, _roundID *big.Int) (*big.Int, *big.Int, *big.Int, *big.Int, *big.Int, error) { + var out []interface{} + err := _PriceFeedImporter.contract.Call(opts, &out, "getRoundData", _roundID) + + if err != nil { + return *new(*big.Int), *new(*big.Int), *new(*big.Int), *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) + out2 := *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + out3 := *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + out4 := *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return out0, out1, out2, out3, out4, err + +} + +// GetRoundData is a free data retrieval call binding the contract method 0x9a6fc8f5. // -// Solidity: function currentAnswer() view returns(int256) -func (_PriceFeedImporter *PriceFeedImporterSession) CurrentAnswer() (*big.Int, error) { - return _PriceFeedImporter.Contract.CurrentAnswer(&_PriceFeedImporter.CallOpts) +// Solidity: function getRoundData(uint80 _roundID) view returns(uint80, int256, uint256, uint256, uint80) +func (_PriceFeedImporter *PriceFeedImporterSession) GetRoundData(_roundID *big.Int) (*big.Int, *big.Int, *big.Int, *big.Int, *big.Int, error) { + return _PriceFeedImporter.Contract.GetRoundData(&_PriceFeedImporter.CallOpts, _roundID) } -// CurrentAnswer is a free data retrieval call binding the contract method 0x7e1b4cb0. +// GetRoundData is a free data retrieval call binding the contract method 0x9a6fc8f5. // -// Solidity: function currentAnswer() view returns(int256) -func (_PriceFeedImporter *PriceFeedImporterCallerSession) CurrentAnswer() (*big.Int, error) { - return _PriceFeedImporter.Contract.CurrentAnswer(&_PriceFeedImporter.CallOpts) +// Solidity: function getRoundData(uint80 _roundID) view returns(uint80, int256, uint256, uint256, uint80) +func (_PriceFeedImporter *PriceFeedImporterCallerSession) GetRoundData(_roundID *big.Int) (*big.Int, *big.Int, *big.Int, *big.Int, *big.Int, error) { + return _PriceFeedImporter.Contract.GetRoundData(&_PriceFeedImporter.CallOpts, _roundID) } // LatestRoundData is a free data retrieval call binding the contract method 0xfeaf968c. @@ -299,6 +365,37 @@ func (_PriceFeedImporter *PriceFeedImporterCallerSession) LatestRoundData() (*bi return _PriceFeedImporter.Contract.LatestRoundData(&_PriceFeedImporter.CallOpts) } +// LatestRoundID is a free data retrieval call binding the contract method 0xf76339dc. +// +// Solidity: function latestRoundID() view returns(uint80) +func (_PriceFeedImporter *PriceFeedImporterCaller) LatestRoundID(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _PriceFeedImporter.contract.Call(opts, &out, "latestRoundID") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// LatestRoundID is a free data retrieval call binding the contract method 0xf76339dc. +// +// Solidity: function latestRoundID() view returns(uint80) +func (_PriceFeedImporter *PriceFeedImporterSession) LatestRoundID() (*big.Int, error) { + return _PriceFeedImporter.Contract.LatestRoundID(&_PriceFeedImporter.CallOpts) +} + +// LatestRoundID is a free data retrieval call binding the contract method 0xf76339dc. +// +// Solidity: function latestRoundID() view returns(uint80) +func (_PriceFeedImporter *PriceFeedImporterCallerSession) LatestRoundID() (*big.Int, error) { + return _PriceFeedImporter.Contract.LatestRoundID(&_PriceFeedImporter.CallOpts) +} + // LatestSourceBlockNumber is a free data retrieval call binding the contract method 0x8716cde5. // // Solidity: function latestSourceBlockNumber() view returns(uint256) @@ -392,35 +489,49 @@ func (_PriceFeedImporter *PriceFeedImporterCallerSession) LatestSourceTxIndex() return _PriceFeedImporter.Contract.LatestSourceTxIndex(&_PriceFeedImporter.CallOpts) } -// RoundID is a free data retrieval call binding the contract method 0x14f8b424. +// Rounds is a free data retrieval call binding the contract method 0x2ede662f. // -// Solidity: function roundID() view returns(uint80) -func (_PriceFeedImporter *PriceFeedImporterCaller) RoundID(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function rounds(uint80 ) view returns(int256 answer, uint256 updatedAt) +func (_PriceFeedImporter *PriceFeedImporterCaller) Rounds(opts *bind.CallOpts, arg0 *big.Int) (struct { + Answer *big.Int + UpdatedAt *big.Int +}, error) { var out []interface{} - err := _PriceFeedImporter.contract.Call(opts, &out, "roundID") + err := _PriceFeedImporter.contract.Call(opts, &out, "rounds", arg0) + outstruct := new(struct { + Answer *big.Int + UpdatedAt *big.Int + }) if err != nil { - return *new(*big.Int), err + return *outstruct, err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Answer = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.UpdatedAt = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - return out0, err + return *outstruct, err } -// RoundID is a free data retrieval call binding the contract method 0x14f8b424. +// Rounds is a free data retrieval call binding the contract method 0x2ede662f. // -// Solidity: function roundID() view returns(uint80) -func (_PriceFeedImporter *PriceFeedImporterSession) RoundID() (*big.Int, error) { - return _PriceFeedImporter.Contract.RoundID(&_PriceFeedImporter.CallOpts) +// Solidity: function rounds(uint80 ) view returns(int256 answer, uint256 updatedAt) +func (_PriceFeedImporter *PriceFeedImporterSession) Rounds(arg0 *big.Int) (struct { + Answer *big.Int + UpdatedAt *big.Int +}, error) { + return _PriceFeedImporter.Contract.Rounds(&_PriceFeedImporter.CallOpts, arg0) } -// RoundID is a free data retrieval call binding the contract method 0x14f8b424. +// Rounds is a free data retrieval call binding the contract method 0x2ede662f. // -// Solidity: function roundID() view returns(uint80) -func (_PriceFeedImporter *PriceFeedImporterCallerSession) RoundID() (*big.Int, error) { - return _PriceFeedImporter.Contract.RoundID(&_PriceFeedImporter.CallOpts) +// Solidity: function rounds(uint80 ) view returns(int256 answer, uint256 updatedAt) +func (_PriceFeedImporter *PriceFeedImporterCallerSession) Rounds(arg0 *big.Int) (struct { + Answer *big.Int + UpdatedAt *big.Int +}, error) { + return _PriceFeedImporter.Contract.Rounds(&_PriceFeedImporter.CallOpts, arg0) } // SourceBlockchainID is a free data retrieval call binding the contract method 0x29b7b3fd. @@ -485,12 +596,12 @@ func (_PriceFeedImporter *PriceFeedImporterCallerSession) SourceOracleAggregator return _PriceFeedImporter.Contract.SourceOracleAggregator(&_PriceFeedImporter.CallOpts) } -// UpdatedAt is a free data retrieval call binding the contract method 0x7519ab50. +// Version is a free data retrieval call binding the contract method 0x54fd4d50. // -// Solidity: function updatedAt() view returns(uint256) -func (_PriceFeedImporter *PriceFeedImporterCaller) UpdatedAt(opts *bind.CallOpts) (*big.Int, error) { +// Solidity: function version() view returns(uint256) +func (_PriceFeedImporter *PriceFeedImporterCaller) Version(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _PriceFeedImporter.contract.Call(opts, &out, "updatedAt") + err := _PriceFeedImporter.contract.Call(opts, &out, "version") if err != nil { return *new(*big.Int), err @@ -502,18 +613,18 @@ func (_PriceFeedImporter *PriceFeedImporterCaller) UpdatedAt(opts *bind.CallOpts } -// UpdatedAt is a free data retrieval call binding the contract method 0x7519ab50. +// Version is a free data retrieval call binding the contract method 0x54fd4d50. // -// Solidity: function updatedAt() view returns(uint256) -func (_PriceFeedImporter *PriceFeedImporterSession) UpdatedAt() (*big.Int, error) { - return _PriceFeedImporter.Contract.UpdatedAt(&_PriceFeedImporter.CallOpts) +// Solidity: function version() view returns(uint256) +func (_PriceFeedImporter *PriceFeedImporterSession) Version() (*big.Int, error) { + return _PriceFeedImporter.Contract.Version(&_PriceFeedImporter.CallOpts) } -// UpdatedAt is a free data retrieval call binding the contract method 0x7519ab50. +// Version is a free data retrieval call binding the contract method 0x54fd4d50. // -// Solidity: function updatedAt() view returns(uint256) -func (_PriceFeedImporter *PriceFeedImporterCallerSession) UpdatedAt() (*big.Int, error) { - return _PriceFeedImporter.Contract.UpdatedAt(&_PriceFeedImporter.CallOpts) +// Solidity: function version() view returns(uint256) +func (_PriceFeedImporter *PriceFeedImporterCallerSession) Version() (*big.Int, error) { + return _PriceFeedImporter.Contract.Version(&_PriceFeedImporter.CallOpts) } // WarpMessenger is a free data retrieval call binding the contract method 0xc9572e14. diff --git a/abi-bindings/go/mocks/MockPriceFeedAggregator/MockPriceFeedAggregator.go b/abi-bindings/go/mocks/MockPriceFeedAggregator/MockPriceFeedAggregator.go index 71ef49a..36a9c0b 100644 --- a/abi-bindings/go/mocks/MockPriceFeedAggregator/MockPriceFeedAggregator.go +++ b/abi-bindings/go/mocks/MockPriceFeedAggregator/MockPriceFeedAggregator.go @@ -32,7 +32,7 @@ var ( // MockPriceFeedAggregatorMetaData contains all meta data concerning the MockPriceFeedAggregator contract. var MockPriceFeedAggregatorMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"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\"},{\"inputs\":[],\"name\":\"currentAnswer\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deployer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestRoundData\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"roundID\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"currentAnswer_\",\"type\":\"int256\"},{\"internalType\":\"uint80\",\"name\":\"roundID_\",\"type\":\"uint80\"},{\"internalType\":\"uint256\",\"name\":\"updatedAt_\",\"type\":\"uint256\"}],\"name\":\"updateAnswer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updatedAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x60a060405234801561001057600080fd5b50336080526080516102a06100366000396000818160d1015261015001526102a06000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c806314f8b42414610067578063683d010d146100975780637519ab50146100ac5780637e1b4cb0146100c3578063d5f39488146100cc578063feaf968c1461010b575b600080fd5b60015461007a906001600160501b031681565b6040516001600160501b0390911681526020015b60405180910390f35b6100aa6100a5366004610226565b610145565b005b6100b560025481565b60405190815260200161008e565b6100b560005481565b6100f37f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161008e565b600154600054600254604080516001600160501b03909416808552602085019390935283018190526060830152608082015260a00161008e565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101c15760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c79206465706c6f7965722063616e2075706461746520616e7377657200604482015260640160405180910390fd5b60008390556001805469ffffffffffffffffffff19166001600160501b038416908117909155600282905560405182815284907f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f9060200160405180910390a3505050565b60008060006060848603121561023b57600080fd5b8335925060208401356001600160501b038116811461025957600080fd5b92959294505050604091909101359056fea2646970667358221220d670ac97b1f226886dc490c248ae6db92e3161ebeaba40164c8a8c131233e62c64736f6c63430008120033", + Bin: "0x60a060405234801561001057600080fd5b50336080526080516102a06100366000396000818160d1015261015001526102a06000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c806314f8b42414610067578063683d010d146100975780637519ab50146100ac5780637e1b4cb0146100c3578063d5f39488146100cc578063feaf968c1461010b575b600080fd5b60015461007a906001600160501b031681565b6040516001600160501b0390911681526020015b60405180910390f35b6100aa6100a5366004610226565b610145565b005b6100b560025481565b60405190815260200161008e565b6100b560005481565b6100f37f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161008e565b600154600054600254604080516001600160501b03909416808552602085019390935283018190526060830152608082015260a00161008e565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101c15760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c79206465706c6f7965722063616e2075706461746520616e7377657200604482015260640160405180910390fd5b60008390556001805469ffffffffffffffffffff19166001600160501b038416908117909155600282905560405182815284907f0559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5f9060200160405180910390a3505050565b60008060006060848603121561023b57600080fd5b8335925060208401356001600160501b038116811461025957600080fd5b92959294505050604091909101359056fea2646970667358221220a4b447b178d078909ee811ebec5b56375dbe5c1951c719f52e6ceeb88c3a60d264736f6c63430008120033", } // MockPriceFeedAggregatorABI is the input ABI used to generate the binding from. diff --git a/contracts/lib/chainlink b/contracts/lib/chainlink new file mode 160000 index 0000000..883c9f9 --- /dev/null +++ b/contracts/lib/chainlink @@ -0,0 +1 @@ +Subproject commit 883c9f9059c259ca17454703b57521ea9ac166cb diff --git a/contracts/remappings.txt b/contracts/remappings.txt index 0f5b009..a1aebd0 100644 --- a/contracts/remappings.txt +++ b/contracts/remappings.txt @@ -1,2 +1,3 @@ @solidity-merkle-trees=lib/solidity-merkle-trees/src/ @subnet-evm=lib/teleporter/contracts/lib/subnet-evm/contracts/ +@chainlink=lib/chainlink/contracts/src/v0.8/shared/ diff --git a/contracts/src/PriceFeedImporter.sol b/contracts/src/PriceFeedImporter.sol index e6acae2..a50851a 100644 --- a/contracts/src/PriceFeedImporter.sol +++ b/contracts/src/PriceFeedImporter.sol @@ -6,6 +6,7 @@ pragma solidity 0.8.18; import {EVMEventInfo, EventImporter} from "./EventImporter.sol"; +import {AggregatorV3Interface} from "@chainlink/interfaces/AggregatorV3Interface.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. @@ -15,19 +16,28 @@ import {EVMEventInfo, EventImporter} from "./EventImporter.sol"; /** * @notice An example EventImporter implementation that imports the latest price feed data from another blockchain. */ -contract PriceFeedImporter is EventImporter { +contract PriceFeedImporter is EventImporter, AggregatorV3Interface { + struct Round { + int256 answer; + uint256 updatedAt; + } + bytes32 public constant ANSWER_UPDATED_EVENT_SIGNATURE = keccak256("AnswerUpdated(int256,uint256,uint256)"); + // Price feed information + uint8 public immutable decimals; + string public description; + uint256 public immutable version; + // Blockchain ID of the oracle chain. bytes32 public immutable sourceBlockchainID; // Address of the Aggregator contract on the source blockchain. address public immutable sourceOracleAggregator; - // Latest answer information. - int256 public currentAnswer; - uint80 public roundID; - uint256 public updatedAt; + // Rounds + uint80 public latestRoundID; + mapping(uint80 => Round) public rounds; // The block and transaction on the source blockchain where the latest answer was updated. uint256 public latestSourceBlockNumber; @@ -63,17 +73,32 @@ contract PriceFeedImporter is EventImporter { _; } - constructor(bytes32 sourceBlockchainID_, address sourceOracleAggregator_) { + constructor( + bytes32 sourceBlockchainID_, + address sourceOracleAggregator_, + uint8 decimals_, + string memory description_, + uint256 version_ + ) { sourceBlockchainID = sourceBlockchainID_; sourceOracleAggregator = sourceOracleAggregator_; + decimals = decimals_; + description = description_; + version = version_; + } + + // solhint-disable-next-line private-vars-leading-underscore + function getRoundData(uint80 _roundID) public view returns (uint80, int256, uint256, uint256, uint80) { + Round memory round = rounds[_roundID]; + require(round.updatedAt != 0, "No data"); + return (_roundID, round.answer, round.updatedAt, round.updatedAt, _roundID); } /** * @notice Returns the latest round data if available. */ - function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80) { - require(updatedAt != 0, "No data"); - return (roundID, currentAnswer, updatedAt, updatedAt, roundID); + function latestRoundData() public view returns (uint80, int256, uint256, uint256, uint80) { + return getRoundData(latestRoundID); } function _onEventImport(EVMEventInfo memory eventInfo) @@ -84,15 +109,22 @@ contract PriceFeedImporter is EventImporter { _onlyMoreRecentEvents(eventInfo) { // Update the latest answer. - currentAnswer = int256(uint256(eventInfo.log.topics[1])); - roundID = uint80(uint256(eventInfo.log.topics[2])); - updatedAt = uint256(bytes32(eventInfo.log.data)); + uint80 roundID = uint80(uint256(eventInfo.log.topics[2])); + if (roundID <= latestRoundID && latestRoundID != 0) { + revert("roundID should be monotonically increasing"); + } + + int256 answer = int256(uint256(eventInfo.log.topics[1])); + uint256 updatedAt = uint256(bytes32(eventInfo.log.data)); + Round memory round = Round({answer: answer, updatedAt: updatedAt}); + rounds[roundID] = round; + latestRoundID = roundID; // Update the latest source block information. latestSourceBlockNumber = eventInfo.blockNumber; latestSourceTxIndex = eventInfo.txIndex; latestSourceLogIndex = eventInfo.logIndex; - emit AnswerUpdated(currentAnswer, roundID, updatedAt); + emit AnswerUpdated(answer, roundID, updatedAt); } } diff --git a/contracts/src/RLPUtils.sol b/contracts/src/RLPUtils.sol index 1ea9839..5fd7873 100644 --- a/contracts/src/RLPUtils.sol +++ b/contracts/src/RLPUtils.sol @@ -12,7 +12,6 @@ import {RLPReader} from "@solidity-merkle-trees/trie/ethereum/RLPReader.sol"; * THIS IS AN EXAMPLE LIBRARY THAT USES UN-AUDITED CODE. * DO NOT USE THIS CODE IN PRODUCTION. */ - library RLPUtils { using RLPReader for bytes; using RLPReader for RLPReader.RLPItem; diff --git a/contracts/test/EventImporterTests.sol b/contracts/test/EventImporterTests.sol new file mode 100644 index 0000000..77fd3df --- /dev/null +++ b/contracts/test/EventImporterTests.sol @@ -0,0 +1,82 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// SPDX-License-Identifier: Ecosystem + +pragma solidity 0.8.18; + +import {Test} from "forge-std/Test.sol"; +import {WarpBlockHash, IWarpMessenger} from "@subnet-evm/contracts/interfaces/IWarpMessenger.sol"; +import {PriceFeedImporter} from "../src/PriceFeedImporter.sol"; + +contract EventImporterTest is Test { + address public constant WARP_PRECOMPILE_ADDRESS = 0x0200000000000000000000000000000000000005; + bytes32 public constant DEFAULT_BLOCKCHAIN_ID = + bytes32(hex"55e1fcfdde01f9f6d4c16fa2ed89ce65a8669120a86f321eef121891cab61241"); + address public constant SOURCE_ORACLE_AGGREGATOR = 0x154baB1FC1D87fF641EeD0E9Bc0f8a50D880D2B6; + + uint8 public constant DECIMALS = 18; + string public description = "WarpETHUSDAggregator"; + uint256 public constant VERSION = 1; + + PriceFeedImporter public priceFeedImporter; + + event AnswerUpdated(int256 currentAnswer, uint80 roundID, uint256 updatedAt); + event EventImported( + bytes32 indexed sourceBlockchainID, + bytes32 indexed sourceBlockHash, + address indexed loggerAddress, + uint256 txIndex, + uint256 logIndex + ); + + function setUp() public virtual { + priceFeedImporter = new PriceFeedImporter(DEFAULT_BLOCKCHAIN_ID, SOURCE_ORACLE_AGGREGATOR, DECIMALS, description, VERSION); + } + + function testImportEvent() public { + // Mock the Warp precompile returning a valid WarpBlockHash. + bytes32 blockHash = 0x2d9215bce478eb82bfd35f7e9bdc9d76e1814e8d7b5aa10ab05e2f17d145c0cf; + bytes memory encodedBlockHeader = + hex"f9027ba05e92b0416d56a052ea29c5267627d489290dd2f87bae4887c56084452349598ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940100000000000000000000000000000000000000a0425ff44c06b858d5ea72ce4261f8174d1a6d729a2ffdadddaa94abe58b37597da000d275e4cce63b7fe0facd8f477d3cf879b7992c3fed522e01ec5bc6b05345f7a07149d37617782b645919054a607d47ffc590e8c8827c616e792b22caf8fb527fb90100202000000000000000000000801000a120020004000080002184810040000008002050000000004000500400200c1004084000000103010200200e02000808000090c0000024800204802009006020200008000081000000000050808002080000210011021008000000000100000800000000400000082000000010000007010800000400000000000014010000000802020490040002094020004800404010000000401008000401000600002000124000180008008008800001800400000002040002000600000000002001020050004018000000007080002024000020008200000020000081000100040000400000020000000000020000020001000000018402b60ce083e4e1c0831ca6e38466452e8db8560000000000095c3f0000000000000000000000000010c6a90000000000000000000000000004ee9900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218505d21dba008080"; + assertEq(blockHash, keccak256(encodedBlockHeader)); + vm.mockCall( + WARP_PRECOMPILE_ADDRESS, + abi.encodeCall(IWarpMessenger.getVerifiedWarpBlockHash, (0)), + abi.encode(WarpBlockHash({blockHash: blockHash, sourceChainID: DEFAULT_BLOCKCHAIN_ID}), true) + ); + + // Assemble the Merkle proof against the receipts root of the block header. + bytes[] memory proof = new bytes[](3); + proof[0] = + hex"f901d180a0cb5cc5565987800aeba057b0af7a83c7d46c3e16d08a0b2e5e97c663af8c0249a091ca9b1a8700045443e3cebc160679c2a8443dafd8f3bd33797836b401f5c0daa0f334d4c8361313ace856c4cd2f762c7954b0e280635e21cf7c5d8a0365b229f7a05a7dda2d8aa8908be6452e5ea4f2176d02c6c59418e8ade5d49cee1b1dab43e7a0ed2f24945ae33093877231e08d6cfc4584151642e49c59ad4cc7b6c6a9be30e3a09a1e4d23e6722be8df80f8e0b0a6978f868e2d09f9a8999c69349012425cb1a8a0d4639be4cfb077205fe324498b3b82165e4f26680b257b402aaf844287986d7ba02bf31869288dd26d1524809068622f88b2d8a7d4ba41e6b3d71103a72fbf81cfa0c8a339bcdd687538e2d6428ec10a9b763d8803c47b58796813fad9325bce9583a0853e20adc93f1f305cae89c704b98dd6ea5ebd2725cbd334a254c496fa25874fa0c2dc37de20dfd81248b7c7373e3858c935cb1377ce96c861fddfe3c6498b22b9a00592cdc2487293d7f933bac6750638a20ce822e652abe776ed20c69f354cd9dba0d472513604ab02f424f3a737de868348662e9caedf883b4213d0b76dbc7c9ae3a043d6dd9e9b84b58f3d23e0dc2c1fbdef9c99e6307431b849fe666696be6345c78080"; + proof[1] = + hex"f905ab20b905a7f905a40183162ae9b9010000000000000000000000000000000000000000000000000000000100000000000000100000000000000000000000000000000000000200000000000000000000000000000000000000000001002000000000000001000000000000000000000000000000020000000000000000000800000000000000000000000000000001000000000000000000000000000000000000000480000000000000000000400000000000001000000000000200000000000000000008000008000000000000000000000000000000000000000000000000004010000000000000000000000020000000000000000000000000000000000000000000000000000000000001000000f90499f9035c94154bab1fc1d87ff641eed0e9bc0f8a50d880d2b6f842a0f6a97944f31ea060dfde0566e4167c1a1082551e64b60ecb14d599a9d023d451a0000000000000000000000000000000000000000000000000000000000002be00b90300000000000000000000000000000000000000000000000000000006010e05e000000000000000000000000000e5b37dc608c73852f9c0f56e30f8d74d89b51c5500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000f4fc72042f23c3a2b6da6ebfecf0b6e30001538902000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000600bc7bda0000000000000000000000000000000000000000000000000000000600bc8b1c4000000000000000000000000000000000000000000000000000000600c0b0c17000000000000000000000000000000000000000000000000000000600d9b39e5000000000000000000000000000000000000000000000000000000600f2e28c6000000000000000000000000000000000000000000000000000000600f9c1e30000000000000000000000000000000000000000000000000000000600f9c1e3000000000000000000000000000000000000000000000000000000060105dd20a8000000000000000000000000000000000000000000000000000006010e05e000000000000000000000000000000000000000000000000000000006010e05e000000000000000000000000000000000000000000000000000000006010e05e000000000000000000000000000000000000000000000000000000006013c1415ba000000000000000000000000000000000000000000000000000006014367c00800000000000000000000000000000000000000000000000000000601bf96ddf600000000000000000000000000000000000000000000000000000601bf96ddf6000000000000000000000000000000000000000000000000000006023b6e36e00000000000000000000000000000000000000000000000000000000000000010010f0d0e0c040903080a000b0607020500000000000000000000000000000000f89b94154bab1fc1d87ff641eed0e9bc0f8a50d880d2b6f863a00109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271a0000000000000000000000000000000000000000000000000000000000002be00a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000066452e8df89b94154bab1fc1d87ff641eed0e9bc0f8a50d880d2b6f863a00559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5fa0000000000000000000000000000000000000000000000000000006010e05e000a0000000000000000000000000000000000000000000000000000000000002be00a00000000000000000000000000000000000000000000000000000000066452e8d"; + proof[2] = + hex"f851a016195dc5b5fc0021cbfee701b341d49721eb17357a1b354ecf55a61cab521b5c80808080808080a085f248d30b0ce90e5d44a50650a12dffc585c1cc2cb9474050891fa23e5306ac8080808080808080"; + + // Current answer should revert since no event has been imported yet. + vm.expectRevert("No data"); + priceFeedImporter.latestRoundData(); + + // Import the event. + vm.expectEmit(true, true, true, true); + emit AnswerUpdated(6_601_600_000_000, 179_712, 1_715_809_933); + vm.expectEmit(true, true, true, true); + emit EventImported(DEFAULT_BLOCKCHAIN_ID, blockHash, 0x154baB1FC1D87fF641EeD0E9Bc0f8a50D880D2B6, 8, 2); + priceFeedImporter.importEvent(bytes32(0), encodedBlockHeader, 8, proof, 2); + + // Verify the latest round data. + (uint80 roundID, int256 currentAnswer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) = + priceFeedImporter.latestRoundData(); + assertEq(roundID, 179_712); + assertEq(currentAnswer, 6_601_600_000_000); + assertEq(startedAt, 1_715_809_933); + assertEq(updatedAt, 1_715_809_933); + assertEq(answeredInRound, 179_712); + + assertEq(priceFeedImporter.latestSourceBlockNumber(), 45_485_280); + assertEq(priceFeedImporter.latestSourceTxIndex(), 8); + assertEq(priceFeedImporter.latestSourceLogIndex(), 2); + } +} diff --git a/contracts/test/PriceFeedImporterTests.sol b/contracts/test/PriceFeedImporterTests.sol index 7cc729c..6a330c4 100644 --- a/contracts/test/PriceFeedImporterTests.sol +++ b/contracts/test/PriceFeedImporterTests.sol @@ -6,16 +6,21 @@ pragma solidity 0.8.18; import {Test} from "forge-std/Test.sol"; -import {WarpBlockHash, IWarpMessenger} from "@subnet-evm/contracts/interfaces/IWarpMessenger.sol"; -import {PriceFeedImporter} from "../src/PriceFeedImporter.sol"; +import {PriceFeedImporter} from "src/PriceFeedImporter.sol"; +import {EVMEventInfo, EVMLog} from "src/IEventImporter.sol"; + +contract PriceFeedImporterMock is PriceFeedImporter(bytes32(0), address(0), 0, "", 0) { + function importEvent(EVMEventInfo memory eventInfo) external { + _onEventImport(eventInfo); + } +} contract PriceFeedImporterTest is Test { - address public constant WARP_PRECOMPILE_ADDRESS = 0x0200000000000000000000000000000000000005; - bytes32 public constant DEFAULT_BLOCKCHAIN_ID = - bytes32(hex"55e1fcfdde01f9f6d4c16fa2ed89ce65a8669120a86f321eef121891cab61241"); - address public constant SOURCE_ORACLE_AGGREGATOR = 0x154baB1FC1D87fF641EeD0E9Bc0f8a50D880D2B6; + PriceFeedImporterMock public priceFeedImporter; + bytes32 public answerUpdatedEventSignature; - PriceFeedImporter public priceFeedImporter; + // temp variable to create increasingly new events + uint256 public blockNumber = 0; event AnswerUpdated(int256 currentAnswer, uint80 roundID, uint256 updatedAt); event EventImported( @@ -27,52 +32,67 @@ contract PriceFeedImporterTest is Test { ); function setUp() public virtual { - priceFeedImporter = new PriceFeedImporter(DEFAULT_BLOCKCHAIN_ID, SOURCE_ORACLE_AGGREGATOR); + priceFeedImporter = new PriceFeedImporterMock(); + answerUpdatedEventSignature = priceFeedImporter.ANSWER_UPDATED_EVENT_SIGNATURE(); } - function testImportEvent() public { - // Mock the Warp precompile returning a valid WarpBlockHash. - bytes32 blockHash = bytes32(hex"2d9215bce478eb82bfd35f7e9bdc9d76e1814e8d7b5aa10ab05e2f17d145c0cf"); - bytes memory encodedBlockHeader = - hex"f9027ba05e92b0416d56a052ea29c5267627d489290dd2f87bae4887c56084452349598ca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940100000000000000000000000000000000000000a0425ff44c06b858d5ea72ce4261f8174d1a6d729a2ffdadddaa94abe58b37597da000d275e4cce63b7fe0facd8f477d3cf879b7992c3fed522e01ec5bc6b05345f7a07149d37617782b645919054a607d47ffc590e8c8827c616e792b22caf8fb527fb90100202000000000000000000000801000a120020004000080002184810040000008002050000000004000500400200c1004084000000103010200200e02000808000090c0000024800204802009006020200008000081000000000050808002080000210011021008000000000100000800000000400000082000000010000007010800000400000000000014010000000802020490040002094020004800404010000000401008000401000600002000124000180008008008800001800400000002040002000600000000002001020050004018000000007080002024000020008200000020000081000100040000400000020000000000020000020001000000018402b60ce083e4e1c0831ca6e38466452e8db8560000000000095c3f0000000000000000000000000010c6a90000000000000000000000000004ee9900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218505d21dba008080"; - assertEq(blockHash, keccak256(encodedBlockHeader)); - vm.mockCall( - WARP_PRECOMPILE_ADDRESS, - abi.encodeCall(IWarpMessenger.getVerifiedWarpBlockHash, (0)), - abi.encode(WarpBlockHash({blockHash: blockHash, sourceChainID: DEFAULT_BLOCKCHAIN_ID}), true) - ); - - // Assemble the Merkle proof against the receipts root of the block header. - bytes[] memory proof = new bytes[](3); - proof[0] = - hex"f901d180a0cb5cc5565987800aeba057b0af7a83c7d46c3e16d08a0b2e5e97c663af8c0249a091ca9b1a8700045443e3cebc160679c2a8443dafd8f3bd33797836b401f5c0daa0f334d4c8361313ace856c4cd2f762c7954b0e280635e21cf7c5d8a0365b229f7a05a7dda2d8aa8908be6452e5ea4f2176d02c6c59418e8ade5d49cee1b1dab43e7a0ed2f24945ae33093877231e08d6cfc4584151642e49c59ad4cc7b6c6a9be30e3a09a1e4d23e6722be8df80f8e0b0a6978f868e2d09f9a8999c69349012425cb1a8a0d4639be4cfb077205fe324498b3b82165e4f26680b257b402aaf844287986d7ba02bf31869288dd26d1524809068622f88b2d8a7d4ba41e6b3d71103a72fbf81cfa0c8a339bcdd687538e2d6428ec10a9b763d8803c47b58796813fad9325bce9583a0853e20adc93f1f305cae89c704b98dd6ea5ebd2725cbd334a254c496fa25874fa0c2dc37de20dfd81248b7c7373e3858c935cb1377ce96c861fddfe3c6498b22b9a00592cdc2487293d7f933bac6750638a20ce822e652abe776ed20c69f354cd9dba0d472513604ab02f424f3a737de868348662e9caedf883b4213d0b76dbc7c9ae3a043d6dd9e9b84b58f3d23e0dc2c1fbdef9c99e6307431b849fe666696be6345c78080"; - proof[1] = - hex"f905ab20b905a7f905a40183162ae9b9010000000000000000000000000000000000000000000000000000000100000000000000100000000000000000000000000000000000000200000000000000000000000000000000000000000001002000000000000001000000000000000000000000000000020000000000000000000800000000000000000000000000000001000000000000000000000000000000000000000480000000000000000000400000000000001000000000000200000000000000000008000008000000000000000000000000000000000000000000000000004010000000000000000000000020000000000000000000000000000000000000000000000000000000000001000000f90499f9035c94154bab1fc1d87ff641eed0e9bc0f8a50d880d2b6f842a0f6a97944f31ea060dfde0566e4167c1a1082551e64b60ecb14d599a9d023d451a0000000000000000000000000000000000000000000000000000000000002be00b90300000000000000000000000000000000000000000000000000000006010e05e000000000000000000000000000e5b37dc608c73852f9c0f56e30f8d74d89b51c5500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000f4fc72042f23c3a2b6da6ebfecf0b6e30001538902000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000600bc7bda0000000000000000000000000000000000000000000000000000000600bc8b1c4000000000000000000000000000000000000000000000000000000600c0b0c17000000000000000000000000000000000000000000000000000000600d9b39e5000000000000000000000000000000000000000000000000000000600f2e28c6000000000000000000000000000000000000000000000000000000600f9c1e30000000000000000000000000000000000000000000000000000000600f9c1e3000000000000000000000000000000000000000000000000000000060105dd20a8000000000000000000000000000000000000000000000000000006010e05e000000000000000000000000000000000000000000000000000000006010e05e000000000000000000000000000000000000000000000000000000006010e05e000000000000000000000000000000000000000000000000000000006013c1415ba000000000000000000000000000000000000000000000000000006014367c00800000000000000000000000000000000000000000000000000000601bf96ddf600000000000000000000000000000000000000000000000000000601bf96ddf6000000000000000000000000000000000000000000000000000006023b6e36e00000000000000000000000000000000000000000000000000000000000000010010f0d0e0c040903080a000b0607020500000000000000000000000000000000f89b94154bab1fc1d87ff641eed0e9bc0f8a50d880d2b6f863a00109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac60271a0000000000000000000000000000000000000000000000000000000000002be00a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000066452e8df89b94154bab1fc1d87ff641eed0e9bc0f8a50d880d2b6f863a00559884fd3a460db3073b7fc896cc77986f16e378210ded43186175bf646fc5fa0000000000000000000000000000000000000000000000000000006010e05e000a0000000000000000000000000000000000000000000000000000000000002be00a00000000000000000000000000000000000000000000000000000000066452e8d"; - proof[2] = - hex"f851a016195dc5b5fc0021cbfee701b341d49721eb17357a1b354ecf55a61cab521b5c80808080808080a085f248d30b0ce90e5d44a50650a12dffc585c1cc2cb9474050891fa23e5306ac8080808080808080"; - - // Current answer should revert since no event has been imported yet. - vm.expectRevert("No data"); - priceFeedImporter.latestRoundData(); + function testSetPriceFeed() public { + int256 answer = 123456; + uint80 logRoundID = 0; + uint256 logUpdatedAt = 1725274805; - // Import the event. - vm.expectEmit(true, true, true, true); - emit AnswerUpdated(6_601_600_000_000, 179_712, 1_715_809_933); - vm.expectEmit(true, true, true, true); - emit EventImported(DEFAULT_BLOCKCHAIN_ID, blockHash, 0x154baB1FC1D87fF641EeD0E9Bc0f8a50D880D2B6, 8, 2); - priceFeedImporter.importEvent(bytes32(0), encodedBlockHeader, 8, proof, 2); + EVMEventInfo memory eventInfo = _buildEVMEvent(answer, logRoundID, logUpdatedAt); + priceFeedImporter.importEvent(eventInfo); - // Verify the latest round data. (uint80 roundID, int256 currentAnswer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) = priceFeedImporter.latestRoundData(); - assertEq(roundID, 179_712); - assertEq(currentAnswer, 6_601_600_000_000); - assertEq(startedAt, 1_715_809_933); - assertEq(updatedAt, 1_715_809_933); - assertEq(answeredInRound, 179_712); - - assertEq(priceFeedImporter.latestSourceBlockNumber(), 45_485_280); - assertEq(priceFeedImporter.latestSourceTxIndex(), 8); - assertEq(priceFeedImporter.latestSourceLogIndex(), 2); + assertEq(roundID, logRoundID); + assertEq(currentAnswer, answer); + assertEq(startedAt, logUpdatedAt); + assertEq(updatedAt, logUpdatedAt); + assertEq(answeredInRound, logRoundID); + } + + function testIncreasingRoundID() public { + priceFeedImporter.importEvent(_buildEVMEvent(0, 0, 1)); + priceFeedImporter.importEvent(_buildEVMEvent(0, 1, 1)); + vm.expectRevert("roundID should be monotonically increasing"); + priceFeedImporter.importEvent(_buildEVMEvent(0, 0, 1)); + vm.expectRevert("roundID should be monotonically increasing"); + priceFeedImporter.importEvent(_buildEVMEvent(0, 1, 1)); + } + + function testHistoricalRoundData() public { + priceFeedImporter.importEvent(_buildEVMEvent(10, 0, 1)); + priceFeedImporter.importEvent(_buildEVMEvent(11, 1, 1)); + (, int256 answer,,,) = priceFeedImporter.getRoundData(0); + assertEq(answer, 10); + (, answer,,,) = priceFeedImporter.getRoundData(1); + assertEq(answer, 11); + vm.expectRevert("No data"); + (, answer,,,) = priceFeedImporter.getRoundData(2); + } + + function _buildEVMEvent(int256 answer, uint80 roundID, uint256 updatedAt) private returns (EVMEventInfo memory) { + bytes32[] memory topics = new bytes32[](3); + topics[0] = answerUpdatedEventSignature; + topics[1] = bytes32(uint256(answer)); + topics[2] = bytes32(uint256(uint80(roundID))); + + EVMLog memory log = EVMLog({ + loggerAddress: address(0), + topics: topics, + data: abi.encode(bytes32(updatedAt)) + }); + + blockNumber += 1; + + return EVMEventInfo({ + blockchainID: bytes32(0), + blockNumber: blockNumber, + txIndex: 0, + logIndex: 0, + log: log + }); } } diff --git a/tests/flows/import_price_feed.go b/tests/flows/import_price_feed.go index 63dd49c..d8c1007 100644 --- a/tests/flows/import_price_feed.go +++ b/tests/flows/import_price_feed.go @@ -47,6 +47,9 @@ func ImportPriceFeed(network interfaces.Network) { subnetAInfo, cChainInfo.BlockchainID, mockPriceFeedAggegratorAddress, + 18, + "WarpETHUSDAggregator", + big.NewInt(1), ) // Update the Mock Price Feed contract on C-Chain diff --git a/tests/utils/utils.go b/tests/utils/utils.go index dc1b9fc..68411de 100644 --- a/tests/utils/utils.go +++ b/tests/utils/utils.go @@ -76,6 +76,9 @@ func DeployPriceFeedImporter( subnet interfaces.SubnetTestInfo, aggregatorBlockchainID ids.ID, aggregatorAddress common.Address, + decimals uint8, + description string, + version *big.Int, ) (common.Address, *pricefeedimporter.PriceFeedImporter) { opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) Expect(err).Should(BeNil()) @@ -84,6 +87,9 @@ func DeployPriceFeedImporter( subnet.RPCClient, aggregatorBlockchainID, aggregatorAddress, + decimals, + description, + version, ) Expect(err).Should(BeNil()) teleporterUtils.WaitForTransactionSuccess(ctx, subnet, tx.Hash())