diff --git a/contract-bindings/artifacts/LightClientMock_bytecode.json b/contract-bindings/artifacts/LightClientMock_bytecode.json index 0873013c7..2999f519a 100644 --- a/contract-bindings/artifacts/LightClientMock_bytecode.json +++ b/contract-bindings/artifacts/LightClientMock_bytecode.json @@ -1 +1 @@ -"0x60a0604052306080523480156200001557600080fd5b506040516200339d3803806200339d8339810160408190526200003891620004ec565b6200004262000058565b6200004f8383836200010c565b5050506200062c565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620000a95760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b0390811614620001095780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b82516001600160401b031615158062000131575060208301516001600160401b031615155b806200013f57506020820151155b806200014d57506040820151155b806200015b57506060820151155b806200016657508151155b80620001795750610e108163ffffffff16105b806200018e57506301e133808163ffffffff16115b15620001ad576040516350dd03f760e11b815260040160405180910390fd5b8251600480546020808701516001600160401b0390811668010000000000000000026001600160801b031993841691909516908117851790935560408088015160058190558751600055918701516001558601516002556060860151600355600680549092169092179092179091556007556008805463ffffffff8316600160a01b0263ffffffff60a01b199091161790556200024c43428562000251565b505050565b60095415801590620002d2575060085460098054600160a01b830463ffffffff1692600160c01b90046001600160401b0316908110620002955762000295620005a5565b6000918252602090912060029091020154620002c7906801000000000000000090046001600160401b031684620005d1565b6001600160401b0316115b156200036c57600854600980549091600160c01b90046001600160401b0316908110620003035762000303620005a5565b60009182526020822060029091020180546001600160c01b03191681556001015560088054600160c01b90046001600160401b03169060186200034683620005fb565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550505b604080516080810182526001600160401b0394851681529284166020808501918252830151851684830190815292909101516060840190815260098054600181018255600091909152935160029094027f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af81018054935194518716600160801b02600160801b600160c01b031995881668010000000000000000026001600160801b03199095169690971695909517929092179290921693909317909155517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b090910155565b604051606081016001600160401b03811182821017156200048357634e487b7160e01b600052604160045260246000fd5b60405290565b604051608081016001600160401b03811182821017156200048357634e487b7160e01b600052604160045260246000fd5b80516001600160401b0381168114620004d257600080fd5b919050565b805163ffffffff81168114620004d257600080fd5b60008060008385036101008112156200050457600080fd5b60608112156200051357600080fd5b6200051d62000452565b6200052886620004ba565b81526200053860208701620004ba565b60208201526040868101519082015293506080605f19820112156200055c57600080fd5b506200056762000489565b60608581015182526080860151602083015260a0860151604083015260c08601519082015291506200059c60e08501620004d7565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6001600160401b03828116828216039080821115620005f457620005f4620005bb565b5092915050565b60006001600160401b038281166002600160401b03198101620006225762000622620005bb565b6001019392505050565b608051612d4762000656600039600081816111520152818161117b01526112fa0152612d476000f3fe60806040526004361061019c5760003560e01c80638584d23f116100ec578063c23b9e9e1161008a578063e030330111610064578063e03033011461060c578063f2fde38b1461062c578063f56761601461064c578063f9e50d191461066c57600080fd5b8063c23b9e9e14610587578063c8e5e498146105c0578063d24d933d146105dc57600080fd5b80639baa3cc9116100c65780639baa3cc91461047b5780639fdb54a71461049b578063ad3cb1cc146104f1578063b5adea3c1461052f57600080fd5b80638584d23f146103e15780638da5cb5b1461041e57806396c1ca611461045b57600080fd5b8063313df7b11161015957806352d1902d1161013357806352d1902d1461036857806369cc6a041461038b578063715018a6146103a0578063826e41fc146103b557600080fd5b8063313df7b1146102da578063426d3194146103125780634f1ef2861461035557600080fd5b8063013fa5fc146101a157806302b592f3146101c35780630d8e6e2c146102215780632063d4f71461024e5780632d52aad61461026e5780632f79889d1461029b575b600080fd5b3480156101ad57600080fd5b506101c16101bc3660046121bb565b610681565b005b3480156101cf57600080fd5b506101e36101de3660046121d6565b610734565b60405161021894939291906001600160401b039485168152928416602084015292166040820152606081019190915260800190565b60405180910390f35b34801561022d57600080fd5b50604080516001815260006020820181905291810191909152606001610218565b34801561025a57600080fd5b506101c161026936600461234c565b61077f565b34801561027a57600080fd5b506101c16102893660046121d6565b600a805460ff19166001179055600b55565b3480156102a757600080fd5b506008546102c290600160c01b90046001600160401b031681565b6040516001600160401b039091168152602001610218565b3480156102e657600080fd5b506008546102fa906001600160a01b031681565b6040516001600160a01b039091168152602001610218565b34801561031e57600080fd5b506000546001546002546003546103359392919084565b604080519485526020850193909352918301526060820152608001610218565b6101c1610363366004612500565b6108d4565b34801561037457600080fd5b5061037d6108f3565b604051908152602001610218565b34801561039757600080fd5b506101c1610910565b3480156103ac57600080fd5b506101c161097f565b3480156103c157600080fd5b506008546001600160a01b031615155b6040519015158152602001610218565b3480156103ed57600080fd5b506104016103fc3660046121d6565b610991565b604080519283526001600160401b03909116602083015201610218565b34801561042a57600080fd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03166102fa565b34801561046757600080fd5b506101c16104763660046125b9565b610ac4565b34801561048757600080fd5b506101c16104963660046125d4565b610b4d565b3480156104a757600080fd5b506006546007546104cb916001600160401b0380821692600160401b909204169083565b604080516001600160401b03948516815293909216602084015290820152606001610218565b3480156104fd57600080fd5b50610522604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516102189190612684565b34801561053b57600080fd5b506101c161054a3660046126b7565b80516006805460208401516001600160401b03908116600160401b026001600160801b031990921693169290921791909117905560400151600755565b34801561059357600080fd5b506008546105ab90600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610218565b3480156105cc57600080fd5b506101c1600a805460ff19169055565b3480156105e857600080fd5b506004546005546104cb916001600160401b0380821692600160401b909204169083565b34801561061857600080fd5b506103d16106273660046126d3565b610c71565b34801561063857600080fd5b506101c16106473660046121bb565b610ca7565b34801561065857600080fd5b506101c16106673660046126f5565b610cea565b34801561067857600080fd5b5060095461037d565b610689610d98565b6001600160a01b0381166106b05760405163e6c4247b60e01b815260040160405180910390fd5b6008546001600160a01b03908116908216036106df5760405163a863aec960e01b815260040160405180910390fd5b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527f8017bb887fdf8fca4314a9d40f6e73b3b81002d67e5cfa85d88173af6aa46072906020015b60405180910390a150565b6009818154811061074457600080fd5b6000918252602090912060029091020180546001909101546001600160401b038083169350600160401b8304811692600160801b9004169084565b6008546001600160a01b0316151580156107a457506008546001600160a01b03163314155b156107c2576040516301474c8f60e71b815260040160405180910390fd5b60065482516001600160401b0391821691161115806107fb575060065460208301516001600160401b03600160401b9092048216911611155b156108195760405163051c46ef60e01b815260040160405180910390fd5b6108268260400151610df3565b6108308282610e63565b81516006805460208501516001600160401b03908116600160401b026001600160801b03199092169316929092179190911790556040820151600755610877434284610f5b565b81602001516001600160401b031682600001516001600160401b03167fa04a773924505a418564363725f56832f5772e6b8d0dbd6efce724dfe803dae684604001516040516108c891815260200190565b60405180910390a35050565b6108dc611147565b6108e5826111ec565b6108ef828261122d565b5050565b60006108fd6112ef565b50600080516020612d1b83398151915290565b610918610d98565b6008546001600160a01b03161561096457600880546001600160a01b03191690556040517f9a5f57de856dd668c54dd95e5c55df93432171cbca49a8776d5620ea59c0245090600090a1565b60405163a863aec960e01b815260040160405180910390fd5b565b610987610d98565b61097d6000611338565b600980546000918291906109a6600183612800565b815481106109b6576109b6612813565b6000918252602090912060029091020154600160801b90046001600160401b03168411156109f757604051631856a49960e21b815260040160405180910390fd5b600854600160c01b90046001600160401b03165b81811015610abd578460098281548110610a2757610a27612813565b6000918252602090912060029091020154600160801b90046001600160401b031610610ab55760098181548110610a6057610a60612813565b90600052602060002090600202016001015460098281548110610a8557610a85612813565b906000526020600020906002020160000160109054906101000a90046001600160401b0316935093505050915091565b600101610a0b565b5050915091565b610acc610d98565b610e108163ffffffff161080610aeb57506301e133808163ffffffff16115b80610b09575060085463ffffffff600160a01b909104811690821611155b15610b27576040516307a5077760e51b815260040160405180910390fd5b6008805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b0316600081158015610b925750825b90506000826001600160401b03166001148015610bae5750303b155b905081158015610bbc575080155b15610bda5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610c0457845460ff60401b1916600160401b1785555b610c0d866113a9565b610c156113ba565b610c208989896113c2565b8315610c6657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b600a5460009060ff16610c8d57610c8883836114f3565b610c9e565b81600b5484610c9c9190612800565b115b90505b92915050565b610caf610d98565b6001600160a01b038116610cde57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b610ce781611338565b50565b610cf660096000611ea9565b60005b81518110156108ef576009828281518110610d1657610d16612813565b602090810291909101810151825460018181018555600094855293839020825160029092020180549383015160408401516001600160401b03908116600160801b0267ffffffffffffffff60801b19928216600160401b026001600160801b031990971691909416179490941793909316178255606001519082015501610cf9565b33610dca7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b03161461097d5760405163118cdaa760e01b8152336004820152602401610cd5565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018110806108ef5760405162461bcd60e51b815260206004820152601b60248201527f426e3235343a20696e76616c6964207363616c6172206669656c6400000000006044820152606401610cd5565b6000610e6d611650565b9050610e77611eca565b83516001600160401b0390811682526020850151168160016020020152604084810151828201526001546060830152600254608083015260035460a083015260005460c08301525163ce537a7760e01b815273__$5c5c07cf4f55be9472c2b47d897172e765$__9063ce537a7790610ef790859085908890600401612a30565b602060405180830381865af4158015610f14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f389190612c5f565b610f55576040516309bde33960e01b815260040160405180910390fd5b50505050565b60095415801590610fd1575060085460098054600160a01b830463ffffffff1692600160c01b90046001600160401b0316908110610f9b57610f9b612813565b6000918252602090912060029091020154610fc690600160401b90046001600160401b031684612c81565b6001600160401b0316115b1561106557600854600980549091600160c01b90046001600160401b0316908110610ffe57610ffe612813565b60009182526020822060029091020180546001600160c01b03191681556001015560088054600160c01b90046001600160401b031690601861103f83612ca8565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550505b604080516080810182526001600160401b0394851681529284166020808501918252830151851684830190815292909101516060840190815260098054600181018255600091909152935160029094027f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af81018054935194518716600160801b0267ffffffffffffffff60801b19958816600160401b026001600160801b03199095169690971695909517929092179290921693909317909155517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b090910155565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806111ce57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166111c2600080516020612d1b833981519152546001600160a01b031690565b6001600160a01b031614155b1561097d5760405163703e46dd60e11b815260040160405180910390fd5b6111f4610d98565b6040516001600160a01b03821681527ff78721226efe9a1bb678189a16d1554928b9f2192e2cb93eeda83b79fa40007d90602001610729565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611287575060408051601f3d908101601f1916820190925261128491810190612cce565b60015b6112af57604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610cd5565b600080516020612d1b83398151915281146112e057604051632a87526960e21b815260048101829052602401610cd5565b6112ea8383611c80565b505050565b306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461097d5760405163703e46dd60e11b815260040160405180910390fd5b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6113b1611cd6565b610ce781611d1f565b61097d611cd6565b82516001600160401b03161515806113e6575060208301516001600160401b031615155b806113f357506020820151155b8061140057506040820151155b8061140d57506060820151155b8061141757508151155b806114295750610e108163ffffffff16105b8061143d57506301e133808163ffffffff16115b1561145b576040516350dd03f760e11b815260040160405180910390fd5b8251600480546020808701516001600160401b03908116600160401b026001600160801b031993841691909516908117851790935560408088015160058190558751600055918701516001558601516002556060860151600355600680549092169092179092179091556007556008805463ffffffff8316600160a01b0263ffffffff60a01b199091161790556112ea434285610f5b565b60095460009043841180611505575080155b806115505750600854600980549091600160c01b90046001600160401b031690811061153357611533612813565b60009182526020909120600290910201546001600160401b031684105b1561156e5760405163b0b4387760e01b815260040160405180910390fd5b6000808061157d600185612800565b90505b8161161b57600854600160c01b90046001600160401b0316811061161b5786600982815481106115b2576115b2612813565b60009182526020909120600290910201546001600160401b0316116116095760019150600981815481106115e8576115e8612813565b60009182526020909120600290910201546001600160401b0316925061161b565b8061161381612ce7565b915050611580565b816116395760405163b0b4387760e01b815260040160405180910390fd5b856116448489612800565b11979650505050505050565b611658611ee8565b620100008152600760208201527f1369aa78dc50135ad756d62c97a64a0edcd30066584168200d9d1facf82ca4f56040820151527f2cf23456d712b06f8e3aa5bf0acc3e46a3d094602a3a2b99d873bba05a4391476020604083015101527f08a35f379d2d2c490a51006697275e4db79b67b4a175c1477e262d29e25e42316060820151527f218828131bb7940ccc88c561b299755af4bf0b71ed930b129e8be0a1218139ea6020606083015101527f23a2172436c1145b36d5bc6d3b31fa1610c73a543ea443918aaa3ee175f9921b6080820151527f2502adf404d62877c310214ae9942e93c40b154d34c024bab48a3ca057e60a116020608083015101527f1bb88ada91ab7734882f7826b81275320081ac485f9cf8bfbc3ba54b6eb4dff360a0820151527f25c74a27e9a3b20114a3a91f31c20f01777e7ed913e0ef949f0285e2e7c2069b602060a083015101527f12b0ce76ac8b0dbd405ebc5dd0bae0f91aed50033c7ea36fc62aaba2b98333dc60c0820151527f185b42af49dd1cbe337a84f74b704172428e754a0bea024ab3eb2f996afb2c47602060c083015101527f21f53ad4538b45438bbf0521446070223920e3df6f9022a64cc16d7f94e85c0860e0820151527f2278ac3dedfdac7feb9725a022497175518eada52c8932fc40e6e75bea889fb8602060e083015101527f0876136f81c16298487bfb1be74d4a3487ec45645ab1d09dc2e5b865d62230df610100820151527f098c641c947ecd798dfd5e1b2fe428024cdf03061a53ff774ea8a9e3de9d3f2b602061010083015101527f15eaac2c6232d2268bf79dc47ed9666f992fb3d96ad23fb21690c21586c5472e610120820151527f0f10f1ffc54881287fda6f200bc85d8245b508d844a974098a41119867b325d0602061012083015101527f0895ceea40b085534e9739ca5442ba48b3a3592affde2b509df74521b47d8ab0610140820151527f2e12ec5800ac92fe2a8e7040bc5b435b9eb71e31380173fa7688bf81fcbba455602061014083015101527f2f5384eb5653e47576efe248e7903f463243414bfed5237dda750df3996bd918610160820151527f1c3cd6b11da8704cdc871ab4fa323d7ee57bd40ce165b49a56d5ef6489cd251a602061016083015101527f13579994957ce1554cc1e5b194fb63c9513707f627414f8442681ae736e36450610180820151527f26c9bdcd96d8e420b12974ade93ad9c312c4185213d2f6831a7c625a18890e95602061018083015101527f0cc70a1d542a9a1535ae5d9201696adc5c99c1bcebd9951dfa8afec79fa0b6446101a0820151527f10b043d9f1869181b96579d6616efc17a5df7b84c4d431d966c9094bf1e8815360206101a083015101527f198a65309d131a43b0ab1c47659d0336cfbf62b27f4727106b4fd971c73dd4036101c0820151527f23df99eac3c1947903b211b800efeb76f47d5e87b7414866543492e8c7798d1a60206101c083015101527f221cc5e47b81ce8dcfa72ef981916a8eddef12fcde59c56c62830c126ebef0de6101e0820151527f231f99340c35c9e09652a6df73c9cec5d88738cb71ff45716fdc9e9e45a4926e60206101e083015101527f2c9f1489fce0f263e03f3e97bf0a72273aafcca9325ff47786adb04a52a6d22c610200820151527f21f66e28f17e01e9fd593e16d022c4eca25bd5db96daec606d97b604cc414838602061020083015101527f2015745604a9571e226bd99043cfaf1f96267cc5de67f497563ff81100531d26610220820151527f206889ff4c58dd08ee1107191a2a5bc5dbae55c49d7d8397801799868d10f805602061022083015101527f21062ab8f8ecd8932b429a1eb8614b1e03db61bff6a5cd2d5d7ea193e90e9927610240820151527f217f9b27b934b88ffe555d682dfe6e8b6d503f86b14bbd96342bc48487a60b27602061024083015101527f1c9eda2d195cb731f903235ead6a4f7c66db49da713ecb27afee076f0eea7154610260820151527f2647c161c00b90258e1cefebb17481f8a5d91b5f9dca626e3e89a9215bcca16a602061026083015101527fb0838893ec1f237e8b07323b0744599f4e97b598b3b589bcc2bc37b8d5c418016102808201527fc18393c0fa30fe4e8b038e357ad851eae8de9107584effe7c7f1f651b2010e266102a082015290565b611c8982611d27565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2805115611cce576112ea8282611d8c565b6108ef611e02565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661097d57604051631afcd79f60e31b815260040160405180910390fd5b610caf611cd6565b806001600160a01b03163b600003611d5d57604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610cd5565b600080516020612d1b83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080846001600160a01b031684604051611da99190612cfe565b600060405180830381855af49150503d8060008114611de4576040519150601f19603f3d011682016040523d82523d6000602084013e611de9565b606091505b5091509150611df9858383611e21565b95945050505050565b341561097d5760405163b398979f60e01b815260040160405180910390fd5b606082611e3657611e3182611e80565b611e79565b8151158015611e4d57506001600160a01b0384163b155b15611e7657604051639996b31560e01b81526001600160a01b0385166004820152602401610cd5565b50805b9392505050565b805115611e905780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b5080546000825560020290600052602060002090810190610ce79190612175565b6040518060e001604052806007906020820280368337509192915050565b604051806102c001604052806000815260200160008152602001611f1f604051806040016040528060008152602001600081525090565b8152602001611f41604051806040016040528060008152602001600081525090565b8152602001611f63604051806040016040528060008152602001600081525090565b8152602001611f85604051806040016040528060008152602001600081525090565b8152602001611fa7604051806040016040528060008152602001600081525090565b8152602001611fc9604051806040016040528060008152602001600081525090565b8152602001611feb604051806040016040528060008152602001600081525090565b815260200161200d604051806040016040528060008152602001600081525090565b815260200161202f604051806040016040528060008152602001600081525090565b8152602001612051604051806040016040528060008152602001600081525090565b8152602001612073604051806040016040528060008152602001600081525090565b8152602001612095604051806040016040528060008152602001600081525090565b81526020016120b7604051806040016040528060008152602001600081525090565b81526020016120d9604051806040016040528060008152602001600081525090565b81526020016120fb604051806040016040528060008152602001600081525090565b815260200161211d604051806040016040528060008152602001600081525090565b815260200161213f604051806040016040528060008152602001600081525090565b8152602001612161604051806040016040528060008152602001600081525090565b815260006020820181905260409091015290565b5b8082111561219b5780546001600160c01b031916815560006001820155600201612176565b5090565b80356001600160a01b03811681146121b657600080fd5b919050565b6000602082840312156121cd57600080fd5b610c9e8261219f565b6000602082840312156121e857600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040516102e081016001600160401b0381118282101715612228576122286121ef565b60405290565b604051608081016001600160401b0381118282101715612228576122286121ef565b604051601f8201601f191681016001600160401b0381118282101715612278576122786121ef565b604052919050565b80356001600160401b03811681146121b657600080fd5b6000606082840312156122a957600080fd5b604051606081018181106001600160401b03821117156122cb576122cb6121ef565b6040529050806122da83612280565b81526122e860208401612280565b6020820152604083013560408201525092915050565b60006040828403121561231057600080fd5b604051604081018181106001600160401b0382111715612332576123326121ef565b604052823581526020928301359281019290925250919050565b6000808284036104e081121561236157600080fd5b61236b8585612297565b925061048080605f198301121561238157600080fd5b612389612205565b915061239886606087016122fe565b82526123a78660a087016122fe565b60208301526123b98660e087016122fe565b60408301526101206123cd878288016122fe565b60608401526101606123e1888289016122fe565b60808501526101a06123f589828a016122fe565b60a08601526101e06124098a828b016122fe565b60c087015261022061241d8b828c016122fe565b60e08801526102606124318c828d016122fe565b6101008901526102a06124468d828e016122fe565b878a01526124588d6102e08e016122fe565b6101408a015261246c8d6103208e016122fe565b868a015261247e8d6103608e016122fe565b6101808a01526103a08c0135948901949094526103c08b01356101c08901526103e08b0135928801929092526104008a01356102008801526104208a013590870152610440890135610240870152610460890135908601529287013561028085015250506104a0850135908201526104c0909301356102c08401525092909150565b6000806040838503121561251357600080fd5b61251c8361219f565b91506020808401356001600160401b038082111561253957600080fd5b818601915086601f83011261254d57600080fd5b81358181111561255f5761255f6121ef565b612571601f8201601f19168501612250565b9150808252878482850101111561258757600080fd5b80848401858401376000848284010152508093505050509250929050565b803563ffffffff811681146121b657600080fd5b6000602082840312156125cb57600080fd5b610c9e826125a5565b6000806000808486036101208112156125ec57600080fd5b6125f68787612297565b94506080605f198201121561260a57600080fd5b5061261361222e565b60608681013582526080870135602083015260a0870135604083015260c087013590820152925061264660e086016125a5565b9150612655610100860161219f565b905092959194509250565b60005b8381101561267b578181015183820152602001612663565b50506000910152565b60208152600082518060208401526126a3816040850160208701612660565b601f01601f19169190910160400192915050565b6000606082840312156126c957600080fd5b610c9e8383612297565b600080604083850312156126e657600080fd5b50508035926020909101359150565b6000602080838503121561270857600080fd5b82356001600160401b038082111561271f57600080fd5b818501915085601f83011261273357600080fd5b813581811115612745576127456121ef565b612753848260051b01612250565b818152848101925060079190911b83018401908782111561277357600080fd5b928401925b818410156127df57608084890312156127915760008081fd5b61279961222e565b6127a285612280565b81526127af868601612280565b8682015260406127c0818701612280565b9082015260608581013590820152835260809093019291840191612778565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610ca157610ca16127ea565b634e487b7160e01b600052603260045260246000fd5b8060005b6007811015610f5557815184526020938401939091019060010161282d565b61286182825180518252602090810151910152565b6020818101518051604085015290810151606084015250604081015180516080840152602081015160a0840152506060810151805160c0840152602081015160e08401525060808101516101006128c48185018380518252602090810151910152565b60a083015191506101406128e48186018480518252602090810151910152565b60c084015192506101806129048187018580518252602090810151910152565b60e085015193506101c06129248188018680518252602090810151910152565b928501519350610200926129448785018680518252602090810151910152565b61012086015194506102406129658189018780518252602090810151910152565b928601519450610280926129858885018780518252602090810151910152565b61016087015195506102c06129a6818a018880518252602090810151910152565b9287015180516103008a0152602001516103208901526101a0870151610340890152908601516103608801526101e0860151610380880152928501516103a08701526102208501516103c0870152918401516103e08601526102608401516104008601528301516104208501526102a0830151610440850152909101516104609092019190915250565b6000610a608201905084518252602085015160208301526040850151612a63604084018280518252602090810151910152565b50606085015180516080840152602081015160a0840152506080850151805160c0840152602081015160e08401525060a0850151610100612ab08185018380518252602090810151910152565b60c08701519150610140612ad08186018480518252602090810151910152565b60e08801519250610180612af08187018580518252602090810151910152565b9188015192506101c091612b108684018580518252602090810151910152565b6101208901519350610200612b318188018680518252602090810151910152565b91890151935061024091612b518784018680518252602090810151910152565b6101608a01519450610280612b728189018780518252602090810151910152565b918a015180516102c08901526020908101516102e08901526101a08b015180516103008a0152810151610320890152938a015180516103408901528401516103608801526101e08a015180516103808901528401516103a088015289015180516103c08801528301516103e087015261022089015180516104008801528301516104208701529088015180516104408701528201516104608601526102608801518051610480870152909101516104a08501528601516104c0840152506102a08501516104e0830152612c49610500830185612829565b612c576105e083018461284c565b949350505050565b600060208284031215612c7157600080fd5b81518015158114611e7957600080fd5b6001600160401b03828116828216039080821115612ca157612ca16127ea565b5092915050565b60006001600160401b03808316818103612cc457612cc46127ea565b6001019392505050565b600060208284031215612ce057600080fd5b5051919050565b600081612cf657612cf66127ea565b506000190190565b60008251612d10818460208701612660565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca164736f6c6343000817000a" +"0x60a0604052306080523480156200001557600080fd5b50604051620033cd380380620033cd8339810160408190526200003891620004ec565b6200004262000058565b6200004f8383836200010c565b5050506200062c565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620000a95760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b0390811614620001095780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b82516001600160401b031615158062000131575060208301516001600160401b031615155b806200013f57506020820151155b806200014d57506040820151155b806200015b57506060820151155b806200016657508151155b80620001795750610e108163ffffffff16105b806200018e57506301e133808163ffffffff16115b15620001ad576040516350dd03f760e11b815260040160405180910390fd5b8251600480546020808701516001600160401b039485166001600160801b03199384168117680100000000000000009690921695909502908117909355604080880151600581905587516000559187015160015586015160025560608601516003556006805490921690931790911790556007556008805463ffffffff60a01b1916600160a01b63ffffffff8416021790556200024c43428562000251565b505050565b60095415801590620002d2575060085460098054600160a01b830463ffffffff1692600160c01b90046001600160401b0316908110620002955762000295620005a5565b6000918252602090912060029091020154620002c7906801000000000000000090046001600160401b031684620005d1565b6001600160401b0316115b156200036c57600854600980549091600160c01b90046001600160401b0316908110620003035762000303620005a5565b60009182526020822060029091020180546001600160c01b03191681556001015560088054600160c01b90046001600160401b03169060186200034683620005fb565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550505b604080516080810182526001600160401b0394851681529284166020808501918252830151851684830190815292909101516060840190815260098054600181018255600091909152935160029094027f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af81018054935194518716600160801b02600160801b600160c01b031995881668010000000000000000026001600160801b03199095169690971695909517929092179290921693909317909155517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b090910155565b604051606081016001600160401b03811182821017156200048357634e487b7160e01b600052604160045260246000fd5b60405290565b604051608081016001600160401b03811182821017156200048357634e487b7160e01b600052604160045260246000fd5b80516001600160401b0381168114620004d257600080fd5b919050565b805163ffffffff81168114620004d257600080fd5b60008060008385036101008112156200050457600080fd5b60608112156200051357600080fd5b6200051d62000452565b6200052886620004ba565b81526200053860208701620004ba565b60208201526040868101519082015293506080605f19820112156200055c57600080fd5b506200056762000489565b60608581015182526080860151602083015260a0860151604083015260c08601519082015291506200059c60e08501620004d7565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6001600160401b03828116828216039080821115620005f457620005f4620005bb565b5092915050565b60006001600160401b038281166002600160401b03198101620006225762000622620005bb565b6001019392505050565b608051612d776200065660003960008181611182015281816111ab015261132a0152612d776000f3fe6080604052600436106101b75760003560e01c80638584d23f116100ec578063c23b9e9e1161008a578063e030330111610064578063e030330114610636578063f2fde38b14610656578063f567616014610676578063f9e50d191461069657600080fd5b8063c23b9e9e146105b1578063c8e5e498146105ea578063d24d933d1461060657600080fd5b80639baa3cc9116100c65780639baa3cc9146104a55780639fdb54a7146104c5578063ad3cb1cc1461051b578063b5adea3c1461055957600080fd5b80638584d23f1461040b5780638da5cb5b1461044857806396c1ca611461048557600080fd5b8063378ec23b1161015957806352d1902d1161013357806352d1902d146103a057806369cc6a04146103b5578063715018a6146103ca578063826e41fc146103df57600080fd5b8063378ec23b1461032d578063426d31941461034a5780634f1ef2861461038d57600080fd5b80632063d4f7116101955780632063d4f7146102695780632d52aad6146102895780632f79889d146102b6578063313df7b1146102f557600080fd5b8063013fa5fc146101bc57806302b592f3146101de5780630d8e6e2c1461023c575b600080fd5b3480156101c857600080fd5b506101dc6101d73660046121eb565b6106ab565b005b3480156101ea57600080fd5b506101fe6101f9366004612206565b61075e565b60405161023394939291906001600160401b039485168152928416602084015292166040820152606081019190915260800190565b60405180910390f35b34801561024857600080fd5b50604080516001815260006020820181905291810191909152606001610233565b34801561027557600080fd5b506101dc61028436600461237c565b6107a9565b34801561029557600080fd5b506101dc6102a4366004612206565b600a805460ff19166001179055600b55565b3480156102c257600080fd5b506008546102dd90600160c01b90046001600160401b031681565b6040516001600160401b039091168152602001610233565b34801561030157600080fd5b50600854610315906001600160a01b031681565b6040516001600160a01b039091168152602001610233565b34801561033957600080fd5b50435b604051908152602001610233565b34801561035657600080fd5b5060005460015460025460035461036d9392919084565b604080519485526020850193909352918301526060820152608001610233565b6101dc61039b366004612530565b610904565b3480156103ac57600080fd5b5061033c610923565b3480156103c157600080fd5b506101dc610940565b3480156103d657600080fd5b506101dc6109af565b3480156103eb57600080fd5b506008546001600160a01b031615155b6040519015158152602001610233565b34801561041757600080fd5b5061042b610426366004612206565b6109c1565b604080519283526001600160401b03909116602083015201610233565b34801561045457600080fd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b0316610315565b34801561049157600080fd5b506101dc6104a03660046125e9565b610af4565b3480156104b157600080fd5b506101dc6104c0366004612604565b610b7d565b3480156104d157600080fd5b506006546007546104f5916001600160401b0380821692600160401b909204169083565b604080516001600160401b03948516815293909216602084015290820152606001610233565b34801561052757600080fd5b5061054c604051806040016040528060058152602001640352e302e360dc1b81525081565b60405161023391906126b4565b34801561056557600080fd5b506101dc6105743660046126e7565b80516006805460208401516001600160401b03908116600160401b026001600160801b031990921693169290921791909117905560400151600755565b3480156105bd57600080fd5b506008546105d590600160a01b900463ffffffff1681565b60405163ffffffff9091168152602001610233565b3480156105f657600080fd5b506101dc600a805460ff19169055565b34801561061257600080fd5b506004546005546104f5916001600160401b0380821692600160401b909204169083565b34801561064257600080fd5b506103fb610651366004612703565b610ca1565b34801561066257600080fd5b506101dc6106713660046121eb565b610cd7565b34801561068257600080fd5b506101dc610691366004612725565b610d1a565b3480156106a257600080fd5b5060095461033c565b6106b3610dc8565b6001600160a01b0381166106da5760405163e6c4247b60e01b815260040160405180910390fd5b6008546001600160a01b03908116908216036107095760405163a863aec960e01b815260040160405180910390fd5b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527f8017bb887fdf8fca4314a9d40f6e73b3b81002d67e5cfa85d88173af6aa46072906020015b60405180910390a150565b6009818154811061076e57600080fd5b6000918252602090912060029091020180546001909101546001600160401b038083169350600160401b8304811692600160801b9004169084565b6008546001600160a01b0316151580156107ce57506008546001600160a01b03163314155b156107ec576040516301474c8f60e71b815260040160405180910390fd5b60065482516001600160401b039182169116111580610825575060065460208301516001600160401b03600160401b9092048216911611155b156108435760405163051c46ef60e01b815260040160405180910390fd5b6108508260400151610e23565b61085a8282610e93565b81516006805460208501516001600160401b03908116600160401b026001600160801b031990921693169290921791909117905560408201516007556108a76108a04390565b4284610f8b565b81602001516001600160401b031682600001516001600160401b03167fa04a773924505a418564363725f56832f5772e6b8d0dbd6efce724dfe803dae684604001516040516108f891815260200190565b60405180910390a35050565b61090c611177565b6109158261121c565b61091f828261125d565b5050565b600061092d61131f565b50600080516020612d4b83398151915290565b610948610dc8565b6008546001600160a01b03161561099457600880546001600160a01b03191690556040517f9a5f57de856dd668c54dd95e5c55df93432171cbca49a8776d5620ea59c0245090600090a1565b60405163a863aec960e01b815260040160405180910390fd5b565b6109b7610dc8565b6109ad6000611368565b600980546000918291906109d6600183612830565b815481106109e6576109e6612843565b6000918252602090912060029091020154600160801b90046001600160401b0316841115610a2757604051631856a49960e21b815260040160405180910390fd5b600854600160c01b90046001600160401b03165b81811015610aed578460098281548110610a5757610a57612843565b6000918252602090912060029091020154600160801b90046001600160401b031610610ae55760098181548110610a9057610a90612843565b90600052602060002090600202016001015460098281548110610ab557610ab5612843565b906000526020600020906002020160000160109054906101000a90046001600160401b0316935093505050915091565b600101610a3b565b5050915091565b610afc610dc8565b610e108163ffffffff161080610b1b57506301e133808163ffffffff16115b80610b39575060085463ffffffff600160a01b909104811690821611155b15610b57576040516307a5077760e51b815260040160405180910390fd5b6008805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b0316600081158015610bc25750825b90506000826001600160401b03166001148015610bde5750303b155b905081158015610bec575080155b15610c0a5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610c3457845460ff60401b1916600160401b1785555b610c3d866113d9565b610c456113ea565b610c508989896113f2565b8315610c9657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b600a5460009060ff16610cbd57610cb88383611523565b610cce565b81600b5484610ccc9190612830565b115b90505b92915050565b610cdf610dc8565b6001600160a01b038116610d0e57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b610d1781611368565b50565b610d2660096000611ed9565b60005b815181101561091f576009828281518110610d4657610d46612843565b602090810291909101810151825460018181018555600094855293839020825160029092020180549383015160408401516001600160401b03908116600160801b0267ffffffffffffffff60801b19928216600160401b026001600160801b031990971691909416179490941793909316178255606001519082015501610d29565b33610dfa7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146109ad5760405163118cdaa760e01b8152336004820152602401610d05565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000181108061091f5760405162461bcd60e51b815260206004820152601b60248201527f426e3235343a20696e76616c6964207363616c6172206669656c6400000000006044820152606401610d05565b6000610e9d611680565b9050610ea7611efa565b83516001600160401b0390811682526020850151168160016020020152604084810151828201526001546060830152600254608083015260035460a083015260005460c08301525163ce537a7760e01b815273__$5c5c07cf4f55be9472c2b47d897172e765$__9063ce537a7790610f2790859085908890600401612a60565b602060405180830381865af4158015610f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f689190612c8f565b610f85576040516309bde33960e01b815260040160405180910390fd5b50505050565b60095415801590611001575060085460098054600160a01b830463ffffffff1692600160c01b90046001600160401b0316908110610fcb57610fcb612843565b6000918252602090912060029091020154610ff690600160401b90046001600160401b031684612cb1565b6001600160401b0316115b1561109557600854600980549091600160c01b90046001600160401b031690811061102e5761102e612843565b60009182526020822060029091020180546001600160c01b03191681556001015560088054600160c01b90046001600160401b031690601861106f83612cd8565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550505b604080516080810182526001600160401b0394851681529284166020808501918252830151851684830190815292909101516060840190815260098054600181018255600091909152935160029094027f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af81018054935194518716600160801b0267ffffffffffffffff60801b19958816600160401b026001600160801b03199095169690971695909517929092179290921693909317909155517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b090910155565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806111fe57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166111f2600080516020612d4b833981519152546001600160a01b031690565b6001600160a01b031614155b156109ad5760405163703e46dd60e11b815260040160405180910390fd5b611224610dc8565b6040516001600160a01b03821681527ff78721226efe9a1bb678189a16d1554928b9f2192e2cb93eeda83b79fa40007d90602001610753565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156112b7575060408051601f3d908101601f191682019092526112b491810190612cfe565b60015b6112df57604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610d05565b600080516020612d4b833981519152811461131057604051632a87526960e21b815260048101829052602401610d05565b61131a8383611cb0565b505050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109ad5760405163703e46dd60e11b815260040160405180910390fd5b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6113e1611d06565b610d1781611d4f565b6109ad611d06565b82516001600160401b0316151580611416575060208301516001600160401b031615155b8061142357506020820151155b8061143057506040820151155b8061143d57506060820151155b8061144757508151155b806114595750610e108163ffffffff16105b8061146d57506301e133808163ffffffff16115b1561148b576040516350dd03f760e11b815260040160405180910390fd5b8251600480546020808701516001600160401b039485166001600160801b03199384168117600160401b9690921695909502908117909355604080880151600581905587516000559187015160015586015160025560608601516003556006805490921690931790911790556007556008805463ffffffff60a01b1916600160a01b63ffffffff84160217905561131a434285610f8b565b60095460009043841180611535575080155b806115805750600854600980549091600160c01b90046001600160401b031690811061156357611563612843565b60009182526020909120600290910201546001600160401b031684105b1561159e5760405163b0b4387760e01b815260040160405180910390fd5b600080806115ad600185612830565b90505b8161164b57600854600160c01b90046001600160401b0316811061164b5786600982815481106115e2576115e2612843565b60009182526020909120600290910201546001600160401b03161161163957600191506009818154811061161857611618612843565b60009182526020909120600290910201546001600160401b0316925061164b565b8061164381612d17565b9150506115b0565b816116695760405163b0b4387760e01b815260040160405180910390fd5b856116748489612830565b11979650505050505050565b611688611f18565b620100008152600760208201527f1369aa78dc50135ad756d62c97a64a0edcd30066584168200d9d1facf82ca4f56040820151527f2cf23456d712b06f8e3aa5bf0acc3e46a3d094602a3a2b99d873bba05a4391476020604083015101527f08a35f379d2d2c490a51006697275e4db79b67b4a175c1477e262d29e25e42316060820151527f218828131bb7940ccc88c561b299755af4bf0b71ed930b129e8be0a1218139ea6020606083015101527f23a2172436c1145b36d5bc6d3b31fa1610c73a543ea443918aaa3ee175f9921b6080820151527f2502adf404d62877c310214ae9942e93c40b154d34c024bab48a3ca057e60a116020608083015101527f1bb88ada91ab7734882f7826b81275320081ac485f9cf8bfbc3ba54b6eb4dff360a0820151527f25c74a27e9a3b20114a3a91f31c20f01777e7ed913e0ef949f0285e2e7c2069b602060a083015101527f12b0ce76ac8b0dbd405ebc5dd0bae0f91aed50033c7ea36fc62aaba2b98333dc60c0820151527f185b42af49dd1cbe337a84f74b704172428e754a0bea024ab3eb2f996afb2c47602060c083015101527f21f53ad4538b45438bbf0521446070223920e3df6f9022a64cc16d7f94e85c0860e0820151527f2278ac3dedfdac7feb9725a022497175518eada52c8932fc40e6e75bea889fb8602060e083015101527f0876136f81c16298487bfb1be74d4a3487ec45645ab1d09dc2e5b865d62230df610100820151527f098c641c947ecd798dfd5e1b2fe428024cdf03061a53ff774ea8a9e3de9d3f2b602061010083015101527f15eaac2c6232d2268bf79dc47ed9666f992fb3d96ad23fb21690c21586c5472e610120820151527f0f10f1ffc54881287fda6f200bc85d8245b508d844a974098a41119867b325d0602061012083015101527f0895ceea40b085534e9739ca5442ba48b3a3592affde2b509df74521b47d8ab0610140820151527f2e12ec5800ac92fe2a8e7040bc5b435b9eb71e31380173fa7688bf81fcbba455602061014083015101527f2f5384eb5653e47576efe248e7903f463243414bfed5237dda750df3996bd918610160820151527f1c3cd6b11da8704cdc871ab4fa323d7ee57bd40ce165b49a56d5ef6489cd251a602061016083015101527f13579994957ce1554cc1e5b194fb63c9513707f627414f8442681ae736e36450610180820151527f26c9bdcd96d8e420b12974ade93ad9c312c4185213d2f6831a7c625a18890e95602061018083015101527f0cc70a1d542a9a1535ae5d9201696adc5c99c1bcebd9951dfa8afec79fa0b6446101a0820151527f10b043d9f1869181b96579d6616efc17a5df7b84c4d431d966c9094bf1e8815360206101a083015101527f198a65309d131a43b0ab1c47659d0336cfbf62b27f4727106b4fd971c73dd4036101c0820151527f23df99eac3c1947903b211b800efeb76f47d5e87b7414866543492e8c7798d1a60206101c083015101527f221cc5e47b81ce8dcfa72ef981916a8eddef12fcde59c56c62830c126ebef0de6101e0820151527f231f99340c35c9e09652a6df73c9cec5d88738cb71ff45716fdc9e9e45a4926e60206101e083015101527f2c9f1489fce0f263e03f3e97bf0a72273aafcca9325ff47786adb04a52a6d22c610200820151527f21f66e28f17e01e9fd593e16d022c4eca25bd5db96daec606d97b604cc414838602061020083015101527f2015745604a9571e226bd99043cfaf1f96267cc5de67f497563ff81100531d26610220820151527f206889ff4c58dd08ee1107191a2a5bc5dbae55c49d7d8397801799868d10f805602061022083015101527f21062ab8f8ecd8932b429a1eb8614b1e03db61bff6a5cd2d5d7ea193e90e9927610240820151527f217f9b27b934b88ffe555d682dfe6e8b6d503f86b14bbd96342bc48487a60b27602061024083015101527f1c9eda2d195cb731f903235ead6a4f7c66db49da713ecb27afee076f0eea7154610260820151527f2647c161c00b90258e1cefebb17481f8a5d91b5f9dca626e3e89a9215bcca16a602061026083015101527fb0838893ec1f237e8b07323b0744599f4e97b598b3b589bcc2bc37b8d5c418016102808201527fc18393c0fa30fe4e8b038e357ad851eae8de9107584effe7c7f1f651b2010e266102a082015290565b611cb982611d57565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2805115611cfe5761131a8282611dbc565b61091f611e32565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff166109ad57604051631afcd79f60e31b815260040160405180910390fd5b610cdf611d06565b806001600160a01b03163b600003611d8d57604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610d05565b600080516020612d4b83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080846001600160a01b031684604051611dd99190612d2e565b600060405180830381855af49150503d8060008114611e14576040519150601f19603f3d011682016040523d82523d6000602084013e611e19565b606091505b5091509150611e29858383611e51565b95945050505050565b34156109ad5760405163b398979f60e01b815260040160405180910390fd5b606082611e6657611e6182611eb0565b611ea9565b8151158015611e7d57506001600160a01b0384163b155b15611ea657604051639996b31560e01b81526001600160a01b0385166004820152602401610d05565b50805b9392505050565b805115611ec05780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b5080546000825560020290600052602060002090810190610d1791906121a5565b6040518060e001604052806007906020820280368337509192915050565b604051806102c001604052806000815260200160008152602001611f4f604051806040016040528060008152602001600081525090565b8152602001611f71604051806040016040528060008152602001600081525090565b8152602001611f93604051806040016040528060008152602001600081525090565b8152602001611fb5604051806040016040528060008152602001600081525090565b8152602001611fd7604051806040016040528060008152602001600081525090565b8152602001611ff9604051806040016040528060008152602001600081525090565b815260200161201b604051806040016040528060008152602001600081525090565b815260200161203d604051806040016040528060008152602001600081525090565b815260200161205f604051806040016040528060008152602001600081525090565b8152602001612081604051806040016040528060008152602001600081525090565b81526020016120a3604051806040016040528060008152602001600081525090565b81526020016120c5604051806040016040528060008152602001600081525090565b81526020016120e7604051806040016040528060008152602001600081525090565b8152602001612109604051806040016040528060008152602001600081525090565b815260200161212b604051806040016040528060008152602001600081525090565b815260200161214d604051806040016040528060008152602001600081525090565b815260200161216f604051806040016040528060008152602001600081525090565b8152602001612191604051806040016040528060008152602001600081525090565b815260006020820181905260409091015290565b5b808211156121cb5780546001600160c01b0319168155600060018201556002016121a6565b5090565b80356001600160a01b03811681146121e657600080fd5b919050565b6000602082840312156121fd57600080fd5b610cce826121cf565b60006020828403121561221857600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040516102e081016001600160401b03811182821017156122585761225861221f565b60405290565b604051608081016001600160401b03811182821017156122585761225861221f565b604051601f8201601f191681016001600160401b03811182821017156122a8576122a861221f565b604052919050565b80356001600160401b03811681146121e657600080fd5b6000606082840312156122d957600080fd5b604051606081018181106001600160401b03821117156122fb576122fb61221f565b60405290508061230a836122b0565b8152612318602084016122b0565b6020820152604083013560408201525092915050565b60006040828403121561234057600080fd5b604051604081018181106001600160401b03821117156123625761236261221f565b604052823581526020928301359281019290925250919050565b6000808284036104e081121561239157600080fd5b61239b85856122c7565b925061048080605f19830112156123b157600080fd5b6123b9612235565b91506123c8866060870161232e565b82526123d78660a0870161232e565b60208301526123e98660e0870161232e565b60408301526101206123fd8782880161232e565b60608401526101606124118882890161232e565b60808501526101a061242589828a0161232e565b60a08601526101e06124398a828b0161232e565b60c087015261022061244d8b828c0161232e565b60e08801526102606124618c828d0161232e565b6101008901526102a06124768d828e0161232e565b878a01526124888d6102e08e0161232e565b6101408a015261249c8d6103208e0161232e565b868a01526124ae8d6103608e0161232e565b6101808a01526103a08c0135948901949094526103c08b01356101c08901526103e08b0135928801929092526104008a01356102008801526104208a013590870152610440890135610240870152610460890135908601529287013561028085015250506104a0850135908201526104c0909301356102c08401525092909150565b6000806040838503121561254357600080fd5b61254c836121cf565b91506020808401356001600160401b038082111561256957600080fd5b818601915086601f83011261257d57600080fd5b81358181111561258f5761258f61221f565b6125a1601f8201601f19168501612280565b915080825287848285010111156125b757600080fd5b80848401858401376000848284010152508093505050509250929050565b803563ffffffff811681146121e657600080fd5b6000602082840312156125fb57600080fd5b610cce826125d5565b60008060008084860361012081121561261c57600080fd5b61262687876122c7565b94506080605f198201121561263a57600080fd5b5061264361225e565b60608681013582526080870135602083015260a0870135604083015260c087013590820152925061267660e086016125d5565b915061268561010086016121cf565b905092959194509250565b60005b838110156126ab578181015183820152602001612693565b50506000910152565b60208152600082518060208401526126d3816040850160208701612690565b601f01601f19169190910160400192915050565b6000606082840312156126f957600080fd5b610cce83836122c7565b6000806040838503121561271657600080fd5b50508035926020909101359150565b6000602080838503121561273857600080fd5b82356001600160401b038082111561274f57600080fd5b818501915085601f83011261276357600080fd5b8135818111156127755761277561221f565b612783848260051b01612280565b818152848101925060079190911b8301840190878211156127a357600080fd5b928401925b8184101561280f57608084890312156127c15760008081fd5b6127c961225e565b6127d2856122b0565b81526127df8686016122b0565b8682015260406127f08187016122b0565b90820152606085810135908201528352608090930192918401916127a8565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610cd157610cd161281a565b634e487b7160e01b600052603260045260246000fd5b8060005b6007811015610f8557815184526020938401939091019060010161285d565b61289182825180518252602090810151910152565b6020818101518051604085015290810151606084015250604081015180516080840152602081015160a0840152506060810151805160c0840152602081015160e08401525060808101516101006128f48185018380518252602090810151910152565b60a083015191506101406129148186018480518252602090810151910152565b60c084015192506101806129348187018580518252602090810151910152565b60e085015193506101c06129548188018680518252602090810151910152565b928501519350610200926129748785018680518252602090810151910152565b61012086015194506102406129958189018780518252602090810151910152565b928601519450610280926129b58885018780518252602090810151910152565b61016087015195506102c06129d6818a018880518252602090810151910152565b9287015180516103008a0152602001516103208901526101a0870151610340890152908601516103608801526101e0860151610380880152928501516103a08701526102208501516103c0870152918401516103e08601526102608401516104008601528301516104208501526102a0830151610440850152909101516104609092019190915250565b6000610a608201905084518252602085015160208301526040850151612a93604084018280518252602090810151910152565b50606085015180516080840152602081015160a0840152506080850151805160c0840152602081015160e08401525060a0850151610100612ae08185018380518252602090810151910152565b60c08701519150610140612b008186018480518252602090810151910152565b60e08801519250610180612b208187018580518252602090810151910152565b9188015192506101c091612b408684018580518252602090810151910152565b6101208901519350610200612b618188018680518252602090810151910152565b91890151935061024091612b818784018680518252602090810151910152565b6101608a01519450610280612ba28189018780518252602090810151910152565b918a015180516102c08901526020908101516102e08901526101a08b015180516103008a0152810151610320890152938a015180516103408901528401516103608801526101e08a015180516103808901528401516103a088015289015180516103c08801528301516103e087015261022089015180516104008801528301516104208701529088015180516104408701528201516104608601526102608801518051610480870152909101516104a08501528601516104c0840152506102a08501516104e0830152612c79610500830185612859565b612c876105e083018461287c565b949350505050565b600060208284031215612ca157600080fd5b81518015158114611ea957600080fd5b6001600160401b03828116828216039080821115612cd157612cd161281a565b5092915050565b60006001600160401b03808316818103612cf457612cf461281a565b6001019392505050565b600060208284031215612d1057600080fd5b5051919050565b600081612d2657612d2661281a565b506000190190565b60008251612d40818460208701612690565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca164736f6c6343000817000a" diff --git a/contract-bindings/artifacts/LightClient_bytecode.json b/contract-bindings/artifacts/LightClient_bytecode.json index f71741606..656720cbe 100644 --- a/contract-bindings/artifacts/LightClient_bytecode.json +++ b/contract-bindings/artifacts/LightClient_bytecode.json @@ -1 +1 @@ -"0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000da565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620000775760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b0390811614620000d75780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b6080516129ea62000104600039600081816110b0015281816110d9015261125801526129ea6000f3fe6080604052600436106101405760003560e01c8063826e41fc116100b6578063ad3cb1cc1161006f578063ad3cb1cc14610468578063c23b9e9e146104a6578063d24d933d146104df578063e03033011461050f578063f2fde38b1461052f578063f9e50d191461054f57600080fd5b8063826e41fc1461032c5780638584d23f146103585780638da5cb5b1461039557806396c1ca61146103d25780639baa3cc9146103f25780639fdb54a71461041257600080fd5b8063313df7b111610108578063313df7b114610251578063426d3194146102895780634f1ef286146102cc57806352d1902d146102df57806369cc6a0414610302578063715018a61461031757600080fd5b8063013fa5fc1461014557806302b592f3146101675780630d8e6e2c146101c55780632063d4f7146101f25780632f79889d14610212575b600080fd5b34801561015157600080fd5b50610165610160366004611f70565b610564565b005b34801561017357600080fd5b50610187610182366004611f8b565b610617565b6040516101bc94939291906001600160401b039485168152928416602084015292166040820152606081019190915260800190565b60405180910390f35b3480156101d157600080fd5b506040805160018152600060208201819052918101919091526060016101bc565b3480156101fe57600080fd5b5061016561020d3660046120df565b610662565b34801561021e57600080fd5b5060085461023990600160c01b90046001600160401b031681565b6040516001600160401b0390911681526020016101bc565b34801561025d57600080fd5b50600854610271906001600160a01b031681565b6040516001600160a01b0390911681526020016101bc565b34801561029557600080fd5b506000546001546002546003546102ac9392919084565b6040805194855260208501939093529183015260608201526080016101bc565b6101656102da366004612293565b6107b7565b3480156102eb57600080fd5b506102f46107d6565b6040519081526020016101bc565b34801561030e57600080fd5b506101656107f3565b34801561032357600080fd5b50610165610862565b34801561033857600080fd5b506008546001600160a01b031615155b60405190151581526020016101bc565b34801561036457600080fd5b50610378610373366004611f8b565b610874565b604080519283526001600160401b039091166020830152016101bc565b3480156103a157600080fd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b0316610271565b3480156103de57600080fd5b506101656103ed36600461234c565b6109a7565b3480156103fe57600080fd5b5061016561040d366004612367565b610a30565b34801561041e57600080fd5b50600654600754610442916001600160401b0380821692600160401b909204169083565b604080516001600160401b039485168152939092166020840152908201526060016101bc565b34801561047457600080fd5b50610499604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516101bc9190612438565b3480156104b257600080fd5b506008546104ca90600160a01b900463ffffffff1681565b60405163ffffffff90911681526020016101bc565b3480156104eb57600080fd5b50600454600554610442916001600160401b0380821692600160401b909204169083565b34801561051b57600080fd5b5061034861052a36600461246b565b610b54565b34801561053b57600080fd5b5061016561054a366004611f70565b610cb3565b34801561055b57600080fd5b506009546102f4565b61056c610cf6565b6001600160a01b0381166105935760405163e6c4247b60e01b815260040160405180910390fd5b6008546001600160a01b03908116908216036105c25760405163a863aec960e01b815260040160405180910390fd5b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527f8017bb887fdf8fca4314a9d40f6e73b3b81002d67e5cfa85d88173af6aa46072906020015b60405180910390a150565b6009818154811061062757600080fd5b6000918252602090912060029091020180546001909101546001600160401b038083169350600160401b8304811692600160801b9004169084565b6008546001600160a01b03161515801561068757506008546001600160a01b03163314155b156106a5576040516301474c8f60e71b815260040160405180910390fd5b60065482516001600160401b0391821691161115806106de575060065460208301516001600160401b03600160401b9092048216911611155b156106fc5760405163051c46ef60e01b815260040160405180910390fd5b6107098260400151610d51565b6107138282610dc1565b81516006805460208501516001600160401b03908116600160401b026001600160801b0319909216931692909217919091179055604082015160075561075a434284610eb9565b81602001516001600160401b031682600001516001600160401b03167fa04a773924505a418564363725f56832f5772e6b8d0dbd6efce724dfe803dae684604001516040516107ab91815260200190565b60405180910390a35050565b6107bf6110a5565b6107c88261114a565b6107d2828261118b565b5050565b60006107e061124d565b506000805160206129be83398151915290565b6107fb610cf6565b6008546001600160a01b03161561084757600880546001600160a01b03191690556040517f9a5f57de856dd668c54dd95e5c55df93432171cbca49a8776d5620ea59c0245090600090a1565b60405163a863aec960e01b815260040160405180910390fd5b565b61086a610cf6565b6108606000611296565b600980546000918291906108896001836124a3565b81548110610899576108996124b6565b6000918252602090912060029091020154600160801b90046001600160401b03168411156108da57604051631856a49960e21b815260040160405180910390fd5b600854600160c01b90046001600160401b03165b818110156109a057846009828154811061090a5761090a6124b6565b6000918252602090912060029091020154600160801b90046001600160401b0316106109985760098181548110610943576109436124b6565b90600052602060002090600202016001015460098281548110610968576109686124b6565b906000526020600020906002020160000160109054906101000a90046001600160401b0316935093505050915091565b6001016108ee565b5050915091565b6109af610cf6565b610e108163ffffffff1610806109ce57506301e133808163ffffffff16115b806109ec575060085463ffffffff600160a01b909104811690821611155b15610a0a576040516307a5077760e51b815260040160405180910390fd5b6008805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b0316600081158015610a755750825b90506000826001600160401b03166001148015610a915750303b155b905081158015610a9f575080155b15610abd5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610ae757845460ff60401b1916600160401b1785555b610af086611307565b610af8611318565b610b03898989611320565b8315610b4957845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b60095460009043841180610b66575080155b80610bb15750600854600980549091600160c01b90046001600160401b0316908110610b9457610b946124b6565b60009182526020909120600290910201546001600160401b031684105b15610bcf5760405163b0b4387760e01b815260040160405180910390fd5b60008080610bde6001856124a3565b90505b81610c7c57600854600160c01b90046001600160401b03168110610c7c578660098281548110610c1357610c136124b6565b60009182526020909120600290910201546001600160401b031611610c6a576001915060098181548110610c4957610c496124b6565b60009182526020909120600290910201546001600160401b03169250610c7c565b80610c74816124cc565b915050610be1565b81610c9a5760405163b0b4387760e01b815260040160405180910390fd5b85610ca584896124a3565b119450505050505b92915050565b610cbb610cf6565b6001600160a01b038116610cea57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b610cf381611296565b50565b33610d287f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146108605760405163118cdaa760e01b8152336004820152602401610ce1565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018110806107d25760405162461bcd60e51b815260206004820152601b60248201527f426e3235343a20696e76616c6964207363616c6172206669656c6400000000006044820152606401610ce1565b6000610dcb611451565b9050610dd5611ca9565b83516001600160401b0390811682526020850151168160016020020152604084810151828201526001546060830152600254608083015260035460a083015260005460c08301525163ce537a7760e01b815273__$5c5c07cf4f55be9472c2b47d897172e765$__9063ce537a7790610e55908590859088906004016126ea565b602060405180830381865af4158015610e72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e969190612919565b610eb3576040516309bde33960e01b815260040160405180910390fd5b50505050565b60095415801590610f2f575060085460098054600160a01b830463ffffffff1692600160c01b90046001600160401b0316908110610ef957610ef96124b6565b6000918252602090912060029091020154610f2490600160401b90046001600160401b03168461293b565b6001600160401b0316115b15610fc357600854600980549091600160c01b90046001600160401b0316908110610f5c57610f5c6124b6565b60009182526020822060029091020180546001600160c01b03191681556001015560088054600160c01b90046001600160401b0316906018610f9d83612962565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550505b604080516080810182526001600160401b0394851681529284166020808501918252830151851684830190815292909101516060840190815260098054600181018255600091909152935160029094027f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af81018054935194518716600160801b0267ffffffffffffffff60801b19958816600160401b026001600160801b03199095169690971695909517929092179290921693909317909155517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b090910155565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061112c57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166111206000805160206129be833981519152546001600160a01b031690565b6001600160a01b031614155b156108605760405163703e46dd60e11b815260040160405180910390fd5b611152610cf6565b6040516001600160a01b03821681527ff78721226efe9a1bb678189a16d1554928b9f2192e2cb93eeda83b79fa40007d9060200161060c565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156111e5575060408051601f3d908101601f191682019092526111e291810190612988565b60015b61120d57604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610ce1565b6000805160206129be833981519152811461123e57604051632a87526960e21b815260048101829052602401610ce1565b6112488383611a80565b505050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108605760405163703e46dd60e11b815260040160405180910390fd5b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b61130f611ad6565b610cf381611b1f565b610860611ad6565b82516001600160401b0316151580611344575060208301516001600160401b031615155b8061135157506020820151155b8061135e57506040820151155b8061136b57506060820151155b8061137557508151155b806113875750610e108163ffffffff16105b8061139b57506301e133808163ffffffff16115b156113b9576040516350dd03f760e11b815260040160405180910390fd5b8251600480546020808701516001600160401b03908116600160401b026001600160801b031993841691909516908117851790935560408088015160058190558751600055918701516001558601516002556060860151600355600680549092169092179092179091556007556008805463ffffffff8316600160a01b0263ffffffff60a01b19909116179055611248434285610eb9565b611459611cc7565b621000008152600760208201527f23783d0e9777b7af65fbf849da7edb75e74b1eaf503e025d7f2f7f80991befa26040820151527f2a4e2fe8adfa53f468525582d5184c4c70bbdb946c21f216418a9879705e54a76020604083015101527f0624b2c1e77f24afceaf39451743b9fa80d5853fca7ba00389c675650774009b6060820151527f250d7719e94ca2df00dfe327938f5a8d4d837779b99837ca777a53d39127b1796020606083015101527f0dc09515152eaea66d0db2f571cc995e369d26fe647394f10db5398c917519dc6080820151527f1273144d6cec2c4a68b24a149379c0f5592bb7fbddbe32fa171919950ca404cb6020608083015101527f119521bb68caec216e2f05eeb466fb3abfe1f39baf7fe7cb392ea057b6a2d9bf60a0820151527f2d52adeaba8045e53ab526fe9982d0ea452def6b3ea0253d27a19ef3b46e8428602060a083015101527f16c3b5b217d302975a920d13374524d7a52e4a50fd7fb930842271ebf4a84efd60c0820151527f200788916b907b196972bde304318e885a2521514b2db5e4a11899c51204f089602060c083015101527f1127581afe753defca9aef12e7332db9978a200b1699ce3888c0f3aea6111dc360e0820151527f0881e13f00723be1a04872ed02b2d078c31e80feaf27724e262ce97c2cb0bb1d602060e083015101527f1482a3a6bb91d6483d153683e2404f2f5546e0e895530fdf132091498406e3de610100820151527efa52db3d52d905ead1248102f3a80a43a90d8400c68f60a62c543c417b2f4b602061010083015101527f0a57dadd4a55199525ac6ac6fabc87a4cccfdc98142bcef9dbf47de00ecc5164610120820151527f18d95abd9b8e12c36936aa218cfff582548a6bbff25c338c2006eaeb1fe5b696602061012083015101527f2bc40e91dd169b8bc143a02952a1b6c6e627bfeb7a2bbe5078e14123f3c54c1c610140820151527f108d65a20c579b6d9883275eb6889fc3f5fc79735ca9f611a13b67daa2fbc8d0602061014083015101527f21bc1f86d0608e5f0626b467ee6f8282b619223f60a7acb0fc63ba7bdaf783be610160820151527f05ef3282f8eef01515fb9a8a7d6ca06b8b007d1d512403efb268fb03ce5f09e9602061016083015101527f2cab66c1cb5a83869e73ac34fbe467486999babd541d9010ee9a804806eee4ef610180820151527f2db1982419c5a4a17593acff9535fa967683d75c8aec01319b64b84aada2ad84602061018083015101527f2c38667c6c7eb868bdd30c34dd3f4b84d9b9b1a27d7867b364c8b7831423e9086101a0820151527f2b2cb4044dd51165c48138219d51cf8d1689f91ed3eeefead6e055eb488a2ce260206101a083015101527f2d48e54703011df2c74a14dafde3af4fd83ec71875d8ddc3554658640cc955016101c0820151527f243a99d80d32eb5408b59d5b08302bede070d3fb0a8efe2f2262f865bffb4d0d60206101c083015101527f0455d2325bf6269a66f07d838f55f36947a3cd9b87edd8480bced95cbb45cc116101e0820151527f0f66d9085a6ed60b838179987e240992bff4c0516ccf6ccde4a1ca94ce8b986460206101e083015101527f2bac0d23c8585d1487ec611b5effc97e5852fea43a7cba36ccdd2c207931f394610200820151527f1860b54e01a06aea5adb4b13bf5baebab92b736807a3a89ff2040992b06ee6ec602061020083015101527f0c0bfa1c2fc6f8ed01233d5168db1e1dfe725504f032f669f50a92ae77c72906610220820151527f0d741e124c7d1069b8a400cbcdcfd90128a533901ad4de1e037fe72984dc34cf602061022083015101527f01cfed30085c9efce04668205794aa39b1a8ee591234b4c77a22f8c26d899e05610240820151527f2ab68ac82d36cedb647d14a5b0035e8c9a0be84780b7bae1133a27a880966ed1602061024083015101527f072e1d50f8b5cf8d574b3847276477d95bbd5116351000841f728da44f4043b5610260820151527f23f8ea6eacd0876d57220f57eabacbe76a2323411663731a251d5dca36f1b59f602061026083015101527fb0838893ec1f237e8b07323b0744599f4e97b598b3b589bcc2bc37b8d5c418016102808201527fc18393c0fa30fe4e8b038e357ad851eae8de9107584effe7c7f1f651b2010e266102a082015290565b611a8982611b27565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2805115611ace576112488282611b8c565b6107d2611c02565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661086057604051631afcd79f60e31b815260040160405180910390fd5b610cbb611ad6565b806001600160a01b03163b600003611b5d57604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610ce1565b6000805160206129be83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080846001600160a01b031684604051611ba991906129a1565b600060405180830381855af49150503d8060008114611be4576040519150601f19603f3d011682016040523d82523d6000602084013e611be9565b606091505b5091509150611bf9858383611c21565b95945050505050565b34156108605760405163b398979f60e01b815260040160405180910390fd5b606082611c3657611c3182611c80565b611c79565b8151158015611c4d57506001600160a01b0384163b155b15611c7657604051639996b31560e01b81526001600160a01b0385166004820152602401610ce1565b50805b9392505050565b805115611c905780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6040518060e001604052806007906020820280368337509192915050565b604051806102c001604052806000815260200160008152602001611cfe604051806040016040528060008152602001600081525090565b8152602001611d20604051806040016040528060008152602001600081525090565b8152602001611d42604051806040016040528060008152602001600081525090565b8152602001611d64604051806040016040528060008152602001600081525090565b8152602001611d86604051806040016040528060008152602001600081525090565b8152602001611da8604051806040016040528060008152602001600081525090565b8152602001611dca604051806040016040528060008152602001600081525090565b8152602001611dec604051806040016040528060008152602001600081525090565b8152602001611e0e604051806040016040528060008152602001600081525090565b8152602001611e30604051806040016040528060008152602001600081525090565b8152602001611e52604051806040016040528060008152602001600081525090565b8152602001611e74604051806040016040528060008152602001600081525090565b8152602001611e96604051806040016040528060008152602001600081525090565b8152602001611eb8604051806040016040528060008152602001600081525090565b8152602001611eda604051806040016040528060008152602001600081525090565b8152602001611efc604051806040016040528060008152602001600081525090565b8152602001611f1e604051806040016040528060008152602001600081525090565b8152602001611f40604051806040016040528060008152602001600081525090565b815260006020820181905260409091015290565b80356001600160a01b0381168114611f6b57600080fd5b919050565b600060208284031215611f8257600080fd5b611c7982611f54565b600060208284031215611f9d57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040516102e081016001600160401b0381118282101715611fdd57611fdd611fa4565b60405290565b604051601f8201601f191681016001600160401b038111828210171561200b5761200b611fa4565b604052919050565b80356001600160401b0381168114611f6b57600080fd5b60006060828403121561203c57600080fd5b604051606081018181106001600160401b038211171561205e5761205e611fa4565b60405290508061206d83612013565b815261207b60208401612013565b6020820152604083013560408201525092915050565b6000604082840312156120a357600080fd5b604051604081018181106001600160401b03821117156120c5576120c5611fa4565b604052823581526020928301359281019290925250919050565b6000808284036104e08112156120f457600080fd5b6120fe858561202a565b925061048080605f198301121561211457600080fd5b61211c611fba565b915061212b8660608701612091565b825261213a8660a08701612091565b602083015261214c8660e08701612091565b604083015261012061216087828801612091565b606084015261016061217488828901612091565b60808501526101a061218889828a01612091565b60a08601526101e061219c8a828b01612091565b60c08701526102206121b08b828c01612091565b60e08801526102606121c48c828d01612091565b6101008901526102a06121d98d828e01612091565b878a01526121eb8d6102e08e01612091565b6101408a01526121ff8d6103208e01612091565b868a01526122118d6103608e01612091565b6101808a01526103a08c0135948901949094526103c08b01356101c08901526103e08b0135928801929092526104008a01356102008801526104208a013590870152610440890135610240870152610460890135908601529287013561028085015250506104a0850135908201526104c0909301356102c08401525092909150565b600080604083850312156122a657600080fd5b6122af83611f54565b91506020808401356001600160401b03808211156122cc57600080fd5b818601915086601f8301126122e057600080fd5b8135818111156122f2576122f2611fa4565b612304601f8201601f19168501611fe3565b9150808252878482850101111561231a57600080fd5b80848401858401376000848284010152508093505050509250929050565b803563ffffffff81168114611f6b57600080fd5b60006020828403121561235e57600080fd5b611c7982612338565b60008060008084860361012081121561237f57600080fd5b612389878761202a565b94506080605f198201121561239d57600080fd5b50604051608081018181106001600160401b03821117156123c0576123c0611fa4565b8060405250606086013581526080860135602082015260a0860135604082015260c08601356060820152809350506123fa60e08601612338565b91506124096101008601611f54565b905092959194509250565b60005b8381101561242f578181015183820152602001612417565b50506000910152565b6020815260008251806020840152612457816040850160208701612414565b601f01601f19169190910160400192915050565b6000806040838503121561247e57600080fd5b50508035926020909101359150565b634e487b7160e01b600052601160045260246000fd5b81810381811115610cad57610cad61248d565b634e487b7160e01b600052603260045260246000fd5b6000816124db576124db61248d565b506000190190565b8060005b6007811015610eb35781518452602093840193909101906001016124e7565b61251b82825180518252602090810151910152565b6020818101518051604085015290810151606084015250604081015180516080840152602081015160a0840152506060810151805160c0840152602081015160e084015250608081015161010061257e8185018380518252602090810151910152565b60a0830151915061014061259e8186018480518252602090810151910152565b60c084015192506101806125be8187018580518252602090810151910152565b60e085015193506101c06125de8188018680518252602090810151910152565b928501519350610200926125fe8785018680518252602090810151910152565b610120860151945061024061261f8189018780518252602090810151910152565b9286015194506102809261263f8885018780518252602090810151910152565b61016087015195506102c0612660818a018880518252602090810151910152565b9287015180516103008a0152602001516103208901526101a0870151610340890152908601516103608801526101e0860151610380880152928501516103a08701526102208501516103c0870152918401516103e08601526102608401516104008601528301516104208501526102a0830151610440850152909101516104609092019190915250565b6000610a60820190508451825260208501516020830152604085015161271d604084018280518252602090810151910152565b50606085015180516080840152602081015160a0840152506080850151805160c0840152602081015160e08401525060a085015161010061276a8185018380518252602090810151910152565b60c0870151915061014061278a8186018480518252602090810151910152565b60e088015192506101806127aa8187018580518252602090810151910152565b9188015192506101c0916127ca8684018580518252602090810151910152565b61012089015193506102006127eb8188018680518252602090810151910152565b9189015193506102409161280b8784018680518252602090810151910152565b6101608a0151945061028061282c8189018780518252602090810151910152565b918a015180516102c08901526020908101516102e08901526101a08b015180516103008a0152810151610320890152938a015180516103408901528401516103608801526101e08a015180516103808901528401516103a088015289015180516103c08801528301516103e087015261022089015180516104008801528301516104208701529088015180516104408701528201516104608601526102608801518051610480870152909101516104a08501528601516104c0840152506102a08501516104e08301526129036105008301856124e3565b6129116105e0830184612506565b949350505050565b60006020828403121561292b57600080fd5b81518015158114611c7957600080fd5b6001600160401b0382811682821603908082111561295b5761295b61248d565b5092915050565b60006001600160401b0380831681810361297e5761297e61248d565b6001019392505050565b60006020828403121561299a57600080fd5b5051919050565b600082516129b3818460208701612414565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca164736f6c6343000817000a" +"0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000da565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620000775760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b0390811614620000d75780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b608051612a0a62000104600039600081816110d0015281816110f901526112780152612a0a6000f3fe60806040526004361061014b5760003560e01c8063826e41fc116100b6578063ad3cb1cc1161006f578063ad3cb1cc14610482578063c23b9e9e146104c0578063d24d933d146104f9578063e030330114610529578063f2fde38b14610549578063f9e50d191461056957600080fd5b8063826e41fc146103465780638584d23f146103725780638da5cb5b146103af57806396c1ca61146103ec5780639baa3cc91461040c5780639fdb54a71461042c57600080fd5b8063378ec23b11610108578063378ec23b14610294578063426d3194146102b15780634f1ef286146102f457806352d1902d1461030757806369cc6a041461031c578063715018a61461033157600080fd5b8063013fa5fc1461015057806302b592f3146101725780630d8e6e2c146101d05780632063d4f7146101fd5780632f79889d1461021d578063313df7b11461025c575b600080fd5b34801561015c57600080fd5b5061017061016b366004611f90565b61057e565b005b34801561017e57600080fd5b5061019261018d366004611fab565b610631565b6040516101c794939291906001600160401b039485168152928416602084015292166040820152606081019190915260800190565b60405180910390f35b3480156101dc57600080fd5b506040805160018152600060208201819052918101919091526060016101c7565b34801561020957600080fd5b506101706102183660046120ff565b61067c565b34801561022957600080fd5b5060085461024490600160c01b90046001600160401b031681565b6040516001600160401b0390911681526020016101c7565b34801561026857600080fd5b5060085461027c906001600160a01b031681565b6040516001600160a01b0390911681526020016101c7565b3480156102a057600080fd5b50435b6040519081526020016101c7565b3480156102bd57600080fd5b506000546001546002546003546102d49392919084565b6040805194855260208501939093529183015260608201526080016101c7565b6101706103023660046122b3565b6107d7565b34801561031357600080fd5b506102a36107f6565b34801561032857600080fd5b50610170610813565b34801561033d57600080fd5b50610170610882565b34801561035257600080fd5b506008546001600160a01b031615155b60405190151581526020016101c7565b34801561037e57600080fd5b5061039261038d366004611fab565b610894565b604080519283526001600160401b039091166020830152016101c7565b3480156103bb57600080fd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031661027c565b3480156103f857600080fd5b5061017061040736600461236c565b6109c7565b34801561041857600080fd5b50610170610427366004612387565b610a50565b34801561043857600080fd5b5060065460075461045c916001600160401b0380821692600160401b909204169083565b604080516001600160401b039485168152939092166020840152908201526060016101c7565b34801561048e57600080fd5b506104b3604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516101c79190612458565b3480156104cc57600080fd5b506008546104e490600160a01b900463ffffffff1681565b60405163ffffffff90911681526020016101c7565b34801561050557600080fd5b5060045460055461045c916001600160401b0380821692600160401b909204169083565b34801561053557600080fd5b5061036261054436600461248b565b610b74565b34801561055557600080fd5b50610170610564366004611f90565b610cd3565b34801561057557600080fd5b506009546102a3565b610586610d16565b6001600160a01b0381166105ad5760405163e6c4247b60e01b815260040160405180910390fd5b6008546001600160a01b03908116908216036105dc5760405163a863aec960e01b815260040160405180910390fd5b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527f8017bb887fdf8fca4314a9d40f6e73b3b81002d67e5cfa85d88173af6aa46072906020015b60405180910390a150565b6009818154811061064157600080fd5b6000918252602090912060029091020180546001909101546001600160401b038083169350600160401b8304811692600160801b9004169084565b6008546001600160a01b0316151580156106a157506008546001600160a01b03163314155b156106bf576040516301474c8f60e71b815260040160405180910390fd5b60065482516001600160401b0391821691161115806106f8575060065460208301516001600160401b03600160401b9092048216911611155b156107165760405163051c46ef60e01b815260040160405180910390fd5b6107238260400151610d71565b61072d8282610de1565b81516006805460208501516001600160401b03908116600160401b026001600160801b0319909216931692909217919091179055604082015160075561077a6107734390565b4284610ed9565b81602001516001600160401b031682600001516001600160401b03167fa04a773924505a418564363725f56832f5772e6b8d0dbd6efce724dfe803dae684604001516040516107cb91815260200190565b60405180910390a35050565b6107df6110c5565b6107e88261116a565b6107f282826111ab565b5050565b600061080061126d565b506000805160206129de83398151915290565b61081b610d16565b6008546001600160a01b03161561086757600880546001600160a01b03191690556040517f9a5f57de856dd668c54dd95e5c55df93432171cbca49a8776d5620ea59c0245090600090a1565b60405163a863aec960e01b815260040160405180910390fd5b565b61088a610d16565b61088060006112b6565b600980546000918291906108a96001836124c3565b815481106108b9576108b96124d6565b6000918252602090912060029091020154600160801b90046001600160401b03168411156108fa57604051631856a49960e21b815260040160405180910390fd5b600854600160c01b90046001600160401b03165b818110156109c057846009828154811061092a5761092a6124d6565b6000918252602090912060029091020154600160801b90046001600160401b0316106109b85760098181548110610963576109636124d6565b90600052602060002090600202016001015460098281548110610988576109886124d6565b906000526020600020906002020160000160109054906101000a90046001600160401b0316935093505050915091565b60010161090e565b5050915091565b6109cf610d16565b610e108163ffffffff1610806109ee57506301e133808163ffffffff16115b80610a0c575060085463ffffffff600160a01b909104811690821611155b15610a2a576040516307a5077760e51b815260040160405180910390fd5b6008805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b0316600081158015610a955750825b90506000826001600160401b03166001148015610ab15750303b155b905081158015610abf575080155b15610add5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610b0757845460ff60401b1916600160401b1785555b610b1086611327565b610b18611338565b610b23898989611340565b8315610b6957845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b60095460009043841180610b86575080155b80610bd15750600854600980549091600160c01b90046001600160401b0316908110610bb457610bb46124d6565b60009182526020909120600290910201546001600160401b031684105b15610bef5760405163b0b4387760e01b815260040160405180910390fd5b60008080610bfe6001856124c3565b90505b81610c9c57600854600160c01b90046001600160401b03168110610c9c578660098281548110610c3357610c336124d6565b60009182526020909120600290910201546001600160401b031611610c8a576001915060098181548110610c6957610c696124d6565b60009182526020909120600290910201546001600160401b03169250610c9c565b80610c94816124ec565b915050610c01565b81610cba5760405163b0b4387760e01b815260040160405180910390fd5b85610cc584896124c3565b119450505050505b92915050565b610cdb610d16565b6001600160a01b038116610d0a57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b610d13816112b6565b50565b33610d487f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b0316146108805760405163118cdaa760e01b8152336004820152602401610d01565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018110806107f25760405162461bcd60e51b815260206004820152601b60248201527f426e3235343a20696e76616c6964207363616c6172206669656c6400000000006044820152606401610d01565b6000610deb611471565b9050610df5611cc9565b83516001600160401b0390811682526020850151168160016020020152604084810151828201526001546060830152600254608083015260035460a083015260005460c08301525163ce537a7760e01b815273__$5c5c07cf4f55be9472c2b47d897172e765$__9063ce537a7790610e759085908590889060040161270a565b602060405180830381865af4158015610e92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eb69190612939565b610ed3576040516309bde33960e01b815260040160405180910390fd5b50505050565b60095415801590610f4f575060085460098054600160a01b830463ffffffff1692600160c01b90046001600160401b0316908110610f1957610f196124d6565b6000918252602090912060029091020154610f4490600160401b90046001600160401b03168461295b565b6001600160401b0316115b15610fe357600854600980549091600160c01b90046001600160401b0316908110610f7c57610f7c6124d6565b60009182526020822060029091020180546001600160c01b03191681556001015560088054600160c01b90046001600160401b0316906018610fbd83612982565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550505b604080516080810182526001600160401b0394851681529284166020808501918252830151851684830190815292909101516060840190815260098054600181018255600091909152935160029094027f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af81018054935194518716600160801b0267ffffffffffffffff60801b19958816600160401b026001600160801b03199095169690971695909517929092179290921693909317909155517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b090910155565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061114c57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166111406000805160206129de833981519152546001600160a01b031690565b6001600160a01b031614155b156108805760405163703e46dd60e11b815260040160405180910390fd5b611172610d16565b6040516001600160a01b03821681527ff78721226efe9a1bb678189a16d1554928b9f2192e2cb93eeda83b79fa40007d90602001610626565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611205575060408051601f3d908101601f19168201909252611202918101906129a8565b60015b61122d57604051634c9c8ce360e01b81526001600160a01b0383166004820152602401610d01565b6000805160206129de833981519152811461125e57604051632a87526960e21b815260048101829052602401610d01565b6112688383611aa0565b505050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108805760405163703e46dd60e11b815260040160405180910390fd5b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b61132f611af6565b610d1381611b3f565b610880611af6565b82516001600160401b0316151580611364575060208301516001600160401b031615155b8061137157506020820151155b8061137e57506040820151155b8061138b57506060820151155b8061139557508151155b806113a75750610e108163ffffffff16105b806113bb57506301e133808163ffffffff16115b156113d9576040516350dd03f760e11b815260040160405180910390fd5b8251600480546020808701516001600160401b039485166001600160801b03199384168117600160401b9690921695909502908117909355604080880151600581905587516000559187015160015586015160025560608601516003556006805490921690931790911790556007556008805463ffffffff60a01b1916600160a01b63ffffffff841602179055611268434285610ed9565b611479611ce7565b621000008152600760208201527f23783d0e9777b7af65fbf849da7edb75e74b1eaf503e025d7f2f7f80991befa26040820151527f2a4e2fe8adfa53f468525582d5184c4c70bbdb946c21f216418a9879705e54a76020604083015101527f0624b2c1e77f24afceaf39451743b9fa80d5853fca7ba00389c675650774009b6060820151527f250d7719e94ca2df00dfe327938f5a8d4d837779b99837ca777a53d39127b1796020606083015101527f0dc09515152eaea66d0db2f571cc995e369d26fe647394f10db5398c917519dc6080820151527f1273144d6cec2c4a68b24a149379c0f5592bb7fbddbe32fa171919950ca404cb6020608083015101527f119521bb68caec216e2f05eeb466fb3abfe1f39baf7fe7cb392ea057b6a2d9bf60a0820151527f2d52adeaba8045e53ab526fe9982d0ea452def6b3ea0253d27a19ef3b46e8428602060a083015101527f16c3b5b217d302975a920d13374524d7a52e4a50fd7fb930842271ebf4a84efd60c0820151527f200788916b907b196972bde304318e885a2521514b2db5e4a11899c51204f089602060c083015101527f1127581afe753defca9aef12e7332db9978a200b1699ce3888c0f3aea6111dc360e0820151527f0881e13f00723be1a04872ed02b2d078c31e80feaf27724e262ce97c2cb0bb1d602060e083015101527f1482a3a6bb91d6483d153683e2404f2f5546e0e895530fdf132091498406e3de610100820151527efa52db3d52d905ead1248102f3a80a43a90d8400c68f60a62c543c417b2f4b602061010083015101527f0a57dadd4a55199525ac6ac6fabc87a4cccfdc98142bcef9dbf47de00ecc5164610120820151527f18d95abd9b8e12c36936aa218cfff582548a6bbff25c338c2006eaeb1fe5b696602061012083015101527f2bc40e91dd169b8bc143a02952a1b6c6e627bfeb7a2bbe5078e14123f3c54c1c610140820151527f108d65a20c579b6d9883275eb6889fc3f5fc79735ca9f611a13b67daa2fbc8d0602061014083015101527f21bc1f86d0608e5f0626b467ee6f8282b619223f60a7acb0fc63ba7bdaf783be610160820151527f05ef3282f8eef01515fb9a8a7d6ca06b8b007d1d512403efb268fb03ce5f09e9602061016083015101527f2cab66c1cb5a83869e73ac34fbe467486999babd541d9010ee9a804806eee4ef610180820151527f2db1982419c5a4a17593acff9535fa967683d75c8aec01319b64b84aada2ad84602061018083015101527f2c38667c6c7eb868bdd30c34dd3f4b84d9b9b1a27d7867b364c8b7831423e9086101a0820151527f2b2cb4044dd51165c48138219d51cf8d1689f91ed3eeefead6e055eb488a2ce260206101a083015101527f2d48e54703011df2c74a14dafde3af4fd83ec71875d8ddc3554658640cc955016101c0820151527f243a99d80d32eb5408b59d5b08302bede070d3fb0a8efe2f2262f865bffb4d0d60206101c083015101527f0455d2325bf6269a66f07d838f55f36947a3cd9b87edd8480bced95cbb45cc116101e0820151527f0f66d9085a6ed60b838179987e240992bff4c0516ccf6ccde4a1ca94ce8b986460206101e083015101527f2bac0d23c8585d1487ec611b5effc97e5852fea43a7cba36ccdd2c207931f394610200820151527f1860b54e01a06aea5adb4b13bf5baebab92b736807a3a89ff2040992b06ee6ec602061020083015101527f0c0bfa1c2fc6f8ed01233d5168db1e1dfe725504f032f669f50a92ae77c72906610220820151527f0d741e124c7d1069b8a400cbcdcfd90128a533901ad4de1e037fe72984dc34cf602061022083015101527f01cfed30085c9efce04668205794aa39b1a8ee591234b4c77a22f8c26d899e05610240820151527f2ab68ac82d36cedb647d14a5b0035e8c9a0be84780b7bae1133a27a880966ed1602061024083015101527f072e1d50f8b5cf8d574b3847276477d95bbd5116351000841f728da44f4043b5610260820151527f23f8ea6eacd0876d57220f57eabacbe76a2323411663731a251d5dca36f1b59f602061026083015101527fb0838893ec1f237e8b07323b0744599f4e97b598b3b589bcc2bc37b8d5c418016102808201527fc18393c0fa30fe4e8b038e357ad851eae8de9107584effe7c7f1f651b2010e266102a082015290565b611aa982611b47565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2805115611aee576112688282611bac565b6107f2611c22565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661088057604051631afcd79f60e31b815260040160405180910390fd5b610cdb611af6565b806001600160a01b03163b600003611b7d57604051634c9c8ce360e01b81526001600160a01b0382166004820152602401610d01565b6000805160206129de83398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6060600080846001600160a01b031684604051611bc991906129c1565b600060405180830381855af49150503d8060008114611c04576040519150601f19603f3d011682016040523d82523d6000602084013e611c09565b606091505b5091509150611c19858383611c41565b95945050505050565b34156108805760405163b398979f60e01b815260040160405180910390fd5b606082611c5657611c5182611ca0565b611c99565b8151158015611c6d57506001600160a01b0384163b155b15611c9657604051639996b31560e01b81526001600160a01b0385166004820152602401610d01565b50805b9392505050565b805115611cb05780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6040518060e001604052806007906020820280368337509192915050565b604051806102c001604052806000815260200160008152602001611d1e604051806040016040528060008152602001600081525090565b8152602001611d40604051806040016040528060008152602001600081525090565b8152602001611d62604051806040016040528060008152602001600081525090565b8152602001611d84604051806040016040528060008152602001600081525090565b8152602001611da6604051806040016040528060008152602001600081525090565b8152602001611dc8604051806040016040528060008152602001600081525090565b8152602001611dea604051806040016040528060008152602001600081525090565b8152602001611e0c604051806040016040528060008152602001600081525090565b8152602001611e2e604051806040016040528060008152602001600081525090565b8152602001611e50604051806040016040528060008152602001600081525090565b8152602001611e72604051806040016040528060008152602001600081525090565b8152602001611e94604051806040016040528060008152602001600081525090565b8152602001611eb6604051806040016040528060008152602001600081525090565b8152602001611ed8604051806040016040528060008152602001600081525090565b8152602001611efa604051806040016040528060008152602001600081525090565b8152602001611f1c604051806040016040528060008152602001600081525090565b8152602001611f3e604051806040016040528060008152602001600081525090565b8152602001611f60604051806040016040528060008152602001600081525090565b815260006020820181905260409091015290565b80356001600160a01b0381168114611f8b57600080fd5b919050565b600060208284031215611fa257600080fd5b611c9982611f74565b600060208284031215611fbd57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6040516102e081016001600160401b0381118282101715611ffd57611ffd611fc4565b60405290565b604051601f8201601f191681016001600160401b038111828210171561202b5761202b611fc4565b604052919050565b80356001600160401b0381168114611f8b57600080fd5b60006060828403121561205c57600080fd5b604051606081018181106001600160401b038211171561207e5761207e611fc4565b60405290508061208d83612033565b815261209b60208401612033565b6020820152604083013560408201525092915050565b6000604082840312156120c357600080fd5b604051604081018181106001600160401b03821117156120e5576120e5611fc4565b604052823581526020928301359281019290925250919050565b6000808284036104e081121561211457600080fd5b61211e858561204a565b925061048080605f198301121561213457600080fd5b61213c611fda565b915061214b86606087016120b1565b825261215a8660a087016120b1565b602083015261216c8660e087016120b1565b6040830152610120612180878288016120b1565b6060840152610160612194888289016120b1565b60808501526101a06121a889828a016120b1565b60a08601526101e06121bc8a828b016120b1565b60c08701526102206121d08b828c016120b1565b60e08801526102606121e48c828d016120b1565b6101008901526102a06121f98d828e016120b1565b878a015261220b8d6102e08e016120b1565b6101408a015261221f8d6103208e016120b1565b868a01526122318d6103608e016120b1565b6101808a01526103a08c0135948901949094526103c08b01356101c08901526103e08b0135928801929092526104008a01356102008801526104208a013590870152610440890135610240870152610460890135908601529287013561028085015250506104a0850135908201526104c0909301356102c08401525092909150565b600080604083850312156122c657600080fd5b6122cf83611f74565b91506020808401356001600160401b03808211156122ec57600080fd5b818601915086601f83011261230057600080fd5b81358181111561231257612312611fc4565b612324601f8201601f19168501612003565b9150808252878482850101111561233a57600080fd5b80848401858401376000848284010152508093505050509250929050565b803563ffffffff81168114611f8b57600080fd5b60006020828403121561237e57600080fd5b611c9982612358565b60008060008084860361012081121561239f57600080fd5b6123a9878761204a565b94506080605f19820112156123bd57600080fd5b50604051608081018181106001600160401b03821117156123e0576123e0611fc4565b8060405250606086013581526080860135602082015260a0860135604082015260c086013560608201528093505061241a60e08601612358565b91506124296101008601611f74565b905092959194509250565b60005b8381101561244f578181015183820152602001612437565b50506000910152565b6020815260008251806020840152612477816040850160208701612434565b601f01601f19169190910160400192915050565b6000806040838503121561249e57600080fd5b50508035926020909101359150565b634e487b7160e01b600052601160045260246000fd5b81810381811115610ccd57610ccd6124ad565b634e487b7160e01b600052603260045260246000fd5b6000816124fb576124fb6124ad565b506000190190565b8060005b6007811015610ed3578151845260209384019390910190600101612507565b61253b82825180518252602090810151910152565b6020818101518051604085015290810151606084015250604081015180516080840152602081015160a0840152506060810151805160c0840152602081015160e084015250608081015161010061259e8185018380518252602090810151910152565b60a083015191506101406125be8186018480518252602090810151910152565b60c084015192506101806125de8187018580518252602090810151910152565b60e085015193506101c06125fe8188018680518252602090810151910152565b9285015193506102009261261e8785018680518252602090810151910152565b610120860151945061024061263f8189018780518252602090810151910152565b9286015194506102809261265f8885018780518252602090810151910152565b61016087015195506102c0612680818a018880518252602090810151910152565b9287015180516103008a0152602001516103208901526101a0870151610340890152908601516103608801526101e0860151610380880152928501516103a08701526102208501516103c0870152918401516103e08601526102608401516104008601528301516104208501526102a0830151610440850152909101516104609092019190915250565b6000610a60820190508451825260208501516020830152604085015161273d604084018280518252602090810151910152565b50606085015180516080840152602081015160a0840152506080850151805160c0840152602081015160e08401525060a085015161010061278a8185018380518252602090810151910152565b60c087015191506101406127aa8186018480518252602090810151910152565b60e088015192506101806127ca8187018580518252602090810151910152565b9188015192506101c0916127ea8684018580518252602090810151910152565b610120890151935061020061280b8188018680518252602090810151910152565b9189015193506102409161282b8784018680518252602090810151910152565b6101608a0151945061028061284c8189018780518252602090810151910152565b918a015180516102c08901526020908101516102e08901526101a08b015180516103008a0152810151610320890152938a015180516103408901528401516103608801526101e08a015180516103808901528401516103a088015289015180516103c08801528301516103e087015261022089015180516104008801528301516104208701529088015180516104408701528201516104608601526102608801518051610480870152909101516104a08501528601516104c0840152506102a08501516104e0830152612923610500830185612503565b6129316105e0830184612526565b949350505050565b60006020828403121561294b57600080fd5b81518015158114611c9957600080fd5b6001600160401b0382811682821603908082111561297b5761297b6124ad565b5092915050565b60006001600160401b0380831681810361299e5761299e6124ad565b6001019392505050565b6000602082840312156129ba57600080fd5b5051919050565b600082516129d3818460208701612434565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca164736f6c6343000817000a" diff --git a/contract-bindings/src/light_client.rs b/contract-bindings/src/light_client.rs index e8783660e..32daa6fc1 100644 --- a/contract-bindings/src/light_client.rs +++ b/contract-bindings/src/light_client.rs @@ -34,6 +34,22 @@ pub mod light_client { state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, },], ), + ( + ::std::borrow::ToOwned::to_owned("currentBlockNumber"), + ::std::vec![::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("currentBlockNumber"), + inputs: ::std::vec![], + outputs: ::std::vec![::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Uint(256usize,), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("uint256"), + ), + },], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + },], + ), ( ::std::borrow::ToOwned::to_owned("disablePermissionedProverMode"), ::std::vec![::ethers::core::abi::ethabi::Function { @@ -959,6 +975,14 @@ pub mod light_client { .method_hash([173, 60, 177, 204], ()) .expect("method not found (this should never happen)") } + ///Calls the contract's `currentBlockNumber` (0x378ec23b) function + pub fn current_block_number( + &self, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([55, 142, 194, 59], ()) + .expect("method not found (this should never happen)") + } ///Calls the contract's `disablePermissionedProverMode` (0x69cc6a04) function pub fn disable_permissioned_prover_mode( &self, @@ -2214,6 +2238,21 @@ pub mod light_client { abi = "UPGRADE_INTERFACE_VERSION()" )] pub struct UpgradeInterfaceVersionCall; + ///Container type for all input parameters for the `currentBlockNumber` function with signature `currentBlockNumber()` and selector `0x378ec23b` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + serde::Serialize, + serde::Deserialize, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + #[ethcall(name = "currentBlockNumber", abi = "currentBlockNumber()")] + pub struct CurrentBlockNumberCall; ///Container type for all input parameters for the `disablePermissionedProverMode` function with signature `disablePermissionedProverMode()` and selector `0x69cc6a04` #[derive( Clone, @@ -2589,6 +2628,7 @@ pub mod light_client { #[derive(Clone, ::ethers::contract::EthAbiType, serde::Serialize, serde::Deserialize)] pub enum LightClientCalls { UpgradeInterfaceVersion(UpgradeInterfaceVersionCall), + CurrentBlockNumber(CurrentBlockNumberCall), DisablePermissionedProverMode(DisablePermissionedProverModeCall), FinalizedState(FinalizedStateCall), GenesisStakeTableState(GenesisStakeTableStateCall), @@ -2622,6 +2662,11 @@ pub mod light_client { { return Ok(Self::UpgradeInterfaceVersion(decoded)); } + if let Ok(decoded) = + ::decode(data) + { + return Ok(Self::CurrentBlockNumber(decoded)); + } if let Ok(decoded) = ::decode(data) { @@ -2733,6 +2778,9 @@ pub mod light_client { Self::UpgradeInterfaceVersion(element) => { ::ethers::core::abi::AbiEncode::encode(element) } + Self::CurrentBlockNumber(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } Self::DisablePermissionedProverMode(element) => { ::ethers::core::abi::AbiEncode::encode(element) } @@ -2786,6 +2834,7 @@ pub mod light_client { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { match self { Self::UpgradeInterfaceVersion(element) => ::core::fmt::Display::fmt(element, f), + Self::CurrentBlockNumber(element) => ::core::fmt::Display::fmt(element, f), Self::DisablePermissionedProverMode(element) => { ::core::fmt::Display::fmt(element, f) } @@ -2820,6 +2869,11 @@ pub mod light_client { Self::UpgradeInterfaceVersion(value) } } + impl ::core::convert::From for LightClientCalls { + fn from(value: CurrentBlockNumberCall) -> Self { + Self::CurrentBlockNumber(value) + } + } impl ::core::convert::From for LightClientCalls { fn from(value: DisablePermissionedProverModeCall) -> Self { Self::DisablePermissionedProverMode(value) @@ -2944,6 +2998,20 @@ pub mod light_client { Hash, )] pub struct UpgradeInterfaceVersionReturn(pub ::std::string::String); + ///Container type for all return fields from the `currentBlockNumber` function with signature `currentBlockNumber()` and selector `0x378ec23b` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + serde::Serialize, + serde::Deserialize, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + pub struct CurrentBlockNumberReturn(pub ::ethers::core::types::U256); ///Container type for all return fields from the `finalizedState` function with signature `finalizedState()` and selector `0x9fdb54a7` #[derive( Clone, diff --git a/contract-bindings/src/light_client_mock.rs b/contract-bindings/src/light_client_mock.rs index 354250869..951f036d3 100644 --- a/contract-bindings/src/light_client_mock.rs +++ b/contract-bindings/src/light_client_mock.rs @@ -65,6 +65,22 @@ pub mod light_client_mock { state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, },], ), + ( + ::std::borrow::ToOwned::to_owned("currentBlockNumber"), + ::std::vec![::ethers::core::abi::ethabi::Function { + name: ::std::borrow::ToOwned::to_owned("currentBlockNumber"), + inputs: ::std::vec![], + outputs: ::std::vec![::ethers::core::abi::ethabi::Param { + name: ::std::string::String::new(), + kind: ::ethers::core::abi::ethabi::ParamType::Uint(256usize,), + internal_type: ::core::option::Option::Some( + ::std::borrow::ToOwned::to_owned("uint256"), + ), + },], + constant: ::core::option::Option::None, + state_mutability: ::ethers::core::abi::ethabi::StateMutability::View, + },], + ), ( ::std::borrow::ToOwned::to_owned("disablePermissionedProverMode"), ::std::vec![::ethers::core::abi::ethabi::Function { @@ -1065,6 +1081,14 @@ pub mod light_client_mock { .method_hash([173, 60, 177, 204], ()) .expect("method not found (this should never happen)") } + ///Calls the contract's `currentBlockNumber` (0x378ec23b) function + pub fn current_block_number( + &self, + ) -> ::ethers::contract::builders::ContractCall { + self.0 + .method_hash([55, 142, 194, 59], ()) + .expect("method not found (this should never happen)") + } ///Calls the contract's `disablePermissionedProverMode` (0x69cc6a04) function pub fn disable_permissioned_prover_mode( &self, @@ -2357,6 +2381,21 @@ pub mod light_client_mock { abi = "UPGRADE_INTERFACE_VERSION()" )] pub struct UpgradeInterfaceVersionCall; + ///Container type for all input parameters for the `currentBlockNumber` function with signature `currentBlockNumber()` and selector `0x378ec23b` + #[derive( + Clone, + ::ethers::contract::EthCall, + ::ethers::contract::EthDisplay, + serde::Serialize, + serde::Deserialize, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + #[ethcall(name = "currentBlockNumber", abi = "currentBlockNumber()")] + pub struct CurrentBlockNumberCall; ///Container type for all input parameters for the `disablePermissionedProverMode` function with signature `disablePermissionedProverMode()` and selector `0x69cc6a04` #[derive( Clone, @@ -2804,6 +2843,7 @@ pub mod light_client_mock { #[derive(Clone, ::ethers::contract::EthAbiType, serde::Serialize, serde::Deserialize)] pub enum LightClientMockCalls { UpgradeInterfaceVersion(UpgradeInterfaceVersionCall), + CurrentBlockNumber(CurrentBlockNumberCall), DisablePermissionedProverMode(DisablePermissionedProverModeCall), FinalizedState(FinalizedStateCall), GenesisStakeTableState(GenesisStakeTableStateCall), @@ -2841,6 +2881,11 @@ pub mod light_client_mock { { return Ok(Self::UpgradeInterfaceVersion(decoded)); } + if let Ok(decoded) = + ::decode(data) + { + return Ok(Self::CurrentBlockNumber(decoded)); + } if let Ok(decoded) = ::decode(data) { @@ -2971,6 +3016,9 @@ pub mod light_client_mock { Self::UpgradeInterfaceVersion(element) => { ::ethers::core::abi::AbiEncode::encode(element) } + Self::CurrentBlockNumber(element) => { + ::ethers::core::abi::AbiEncode::encode(element) + } Self::DisablePermissionedProverMode(element) => { ::ethers::core::abi::AbiEncode::encode(element) } @@ -3030,6 +3078,7 @@ pub mod light_client_mock { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { match self { Self::UpgradeInterfaceVersion(element) => ::core::fmt::Display::fmt(element, f), + Self::CurrentBlockNumber(element) => ::core::fmt::Display::fmt(element, f), Self::DisablePermissionedProverMode(element) => { ::core::fmt::Display::fmt(element, f) } @@ -3068,6 +3117,11 @@ pub mod light_client_mock { Self::UpgradeInterfaceVersion(value) } } + impl ::core::convert::From for LightClientMockCalls { + fn from(value: CurrentBlockNumberCall) -> Self { + Self::CurrentBlockNumber(value) + } + } impl ::core::convert::From for LightClientMockCalls { fn from(value: DisablePermissionedProverModeCall) -> Self { Self::DisablePermissionedProverMode(value) @@ -3212,6 +3266,20 @@ pub mod light_client_mock { Hash, )] pub struct UpgradeInterfaceVersionReturn(pub ::std::string::String); + ///Container type for all return fields from the `currentBlockNumber` function with signature `currentBlockNumber()` and selector `0x378ec23b` + #[derive( + Clone, + ::ethers::contract::EthAbiType, + ::ethers::contract::EthAbiCodec, + serde::Serialize, + serde::Deserialize, + Default, + Debug, + PartialEq, + Eq, + Hash, + )] + pub struct CurrentBlockNumberReturn(pub ::ethers::core::types::U256); ///Container type for all return fields from the `finalizedState` function with signature `finalizedState()` and selector `0x9fdb54a7` #[derive( Clone, diff --git a/contracts/src/LightClient.sol b/contracts/src/LightClient.sol index e893f8299..944ed5f9f 100644 --- a/contracts/src/LightClient.sol +++ b/contracts/src/LightClient.sol @@ -2,9 +2,11 @@ pragma solidity ^0.8.0; -import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import { OwnableUpgradeable } from + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; -import { UUPSUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import { UUPSUpgradeable } from + "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import { BN254 } from "bn254/BN254.sol"; import { IPlonkVerifier } from "./interfaces/IPlonkVerifier.sol"; @@ -26,416 +28,448 @@ import { LightClientStateUpdateVK as VkLib } from "./libraries/LightClientStateU /// @dev You can use this contract to keep track of its finalized states in safe, /// authenticated ways. contract LightClient is Initializable, OwnableUpgradeable, UUPSUpgradeable { - // === Events === - // - /// @notice upgrade event when the proxy updates the implementation it's pointing to - event Upgrade(address implementation); - - /// @notice when a permissioned prover is set, this event is emitted. - event PermissionedProverRequired(address permissionedProver); - - /// @notice when the permissioned prover is unset, this event is emitted. - event PermissionedProverNotRequired(); - - // === System Parameters === - // - // === Storage === - // - /// @notice genesis stake commitment - StakeTableState public genesisStakeTableState; - - /// @notice genesis block commitment - LightClientState public genesisState; - - /// @notice Finalized HotShot's light client state - LightClientState public finalizedState; - - /// @notice the address of the prover that can call the newFinalizedState function when the - /// contract is in permissioned prover mode. This address is address(0) when the contract is - /// not in permissioned prover mode - address public permissionedProver; - - /// @notice Max number of seconds worth of state commitments to record based on this block - /// timestamp - uint32 public stateHistoryRetentionPeriod; - - /// @notice index of first block in block state series - ///@dev use this instead of index 0 since old states would be set to zero to keep storage costs - /// constant to stateHistoryRetentionPeriod - uint64 public stateHistoryFirstIndex; - - /// @notice an array to store the L1 block heights, HotShot Block Heights and their respective - /// state history - /// commitments - StateHistoryCommitment[] public stateHistoryCommitments; - - // === Data Structure === - // - /// @notice The finalized HotShot state (as the digest of the entire HotShot state) - /// @param viewNum The latest view number of the finalized HotShot chain - /// @param blockHeight The block height of the latest finalized block - /// @param blockCommRoot The merkle root of historical block commitments (BN254::ScalarField) - struct LightClientState { - uint64 viewNum; - uint64 blockHeight; - BN254.ScalarField blockCommRoot; - } - - /// @notice The finalized HotShot Stake state (as the digest of the entire HotShot state) - /// @param threshold The (stake-weighted) quorum threshold for a QC to be considered as valid - /// @param blsKeyComm The commitment to the BlsVerKey column of the stake table - /// @param schnorrKeyComm The commitment to the SchnorrVerKey column of the table - /// @param amountComm The commitment to the stake amount column of the stake table - struct StakeTableState { - uint256 threshold; - BN254.ScalarField blsKeyComm; - BN254.ScalarField schnorrKeyComm; - BN254.ScalarField amountComm; - } - - /// @notice Simplified HotShot commitment struct - /// @param l1BlockHeight the block height of l1 when this state update was stored - /// @param l1BlockTimestamp the block timestamp of l1 when this state update was stored - /// @param hotShotBlockHeight The block height of the latest finalized HotShot block - /// @param hotShotBlockCommRoot The merkle root of historical block commitments - /// (BN254::ScalarField) - struct StateHistoryCommitment { - uint64 l1BlockHeight; - uint64 l1BlockTimestamp; - uint64 hotShotBlockHeight; - BN254.ScalarField hotShotBlockCommRoot; - } - - /// @notice Event that a new finalized state has been successfully verified and updated - event NewState(uint64 indexed viewNum, uint64 indexed blockHeight, BN254.ScalarField blockCommRoot); - - /// @notice The state is outdated and older than currently known `finalizedState` - error OutdatedState(); - /// @notice Invalid user inputs: wrong format or non-sensible arguments - error InvalidArgs(); - /// @notice Wrong plonk proof or public inputs. - error InvalidProof(); - /// @notice Wrong stake table used, should match `finalizedState` - error WrongStakeTableUsed(); - /// @notice Invalid address - error InvalidAddress(); - /// @notice Only a permissioned prover can perform this action - error ProverNotPermissioned(); - /// @notice If the same mode or prover is sent to the function, then no change is required - error NoChangeRequired(); - /// @notice Invalid L1 Block for checking Light Client Updates, premature or in the future - error InsufficientSnapshotHistory(); - /// @notice Invalid HotShot Block for checking HotShot commitments, premature or in the future - error InvalidHotShotBlockForCommitmentCheck(); - /// @notice Invalid Max Block States - error InvalidMaxStateHistory(); - - /// @notice Constructor disables initializers to prevent the implementation contract from being - /// initialized - /// @dev This is standard practice for OpenZeppelin upgradeable contracts. Storage is on the - /// proxy contract - /// since it calls this cnotract via delegatecall - /// @custom:oz-upgrades-unsafe-allow constructor - constructor() { - _disableInitializers(); - } - - /// @notice This contract is called by the proxy when you deploy this contract - /// @param _genesis The initial state of the light client - /// @param _stateHistoryRetentionPeriod The maximum retention period (in seconds) for the state - /// history. the min retention period allowed is 1 hour and max 365 days - /// @param owner The address of the contract owner - function initialize( - LightClientState memory _genesis, - StakeTableState memory _genesisStakeTableState, - uint32 _stateHistoryRetentionPeriod, - address owner - ) public initializer { - __Ownable_init(owner); //sets owner of the contract - __UUPSUpgradeable_init(); - _initializeState(_genesis, _genesisStakeTableState, _stateHistoryRetentionPeriod); - } - - /// @notice returns the current block number - function currentBlockNumber() public view virtual returns (uint256) { - return block.number; - } - - /// @notice Use this to get the implementation contract version - /// @return majorVersion The major version of the contract - /// @return minorVersion The minor version of the contract - /// @return patchVersion The patch version of the contract - function getVersion() public pure virtual returns (uint8 majorVersion, uint8 minorVersion, uint8 patchVersion) { - return (1, 0, 0); - } - - /// @notice only the owner can authorize an upgrade - function _authorizeUpgrade(address newImplementation) internal virtual override onlyOwner { - emit Upgrade(newImplementation); - } - - /// @dev Initialization of contract variables happens in this method because the LightClient - /// contract is upgradable and thus has its constructor method disabled. - /// @param _genesis The initial state of the light client - /// @param _genesisStakeTableState The initial stake table state of the light client - /// @param _stateHistoryRetentionPeriod The maximum retention period (in seconds) for the state - /// history. The min retention period allowed is 1 hour and the max is 365 days. - function _initializeState( - LightClientState memory _genesis, - StakeTableState memory _genesisStakeTableState, - uint32 _stateHistoryRetentionPeriod - ) internal { - // The viewNum and blockHeight in the genesis state must be zero to indicate that this is - // the initial state. Stake table commitments and threshold cannot be zero, otherwise it's - // impossible to generate valid proof to move finalized state forward. The - // stateHistoryRetentionPeriod must be at least 1 hour and no more than 365 days - // to ensure proper state retention. - if ( - _genesis.viewNum != 0 || - _genesis.blockHeight != 0 || - BN254.ScalarField.unwrap(_genesisStakeTableState.blsKeyComm) == 0 || - BN254.ScalarField.unwrap(_genesisStakeTableState.schnorrKeyComm) == 0 || - BN254.ScalarField.unwrap(_genesisStakeTableState.amountComm) == 0 || - _genesisStakeTableState.threshold == 0 || - _stateHistoryRetentionPeriod < 1 hours || - _stateHistoryRetentionPeriod > 365 days - ) { - revert InvalidArgs(); + // === Events === + // + /// @notice upgrade event when the proxy updates the implementation it's pointing to + event Upgrade(address implementation); + + /// @notice when a permissioned prover is set, this event is emitted. + event PermissionedProverRequired(address permissionedProver); + + /// @notice when the permissioned prover is unset, this event is emitted. + event PermissionedProverNotRequired(); + + // === System Parameters === + // + // === Storage === + // + /// @notice genesis stake commitment + StakeTableState public genesisStakeTableState; + + /// @notice genesis block commitment + LightClientState public genesisState; + + /// @notice Finalized HotShot's light client state + LightClientState public finalizedState; + + /// @notice the address of the prover that can call the newFinalizedState function when the + /// contract is in permissioned prover mode. This address is address(0) when the contract is + /// not in permissioned prover mode + address public permissionedProver; + + /// @notice Max number of seconds worth of state commitments to record based on this block + /// timestamp + uint32 public stateHistoryRetentionPeriod; + + /// @notice index of first block in block state series + ///@dev use this instead of index 0 since old states would be set to zero to keep storage costs + /// constant to stateHistoryRetentionPeriod + uint64 public stateHistoryFirstIndex; + + /// @notice an array to store the L1 block heights, HotShot Block Heights and their respective + /// state history + /// commitments + StateHistoryCommitment[] public stateHistoryCommitments; + + // === Data Structure === + // + /// @notice The finalized HotShot state (as the digest of the entire HotShot state) + /// @param viewNum The latest view number of the finalized HotShot chain + /// @param blockHeight The block height of the latest finalized block + /// @param blockCommRoot The merkle root of historical block commitments (BN254::ScalarField) + struct LightClientState { + uint64 viewNum; + uint64 blockHeight; + BN254.ScalarField blockCommRoot; } - genesisState = _genesis; - genesisStakeTableState = _genesisStakeTableState; - finalizedState = _genesis; - - stateHistoryRetentionPeriod = _stateHistoryRetentionPeriod; - - updateStateHistory(uint64(currentBlockNumber()), uint64(block.timestamp), _genesis); - } - - // === State Modifying APIs === - // - /// @notice Update the latest finalized light client state. It must be updated - /// periodically, especially an update for the last block for every - /// period has to be submitted - /// before any newer state can be accepted since the stake table commitments of that block - /// become the snapshots used for vote verifications later on. - /// @dev if the permissionedProver is set, only the permissionedProver can call this function - /// @dev the state history for `stateHistoryRetentionPeriod` L1 blocks are also recorded in the - /// `stateHistoryCommitments` array - /// @notice While `newState.stakeTable*` refers to the (possibly) new stake table states, - /// the entire `newState` needs to be signed by stakers in `finalizedState` - /// @param newState new light client state - /// @param proof PlonkProof - function newFinalizedState( - LightClientState memory newState, - IPlonkVerifier.PlonkProof memory proof - ) external virtual { - //revert if we're in permissionedProver mode and the permissioned prover has not been set - if (isPermissionedProverEnabled() && msg.sender != permissionedProver) { - revert ProverNotPermissioned(); + /// @notice The finalized HotShot Stake state (as the digest of the entire HotShot state) + /// @param threshold The (stake-weighted) quorum threshold for a QC to be considered as valid + /// @param blsKeyComm The commitment to the BlsVerKey column of the stake table + /// @param schnorrKeyComm The commitment to the SchnorrVerKey column of the table + /// @param amountComm The commitment to the stake amount column of the stake table + struct StakeTableState { + uint256 threshold; + BN254.ScalarField blsKeyComm; + BN254.ScalarField schnorrKeyComm; + BN254.ScalarField amountComm; } - if (newState.viewNum <= finalizedState.viewNum || newState.blockHeight <= finalizedState.blockHeight) { - revert OutdatedState(); + /// @notice Simplified HotShot commitment struct + /// @param l1BlockHeight the block height of l1 when this state update was stored + /// @param l1BlockTimestamp the block timestamp of l1 when this state update was stored + /// @param hotShotBlockHeight The block height of the latest finalized HotShot block + /// @param hotShotBlockCommRoot The merkle root of historical block commitments + /// (BN254::ScalarField) + struct StateHistoryCommitment { + uint64 l1BlockHeight; + uint64 l1BlockTimestamp; + uint64 hotShotBlockHeight; + BN254.ScalarField hotShotBlockCommRoot; } - // format validity check - BN254.validateScalarField(newState.blockCommRoot); - // check plonk proof - verifyProof(newState, proof); - - // upon successful verification, update the latest finalized state - finalizedState = newState; - - updateStateHistory(uint64(currentBlockNumber()), uint64(block.timestamp), newState); + /// @notice Event that a new finalized state has been successfully verified and updated + event NewState( + uint64 indexed viewNum, uint64 indexed blockHeight, BN254.ScalarField blockCommRoot + ); - emit NewState(newState.viewNum, newState.blockHeight, newState.blockCommRoot); - } + /// @notice The state is outdated and older than currently known `finalizedState` + error OutdatedState(); + /// @notice Invalid user inputs: wrong format or non-sensible arguments + error InvalidArgs(); + /// @notice Wrong plonk proof or public inputs. + error InvalidProof(); + /// @notice Wrong stake table used, should match `finalizedState` + error WrongStakeTableUsed(); + /// @notice Invalid address + error InvalidAddress(); + /// @notice Only a permissioned prover can perform this action + error ProverNotPermissioned(); + /// @notice If the same mode or prover is sent to the function, then no change is required + error NoChangeRequired(); + /// @notice Invalid L1 Block for checking Light Client Updates, premature or in the future + error InsufficientSnapshotHistory(); + /// @notice Invalid HotShot Block for checking HotShot commitments, premature or in the future + error InvalidHotShotBlockForCommitmentCheck(); + /// @notice Invalid Max Block States + error InvalidMaxStateHistory(); + + /// @notice Constructor disables initializers to prevent the implementation contract from being + /// initialized + /// @dev This is standard practice for OpenZeppelin upgradeable contracts. Storage is on the + /// proxy contract + /// since it calls this cnotract via delegatecall + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } - /// @notice Verify the Plonk proof, marked as `virtual` for easier testing as we can swap VK - /// used in inherited contracts. - function verifyProof(LightClientState memory state, IPlonkVerifier.PlonkProof memory proof) internal virtual { - IPlonkVerifier.VerifyingKey memory vk = VkLib.getVk(); + /// @notice This contract is called by the proxy when you deploy this contract + /// @param _genesis The initial state of the light client + /// @param _stateHistoryRetentionPeriod The maximum retention period (in seconds) for the state + /// history. the min retention period allowed is 1 hour and max 365 days + /// @param owner The address of the contract owner + function initialize( + LightClientState memory _genesis, + StakeTableState memory _genesisStakeTableState, + uint32 _stateHistoryRetentionPeriod, + address owner + ) public initializer { + __Ownable_init(owner); //sets owner of the contract + __UUPSUpgradeable_init(); + _initializeState(_genesis, _genesisStakeTableState, _stateHistoryRetentionPeriod); + } - // Prepare the public input - uint256[7] memory publicInput; - publicInput[0] = uint256(state.viewNum); - publicInput[1] = uint256(state.blockHeight); - publicInput[2] = BN254.ScalarField.unwrap(state.blockCommRoot); - publicInput[3] = BN254.ScalarField.unwrap(genesisStakeTableState.blsKeyComm); - publicInput[4] = BN254.ScalarField.unwrap(genesisStakeTableState.schnorrKeyComm); - publicInput[5] = BN254.ScalarField.unwrap(genesisStakeTableState.amountComm); - publicInput[6] = genesisStakeTableState.threshold; + /// @notice returns the current block number + function currentBlockNumber() public view virtual returns (uint256) { + return block.number; + } - if (!PlonkVerifier.verify(vk, publicInput, proof)) { - revert InvalidProof(); + /// @notice Use this to get the implementation contract version + /// @return majorVersion The major version of the contract + /// @return minorVersion The minor version of the contract + /// @return patchVersion The patch version of the contract + function getVersion() + public + pure + virtual + returns (uint8 majorVersion, uint8 minorVersion, uint8 patchVersion) + { + return (1, 0, 0); } - } - - /// @notice set the permissionedProver to the non-zero address provided - /// @dev this function can also be used to update the permissioned prover once it's a different - /// address to the current permissioned prover - function setPermissionedProver(address prover) public virtual onlyOwner { - if (prover == address(0)) { - revert InvalidAddress(); + + /// @notice only the owner can authorize an upgrade + function _authorizeUpgrade(address newImplementation) internal virtual override onlyOwner { + emit Upgrade(newImplementation); } - if (prover == permissionedProver) { - revert NoChangeRequired(); + + /// @dev Initialization of contract variables happens in this method because the LightClient + /// contract is upgradable and thus has its constructor method disabled. + /// @param _genesis The initial state of the light client + /// @param _genesisStakeTableState The initial stake table state of the light client + /// @param _stateHistoryRetentionPeriod The maximum retention period (in seconds) for the state + /// history. The min retention period allowed is 1 hour and the max is 365 days. + function _initializeState( + LightClientState memory _genesis, + StakeTableState memory _genesisStakeTableState, + uint32 _stateHistoryRetentionPeriod + ) internal { + // The viewNum and blockHeight in the genesis state must be zero to indicate that this is + // the initial state. Stake table commitments and threshold cannot be zero, otherwise it's + // impossible to generate valid proof to move finalized state forward. The + // stateHistoryRetentionPeriod must be at least 1 hour and no more than 365 days + // to ensure proper state retention. + if ( + _genesis.viewNum != 0 || _genesis.blockHeight != 0 + || BN254.ScalarField.unwrap(_genesisStakeTableState.blsKeyComm) == 0 + || BN254.ScalarField.unwrap(_genesisStakeTableState.schnorrKeyComm) == 0 + || BN254.ScalarField.unwrap(_genesisStakeTableState.amountComm) == 0 + || _genesisStakeTableState.threshold == 0 || _stateHistoryRetentionPeriod < 1 hours + || _stateHistoryRetentionPeriod > 365 days + ) { + revert InvalidArgs(); + } + + genesisState = _genesis; + genesisStakeTableState = _genesisStakeTableState; + finalizedState = _genesis; + + stateHistoryRetentionPeriod = _stateHistoryRetentionPeriod; + + updateStateHistory(uint64(currentBlockNumber()), uint64(block.timestamp), _genesis); } - permissionedProver = prover; - emit PermissionedProverRequired(permissionedProver); - } - - /// @notice set the permissionedProver to address(0) - /// @dev if it was already disabled, then revert with the error, NoChangeRequired - function disablePermissionedProverMode() public virtual onlyOwner { - if (isPermissionedProverEnabled()) { - permissionedProver = address(0); - emit PermissionedProverNotRequired(); - } else { - revert NoChangeRequired(); + + // === State Modifying APIs === + // + /// @notice Update the latest finalized light client state. It must be updated + /// periodically, especially an update for the last block for every + /// period has to be submitted + /// before any newer state can be accepted since the stake table commitments of that block + /// become the snapshots used for vote verifications later on. + /// @dev if the permissionedProver is set, only the permissionedProver can call this function + /// @dev the state history for `stateHistoryRetentionPeriod` L1 blocks are also recorded in the + /// `stateHistoryCommitments` array + /// @notice While `newState.stakeTable*` refers to the (possibly) new stake table states, + /// the entire `newState` needs to be signed by stakers in `finalizedState` + /// @param newState new light client state + /// @param proof PlonkProof + function newFinalizedState( + LightClientState memory newState, + IPlonkVerifier.PlonkProof memory proof + ) external virtual { + //revert if we're in permissionedProver mode and the permissioned prover has not been set + if (isPermissionedProverEnabled() && msg.sender != permissionedProver) { + revert ProverNotPermissioned(); + } + + if ( + newState.viewNum <= finalizedState.viewNum + || newState.blockHeight <= finalizedState.blockHeight + ) { + revert OutdatedState(); + } + // format validity check + BN254.validateScalarField(newState.blockCommRoot); + + // check plonk proof + verifyProof(newState, proof); + + // upon successful verification, update the latest finalized state + finalizedState = newState; + + updateStateHistory(uint64(currentBlockNumber()), uint64(block.timestamp), newState); + + emit NewState(newState.viewNum, newState.blockHeight, newState.blockCommRoot); } - } - - /// @notice Updates the `stateHistoryCommitments` array when a new finalized state is added - /// and prunes the most outdated element starting from the first element if they fall outside - /// the - /// `stateHistoryRetentionPeriod`. - /// @dev the block timestamp is used to determine if the stateHistoryCommitments array - /// should be pruned, based on the stateHistoryRetentionPeriod (seconds). - /// @dev A FIFO approach is used to remove the most outdated element from the start of the - /// array. - /// However, only one outdated element is removed per invocation of this function, even if - /// multiple elements exceed the retention period. As a result, some outdated elements may - /// remain in the array temporarily until subsequent invocations of this function. - /// @dev the `delete` method does not reduce the array length but resets the value at the - /// specified index to zero. the stateHistoryFirstIndex variable acts as an offset to indicate - /// the starting point for reading the array, since the length of the array is not reduced - /// even after deletion. - /// @param blockNumber The block number of the new finalized state. - /// @param blockTimestamp The block timestamp used to check the retention period. - /// @param state The new `LightClientState` being added to the array. - function updateStateHistory(uint64 blockNumber, uint64 blockTimestamp, LightClientState memory state) internal { - if ( - stateHistoryCommitments.length != 0 && - blockTimestamp - stateHistoryCommitments[stateHistoryFirstIndex].l1BlockTimestamp > stateHistoryRetentionPeriod - ) { - // The stateHistoryCommitments array has reached the maximum retention period - // delete the oldest (first) non-empty element to maintain the FIFO structure. - delete stateHistoryCommitments[stateHistoryFirstIndex]; - - // increment the offset to the first non-zero element in the stateHistoryCommitments - // array - stateHistoryFirstIndex++; + + /// @notice Verify the Plonk proof, marked as `virtual` for easier testing as we can swap VK + /// used in inherited contracts. + function verifyProof(LightClientState memory state, IPlonkVerifier.PlonkProof memory proof) + internal + virtual + { + IPlonkVerifier.VerifyingKey memory vk = VkLib.getVk(); + + // Prepare the public input + uint256[7] memory publicInput; + publicInput[0] = uint256(state.viewNum); + publicInput[1] = uint256(state.blockHeight); + publicInput[2] = BN254.ScalarField.unwrap(state.blockCommRoot); + publicInput[3] = BN254.ScalarField.unwrap(genesisStakeTableState.blsKeyComm); + publicInput[4] = BN254.ScalarField.unwrap(genesisStakeTableState.schnorrKeyComm); + publicInput[5] = BN254.ScalarField.unwrap(genesisStakeTableState.amountComm); + publicInput[6] = genesisStakeTableState.threshold; + + if (!PlonkVerifier.verify(vk, publicInput, proof)) { + revert InvalidProof(); + } } - // add the L1 Block & HotShot commitment to the stateHistoryCommitments - stateHistoryCommitments.push( - StateHistoryCommitment(blockNumber, blockTimestamp, state.blockHeight, state.blockCommRoot) - ); - } - - /// @notice checks if the state updates lag behind the specified block threshold based on the - /// provided block number. - /// @dev Reverts if there isn't enough state history to make an accurate comparison. - /// Reverts if the blockThreshold is zero - /// @param blockNumber The block number to compare against the latest state updates. - /// @param blockThreshold The number of blocks updates this contract is allowed to lag behind. - /// @return bool returns true if the lag exceeds the blockThreshold; otherwise, false. - function lagOverEscapeHatchThreshold(uint256 blockNumber, uint256 blockThreshold) public view virtual returns (bool) { - uint256 updatesCount = stateHistoryCommitments.length; - - // Edge Case Handling: - // 1. Provided block number is greater than the current block (invalid) - // 2. No updates have occurred (i.e., state history is empty) - // 3. Provided block number is earlier than the first recorded state update - // the stateHistoryFirstIndex is used to check for the first nonZero element - if ( - blockNumber > currentBlockNumber() || - updatesCount == 0 || - blockNumber < stateHistoryCommitments[stateHistoryFirstIndex].l1BlockHeight - ) { - revert InsufficientSnapshotHistory(); + /// @notice set the permissionedProver to the non-zero address provided + /// @dev this function can also be used to update the permissioned prover once it's a different + /// address to the current permissioned prover + function setPermissionedProver(address prover) public virtual onlyOwner { + if (prover == address(0)) { + revert InvalidAddress(); + } + if (prover == permissionedProver) { + revert NoChangeRequired(); + } + permissionedProver = prover; + emit PermissionedProverRequired(permissionedProver); } - uint256 eligibleStateUpdateBlockNumber; // the eligibleStateUpdateBlockNumber is <= - // blockNumber - bool stateUpdateFound; // if an eligible block number is found in the state update history, - // then this variable is set to true - - // Search from the most recent state update back to find the first update <= blockNumber - uint256 i = updatesCount - 1; - while (!stateUpdateFound) { - // Stop searching if we've exhausted the recorded state history - if (i < stateHistoryFirstIndex) { - break; - } - - // Find the first update with a block height <= blockNumber - if (stateHistoryCommitments[i].l1BlockHeight <= blockNumber) { - stateUpdateFound = true; - eligibleStateUpdateBlockNumber = stateHistoryCommitments[i].l1BlockHeight; - break; - } - - i--; + /// @notice set the permissionedProver to address(0) + /// @dev if it was already disabled, then revert with the error, NoChangeRequired + function disablePermissionedProverMode() public virtual onlyOwner { + if (isPermissionedProverEnabled()) { + permissionedProver = address(0); + emit PermissionedProverNotRequired(); + } else { + revert NoChangeRequired(); + } } - // If no snapshot is found, we don't have enough history stored - // to tell whether HotShot was down. - if (!stateUpdateFound) { - revert InsufficientSnapshotHistory(); + /// @notice Updates the `stateHistoryCommitments` array when a new finalized state is added + /// and prunes the most outdated element starting from the first element if they fall outside + /// the + /// `stateHistoryRetentionPeriod`. + /// @dev the block timestamp is used to determine if the stateHistoryCommitments array + /// should be pruned, based on the stateHistoryRetentionPeriod (seconds). + /// @dev A FIFO approach is used to remove the most outdated element from the start of the + /// array. + /// However, only one outdated element is removed per invocation of this function, even if + /// multiple elements exceed the retention period. As a result, some outdated elements may + /// remain in the array temporarily until subsequent invocations of this function. + /// @dev the `delete` method does not reduce the array length but resets the value at the + /// specified index to zero. the stateHistoryFirstIndex variable acts as an offset to indicate + /// the starting point for reading the array, since the length of the array is not reduced + /// even after deletion. + /// @param blockNumber The block number of the new finalized state. + /// @param blockTimestamp The block timestamp used to check the retention period. + /// @param state The new `LightClientState` being added to the array. + function updateStateHistory( + uint64 blockNumber, + uint64 blockTimestamp, + LightClientState memory state + ) internal { + if ( + stateHistoryCommitments.length != 0 + && blockTimestamp - stateHistoryCommitments[stateHistoryFirstIndex].l1BlockTimestamp + > stateHistoryRetentionPeriod + ) { + // The stateHistoryCommitments array has reached the maximum retention period + // delete the oldest (first) non-empty element to maintain the FIFO structure. + delete stateHistoryCommitments[stateHistoryFirstIndex]; + + // increment the offset to the first non-zero element in the stateHistoryCommitments + // array + stateHistoryFirstIndex++; + } + + // add the L1 Block & HotShot commitment to the stateHistoryCommitments + stateHistoryCommitments.push( + StateHistoryCommitment( + blockNumber, blockTimestamp, state.blockHeight, state.blockCommRoot + ) + ); } - return blockNumber - eligibleStateUpdateBlockNumber > blockThreshold; - } - - /// @notice get the HotShot commitment that represents the Merkle root containing the leaf at - /// the provided hotShotBlockHeight where the block height in the array is greater than - // or equal to the provided hotShotBlockHeight. - /// @dev if the provided hotShotBlockHeight is greater than the latest commitment in the array, - /// the function reverts. - /// @param hotShotBlockHeight the HotShot block height - /// @return hotShotBlockCommRoot the HotShot commitment root - /// @return hotshotBlockHeight the HotShot block height for the corresponding commitment root - function getHotShotCommitment( - uint256 hotShotBlockHeight - ) public view virtual returns (BN254.ScalarField hotShotBlockCommRoot, uint64 hotshotBlockHeight) { - uint256 commitmentsHeight = stateHistoryCommitments.length; - if (hotShotBlockHeight > stateHistoryCommitments[commitmentsHeight - 1].hotShotBlockHeight) { - revert InvalidHotShotBlockForCommitmentCheck(); + /// @notice checks if the state updates lag behind the specified block threshold based on the + /// provided block number. + /// @dev Reverts if there isn't enough state history to make an accurate comparison. + /// Reverts if the blockThreshold is zero + /// @param blockNumber The block number to compare against the latest state updates. + /// @param blockThreshold The number of blocks updates this contract is allowed to lag behind. + /// @return bool returns true if the lag exceeds the blockThreshold; otherwise, false. + function lagOverEscapeHatchThreshold(uint256 blockNumber, uint256 blockThreshold) + public + view + virtual + returns (bool) + { + uint256 updatesCount = stateHistoryCommitments.length; + + // Edge Case Handling: + // 1. Provided block number is greater than the current block (invalid) + // 2. No updates have occurred (i.e., state history is empty) + // 3. Provided block number is earlier than the first recorded state update + // the stateHistoryFirstIndex is used to check for the first nonZero element + if ( + blockNumber > currentBlockNumber() || updatesCount == 0 + || blockNumber < stateHistoryCommitments[stateHistoryFirstIndex].l1BlockHeight + ) { + revert InsufficientSnapshotHistory(); + } + + uint256 eligibleStateUpdateBlockNumber; // the eligibleStateUpdateBlockNumber is <= + // blockNumber + bool stateUpdateFound; // if an eligible block number is found in the state update history, + // then this variable is set to true + + // Search from the most recent state update back to find the first update <= blockNumber + uint256 i = updatesCount - 1; + while (!stateUpdateFound) { + // Stop searching if we've exhausted the recorded state history + if (i < stateHistoryFirstIndex) { + break; + } + + // Find the first update with a block height <= blockNumber + if (stateHistoryCommitments[i].l1BlockHeight <= blockNumber) { + stateUpdateFound = true; + eligibleStateUpdateBlockNumber = stateHistoryCommitments[i].l1BlockHeight; + break; + } + + i--; + } + + // If no snapshot is found, we don't have enough history stored + // to tell whether HotShot was down. + if (!stateUpdateFound) { + revert InsufficientSnapshotHistory(); + } + + return blockNumber - eligibleStateUpdateBlockNumber > blockThreshold; } - for (uint256 i = stateHistoryFirstIndex; i < commitmentsHeight; i++) { - // Finds and returns the first HotShot commitment whose height is greater than - // or equal to the specified HotShot height. - if (stateHistoryCommitments[i].hotShotBlockHeight >= hotShotBlockHeight) { - return (stateHistoryCommitments[i].hotShotBlockCommRoot, stateHistoryCommitments[i].hotShotBlockHeight); - } + + /// @notice get the HotShot commitment that represents the Merkle root containing the leaf at + /// the provided hotShotBlockHeight where the block height in the array is greater than + // or equal to the provided hotShotBlockHeight. + /// @dev if the provided hotShotBlockHeight is greater than the latest commitment in the array, + /// the function reverts. + /// @param hotShotBlockHeight the HotShot block height + /// @return hotShotBlockCommRoot the HotShot commitment root + /// @return hotshotBlockHeight the HotShot block height for the corresponding commitment root + function getHotShotCommitment(uint256 hotShotBlockHeight) + public + view + virtual + returns (BN254.ScalarField hotShotBlockCommRoot, uint64 hotshotBlockHeight) + { + uint256 commitmentsHeight = stateHistoryCommitments.length; + if (hotShotBlockHeight > stateHistoryCommitments[commitmentsHeight - 1].hotShotBlockHeight) + { + revert InvalidHotShotBlockForCommitmentCheck(); + } + for (uint256 i = stateHistoryFirstIndex; i < commitmentsHeight; i++) { + // Finds and returns the first HotShot commitment whose height is greater than + // or equal to the specified HotShot height. + if (stateHistoryCommitments[i].hotShotBlockHeight >= hotShotBlockHeight) { + return ( + stateHistoryCommitments[i].hotShotBlockCommRoot, + stateHistoryCommitments[i].hotShotBlockHeight + ); + } + } } - } - - /// @notice get the number of state history commitments - /// @return uint256 The number of state history commitments - function getStateHistoryCount() public view returns (uint256) { - return stateHistoryCommitments.length; - } - - /// @notice sets the maximum retention period for storing block state history. - /// @param historySeconds The maximum number of seconds for which state history updates - /// will be stored, based on the block timestamp. It must be greater than or equal to - /// the current state history retention period and must be at least 1 hour and max 365 days. - /// @dev Reverts with `InvalidMaxStateHistory` if the provided value is less than 1 hour, - /// more than 365 days or less than or equal to the current state history retention period. - function setstateHistoryRetentionPeriod(uint32 historySeconds) public onlyOwner { - if (historySeconds < 1 hours || historySeconds > 365 days || historySeconds <= stateHistoryRetentionPeriod) { - revert InvalidMaxStateHistory(); + + /// @notice get the number of state history commitments + /// @return uint256 The number of state history commitments + function getStateHistoryCount() public view returns (uint256) { + return stateHistoryCommitments.length; } - stateHistoryRetentionPeriod = historySeconds; - } + /// @notice sets the maximum retention period for storing block state history. + /// @param historySeconds The maximum number of seconds for which state history updates + /// will be stored, based on the block timestamp. It must be greater than or equal to + /// the current state history retention period and must be at least 1 hour and max 365 days. + /// @dev Reverts with `InvalidMaxStateHistory` if the provided value is less than 1 hour, + /// more than 365 days or less than or equal to the current state history retention period. + function setstateHistoryRetentionPeriod(uint32 historySeconds) public onlyOwner { + if ( + historySeconds < 1 hours || historySeconds > 365 days + || historySeconds <= stateHistoryRetentionPeriod + ) { + revert InvalidMaxStateHistory(); + } + + stateHistoryRetentionPeriod = historySeconds; + } - /// @notice Check if permissioned prover is enabled - function isPermissionedProverEnabled() public view returns (bool) { - return (permissionedProver != address(0)); - } + /// @notice Check if permissioned prover is enabled + function isPermissionedProverEnabled() public view returns (bool) { + return (permissionedProver != address(0)); + } } diff --git a/contracts/src/LightClientArbitrum.sol b/contracts/src/LightClientArbitrum.sol index 175de4600..f173890b6 100644 --- a/contracts/src/LightClientArbitrum.sol +++ b/contracts/src/LightClientArbitrum.sol @@ -5,11 +5,11 @@ pragma solidity ^0.8.0; import { LightClient } from "./LightClient.sol"; interface ArbSys { - function arbBlockNumber() external view returns (uint256); + function arbBlockNumber() external view returns (uint256); } contract LightClientArbitrum is LightClient { - function currentBlockNumber() public view virtual override returns (uint256) { - return ArbSys(address(uint160(100))).arbBlockNumber(); - } + function currentBlockNumber() public view virtual override returns (uint256) { + return ArbSys(address(uint160(100))).arbBlockNumber(); + } }