diff --git a/.env b/.env index bba7608456..cbef20d655 100644 --- a/.env +++ b/.env @@ -65,7 +65,7 @@ ESP_TOKEN_NAME="Espresso" ESP_TOKEN_SYMBOL="ESP" # Contracts -ESPRESSO_SEQUENCER_LIGHT_CLIENT_PROXY_ADDRESS=0x196dbcbb54b8ec4958c959d8949ebfe87ac2aaaf +ESPRESSO_SEQUENCER_LIGHT_CLIENT_PROXY_ADDRESS=0x05b4cb126885fb10464fdd12666feb25e2563b76 ESPRESSO_SEQUENCER_STAKE_TABLE_PROXY_ADDRESS=0xed1db453c3156ff3155a97ad217b3087d5dc5f6e ESPRESSO_SEQUENCER_FEE_CONTRACT_PROXY_ADDRESS=0xa15bb66138824a1c7167f5e85b957d04dd34e468 ESPRESSO_SEQUENCER_ESP_TOKEN_PROXY_ADDRESS=0xe1aa25618fa0c7a1cfdab5d6b456af611873b629 diff --git a/Cargo.lock b/Cargo.lock index 93055e6d5e..85a99adb81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4095,6 +4095,7 @@ dependencies = [ "espresso-types", "hotshot-contract-adapter", "hotshot-types", + "sequencer-utils", "surf-disco", "tide-disco", "tokio", @@ -4181,6 +4182,8 @@ dependencies = [ "portpicker", "pretty_assertions", "rand 0.8.5", + "rstest", + "rstest_reuse", "sequencer-utils", "serde", "serde_json", @@ -4960,6 +4963,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "generic-tests" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9ff6d6584f4f6fa911d5e07856abf1a48dc5599b3734f2eaea130f2c3baa989" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -5538,11 +5552,13 @@ dependencies = [ "hotshot-types", "jf-pcs", "jf-plonk", + "jf-signature 0.2.0", "jf-utils", "num-bigint", "num-traits", "rand 0.8.5", "serde", + "thiserror 1.0.69", "tokio", ] @@ -9707,6 +9723,12 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + [[package]] name = "rend" version = "0.4.2" @@ -9976,6 +9998,47 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rstest" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fc39292f8613e913f7df8fa892b8944ceb47c247b78e1b1ae2f09e019be789d" +dependencies = [ + "futures-timer", + "futures-util", + "rstest_macros", + "rustc_version 0.4.1", +] + +[[package]] +name = "rstest_macros" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f168d99749d307be9de54d23fd226628d99768225ef08f6ffb52e0182a27746" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version 0.4.1", + "syn 2.0.101", + "unicode-ident", +] + +[[package]] +name = "rstest_reuse" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a8fb4672e840a587a66fc577a5491375df51ddb88f2a2c2a792598c326fe14" +dependencies = [ + "quote", + "rand 0.8.5", + "syn 2.0.101", +] + [[package]] name = "rtnetlink" version = "0.13.1" @@ -10508,6 +10571,7 @@ dependencies = [ "espresso-macros", "espresso-types", "futures", + "generic-tests", "hotshot", "hotshot-builder-core-refactored", "hotshot-contract-adapter", @@ -10538,6 +10602,8 @@ dependencies = [ "rand_distr", "request-response", "reqwest 0.12.15", + "rstest", + "rstest_reuse", "semver 1.0.26", "sequencer", "sequencer-utils", @@ -11261,8 +11327,7 @@ version = "0.1.0" dependencies = [ "alloy", "anyhow", - "ark-ec", - "ark-ed-on-bn254", + "ark-serialize 0.4.2", "clap 4.5.37", "clap-serde", "clap-serde-derive", @@ -11280,6 +11345,8 @@ dependencies = [ "portpicker", "rand 0.8.5", "rand_chacha 0.3.1", + "rstest", + "rstest_reuse", "rust_decimal", "sequencer-utils", "serde", diff --git a/Cargo.toml b/Cargo.toml index 26e6aff1c9..90a5d9f8c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -228,6 +228,8 @@ paste = "1.0" rand = "0.8.5" time = "0.3" trait-set = "0.3.0" +rstest = "0.25.0" +rstest_reuse = "0.7.0" # NOTE: when making changes here also update sequencer-sqlite/Cargo.toml. [profile.dev] diff --git a/contracts/rust/adapter/Cargo.toml b/contracts/rust/adapter/Cargo.toml index b98ba4dec4..8e4ff48dbb 100644 --- a/contracts/rust/adapter/Cargo.toml +++ b/contracts/rust/adapter/Cargo.toml @@ -22,11 +22,13 @@ ark-std = { workspace = true } hotshot-types = { workspace = true } jf-pcs = { workspace = true } jf-plonk = { workspace = true } +jf-signature = { workspace = true, features = ["bls", "schnorr"] } jf-utils = { workspace = true } num-bigint = { version = "0.4", default-features = false } num-traits = { version = "0.2", default-features = false } rand = { workspace = true } serde = { workspace = true } +thiserror = { workspace = true } [dev-dependencies] tokio = { workspace = true } diff --git a/contracts/rust/adapter/src/bindings/staketablev2.rs b/contracts/rust/adapter/src/bindings/staketablev2.rs index 3c0d9ce300..b21c5f9628 100644 --- a/contracts/rust/adapter/src/bindings/staketablev2.rs +++ b/contracts/rust/adapter/src/bindings/staketablev2.rs @@ -1277,7 +1277,7 @@ interface StakeTableV2 { error ZeroAmount(); event ConsensusKeysUpdated(address indexed account, BN254.G2Point blsVK, EdOnBN254.EdOnBN254Point schnorrVK); - event ConsensusKeysUpdatedV2(address indexed account, BN254.G2Point blsVK, EdOnBN254.EdOnBN254Point schnorrVK, BN254.G1Point blsSig, EdOnBN254.EdOnBN254Point schnorrSig); + event ConsensusKeysUpdatedV2(address indexed account, BN254.G2Point blsVK, EdOnBN254.EdOnBN254Point schnorrVK, BN254.G1Point blsSig, bytes schnorrSig); event Delegated(address indexed delegator, address indexed validator, uint256 amount); event ExitEscrowPeriodUpdated(uint64 newExitEscrowPeriod); event Initialized(uint64 version); @@ -1287,7 +1287,7 @@ interface StakeTableV2 { event Upgraded(address indexed implementation); event ValidatorExit(address indexed validator); event ValidatorRegistered(address indexed account, BN254.G2Point blsVk, EdOnBN254.EdOnBN254Point schnorrVk, uint16 commission); - event ValidatorRegisteredV2(address indexed account, BN254.G2Point blsVk, EdOnBN254.EdOnBN254Point schnorrVk, uint16 commission, BN254.G1Point blsSig, EdOnBN254.EdOnBN254Point schnorrSig); + event ValidatorRegisteredV2(address indexed account, BN254.G2Point blsVK, EdOnBN254.EdOnBN254Point schnorrVK, uint16 commission, BN254.G1Point blsSig, bytes schnorrSig); event Withdrawal(address indexed account, uint256 amount); constructor(); @@ -1308,14 +1308,14 @@ interface StakeTableV2 { function owner() external view returns (address); function proxiableUUID() external view returns (bytes32); function registerValidator(BN254.G2Point memory, EdOnBN254.EdOnBN254Point memory, BN254.G1Point memory, uint16) external pure; - function registerValidator(BN254.G2Point memory blsVK, EdOnBN254.EdOnBN254Point memory schnorrVK, BN254.G1Point memory blsSig, EdOnBN254.EdOnBN254Point memory schnorrSig, uint16 commission) external; + function registerValidatorV2(BN254.G2Point memory blsVK, EdOnBN254.EdOnBN254Point memory schnorrVK, BN254.G1Point memory blsSig, bytes memory schnorrSig, uint16 commission) external; function renounceOwnership() external; function token() external view returns (address); function transferOwnership(address newOwner) external; function undelegate(address validator, uint256 amount) external; function undelegations(address validator, address delegator) external view returns (uint256 amount, uint256 unlocksAt); function updateConsensusKeys(BN254.G2Point memory, EdOnBN254.EdOnBN254Point memory, BN254.G1Point memory) external pure; - function updateConsensusKeys(BN254.G2Point memory blsVK, EdOnBN254.EdOnBN254Point memory schnorrVK, BN254.G1Point memory blsSig, EdOnBN254.EdOnBN254Point memory schnorrSig) external; + function updateConsensusKeysV2(BN254.G2Point memory blsVK, EdOnBN254.EdOnBN254Point memory schnorrVK, BN254.G1Point memory blsSig, bytes memory schnorrSig) external; function updateExitEscrowPeriod(uint64 newExitEscrowPeriod) external; function upgradeToAndCall(address newImplementation, bytes memory data) external payable; function validatorExits(address validator) external view returns (uint256 unlocksAt); @@ -1671,7 +1671,7 @@ interface StakeTableV2 { }, { "type": "function", - "name": "registerValidator", + "name": "registerValidatorV2", "inputs": [ { "name": "blsVK", @@ -1736,20 +1736,8 @@ interface StakeTableV2 { }, { "name": "schnorrSig", - "type": "tuple", - "internalType": "struct EdOnBN254.EdOnBN254Point", - "components": [ - { - "name": "x", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "y", - "type": "uint256", - "internalType": "uint256" - } - ] + "type": "bytes", + "internalType": "bytes" }, { "name": "commission", @@ -1911,7 +1899,7 @@ interface StakeTableV2 { }, { "type": "function", - "name": "updateConsensusKeys", + "name": "updateConsensusKeysV2", "inputs": [ { "name": "blsVK", @@ -1976,20 +1964,8 @@ interface StakeTableV2 { }, { "name": "schnorrSig", - "type": "tuple", - "internalType": "struct EdOnBN254.EdOnBN254Point", - "components": [ - { - "name": "x", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "y", - "type": "uint256", - "internalType": "uint256" - } - ] + "type": "bytes", + "internalType": "bytes" } ], "outputs": [], @@ -2204,21 +2180,9 @@ interface StakeTableV2 { }, { "name": "schnorrSig", - "type": "tuple", + "type": "bytes", "indexed": false, - "internalType": "struct EdOnBN254.EdOnBN254Point", - "components": [ - { - "name": "x", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "y", - "type": "uint256", - "internalType": "uint256" - } - ] + "internalType": "bytes" } ], "anonymous": false @@ -2433,7 +2397,7 @@ interface StakeTableV2 { "internalType": "address" }, { - "name": "blsVk", + "name": "blsVK", "type": "tuple", "indexed": false, "internalType": "struct BN254.G2Point", @@ -2461,7 +2425,7 @@ interface StakeTableV2 { ] }, { - "name": "schnorrVk", + "name": "schnorrVK", "type": "tuple", "indexed": false, "internalType": "struct EdOnBN254.EdOnBN254Point", @@ -2504,21 +2468,9 @@ interface StakeTableV2 { }, { "name": "schnorrSig", - "type": "tuple", + "type": "bytes", "indexed": false, - "internalType": "struct EdOnBN254.EdOnBN254Point", - "components": [ - { - "name": "x", - "type": "uint256", - "internalType": "uint256" - }, - { - "name": "y", - "type": "uint256", - "internalType": "uint256" - } - ] + "internalType": "bytes" } ], "anonymous": false @@ -2740,22 +2692,22 @@ pub mod StakeTableV2 { /// The creation / init bytecode of the contract. /// /// ```text - ///0x60a060405230608052348015610013575f5ffd5b5061001c610031565b610024610031565b61002c610031565b6100e3565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100815760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146100e05780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b608051612df76101095f395f818161140d0152818161143601526115b90152612df75ff3fe6080604052600436106101af575f3560e01c80639e9a8f31116100e7578063b5ecb34411610087578063e53b2a7411610062578063e53b2a7414610539578063f2fde38b14610558578063fa52c7d814610577578063fc0c546a146105ba575f5ffd5b8063b5ecb344146104b9578063be203094146104e4578063c64814dd14610503575f5ffd5b8063a5857ff3116100c2578063a5857ff314610400578063ad3cb1cc1461041f578063b3e6ebd51461045c578063b5700e681461049a575f5ffd5b80639e9a8f311461037a578063a2d78dd51461038f578063a3066aab146103e1575f5ffd5b80634f1ef286116101525780636a911ccf1161012d5780636a911ccf146102e3578063715018a6146102f75780638da5cb5b1461030b5780639b30a5e61461035b575f5ffd5b80634f1ef286146102a257806352d1902d146102b55780635544c2f1146102c9575f5ffd5b80631a20cd631161018d5780631a20cd63146102235780632140fecd146102425780633e9df9b5146102615780634d99dd1614610283575f5ffd5b8063026e402b146101b35780630d8e6e2c146101d457806313b9057a14610204575b5f5ffd5b3480156101be575f5ffd5b506101d26101cd366004612616565b6105d9565b005b3480156101df575f5ffd5b5060408051600281525f60208201819052918101919091526060015b60405180910390f35b34801561020f575f5ffd5b506101d261021e36600461274a565b61077c565b34801561022e575f5ffd5b506101d261023d3660046127b4565b610795565b34801561024d575f5ffd5b506101d261025c3660046127cf565b6108a9565b34801561026c575f5ffd5b506102755f5481565b6040519081526020016101fb565b34801561028e575f5ffd5b506101d261029d366004612616565b6109ca565b6101d26102b03660046127e8565b610b7c565b3480156102c0575f5ffd5b50610275610b9b565b3480156102d4575f5ffd5b506101d261021e36600461288b565b3480156102ee575f5ffd5b506101d2610bb6565b348015610302575f5ffd5b506101d2610c44565b348015610316575f5ffd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03165b6040516001600160a01b0390911681526020016101fb565b348015610366575f5ffd5b506102756103753660046128cf565b610c57565b348015610385575f5ffd5b5061027560085481565b34801561039a575f5ffd5b506103cc6103a93660046128e9565b600760209081525f92835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101fb565b3480156103ec575f5ffd5b506101d26103fb3660046127cf565b610cb1565b34801561040b575f5ffd5b506101d261041a36600461291a565b610dc1565b34801561042a575f5ffd5b5061044f604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516101fb9190612982565b348015610467575f5ffd5b5061048a6104763660046129b7565b60046020525f908152604090205460ff1681565b60405190151581526020016101fb565b3480156104a5575f5ffd5b50600154610343906001600160a01b031681565b3480156104c4575f5ffd5b506102756104d33660046127cf565b60056020525f908152604090205481565b3480156104ef575f5ffd5b506101d26104fe3660046129ce565b610f79565b34801561050e575f5ffd5b5061027561051d3660046128e9565b600660209081525f928352604080842090915290825290205481565b348015610544575f5ffd5b506101d2610553366004612a0d565b6110a3565b348015610563575f5ffd5b506101d26105723660046127cf565b6111b6565b348015610582575f5ffd5b506105ac6105913660046127cf565b60036020525f90815260409020805460019091015460ff1682565b6040516101fb929190612a6d565b3480156105c5575f5ffd5b50600254610343906001600160a01b031681565b6105e2826111f3565b335f82900361060457604051631f2a200560e01b815260040160405180910390fd5b600254604051636eb1769f60e11b81526001600160a01b0383811660048301523060248301525f92169063dd62ed3e90604401602060405180830381865afa158015610652573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106769190612a9d565b9050828110156106a85760405163054365bb60e31b815260048101829052602481018490526044015b60405180910390fd5b6002546106c0906001600160a01b0316833086611274565b6001600160a01b0384165f90815260036020526040812080548592906106e7908490612ac8565b90915550506001600160a01b038085165f90815260066020908152604080832093861683529290529081208054859290610722908490612ac8565b92505081905550836001600160a01b0316826001600160a01b03167fe5541a6b6103d4fa7e021ed54fad39c66f27a76bd13d374cf6240ae6bd0bb72b8560405161076e91815260200190565b60405180910390a350505050565b60405163c2d7f81360e01b815260040160405180910390fd5b61079d611318565b60015460408051633c1a081560e21b815290515f926001600160a01b03169163f06820549160048083019260209291908290030181865afa1580156107e4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108089190612adb565b61081390600f612af6565b9050621275006001600160401b0380831690841610806108445750806001600160401b0316836001600160401b0316115b156108625760405163b57e21df60e01b815260040160405180910390fd5b6001600160401b03831660088190556040519081527f793e3b1e1bcd677bb11900c83124d3c44c9946ea8ddf978a0ca250b034ec9dde9060200160405180910390a1505050565b6001600160a01b0381165f9081526005602052604081205433918190036108e3576040516379298a5360e11b815260040160405180910390fd5b8042101561090457604051635a77435760e01b815260040160405180910390fd5b6001600160a01b038084165f9081526006602090815260408083209386168352929052908120549081900361094c57604051630686827b60e51b815260040160405180910390fd5b6001600160a01b038085165f908152600660209081526040808320878516845290915281205560025461098191168483611373565b826001600160a01b03167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040516109bc91815260200190565b60405180910390a250505050565b6109d3826111f3565b335f8290036109f557604051631f2a200560e01b815260040160405180910390fd5b6001600160a01b038084165f9081526007602090815260408083209385168352929052205415610a385760405163d423a4f160e01b815260040160405180910390fd5b6001600160a01b038084165f9081526006602090815260408083209385168352929052205482811015610a8157604051639266535160e01b81526004810182905260240161069f565b6001600160a01b038085165f90815260066020908152604080832093861683529290529081208054859290610ab7908490612b18565b92505081905550604051806040016040528084815260200160085442610add9190612ac8565b90526001600160a01b038086165f81815260076020908152604080832094881683529381528382208551815594810151600190950194909455908152600390925281208054859290610b30908490612b18565b92505081905550836001600160a01b0316826001600160a01b03167f4d10bd049775c77bd7f255195afba5088028ecb3c7c277d393ccff7934f2f92c8560405161076e91815260200190565b610b84611402565b610b8d826114a6565b610b9782826114ed565b5050565b5f610ba46115ae565b505f516020612dcb5f395f51905f5290565b33610bc0816111f3565b6001600160a01b0381165f908152600360205260409020600101805460ff19166002179055600854610bf29042612ac8565b6001600160a01b0382165f8181526005602090815260408083209490945560039052828120819055915190917ffb24305354c87762d557487ae4a564e8d03ecbb9a97dd8afff8e1f6fcaf0dd1691a250565b610c4c611318565b610c555f6115f7565b565b5f815f0151826020015183604001518460600151604051602001610c94949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b6001600160a01b0381165f9081526007602090815260408083203380855292528220549091819003610cf657604051630686827b60e51b815260040160405180910390fd5b6001600160a01b038084165f90815260076020908152604080832093861683529290522060010154421015610d3e57604051635a77435760e01b815260040160405180910390fd5b6001600160a01b038084165f9081526007602090815260408083208685168452909152812081815560010155600254610d7991168383611373565b816001600160a01b03167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6582604051610db491815260200190565b60405180910390a2505050565b33610dcb81611667565b610dd4856116b4565b610ddd866116ef565b604080516001600160a01b03831660208201525f91016040516020818303038152906040529050610e0f81868961172b565b6127108361ffff161115610e365760405163dc81db8560e01b815260040160405180910390fd5b600160045f610e448a610c57565b81526020019081526020015f205f6101000a81548160ff02191690831515021790555060405180604001604052805f815260200160016002811115610e8b57610e8b612a59565b90526001600160a01b0383165f908152600360209081526040909120825181559082015160018083018054909160ff1990911690836002811115610ed157610ed1612a59565b02179055505060408051895181526020808b0151818301528a830151828401526060808c015190830152895160808301528981015160a083015261ffff871660c0830152885160e083015288810151610100830152875161012083015287015161014082015290516001600160a01b03851692507f8e1c394d8f3c83d8e24d20790bd0586fe71354810a93c2ee368b418745553b2e918190036101600190a250505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f81158015610fbd5750825b90505f826001600160401b03166001148015610fd85750303b155b905081158015610fe6575080155b156110045760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561102e57845460ff60401b1916600160401b1785555b611037866117c0565b61103f6117d1565b6110476117d9565b6110528989896118dd565b831561109857845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b336110ad816111f3565b6110b6846116b4565b6110bf856116ef565b604080516001600160a01b03831660208201525f910160405160208183030381529060405290506110f181858861172b565b600160045f6110ff89610c57565b815260208082019290925260409081015f20805460ff1916931515939093179092558151885181528882015181830152888301519281019290925260608089015190830152865160808301528681015160a0830152855160c08301528581015160e083015284516101008301528401516101208201526001600160a01b038316907f04cf8cf47a6bf2ea5f71b8eebdec9de2117f47d2b67bc608338f81acb1a466d5906101400160405180910390a2505050505050565b6111be611318565b6001600160a01b0381166111e757604051631e4fbdf760e01b81525f600482015260240161069f565b6111f0816115f7565b50565b6001600160a01b0381165f9081526003602052604081206001015460ff169081600281111561122457611224612a59565b036112425760405163508a793f60e01b815260040160405180910390fd5b600281600281111561125657611256612a59565b03610b975760405163eab4a96360e01b815260040160405180910390fd5b5f6040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260205f6064835f8a5af191505080601f3d1160015f5114161516156112cd5750833b153d17155b806113115760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b604482015260640161069f565b5050505050565b3361134a7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b031614610c555760405163118cdaa760e01b815233600482015260240161069f565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af191505080601f3d1160015f5114161516156113bd5750823b153d17155b806113fc5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015260640161069f565b50505050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061148857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661147c5f516020612dcb5f395f51905f52546001600160a01b031690565b6001600160a01b031614155b15610c555760405163703e46dd60e11b815260040160405180910390fd5b6114ae611318565b6040516001600160a01b03821681527ff78721226efe9a1bb678189a16d1554928b9f2192e2cb93eeda83b79fa40007d9060200160405180910390a150565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611547575060408051601f3d908101601f1916820190925261154491810190612a9d565b60015b61156f57604051634c9c8ce360e01b81526001600160a01b038316600482015260240161069f565b5f516020612dcb5f395f51905f52811461159f57604051632a87526960e21b81526004810182905260240161069f565b6115a98383611960565b505050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c555760405163703e46dd60e11b815260040160405180910390fd5b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b6001600160a01b0381165f9081526003602052604081206001015460ff16600281111561169657611696612a59565b146111f05760405163132e7efb60e31b815260040160405180910390fd5b604080518082019091525f80825260208201526116d182826119b5565b15610b97576040516306cf438f60e01b815260040160405180910390fd5b60045f6116fb83610c57565b815260208101919091526040015f205460ff16156111f05760405162da8a5760e11b815260040160405180910390fd5b611734826119d8565b5f604051806060016040528060248152602001612d876024913990505f8482604051602001611764929190612b42565b60405160208183030381529060405290505f61177f82611a6e565b905061179c818561178f88611b5b565b611797611bd2565b611c9f565b6117b85760405162ced3e560e41b815260040160405180910390fd5b505050505050565b6117c8611d7d565b6111f081611dc6565b610c55611d7d565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f8115801561181d5750825b90505f826001600160401b031660011480156118385750303b155b905081158015611846575080155b156118645760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561188e57845460ff60401b1916600160401b1785555b435f55831561131157845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050565b6001600160a01b0383166119045760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03821661192b5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b039485166001600160a01b0319918216179091556001805493909416921691909117909155600855565b61196982611dce565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a28051156119ad576115a98282611e31565b610b97611ea3565b805182515f911480156119cf575081602001518360200151145b90505b92915050565b805160208201515f915f516020612dab5f395f51905f529115901516156119fe57505050565b8251602084015182600384858586098509088382830914838210848410161693505050816115a95760405162461bcd60e51b815260206004820152601760248201527f426e3235343a20696e76616c696420473120706f696e74000000000000000000604482015260640161069f565b604080518082019091525f80825260208201525f611a8b83611ec2565b90505f516020612dab5f395f51905f5260035f8284850990508280611ab257611ab2612b5e565b84820990508280611ac557611ac5612b5e565b82820890505f5f611ad5836120ca565b925090505b80611b3e578480611aed57611aed612b5e565b6001870895508480611b0157611b01612b5e565b86870992508480611b1457611b14612b5e565b86840992508480611b2757611b27612b5e565b8484089250611b35836120ca565b92509050611ada565b506040805180820190915294855260208501525091949350505050565b604080518082019091525f8082526020820152815160208301511590151615611b82575090565b6040518060400160405280835f015181526020015f516020612dab5f395f51905f528460200151611bb39190612b72565b611bca905f516020612dab5f395f51905f52612b18565b905292915050565b611bf960405180608001604052805f81526020015f81526020015f81526020015f81525090565b60405180608001604052807f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed81526020017f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa81526020017f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b815250905090565b5f5f5f6040518751815260208801516020820152602087015160408201528651606082015260608701516080820152604087015160a0820152855160c0820152602086015160e0820152602085015161010082015284516101208201526060850151610140820152604085015161016082015260205f6101808360085afa9150505f51915080611d715760405162461bcd60e51b815260206004820152601c60248201527f426e3235343a2050616972696e6720636865636b206661696c65642100000000604482015260640161069f565b50151595945050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16610c5557604051631afcd79f60e31b815260040160405180910390fd5b6111be611d7d565b806001600160a01b03163b5f03611e0357604051634c9c8ce360e01b81526001600160a01b038216600482015260240161069f565b5f516020612dcb5f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b031684604051611e4d9190612b91565b5f60405180830381855af49150503d805f8114611e85576040519150601f19603f3d011682016040523d82523d5f602084013e611e8a565b606091505b5091509150611e9a8583836121c1565b95945050505050565b3415610c555760405163b398979f60e01b815260040160405180910390fd5b5f5f611ecd83612220565b805190915060308114611ee257611ee2612b9c565b5f816001600160401b03811115611efb57611efb61263e565b6040519080825280601f01601f191660200182016040528015611f25576020820181803683370190505b5090505f5b82811015611f9457836001611f3f8386612b18565b611f499190612b18565b81518110611f5957611f59612bb0565b602001015160f81c60f81b828281518110611f7657611f76612bb0565b60200101906001600160f81b03191690815f1a905350600101611f2a565b5060408051601f80825261040082019092525f9082602082016103e0803683370190505090505f5b82811015612024578381611fd08588612b18565b611fda9190612ac8565b81518110611fea57611fea612bb0565b602001015160f81c60f81b60f81c82828151811061200a5761200a612bb0565b60ff90921660209283029190910190910152600101611fbc565b505f61202f8261256b565b90506101005f516020612dab5f395f51905f525f61204d8689612b18565b90505f5b818110156120ba575f8860016120678486612b18565b6120719190612b18565b8151811061208157612081612bb0565b016020015160f81c9050838061209957612099612b5e565b858709955083806120ac576120ac612b5e565b818708955050600101612051565b50929a9950505050505050505050565b5f5f5f5f5f7f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f5290505f5f516020612dab5f395f51905f52905060405160208152602080820152602060408201528760608201528260808201528160a082015260205f60c08360055afa9450505f519250836121875760405162461bcd60e51b815260206004820152601b60248201527f706f7720707265636f6d70696c652063616c6c206661696c6564210000000000604482015260640161069f565b80600184901b11156121a05761219d8382612b18565b92505b80806121ae576121ae612b5e565b8384099690961496919550909350505050565b6060826121d6576121d1826125d2565b612219565b81511580156121ed57506001600160a01b0384163b155b1561221657604051639996b31560e01b81526001600160a01b038516600482015260240161069f565b50805b9392505050565b604080516030808252606082810190935290602090600160f91b905f90846020820181803683370190505090508086604051602001612260929190612b42565b6040516020818303038152906040529050808460f81b604051602001612287929190612bc4565b6040516020818303038152906040529050806040516020016122a99190612bee565b60408051601f1981840301815290829052915061010160f01b906122d39083908390602001612c06565b60408051808303601f190181528282528051602091820120818401819052600160f81b848401526001600160f01b031985166041850152825160238186030181526043909401909252825190830120919350905f60ff88166001600160401b038111156123425761234261263e565b6040519080825280601f01601f19166020018201604052801561236c576020820181803683370190505b5090505f8260405160200161238391815260200190565b60408051601f1981840301815291905290505f5b81518110156123ed578181815181106123b2576123b2612bb0565b602001015160f81c60f81b8382815181106123cf576123cf612bb0565b60200101906001600160f81b03191690815f1a905350600101612397565b505f8460405160200161240291815260200190565b60408051601f19818403018152602083019091525f80835291985091505b89811015612494575f83828151811061243b5761243b612bb0565b602001015160f81c60f81b83838151811061245857612458612bb0565b602001015160f81c60f81b1890508881604051602001612479929190612c2a565b60408051601f19818403018152919052985050600101612420565b508688876040516020016124aa93929190612c4e565b604051602081830303815290604052965086805190602001209350836040516020016124d891815260200190565b60408051601f1981840301815291905291505f5b6124f98a60ff8d16612b18565b81101561255a5782818151811061251257612512612bb0565b01602001516001600160f81b0319168461252c838d612ac8565b8151811061253c5761253c612bb0565b60200101906001600160f81b03191690815f1a9053506001016124ec565b50919b9a5050505050505050505050565b5f80805b83518110156125cb5783818151811061258a5761258a612bb0565b602002602001015160ff168160086125a29190612c81565b6125ad906002612d7b565b6125b79190612c81565b6125c19083612ac8565b915060010161256f565b5092915050565b8051156125e25780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b80356001600160a01b0381168114612611575f5ffd5b919050565b5f5f60408385031215612627575f5ffd5b612630836125fb565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156126745761267461263e565b60405290565b604051601f8201601f191681016001600160401b03811182821017156126a2576126a261263e565b604052919050565b5f608082840312156126ba575f5ffd5b604051608081016001600160401b03811182821017156126dc576126dc61263e565b6040908152833582526020808501359083015283810135908201526060928301359281019290925250919050565b5f6040828403121561271a575f5ffd5b612722612652565b823581526020928301359281019290925250919050565b803561ffff81168114612611575f5ffd5b5f5f5f5f610120858703121561275e575f5ffd5b61276886866126aa565b9350612777866080870161270a565b92506127868660c0870161270a565b91506127956101008601612739565b905092959194509250565b6001600160401b03811681146111f0575f5ffd5b5f602082840312156127c4575f5ffd5b8135612219816127a0565b5f602082840312156127df575f5ffd5b6119cf826125fb565b5f5f604083850312156127f9575f5ffd5b612802836125fb565b915060208301356001600160401b0381111561281c575f5ffd5b8301601f8101851361282c575f5ffd5b80356001600160401b038111156128455761284561263e565b612858601f8201601f191660200161267a565b81815286602083850101111561286c575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f5f5f610100848603121561289e575f5ffd5b6128a885856126aa565b92506128b7856080860161270a565b91506128c68560c0860161270a565b90509250925092565b5f608082840312156128df575f5ffd5b6119cf83836126aa565b5f5f604083850312156128fa575f5ffd5b612903836125fb565b9150612911602084016125fb565b90509250929050565b5f5f5f5f5f610160868803121561292f575f5ffd5b61293987876126aa565b9450612948876080880161270a565b93506129578760c0880161270a565b925061296787610100880161270a565b91506129766101408701612739565b90509295509295909350565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156129c7575f5ffd5b5035919050565b5f5f5f5f608085870312156129e1575f5ffd5b6129ea856125fb565b93506129f8602086016125fb565b925060408501359150612795606086016125fb565b5f5f5f5f6101408587031215612a21575f5ffd5b612a2b86866126aa565b9350612a3a866080870161270a565b9250612a498660c0870161270a565b915061279586610100870161270a565b634e487b7160e01b5f52602160045260245ffd5b8281526040810160038310612a9057634e487b7160e01b5f52602160045260245ffd5b8260208301529392505050565b5f60208284031215612aad575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156119d2576119d2612ab4565b5f60208284031215612aeb575f5ffd5b8151612219816127a0565b6001600160401b0381811683821602908116908181146125cb576125cb612ab4565b818103818111156119d2576119d2612ab4565b5f81518060208401855e5f93019283525090919050565b5f612b56612b508386612b2b565b84612b2b565b949350505050565b634e487b7160e01b5f52601260045260245ffd5b5f82612b8c57634e487b7160e01b5f52601260045260245ffd5b500690565b5f6119cf8284612b2b565b634e487b7160e01b5f52600160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f612bcf8285612b2b565b5f81526001600160f81b03199390931660018401525050600201919050565b5f612bf98284612b2b565b5f81526001019392505050565b5f612c118285612b2b565b6001600160f01b03199390931683525050600201919050565b5f612c358285612b2b565b6001600160f81b03199390931683525050600101919050565b5f612c598286612b2b565b6001600160f81b031994909416845250506001600160f01b0319166001820152600301919050565b80820281158282048414176119d2576119d2612ab4565b6001815b6001841115612cd357808504811115612cb757612cb7612ab4565b6001841615612cc557908102905b60019390931c928002612c9c565b935093915050565b5f82612ce9575060016119d2565b81612cf557505f6119d2565b8160018114612d0b5760028114612d1557612d31565b60019150506119d2565b60ff841115612d2657612d26612ab4565b50506001821b6119d2565b5060208310610133831016604e8410600b8410161715612d54575081810a6119d2565b612d605f198484612c98565b805f1904821115612d7357612d73612ab4565b029392505050565b5f6119cf8383612cdb56fe424c535f5349475f424e32353447315f584d443a4b454343414b5f4e4354485f4e554c5f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca164736f6c634300081c000a + ///0x60a060405230608052348015610013575f5ffd5b5061001c610031565b610024610031565b61002c610031565b6100e3565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100815760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146100e05780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b608051612e826101095f395f81816114d3015281816114fc015261167f0152612e825ff3fe6080604052600436106101af575f3560e01c80639b30a5e6116100e7578063b5700e6811610087578063c64814dd11610062578063c64814dd14610522578063f2fde38b14610558578063fa52c7d814610577578063fc0c546a146105ba575f5ffd5b8063b5700e68146104b9578063b5ecb344146104d8578063be20309414610503575f5ffd5b8063a3066aab116100c2578063a3066aab14610400578063ac5c2ad01461041f578063ad3cb1cc1461043e578063b3e6ebd51461047b575f5ffd5b80639b30a5e61461037a5780639e9a8f3114610399578063a2d78dd5146103ae575f5ffd5b80634d99dd16116101525780635544c2f11161012d5780635544c2f1146102e85780636a911ccf14610302578063715018a6146103165780638da5cb5b1461032a575f5ffd5b80634d99dd16146102a25780634f1ef286146102c157806352d1902d146102d4575f5ffd5b80631a20cd631161018d5780631a20cd63146102235780632140fecd14610242578063304240bf146102615780633e9df9b514610280575f5ffd5b8063026e402b146101b35780630d8e6e2c146101d457806313b9057a14610204575b5f5ffd5b3480156101be575f5ffd5b506101d26101cd366004612583565b6105d9565b005b3480156101df575f5ffd5b5060408051600281525f60208201819052918101919091526060015b60405180910390f35b34801561020f575f5ffd5b506101d261021e366004612687565b61077c565b34801561022e575f5ffd5b506101d261023d3660046126f1565b610795565b34801561024d575f5ffd5b506101d261025c36600461270c565b6108a9565b34801561026c575f5ffd5b506101d261027b3660046127ae565b6109ca565b34801561028b575f5ffd5b506102945f5481565b6040519081526020016101fb565b3480156102ad575f5ffd5b506101d26102bc366004612583565b610b34565b6101d26102cf36600461282e565b610ce6565b3480156102df575f5ffd5b50610294610d05565b3480156102f3575f5ffd5b506101d261021e366004612878565b34801561030d575f5ffd5b506101d2610d20565b348015610321575f5ffd5b506101d2610dae565b348015610335575f5ffd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03165b6040516001600160a01b0390911681526020016101fb565b348015610385575f5ffd5b506102946103943660046128bc565b610dc1565b3480156103a4575f5ffd5b5061029460085481565b3480156103b9575f5ffd5b506103eb6103c83660046128d6565b600760209081525f92835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101fb565b34801561040b575f5ffd5b506101d261041a36600461270c565b610e1b565b34801561042a575f5ffd5b506101d2610439366004612907565b610f2b565b348015610449575f5ffd5b5061046e604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516101fb91906129a4565b348015610486575f5ffd5b506104a96104953660046129b6565b60046020525f908152604090205460ff1681565b60405190151581526020016101fb565b3480156104c4575f5ffd5b50600154610362906001600160a01b031681565b3480156104e3575f5ffd5b506102946104f236600461270c565b60056020525f908152604090205481565b34801561050e575f5ffd5b506101d261051d3660046129cd565b610ff9565b34801561052d575f5ffd5b5061029461053c3660046128d6565b600660209081525f928352604080842090915290825290205481565b348015610563575f5ffd5b506101d261057236600461270c565b611123565b348015610582575f5ffd5b506105ac61059136600461270c565b60036020525f90815260409020805460019091015460ff1682565b6040516101fb929190612a20565b3480156105c5575f5ffd5b50600254610362906001600160a01b031681565b6105e282611160565b335f82900361060457604051631f2a200560e01b815260040160405180910390fd5b600254604051636eb1769f60e11b81526001600160a01b0383811660048301523060248301525f92169063dd62ed3e90604401602060405180830381865afa158015610652573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106769190612a50565b9050828110156106a85760405163054365bb60e31b815260048101829052602481018490526044015b60405180910390fd5b6002546106c0906001600160a01b03168330866111e1565b6001600160a01b0384165f90815260036020526040812080548592906106e7908490612a7b565b90915550506001600160a01b038085165f90815260066020908152604080832093861683529290529081208054859290610722908490612a7b565b92505081905550836001600160a01b0316826001600160a01b03167fe5541a6b6103d4fa7e021ed54fad39c66f27a76bd13d374cf6240ae6bd0bb72b8560405161076e91815260200190565b60405180910390a350505050565b60405163c2d7f81360e01b815260040160405180910390fd5b61079d611285565b60015460408051633c1a081560e21b815290515f926001600160a01b03169163f06820549160048083019260209291908290030181865afa1580156107e4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108089190612a8e565b61081390600f612aa9565b9050621275006001600160401b0380831690841610806108445750806001600160401b0316836001600160401b0316115b156108625760405163b57e21df60e01b815260040160405180910390fd5b6001600160401b03831660088190556040519081527f793e3b1e1bcd677bb11900c83124d3c44c9946ea8ddf978a0ca250b034ec9dde9060200160405180910390a1505050565b6001600160a01b0381165f9081526005602052604081205433918190036108e3576040516379298a5360e11b815260040160405180910390fd5b8042101561090457604051635a77435760e01b815260040160405180910390fd5b6001600160a01b038084165f9081526006602090815260408083209386168352929052908120549081900361094c57604051630686827b60e51b815260040160405180910390fd5b6001600160a01b038085165f9081526006602090815260408083208785168452909152812055600254610981911684836112e0565b826001600160a01b03167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040516109bc91815260200190565b60405180910390a250505050565b336109d48161136f565b6109dd856113bc565b6109e6866113f7565b604080516001600160a01b03831660208201525f91016040516020818303038152906040529050610a18818689611433565b6127108361ffff161115610a3f5760405163dc81db8560e01b815260040160405180910390fd5b600160045f610a4d8a610dc1565b81526020019081526020015f205f6101000a81548160ff02191690831515021790555060405180604001604052805f815260200160016002811115610a9457610a94612a0c565b90526001600160a01b0383165f908152600360209081526040909120825181559082015160018083018054909160ff1990911690836002811115610ada57610ada612a0c565b0217905550905050816001600160a01b03167ff057d4ea81e98628653a8f90788541972078137334a92b42347eaccda80fc40a8888868989604051610b23959493929190612acb565b60405180910390a250505050505050565b610b3d82611160565b335f829003610b5f57604051631f2a200560e01b815260040160405180910390fd5b6001600160a01b038084165f9081526007602090815260408083209385168352929052205415610ba25760405163d423a4f160e01b815260040160405180910390fd5b6001600160a01b038084165f9081526006602090815260408083209385168352929052205482811015610beb57604051639266535160e01b81526004810182905260240161069f565b6001600160a01b038085165f90815260066020908152604080832093861683529290529081208054859290610c21908490612b3d565b92505081905550604051806040016040528084815260200160085442610c479190612a7b565b90526001600160a01b038086165f81815260076020908152604080832094881683529381528382208551815594810151600190950194909455908152600390925281208054859290610c9a908490612b3d565b92505081905550836001600160a01b0316826001600160a01b03167f4d10bd049775c77bd7f255195afba5088028ecb3c7c277d393ccff7934f2f92c8560405161076e91815260200190565b610cee6114c8565b610cf78261156c565b610d0182826115b3565b5050565b5f610d0e611674565b505f516020612e565f395f51905f5290565b33610d2a81611160565b6001600160a01b0381165f908152600360205260409020600101805460ff19166002179055600854610d5c9042612a7b565b6001600160a01b0382165f8181526005602090815260408083209490945560039052828120819055915190917ffb24305354c87762d557487ae4a564e8d03ecbb9a97dd8afff8e1f6fcaf0dd1691a250565b610db6611285565b610dbf5f6116bd565b565b5f815f0151826020015183604001518460600151604051602001610dfe949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b6001600160a01b0381165f9081526007602090815260408083203380855292528220549091819003610e6057604051630686827b60e51b815260040160405180910390fd5b6001600160a01b038084165f90815260076020908152604080832093861683529290522060010154421015610ea857604051635a77435760e01b815260040160405180910390fd5b6001600160a01b038084165f9081526007602090815260408083208685168452909152812081815560010155600254610ee3911683836112e0565b816001600160a01b03167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6582604051610f1e91815260200190565b60405180910390a2505050565b33610f3581611160565b610f3e846113bc565b610f47856113f7565b604080516001600160a01b03831660208201525f91016040516020818303038152906040529050610f79818588611433565b600160045f610f8789610dc1565b81526020019081526020015f205f6101000a81548160ff021916908315150217905550816001600160a01b03167fc8c5b37aec7f2ddbd3a13c51361e54a0a8df3bca256ab758a77f5ad741d281e587878787604051610fe99493929190612b50565b60405180910390a2505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f8115801561103d5750825b90505f826001600160401b031660011480156110585750303b155b905081158015611066575080155b156110845760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156110ae57845460ff60401b1916600160401b1785555b6110b78661172d565b6110bf61173e565b6110c7611746565b6110d289898961184a565b831561111857845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b61112b611285565b6001600160a01b03811661115457604051631e4fbdf760e01b81525f600482015260240161069f565b61115d816116bd565b50565b6001600160a01b0381165f9081526003602052604081206001015460ff169081600281111561119157611191612a0c565b036111af5760405163508a793f60e01b815260040160405180910390fd5b60028160028111156111c3576111c3612a0c565b03610d015760405163eab4a96360e01b815260040160405180910390fd5b5f6040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260205f6064835f8a5af191505080601f3d1160015f51141615161561123a5750833b153d17155b8061127e5760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b604482015260640161069f565b5050505050565b336112b77f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b031614610dbf5760405163118cdaa760e01b815233600482015260240161069f565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af191505080601f3d1160015f51141615161561132a5750823b153d17155b806113695760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015260640161069f565b50505050565b6001600160a01b0381165f9081526003602052604081206001015460ff16600281111561139e5761139e612a0c565b1461115d5760405163132e7efb60e31b815260040160405180910390fd5b604080518082019091525f80825260208201526113d982826118cd565b15610d01576040516306cf438f60e01b815260040160405180910390fd5b60045f61140383610dc1565b815260208101919091526040015f205460ff161561115d5760405162da8a5760e11b815260040160405180910390fd5b61143c826118f0565b5f604051806060016040528060248152602001612e126024913990505f848260405160200161146c929190612bcd565b60405160208183030381529060405290505f61148782611986565b90506114a4818561149788611a73565b61149f611aea565b611bb7565b6114c05760405162ced3e560e41b815260040160405180910390fd5b505050505050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061154e57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166115425f516020612e565f395f51905f52546001600160a01b031690565b6001600160a01b031614155b15610dbf5760405163703e46dd60e11b815260040160405180910390fd5b611574611285565b6040516001600160a01b03821681527ff78721226efe9a1bb678189a16d1554928b9f2192e2cb93eeda83b79fa40007d9060200160405180910390a150565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561160d575060408051601f3d908101601f1916820190925261160a91810190612a50565b60015b61163557604051634c9c8ce360e01b81526001600160a01b038316600482015260240161069f565b5f516020612e565f395f51905f52811461166557604051632a87526960e21b81526004810182905260240161069f565b61166f8383611c95565b505050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610dbf5760405163703e46dd60e11b815260040160405180910390fd5b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b611735611cea565b61115d81611d33565b610dbf611cea565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f8115801561178a5750825b90505f826001600160401b031660011480156117a55750303b155b9050811580156117b3575080155b156117d15760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156117fb57845460ff60401b1916600160401b1785555b435f55831561127e57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050565b6001600160a01b0383166118715760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0382166118985760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b039485166001600160a01b0319918216179091556001805493909416921691909117909155600855565b805182515f911480156118e7575081602001518360200151145b90505b92915050565b805160208201515f915f516020612e365f395f51905f5291159015161561191657505050565b82516020840151826003848585860985090883828309148382108484101616935050508161166f5760405162461bcd60e51b815260206004820152601760248201527f426e3235343a20696e76616c696420473120706f696e74000000000000000000604482015260640161069f565b604080518082019091525f80825260208201525f6119a383611d3b565b90505f516020612e365f395f51905f5260035f82848509905082806119ca576119ca612be9565b848209905082806119dd576119dd612be9565b82820890505f5f6119ed83611f43565b925090505b80611a56578480611a0557611a05612be9565b6001870895508480611a1957611a19612be9565b86870992508480611a2c57611a2c612be9565b86840992508480611a3f57611a3f612be9565b8484089250611a4d83611f43565b925090506119f2565b506040805180820190915294855260208501525091949350505050565b604080518082019091525f8082526020820152815160208301511590151615611a9a575090565b6040518060400160405280835f015181526020015f516020612e365f395f51905f528460200151611acb9190612bfd565b611ae2905f516020612e365f395f51905f52612b3d565b905292915050565b611b1160405180608001604052805f81526020015f81526020015f81526020015f81525090565b60405180608001604052807f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed81526020017f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa81526020017f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b815250905090565b5f5f5f6040518751815260208801516020820152602087015160408201528651606082015260608701516080820152604087015160a0820152855160c0820152602086015160e0820152602085015161010082015284516101208201526060850151610140820152604085015161016082015260205f6101808360085afa9150505f51915080611c895760405162461bcd60e51b815260206004820152601c60248201527f426e3235343a2050616972696e6720636865636b206661696c65642100000000604482015260640161069f565b50151595945050505050565b611c9e8261203a565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115611ce25761166f828261209d565b610d0161210f565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16610dbf57604051631afcd79f60e31b815260040160405180910390fd5b61112b611cea565b5f5f611d468361212e565b805190915060308114611d5b57611d5b612c1c565b5f816001600160401b03811115611d7457611d746125ab565b6040519080825280601f01601f191660200182016040528015611d9e576020820181803683370190505b5090505f5b82811015611e0d57836001611db88386612b3d565b611dc29190612b3d565b81518110611dd257611dd2612c30565b602001015160f81c60f81b828281518110611def57611def612c30565b60200101906001600160f81b03191690815f1a905350600101611da3565b5060408051601f80825261040082019092525f9082602082016103e0803683370190505090505f5b82811015611e9d578381611e498588612b3d565b611e539190612a7b565b81518110611e6357611e63612c30565b602001015160f81c60f81b60f81c828281518110611e8357611e83612c30565b60ff90921660209283029190910190910152600101611e35565b505f611ea882612479565b90506101005f516020612e365f395f51905f525f611ec68689612b3d565b90505f5b81811015611f33575f886001611ee08486612b3d565b611eea9190612b3d565b81518110611efa57611efa612c30565b016020015160f81c90508380611f1257611f12612be9565b85870995508380611f2557611f25612be9565b818708955050600101611eca565b50929a9950505050505050505050565b5f5f5f5f5f7f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f5290505f5f516020612e365f395f51905f52905060405160208152602080820152602060408201528760608201528260808201528160a082015260205f60c08360055afa9450505f519250836120005760405162461bcd60e51b815260206004820152601b60248201527f706f7720707265636f6d70696c652063616c6c206661696c6564210000000000604482015260640161069f565b80600184901b1115612019576120168382612b3d565b92505b808061202757612027612be9565b8384099690961496919550909350505050565b806001600160a01b03163b5f0361206f57604051634c9c8ce360e01b81526001600160a01b038216600482015260240161069f565b5f516020612e565f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b0316846040516120b99190612c44565b5f60405180830381855af49150503d805f81146120f1576040519150601f19603f3d011682016040523d82523d5f602084013e6120f6565b606091505b50915091506121068583836124e0565b95945050505050565b3415610dbf5760405163b398979f60e01b815260040160405180910390fd5b604080516030808252606082810190935290602090600160f91b905f9084602082018180368337019050509050808660405160200161216e929190612bcd565b6040516020818303038152906040529050808460f81b604051602001612195929190612c4f565b6040516020818303038152906040529050806040516020016121b79190612c79565b60408051601f1981840301815290829052915061010160f01b906121e19083908390602001612c91565b60408051808303601f190181528282528051602091820120818401819052600160f81b848401526001600160f01b031985166041850152825160238186030181526043909401909252825190830120919350905f60ff88166001600160401b03811115612250576122506125ab565b6040519080825280601f01601f19166020018201604052801561227a576020820181803683370190505b5090505f8260405160200161229191815260200190565b60408051601f1981840301815291905290505f5b81518110156122fb578181815181106122c0576122c0612c30565b602001015160f81c60f81b8382815181106122dd576122dd612c30565b60200101906001600160f81b03191690815f1a9053506001016122a5565b505f8460405160200161231091815260200190565b60408051601f19818403018152602083019091525f80835291985091505b898110156123a2575f83828151811061234957612349612c30565b602001015160f81c60f81b83838151811061236657612366612c30565b602001015160f81c60f81b1890508881604051602001612387929190612cb5565b60408051601f1981840301815291905298505060010161232e565b508688876040516020016123b893929190612cd9565b604051602081830303815290604052965086805190602001209350836040516020016123e691815260200190565b60408051601f1981840301815291905291505f5b6124078a60ff8d16612b3d565b8110156124685782818151811061242057612420612c30565b01602001516001600160f81b0319168461243a838d612a7b565b8151811061244a5761244a612c30565b60200101906001600160f81b03191690815f1a9053506001016123fa565b50919b9a5050505050505050505050565b5f80805b83518110156124d95783818151811061249857612498612c30565b602002602001015160ff168160086124b09190612d0c565b6124bb906002612e06565b6124c59190612d0c565b6124cf9083612a7b565b915060010161247d565b5092915050565b6060826124f5576124f08261253f565b612538565b815115801561250c57506001600160a01b0384163b155b1561253557604051639996b31560e01b81526001600160a01b038516600482015260240161069f565b50805b9392505050565b80511561254f5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b80356001600160a01b038116811461257e575f5ffd5b919050565b5f5f60408385031215612594575f5ffd5b61259d83612568565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156125e1576125e16125ab565b60405290565b5f608082840312156125f7575f5ffd5b604051608081016001600160401b0381118282101715612619576126196125ab565b6040908152833582526020808501359083015283810135908201526060928301359281019290925250919050565b5f60408284031215612657575f5ffd5b61265f6125bf565b823581526020928301359281019290925250919050565b803561ffff8116811461257e575f5ffd5b5f5f5f5f610120858703121561269b575f5ffd5b6126a586866125e7565b93506126b48660808701612647565b92506126c38660c08701612647565b91506126d26101008601612676565b905092959194509250565b6001600160401b038116811461115d575f5ffd5b5f60208284031215612701575f5ffd5b8135612538816126dd565b5f6020828403121561271c575f5ffd5b6118e782612568565b5f82601f830112612734575f5ffd5b81356001600160401b0381111561274d5761274d6125ab565b604051601f8201601f19908116603f011681016001600160401b038111828210171561277b5761277b6125ab565b604052818152838201602001851015612792575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f5f5f5f61014086880312156127c3575f5ffd5b6127cd87876125e7565b94506127dc8760808801612647565b93506127eb8760c08801612647565b92506101008601356001600160401b03811115612806575f5ffd5b61281288828901612725565b9250506128226101208701612676565b90509295509295909350565b5f5f6040838503121561283f575f5ffd5b61284883612568565b915060208301356001600160401b03811115612862575f5ffd5b61286e85828601612725565b9150509250929050565b5f5f5f610100848603121561288b575f5ffd5b61289585856125e7565b92506128a48560808601612647565b91506128b38560c08601612647565b90509250925092565b5f608082840312156128cc575f5ffd5b6118e783836125e7565b5f5f604083850312156128e7575f5ffd5b6128f083612568565b91506128fe60208401612568565b90509250929050565b5f5f5f5f610120858703121561291b575f5ffd5b61292586866125e7565b93506129348660808701612647565b92506129438660c08701612647565b91506101008501356001600160401b0381111561295e575f5ffd5b61296a87828801612725565b91505092959194509250565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6118e76020830184612976565b5f602082840312156129c6575f5ffd5b5035919050565b5f5f5f5f608085870312156129e0575f5ffd5b6129e985612568565b93506129f760208601612568565b9250604085013591506126d260608601612568565b634e487b7160e01b5f52602160045260245ffd5b8281526040810160038310612a4357634e487b7160e01b5f52602160045260245ffd5b8260208301529392505050565b5f60208284031215612a60575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156118ea576118ea612a67565b5f60208284031215612a9e575f5ffd5b8151612538816126dd565b6001600160401b0381811683821602908116908181146124d9576124d9612a67565b8551815260208087015190820152604080870151908201526060808701519082015284516080820152602085015160a082015261ffff841660c0820152825160e082015260208301516101008201526101406101208201525f612b32610140830184612976565b979650505050505050565b818103818111156118ea576118ea612a67565b8451815260208086015190820152604080860151908201526060808601519082015283516080820152602084015160a0820152825160c0820152602083015160e08201526101206101008201525f612bac610120830184612976565b9695505050505050565b5f81518060208401855e5f93019283525090919050565b5f612be1612bdb8386612bb6565b84612bb6565b949350505050565b634e487b7160e01b5f52601260045260245ffd5b5f82612c1757634e487b7160e01b5f52601260045260245ffd5b500690565b634e487b7160e01b5f52600160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f6118e78284612bb6565b5f612c5a8285612bb6565b5f81526001600160f81b03199390931660018401525050600201919050565b5f612c848284612bb6565b5f81526001019392505050565b5f612c9c8285612bb6565b6001600160f01b03199390931683525050600201919050565b5f612cc08285612bb6565b6001600160f81b03199390931683525050600101919050565b5f612ce48286612bb6565b6001600160f81b031994909416845250506001600160f01b0319166001820152600301919050565b80820281158282048414176118ea576118ea612a67565b6001815b6001841115612d5e57808504811115612d4257612d42612a67565b6001841615612d5057908102905b60019390931c928002612d27565b935093915050565b5f82612d74575060016118ea565b81612d8057505f6118ea565b8160018114612d965760028114612da057612dbc565b60019150506118ea565b60ff841115612db157612db1612a67565b50506001821b6118ea565b5060208310610133831016604e8410600b8410161715612ddf575081810a6118ea565b612deb5f198484612d23565b805f1904821115612dfe57612dfe612a67565b029392505050565b5f6118e78383612d6656fe424c535f5349475f424e32353447315f584d443a4b454343414b5f4e4354485f4e554c5f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca164736f6c634300081c000a /// ``` #[rustfmt::skip] #[allow(clippy::all)] pub static BYTECODE: alloy_sol_types::private::Bytes = alloy_sol_types::private::Bytes::from_static( - b"`\xA0`@R0`\x80R4\x80\x15a\0\x13W__\xFD[Pa\0\x1Ca\x001V[a\0$a\x001V[a\0,a\x001V[a\0\xE3V[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0\x80Th\x01\0\0\0\0\0\0\0\0\x90\x04`\xFF\x16\x15a\0\x81W`@Qc\xF9.\xE8\xA9`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x80T`\x01`\x01`@\x1B\x03\x90\x81\x16\x14a\0\xE0W\x80T`\x01`\x01`@\x1B\x03\x19\x16`\x01`\x01`@\x1B\x03\x90\x81\x17\x82U`@Q\x90\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1[PV[`\x80Qa-\xF7a\x01\t_9_\x81\x81a\x14\r\x01R\x81\x81a\x146\x01Ra\x15\xB9\x01Ra-\xF7_\xF3\xFE`\x80`@R`\x046\x10a\x01\xAFW_5`\xE0\x1C\x80c\x9E\x9A\x8F1\x11a\0\xE7W\x80c\xB5\xEC\xB3D\x11a\0\x87W\x80c\xE5;*t\x11a\0bW\x80c\xE5;*t\x14a\x059W\x80c\xF2\xFD\xE3\x8B\x14a\x05XW\x80c\xFAR\xC7\xD8\x14a\x05wW\x80c\xFC\x0CTj\x14a\x05\xBAW__\xFD[\x80c\xB5\xEC\xB3D\x14a\x04\xB9W\x80c\xBE 0\x94\x14a\x04\xE4W\x80c\xC6H\x14\xDD\x14a\x05\x03W__\xFD[\x80c\xA5\x85\x7F\xF3\x11a\0\xC2W\x80c\xA5\x85\x7F\xF3\x14a\x04\0W\x80c\xAD<\xB1\xCC\x14a\x04\x1FW\x80c\xB3\xE6\xEB\xD5\x14a\x04\\W\x80c\xB5p\x0Eh\x14a\x04\x9AW__\xFD[\x80c\x9E\x9A\x8F1\x14a\x03zW\x80c\xA2\xD7\x8D\xD5\x14a\x03\x8FW\x80c\xA3\x06j\xAB\x14a\x03\xE1W__\xFD[\x80cO\x1E\xF2\x86\x11a\x01RW\x80cj\x91\x1C\xCF\x11a\x01-W\x80cj\x91\x1C\xCF\x14a\x02\xE3W\x80cqP\x18\xA6\x14a\x02\xF7W\x80c\x8D\xA5\xCB[\x14a\x03\x0BW\x80c\x9B0\xA5\xE6\x14a\x03[W__\xFD[\x80cO\x1E\xF2\x86\x14a\x02\xA2W\x80cR\xD1\x90-\x14a\x02\xB5W\x80cUD\xC2\xF1\x14a\x02\xC9W__\xFD[\x80c\x1A \xCDc\x11a\x01\x8DW\x80c\x1A \xCDc\x14a\x02#W\x80c!@\xFE\xCD\x14a\x02BW\x80c>\x9D\xF9\xB5\x14a\x02aW\x80cM\x99\xDD\x16\x14a\x02\x83W__\xFD[\x80c\x02n@+\x14a\x01\xB3W\x80c\r\x8En,\x14a\x01\xD4W\x80c\x13\xB9\x05z\x14a\x02\x04W[__\xFD[4\x80\x15a\x01\xBEW__\xFD[Pa\x01\xD2a\x01\xCD6`\x04a&\x16V[a\x05\xD9V[\0[4\x80\x15a\x01\xDFW__\xFD[P`@\x80Q`\x02\x81R_` \x82\x01\x81\x90R\x91\x81\x01\x91\x90\x91R``\x01[`@Q\x80\x91\x03\x90\xF3[4\x80\x15a\x02\x0FW__\xFD[Pa\x01\xD2a\x02\x1E6`\x04a'JV[a\x07|V[4\x80\x15a\x02.W__\xFD[Pa\x01\xD2a\x02=6`\x04a'\xB4V[a\x07\x95V[4\x80\x15a\x02MW__\xFD[Pa\x01\xD2a\x02\\6`\x04a'\xCFV[a\x08\xA9V[4\x80\x15a\x02lW__\xFD[Pa\x02u_T\x81V[`@Q\x90\x81R` \x01a\x01\xFBV[4\x80\x15a\x02\x8EW__\xFD[Pa\x01\xD2a\x02\x9D6`\x04a&\x16V[a\t\xCAV[a\x01\xD2a\x02\xB06`\x04a'\xE8V[a\x0B|V[4\x80\x15a\x02\xC0W__\xFD[Pa\x02ua\x0B\x9BV[4\x80\x15a\x02\xD4W__\xFD[Pa\x01\xD2a\x02\x1E6`\x04a(\x8BV[4\x80\x15a\x02\xEEW__\xFD[Pa\x01\xD2a\x0B\xB6V[4\x80\x15a\x03\x02W__\xFD[Pa\x01\xD2a\x0CDV[4\x80\x15a\x03\x16W__\xFD[P\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0T`\x01`\x01`\xA0\x1B\x03\x16[`@Q`\x01`\x01`\xA0\x1B\x03\x90\x91\x16\x81R` \x01a\x01\xFBV[4\x80\x15a\x03fW__\xFD[Pa\x02ua\x03u6`\x04a(\xCFV[a\x0CWV[4\x80\x15a\x03\x85W__\xFD[Pa\x02u`\x08T\x81V[4\x80\x15a\x03\x9AW__\xFD[Pa\x03\xCCa\x03\xA96`\x04a(\xE9V[`\x07` \x90\x81R_\x92\x83R`@\x80\x84 \x90\x91R\x90\x82R\x90 \x80T`\x01\x90\x91\x01T\x82V[`@\x80Q\x92\x83R` \x83\x01\x91\x90\x91R\x01a\x01\xFBV[4\x80\x15a\x03\xECW__\xFD[Pa\x01\xD2a\x03\xFB6`\x04a'\xCFV[a\x0C\xB1V[4\x80\x15a\x04\x0BW__\xFD[Pa\x01\xD2a\x04\x1A6`\x04a)\x1AV[a\r\xC1V[4\x80\x15a\x04*W__\xFD[Pa\x04O`@Q\x80`@\x01`@R\x80`\x05\x81R` \x01d\x03R\xE3\x02\xE3`\xDC\x1B\x81RP\x81V[`@Qa\x01\xFB\x91\x90a)\x82V[4\x80\x15a\x04gW__\xFD[Pa\x04\x8Aa\x04v6`\x04a)\xB7V[`\x04` R_\x90\x81R`@\x90 T`\xFF\x16\x81V[`@Q\x90\x15\x15\x81R` \x01a\x01\xFBV[4\x80\x15a\x04\xA5W__\xFD[P`\x01Ta\x03C\x90`\x01`\x01`\xA0\x1B\x03\x16\x81V[4\x80\x15a\x04\xC4W__\xFD[Pa\x02ua\x04\xD36`\x04a'\xCFV[`\x05` R_\x90\x81R`@\x90 T\x81V[4\x80\x15a\x04\xEFW__\xFD[Pa\x01\xD2a\x04\xFE6`\x04a)\xCEV[a\x0FyV[4\x80\x15a\x05\x0EW__\xFD[Pa\x02ua\x05\x1D6`\x04a(\xE9V[`\x06` \x90\x81R_\x92\x83R`@\x80\x84 \x90\x91R\x90\x82R\x90 T\x81V[4\x80\x15a\x05DW__\xFD[Pa\x01\xD2a\x05S6`\x04a*\rV[a\x10\xA3V[4\x80\x15a\x05cW__\xFD[Pa\x01\xD2a\x05r6`\x04a'\xCFV[a\x11\xB6V[4\x80\x15a\x05\x82W__\xFD[Pa\x05\xACa\x05\x916`\x04a'\xCFV[`\x03` R_\x90\x81R`@\x90 \x80T`\x01\x90\x91\x01T`\xFF\x16\x82V[`@Qa\x01\xFB\x92\x91\x90a*mV[4\x80\x15a\x05\xC5W__\xFD[P`\x02Ta\x03C\x90`\x01`\x01`\xA0\x1B\x03\x16\x81V[a\x05\xE2\x82a\x11\xF3V[3_\x82\x90\x03a\x06\x04W`@Qc\x1F* \x05`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02T`@Qcn\xB1v\x9F`\xE1\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x83\x81\x16`\x04\x83\x01R0`$\x83\x01R_\x92\x16\x90c\xDDb\xED>\x90`D\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x06RW=__>=_\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x06v\x91\x90a*\x9DV[\x90P\x82\x81\x10\x15a\x06\xA8W`@Qc\x05Ce\xBB`\xE3\x1B\x81R`\x04\x81\x01\x82\x90R`$\x81\x01\x84\x90R`D\x01[`@Q\x80\x91\x03\x90\xFD[`\x02Ta\x06\xC0\x90`\x01`\x01`\xA0\x1B\x03\x16\x830\x86a\x12tV[`\x01`\x01`\xA0\x1B\x03\x84\x16_\x90\x81R`\x03` R`@\x81 \x80T\x85\x92\x90a\x06\xE7\x90\x84\x90a*\xC8V[\x90\x91UPP`\x01`\x01`\xA0\x1B\x03\x80\x85\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R\x90\x81 \x80T\x85\x92\x90a\x07\"\x90\x84\x90a*\xC8V[\x92PP\x81\x90UP\x83`\x01`\x01`\xA0\x1B\x03\x16\x82`\x01`\x01`\xA0\x1B\x03\x16\x7F\xE5T\x1Aka\x03\xD4\xFA~\x02\x1E\xD5O\xAD9\xC6o'\xA7k\xD1=7L\xF6$\n\xE6\xBD\x0B\xB7+\x85`@Qa\x07n\x91\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA3PPPPV[`@Qc\xC2\xD7\xF8\x13`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x07\x9Da\x13\x18V[`\x01T`@\x80Qc<\x1A\x08\x15`\xE2\x1B\x81R\x90Q_\x92`\x01`\x01`\xA0\x1B\x03\x16\x91c\xF0h T\x91`\x04\x80\x83\x01\x92` \x92\x91\x90\x82\x90\x03\x01\x81\x86Z\xFA\x15\x80\x15a\x07\xE4W=__>=_\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x08\x08\x91\x90a*\xDBV[a\x08\x13\x90`\x0Fa*\xF6V[\x90Pb\x12u\0`\x01`\x01`@\x1B\x03\x80\x83\x16\x90\x84\x16\x10\x80a\x08DWP\x80`\x01`\x01`@\x1B\x03\x16\x83`\x01`\x01`@\x1B\x03\x16\x11[\x15a\x08bW`@Qc\xB5~!\xDF`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`@\x1B\x03\x83\x16`\x08\x81\x90U`@Q\x90\x81R\x7Fy>;\x1E\x1B\xCDg{\xB1\x19\0\xC81$\xD3\xC4L\x99F\xEA\x8D\xDF\x97\x8A\x0C\xA2P\xB04\xEC\x9D\xDE\x90` \x01`@Q\x80\x91\x03\x90\xA1PPPV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x05` R`@\x81 T3\x91\x81\x90\x03a\x08\xE3W`@Qcy)\x8AS`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x80B\x10\x15a\t\x04W`@QcZwCW`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R\x90\x81 T\x90\x81\x90\x03a\tLW`@Qc\x06\x86\x82{`\xE5\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x85\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x87\x85\x16\x84R\x90\x91R\x81 U`\x02Ta\t\x81\x91\x16\x84\x83a\x13sV[\x82`\x01`\x01`\xA0\x1B\x03\x16\x7F\x7F\xCFS,\x15\xF0\xA6\xDB\x0B\xD6\xD0\xE08\xBE\xA7\x1D0\xD8\x08\xC7\xD9\x8C\xB3\xBFrh\xA9[\xF5\x08\x1Be\x82`@Qa\t\xBC\x91\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA2PPPPV[a\t\xD3\x82a\x11\xF3V[3_\x82\x90\x03a\t\xF5W`@Qc\x1F* \x05`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 \x93\x85\x16\x83R\x92\x90R T\x15a\n8W`@Qc\xD4#\xA4\xF1`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x85\x16\x83R\x92\x90R T\x82\x81\x10\x15a\n\x81W`@Qc\x92fSQ`\xE0\x1B\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\x9FV[`\x01`\x01`\xA0\x1B\x03\x80\x85\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R\x90\x81 \x80T\x85\x92\x90a\n\xB7\x90\x84\x90a+\x18V[\x92PP\x81\x90UP`@Q\x80`@\x01`@R\x80\x84\x81R` \x01`\x08TBa\n\xDD\x91\x90a*\xC8V[\x90R`\x01`\x01`\xA0\x1B\x03\x80\x86\x16_\x81\x81R`\x07` \x90\x81R`@\x80\x83 \x94\x88\x16\x83R\x93\x81R\x83\x82 \x85Q\x81U\x94\x81\x01Q`\x01\x90\x95\x01\x94\x90\x94U\x90\x81R`\x03\x90\x92R\x81 \x80T\x85\x92\x90a\x0B0\x90\x84\x90a+\x18V[\x92PP\x81\x90UP\x83`\x01`\x01`\xA0\x1B\x03\x16\x82`\x01`\x01`\xA0\x1B\x03\x16\x7FM\x10\xBD\x04\x97u\xC7{\xD7\xF2U\x19Z\xFB\xA5\x08\x80(\xEC\xB3\xC7\xC2w\xD3\x93\xCC\xFFy4\xF2\xF9,\x85`@Qa\x07n\x91\x81R` \x01\x90V[a\x0B\x84a\x14\x02V[a\x0B\x8D\x82a\x14\xA6V[a\x0B\x97\x82\x82a\x14\xEDV[PPV[_a\x0B\xA4a\x15\xAEV[P_Q` a-\xCB_9_Q\x90_R\x90V[3a\x0B\xC0\x81a\x11\xF3V[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x03` R`@\x90 `\x01\x01\x80T`\xFF\x19\x16`\x02\x17\x90U`\x08Ta\x0B\xF2\x90Ba*\xC8V[`\x01`\x01`\xA0\x1B\x03\x82\x16_\x81\x81R`\x05` \x90\x81R`@\x80\x83 \x94\x90\x94U`\x03\x90R\x82\x81 \x81\x90U\x91Q\x90\x91\x7F\xFB$0ST\xC8wb\xD5WHz\xE4\xA5d\xE8\xD0>\xCB\xB9\xA9}\xD8\xAF\xFF\x8E\x1Fo\xCA\xF0\xDD\x16\x91\xA2PV[a\x0CLa\x13\x18V[a\x0CU_a\x15\xF7V[V[_\x81_\x01Q\x82` \x01Q\x83`@\x01Q\x84``\x01Q`@Q` \x01a\x0C\x94\x94\x93\x92\x91\x90\x93\x84R` \x84\x01\x92\x90\x92R`@\x83\x01R``\x82\x01R`\x80\x01\x90V[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x80Q\x90` \x01 \x90P\x91\x90PV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 3\x80\x85R\x92R\x82 T\x90\x91\x81\x90\x03a\x0C\xF6W`@Qc\x06\x86\x82{`\xE5\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R `\x01\x01TB\x10\x15a\r>W`@QcZwCW`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 \x86\x85\x16\x84R\x90\x91R\x81 \x81\x81U`\x01\x01U`\x02Ta\ry\x91\x16\x83\x83a\x13sV[\x81`\x01`\x01`\xA0\x1B\x03\x16\x7F\x7F\xCFS,\x15\xF0\xA6\xDB\x0B\xD6\xD0\xE08\xBE\xA7\x1D0\xD8\x08\xC7\xD9\x8C\xB3\xBFrh\xA9[\xF5\x08\x1Be\x82`@Qa\r\xB4\x91\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA2PPPV[3a\r\xCB\x81a\x16gV[a\r\xD4\x85a\x16\xB4V[a\r\xDD\x86a\x16\xEFV[`@\x80Q`\x01`\x01`\xA0\x1B\x03\x83\x16` \x82\x01R_\x91\x01`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90Pa\x0E\x0F\x81\x86\x89a\x17+V[a'\x10\x83a\xFF\xFF\x16\x11\x15a\x0E6W`@Qc\xDC\x81\xDB\x85`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x04_a\x0ED\x8Aa\x0CWV[\x81R` \x01\x90\x81R` \x01_ _a\x01\0\n\x81T\x81`\xFF\x02\x19\x16\x90\x83\x15\x15\x02\x17\x90UP`@Q\x80`@\x01`@R\x80_\x81R` \x01`\x01`\x02\x81\x11\x15a\x0E\x8BWa\x0E\x8Ba*YV[\x90R`\x01`\x01`\xA0\x1B\x03\x83\x16_\x90\x81R`\x03` \x90\x81R`@\x90\x91 \x82Q\x81U\x90\x82\x01Q`\x01\x80\x83\x01\x80T\x90\x91`\xFF\x19\x90\x91\x16\x90\x83`\x02\x81\x11\x15a\x0E\xD1Wa\x0E\xD1a*YV[\x02\x17\x90UPP`@\x80Q\x89Q\x81R` \x80\x8B\x01Q\x81\x83\x01R\x8A\x83\x01Q\x82\x84\x01R``\x80\x8C\x01Q\x90\x83\x01R\x89Q`\x80\x83\x01R\x89\x81\x01Q`\xA0\x83\x01Ra\xFF\xFF\x87\x16`\xC0\x83\x01R\x88Q`\xE0\x83\x01R\x88\x81\x01Qa\x01\0\x83\x01R\x87Qa\x01 \x83\x01R\x87\x01Qa\x01@\x82\x01R\x90Q`\x01`\x01`\xA0\x1B\x03\x85\x16\x92P\x7F\x8E\x1C9M\x8F<\x83\xD8\xE2M y\x0B\xD0Xo\xE7\x13T\x81\n\x93\xC2\xEE6\x8BA\x87EU;.\x91\x81\x90\x03a\x01`\x01\x90\xA2PPPPPPPV[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0\x80T`\x01`@\x1B\x81\x04`\xFF\x16\x15\x90`\x01`\x01`@\x1B\x03\x16_\x81\x15\x80\x15a\x0F\xBDWP\x82[\x90P_\x82`\x01`\x01`@\x1B\x03\x16`\x01\x14\x80\x15a\x0F\xD8WP0;\x15[\x90P\x81\x15\x80\x15a\x0F\xE6WP\x80\x15[\x15a\x10\x04W`@Qc\xF9.\xE8\xA9`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x84Tg\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16`\x01\x17\x85U\x83\x15a\x10.W\x84T`\xFF`@\x1B\x19\x16`\x01`@\x1B\x17\x85U[a\x107\x86a\x17\xC0V[a\x10?a\x17\xD1V[a\x10Ga\x17\xD9V[a\x10R\x89\x89\x89a\x18\xDDV[\x83\x15a\x10\x98W\x84T`\xFF`@\x1B\x19\x16\x85U`@Q`\x01\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1[PPPPPPPPPV[3a\x10\xAD\x81a\x11\xF3V[a\x10\xB6\x84a\x16\xB4V[a\x10\xBF\x85a\x16\xEFV[`@\x80Q`\x01`\x01`\xA0\x1B\x03\x83\x16` \x82\x01R_\x91\x01`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90Pa\x10\xF1\x81\x85\x88a\x17+V[`\x01`\x04_a\x10\xFF\x89a\x0CWV[\x81R` \x80\x82\x01\x92\x90\x92R`@\x90\x81\x01_ \x80T`\xFF\x19\x16\x93\x15\x15\x93\x90\x93\x17\x90\x92U\x81Q\x88Q\x81R\x88\x82\x01Q\x81\x83\x01R\x88\x83\x01Q\x92\x81\x01\x92\x90\x92R``\x80\x89\x01Q\x90\x83\x01R\x86Q`\x80\x83\x01R\x86\x81\x01Q`\xA0\x83\x01R\x85Q`\xC0\x83\x01R\x85\x81\x01Q`\xE0\x83\x01R\x84Qa\x01\0\x83\x01R\x84\x01Qa\x01 \x82\x01R`\x01`\x01`\xA0\x1B\x03\x83\x16\x90\x7F\x04\xCF\x8C\xF4zk\xF2\xEA_q\xB8\xEE\xBD\xEC\x9D\xE2\x11\x7FG\xD2\xB6{\xC6\x083\x8F\x81\xAC\xB1\xA4f\xD5\x90a\x01@\x01`@Q\x80\x91\x03\x90\xA2PPPPPPV[a\x11\xBEa\x13\x18V[`\x01`\x01`\xA0\x1B\x03\x81\x16a\x11\xE7W`@Qc\x1EO\xBD\xF7`\xE0\x1B\x81R_`\x04\x82\x01R`$\x01a\x06\x9FV[a\x11\xF0\x81a\x15\xF7V[PV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x03` R`@\x81 `\x01\x01T`\xFF\x16\x90\x81`\x02\x81\x11\x15a\x12$Wa\x12$a*YV[\x03a\x12BW`@QcP\x8Ay?`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02\x81`\x02\x81\x11\x15a\x12VWa\x12Va*YV[\x03a\x0B\x97W`@Qc\xEA\xB4\xA9c`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[_`@Qc#\xB8r\xDD`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x85\x16`\x04\x82\x01R`\x01`\x01`\xA0\x1B\x03\x84\x16`$\x82\x01R\x82`D\x82\x01R` _`d\x83_\x8AZ\xF1\x91PP\x80`\x1F=\x11`\x01_Q\x14\x16\x15\x16\x15a\x12\xCDWP\x83;\x15=\x17\x15[\x80a\x13\x11W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x14`$\x82\x01Rs\x15\x14\x90S\x94\xD1\x91T\x97\xD1\x94\x93\xD3W\xD1\x90RS\x11Q`b\x1B`D\x82\x01R`d\x01a\x06\x9FV[PPPPPV[3a\x13J\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0T`\x01`\x01`\xA0\x1B\x03\x16\x90V[`\x01`\x01`\xA0\x1B\x03\x16\x14a\x0CUW`@Qc\x11\x8C\xDA\xA7`\xE0\x1B\x81R3`\x04\x82\x01R`$\x01a\x06\x9FV[_`@Qc\xA9\x05\x9C\xBB`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x84\x16`\x04\x82\x01R\x82`$\x82\x01R` _`D\x83_\x89Z\xF1\x91PP\x80`\x1F=\x11`\x01_Q\x14\x16\x15\x16\x15a\x13\xBDWP\x82;\x15=\x17\x15[\x80a\x13\xFCW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x0F`$\x82\x01Rn\x15\x14\x90S\x94\xD1\x91T\x97\xD1\x90RS\x11Q`\x8A\x1B`D\x82\x01R`d\x01a\x06\x9FV[PPPPV[0`\x01`\x01`\xA0\x1B\x03\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14\x80a\x14\x88WP\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x01`\x01`\xA0\x1B\x03\x16a\x14|_Q` a-\xCB_9_Q\x90_RT`\x01`\x01`\xA0\x1B\x03\x16\x90V[`\x01`\x01`\xA0\x1B\x03\x16\x14\x15[\x15a\x0CUW`@Qcp>F\xDD`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x14\xAEa\x13\x18V[`@Q`\x01`\x01`\xA0\x1B\x03\x82\x16\x81R\x7F\xF7\x87!\"n\xFE\x9A\x1B\xB6x\x18\x9A\x16\xD1UI(\xB9\xF2\x19.,\xB9>\xED\xA8;y\xFA@\0}\x90` \x01`@Q\x80\x91\x03\x90\xA1PV[\x81`\x01`\x01`\xA0\x1B\x03\x16cR\xD1\x90-`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x92PPP\x80\x15a\x15GWP`@\x80Q`\x1F=\x90\x81\x01`\x1F\x19\x16\x82\x01\x90\x92Ra\x15D\x91\x81\x01\x90a*\x9DV[`\x01[a\x15oW`@QcL\x9C\x8C\xE3`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x83\x16`\x04\x82\x01R`$\x01a\x06\x9FV[_Q` a-\xCB_9_Q\x90_R\x81\x14a\x15\x9FW`@Qc*\x87Ri`\xE2\x1B\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\x9FV[a\x15\xA9\x83\x83a\x19`V[PPPV[0`\x01`\x01`\xA0\x1B\x03\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14a\x0CUW`@Qcp>F\xDD`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0\x80T`\x01`\x01`\xA0\x1B\x03\x19\x81\x16`\x01`\x01`\xA0\x1B\x03\x84\x81\x16\x91\x82\x17\x84U`@Q\x92\x16\x91\x82\x90\x7F\x8B\xE0\x07\x9CS\x16Y\x14\x13D\xCD\x1F\xD0\xA4\xF2\x84\x19I\x7F\x97\"\xA3\xDA\xAF\xE3\xB4\x18okdW\xE0\x90_\x90\xA3PPPV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x03` R`@\x81 `\x01\x01T`\xFF\x16`\x02\x81\x11\x15a\x16\x96Wa\x16\x96a*YV[\x14a\x11\xF0W`@Qc\x13.~\xFB`\xE3\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`@\x80Q\x80\x82\x01\x90\x91R_\x80\x82R` \x82\x01Ra\x16\xD1\x82\x82a\x19\xB5V[\x15a\x0B\x97W`@Qc\x06\xCFC\x8F`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x04_a\x16\xFB\x83a\x0CWV[\x81R` \x81\x01\x91\x90\x91R`@\x01_ T`\xFF\x16\x15a\x11\xF0W`@Qb\xDA\x8AW`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x174\x82a\x19\xD8V[_`@Q\x80``\x01`@R\x80`$\x81R` \x01a-\x87`$\x919\x90P_\x84\x82`@Q` \x01a\x17d\x92\x91\x90a+BV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P_a\x17\x7F\x82a\x1AnV[\x90Pa\x17\x9C\x81\x85a\x17\x8F\x88a\x1B[V[a\x17\x97a\x1B\xD2V[a\x1C\x9FV[a\x17\xB8W`@Qb\xCE\xD3\xE5`\xE4\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[PPPPPPV[a\x17\xC8a\x1D}V[a\x11\xF0\x81a\x1D\xC6V[a\x0CUa\x1D}V[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0\x80T`\x01`@\x1B\x81\x04`\xFF\x16\x15\x90`\x01`\x01`@\x1B\x03\x16_\x81\x15\x80\x15a\x18\x1DWP\x82[\x90P_\x82`\x01`\x01`@\x1B\x03\x16`\x01\x14\x80\x15a\x188WP0;\x15[\x90P\x81\x15\x80\x15a\x18FWP\x80\x15[\x15a\x18dW`@Qc\xF9.\xE8\xA9`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x84Tg\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16`\x01\x17\x85U\x83\x15a\x18\x8EW\x84T`\xFF`@\x1B\x19\x16`\x01`@\x1B\x17\x85U[C_U\x83\x15a\x13\x11W\x84T`\xFF`@\x1B\x19\x16\x85U`@Q`\x01\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1PPPPPV[`\x01`\x01`\xA0\x1B\x03\x83\x16a\x19\x04W`@Qc\xD9.#=`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x82\x16a\x19+W`@Qc\xD9.#=`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02\x80T`\x01`\x01`\xA0\x1B\x03\x94\x85\x16`\x01`\x01`\xA0\x1B\x03\x19\x91\x82\x16\x17\x90\x91U`\x01\x80T\x93\x90\x94\x16\x92\x16\x91\x90\x91\x17\x90\x91U`\x08UV[a\x19i\x82a\x1D\xCEV[`@Q`\x01`\x01`\xA0\x1B\x03\x83\x16\x90\x7F\xBC|\xD7Z \xEE'\xFD\x9A\xDE\xBA\xB3 A\xF7U!M\xBCk\xFF\xA9\x0C\xC0\"[9\xDA.\\-;\x90_\x90\xA2\x80Q\x15a\x19\xADWa\x15\xA9\x82\x82a\x1E1V[a\x0B\x97a\x1E\xA3V[\x80Q\x82Q_\x91\x14\x80\x15a\x19\xCFWP\x81` \x01Q\x83` \x01Q\x14[\x90P[\x92\x91PPV[\x80Q` \x82\x01Q_\x91_Q` a-\xAB_9_Q\x90_R\x91\x15\x90\x15\x16\x15a\x19\xFEWPPPV[\x82Q` \x84\x01Q\x82`\x03\x84\x85\x85\x86\t\x85\t\x08\x83\x82\x83\t\x14\x83\x82\x10\x84\x84\x10\x16\x16\x93PPP\x81a\x15\xA9W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7FBn254: invalid G1 point\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\x9FV[`@\x80Q\x80\x82\x01\x90\x91R_\x80\x82R` \x82\x01R_a\x1A\x8B\x83a\x1E\xC2V[\x90P_Q` a-\xAB_9_Q\x90_R`\x03_\x82\x84\x85\t\x90P\x82\x80a\x1A\xB2Wa\x1A\xB2a+^V[\x84\x82\t\x90P\x82\x80a\x1A\xC5Wa\x1A\xC5a+^V[\x82\x82\x08\x90P__a\x1A\xD5\x83a \xCAV[\x92P\x90P[\x80a\x1B>W\x84\x80a\x1A\xEDWa\x1A\xEDa+^V[`\x01\x87\x08\x95P\x84\x80a\x1B\x01Wa\x1B\x01a+^V[\x86\x87\t\x92P\x84\x80a\x1B\x14Wa\x1B\x14a+^V[\x86\x84\t\x92P\x84\x80a\x1B'Wa\x1B'a+^V[\x84\x84\x08\x92Pa\x1B5\x83a \xCAV[\x92P\x90Pa\x1A\xDAV[P`@\x80Q\x80\x82\x01\x90\x91R\x94\x85R` \x85\x01RP\x91\x94\x93PPPPV[`@\x80Q\x80\x82\x01\x90\x91R_\x80\x82R` \x82\x01R\x81Q` \x83\x01Q\x15\x90\x15\x16\x15a\x1B\x82WP\x90V[`@Q\x80`@\x01`@R\x80\x83_\x01Q\x81R` \x01_Q` a-\xAB_9_Q\x90_R\x84` \x01Qa\x1B\xB3\x91\x90a+rV[a\x1B\xCA\x90_Q` a-\xAB_9_Q\x90_Ra+\x18V[\x90R\x92\x91PPV[a\x1B\xF9`@Q\x80`\x80\x01`@R\x80_\x81R` \x01_\x81R` \x01_\x81R` \x01_\x81RP\x90V[`@Q\x80`\x80\x01`@R\x80\x7F\x18\0\xDE\xEF\x12\x1F\x1EvBj\0f^\\DygC\"\xD4\xF7^\xDA\xDDF\xDE\xBD\\\xD9\x92\xF6\xED\x81R` \x01\x7F\x19\x8E\x93\x93\x92\rH:r`\xBF\xB71\xFB]%\xF1\xAAI35\xA9\xE7\x12\x97\xE4\x85\xB7\xAE\xF3\x12\xC2\x81R` \x01\x7F\x12\xC8^\xA5\xDB\x8Cm\xEBJ\xABq\x80\x8D\xCB@\x8F\xE3\xD1\xE7i\x0CC\xD3{L\xE6\xCC\x01f\xFA}\xAA\x81R` \x01\x7F\t\x06\x89\xD0X_\xF0u\xEC\x9E\x99\xADi\x0C3\x95\xBCK13p\xB3\x8E\xF3U\xAC\xDA\xDC\xD1\"\x97[\x81RP\x90P\x90V[___`@Q\x87Q\x81R` \x88\x01Q` \x82\x01R` \x87\x01Q`@\x82\x01R\x86Q``\x82\x01R``\x87\x01Q`\x80\x82\x01R`@\x87\x01Q`\xA0\x82\x01R\x85Q`\xC0\x82\x01R` \x86\x01Q`\xE0\x82\x01R` \x85\x01Qa\x01\0\x82\x01R\x84Qa\x01 \x82\x01R``\x85\x01Qa\x01@\x82\x01R`@\x85\x01Qa\x01`\x82\x01R` _a\x01\x80\x83`\x08Z\xFA\x91PP_Q\x91P\x80a\x1DqW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1C`$\x82\x01R\x7FBn254: Pairing check failed!\0\0\0\0`D\x82\x01R`d\x01a\x06\x9FV[P\x15\x15\x95\x94PPPPPV[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0T`\x01`@\x1B\x90\x04`\xFF\x16a\x0CUW`@Qc\x1A\xFC\xD7\x9F`\xE3\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x11\xBEa\x1D}V[\x80`\x01`\x01`\xA0\x1B\x03\x16;_\x03a\x1E\x03W`@QcL\x9C\x8C\xE3`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x82\x16`\x04\x82\x01R`$\x01a\x06\x9FV[_Q` a-\xCB_9_Q\x90_R\x80T`\x01`\x01`\xA0\x1B\x03\x19\x16`\x01`\x01`\xA0\x1B\x03\x92\x90\x92\x16\x91\x90\x91\x17\x90UV[``__\x84`\x01`\x01`\xA0\x1B\x03\x16\x84`@Qa\x1EM\x91\x90a+\x91V[_`@Q\x80\x83\x03\x81\x85Z\xF4\x91PP=\x80_\x81\x14a\x1E\x85W`@Q\x91P`\x1F\x19`?=\x01\x16\x82\x01`@R=\x82R=_` \x84\x01>a\x1E\x8AV[``\x91P[P\x91P\x91Pa\x1E\x9A\x85\x83\x83a!\xC1V[\x95\x94PPPPPV[4\x15a\x0CUW`@Qc\xB3\x98\x97\x9F`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[__a\x1E\xCD\x83a\" V[\x80Q\x90\x91P`0\x81\x14a\x1E\xE2Wa\x1E\xE2a+\x9CV[_\x81`\x01`\x01`@\x1B\x03\x81\x11\x15a\x1E\xFBWa\x1E\xFBa&>V[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a\x1F%W` \x82\x01\x81\x806\x837\x01\x90P[P\x90P_[\x82\x81\x10\x15a\x1F\x94W\x83`\x01a\x1F?\x83\x86a+\x18V[a\x1FI\x91\x90a+\x18V[\x81Q\x81\x10a\x1FYWa\x1FYa+\xB0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x82\x82\x81Q\x81\x10a\x1FvWa\x1Fva+\xB0V[` \x01\x01\x90`\x01`\x01`\xF8\x1B\x03\x19\x16\x90\x81_\x1A\x90SP`\x01\x01a\x1F*V[P`@\x80Q`\x1F\x80\x82Ra\x04\0\x82\x01\x90\x92R_\x90\x82` \x82\x01a\x03\xE0\x806\x837\x01\x90PP\x90P_[\x82\x81\x10\x15a $W\x83\x81a\x1F\xD0\x85\x88a+\x18V[a\x1F\xDA\x91\x90a*\xC8V[\x81Q\x81\x10a\x1F\xEAWa\x1F\xEAa+\xB0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B`\xF8\x1C\x82\x82\x81Q\x81\x10a \nWa \na+\xB0V[`\xFF\x90\x92\x16` \x92\x83\x02\x91\x90\x91\x01\x90\x91\x01R`\x01\x01a\x1F\xBCV[P_a /\x82a%kV[\x90Pa\x01\0_Q` a-\xAB_9_Q\x90_R_a M\x86\x89a+\x18V[\x90P_[\x81\x81\x10\x15a \xBAW_\x88`\x01a g\x84\x86a+\x18V[a q\x91\x90a+\x18V[\x81Q\x81\x10a \x81Wa \x81a+\xB0V[\x01` \x01Q`\xF8\x1C\x90P\x83\x80a \x99Wa \x99a+^V[\x85\x87\t\x95P\x83\x80a \xACWa \xACa+^V[\x81\x87\x08\x95PP`\x01\x01a QV[P\x92\x9A\x99PPPPPPPPPPV[_____\x7F\x0C\x19\x13\x9C\xB8Lh\nn\x14\x11m\xA0`V\x17e\xE0Z\xA4Z\x1Cr\xA3O\x08#\x05\xB6\x1F?R\x90P__Q` a-\xAB_9_Q\x90_R\x90P`@Q` \x81R` \x80\x82\x01R` `@\x82\x01R\x87``\x82\x01R\x82`\x80\x82\x01R\x81`\xA0\x82\x01R` _`\xC0\x83`\x05Z\xFA\x94PP_Q\x92P\x83a!\x87W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1B`$\x82\x01R\x7Fpow precompile call failed!\0\0\0\0\0`D\x82\x01R`d\x01a\x06\x9FV[\x80`\x01\x84\x90\x1B\x11\x15a!\xA0Wa!\x9D\x83\x82a+\x18V[\x92P[\x80\x80a!\xAEWa!\xAEa+^V[\x83\x84\t\x96\x90\x96\x14\x96\x91\x95P\x90\x93PPPPV[``\x82a!\xD6Wa!\xD1\x82a%\xD2V[a\"\x19V[\x81Q\x15\x80\x15a!\xEDWP`\x01`\x01`\xA0\x1B\x03\x84\x16;\x15[\x15a\"\x16W`@Qc\x99\x96\xB3\x15`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x85\x16`\x04\x82\x01R`$\x01a\x06\x9FV[P\x80[\x93\x92PPPV[`@\x80Q`0\x80\x82R``\x82\x81\x01\x90\x93R\x90` \x90`\x01`\xF9\x1B\x90_\x90\x84` \x82\x01\x81\x806\x837\x01\x90PP\x90P\x80\x86`@Q` \x01a\"`\x92\x91\x90a+BV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P\x80\x84`\xF8\x1B`@Q` \x01a\"\x87\x92\x91\x90a+\xC4V[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P\x80`@Q` \x01a\"\xA9\x91\x90a+\xEEV[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x90\x82\x90R\x91Pa\x01\x01`\xF0\x1B\x90a\"\xD3\x90\x83\x90\x83\x90` \x01a,\x06V[`@\x80Q\x80\x83\x03`\x1F\x19\x01\x81R\x82\x82R\x80Q` \x91\x82\x01 \x81\x84\x01\x81\x90R`\x01`\xF8\x1B\x84\x84\x01R`\x01`\x01`\xF0\x1B\x03\x19\x85\x16`A\x85\x01R\x82Q`#\x81\x86\x03\x01\x81R`C\x90\x94\x01\x90\x92R\x82Q\x90\x83\x01 \x91\x93P\x90_`\xFF\x88\x16`\x01`\x01`@\x1B\x03\x81\x11\x15a#BWa#Ba&>V[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a#lW` \x82\x01\x81\x806\x837\x01\x90P[P\x90P_\x82`@Q` \x01a#\x83\x91\x81R` \x01\x90V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x91\x90R\x90P_[\x81Q\x81\x10\x15a#\xEDW\x81\x81\x81Q\x81\x10a#\xB2Wa#\xB2a+\xB0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x83\x82\x81Q\x81\x10a#\xCFWa#\xCFa+\xB0V[` \x01\x01\x90`\x01`\x01`\xF8\x1B\x03\x19\x16\x90\x81_\x1A\x90SP`\x01\x01a#\x97V[P_\x84`@Q` \x01a$\x02\x91\x81R` \x01\x90V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R` \x83\x01\x90\x91R_\x80\x83R\x91\x98P\x91P[\x89\x81\x10\x15a$\x94W_\x83\x82\x81Q\x81\x10a$;Wa$;a+\xB0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x83\x83\x81Q\x81\x10a$XWa$Xa+\xB0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x18\x90P\x88\x81`@Q` \x01a$y\x92\x91\x90a,*V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x91\x90R\x98PP`\x01\x01a$ V[P\x86\x88\x87`@Q` \x01a$\xAA\x93\x92\x91\x90a,NV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x96P\x86\x80Q\x90` \x01 \x93P\x83`@Q` \x01a$\xD8\x91\x81R` \x01\x90V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x91\x90R\x91P_[a$\xF9\x8A`\xFF\x8D\x16a+\x18V[\x81\x10\x15a%ZW\x82\x81\x81Q\x81\x10a%\x12Wa%\x12a+\xB0V[\x01` \x01Q`\x01`\x01`\xF8\x1B\x03\x19\x16\x84a%,\x83\x8Da*\xC8V[\x81Q\x81\x10a%V[`@R\x90V[`@Q`\x1F\x82\x01`\x1F\x19\x16\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a&\xA2Wa&\xA2a&>V[`@R\x91\x90PV[_`\x80\x82\x84\x03\x12\x15a&\xBAW__\xFD[`@Q`\x80\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a&\xDCWa&\xDCa&>V[`@\x90\x81R\x835\x82R` \x80\x85\x015\x90\x83\x01R\x83\x81\x015\x90\x82\x01R``\x92\x83\x015\x92\x81\x01\x92\x90\x92RP\x91\x90PV[_`@\x82\x84\x03\x12\x15a'\x1AW__\xFD[a'\"a&RV[\x825\x81R` \x92\x83\x015\x92\x81\x01\x92\x90\x92RP\x91\x90PV[\x805a\xFF\xFF\x81\x16\x81\x14a&\x11W__\xFD[____a\x01 \x85\x87\x03\x12\x15a'^W__\xFD[a'h\x86\x86a&\xAAV[\x93Pa'w\x86`\x80\x87\x01a'\nV[\x92Pa'\x86\x86`\xC0\x87\x01a'\nV[\x91Pa'\x95a\x01\0\x86\x01a'9V[\x90P\x92\x95\x91\x94P\x92PV[`\x01`\x01`@\x1B\x03\x81\x16\x81\x14a\x11\xF0W__\xFD[_` \x82\x84\x03\x12\x15a'\xC4W__\xFD[\x815a\"\x19\x81a'\xA0V[_` \x82\x84\x03\x12\x15a'\xDFW__\xFD[a\x19\xCF\x82a%\xFBV[__`@\x83\x85\x03\x12\x15a'\xF9W__\xFD[a(\x02\x83a%\xFBV[\x91P` \x83\x015`\x01`\x01`@\x1B\x03\x81\x11\x15a(\x1CW__\xFD[\x83\x01`\x1F\x81\x01\x85\x13a(,W__\xFD[\x805`\x01`\x01`@\x1B\x03\x81\x11\x15a(EWa(Ea&>V[a(X`\x1F\x82\x01`\x1F\x19\x16` \x01a&zV[\x81\x81R\x86` \x83\x85\x01\x01\x11\x15a(lW__\xFD[\x81` \x84\x01` \x83\x017_` \x83\x83\x01\x01R\x80\x93PPPP\x92P\x92\x90PV[___a\x01\0\x84\x86\x03\x12\x15a(\x9EW__\xFD[a(\xA8\x85\x85a&\xAAV[\x92Pa(\xB7\x85`\x80\x86\x01a'\nV[\x91Pa(\xC6\x85`\xC0\x86\x01a'\nV[\x90P\x92P\x92P\x92V[_`\x80\x82\x84\x03\x12\x15a(\xDFW__\xFD[a\x19\xCF\x83\x83a&\xAAV[__`@\x83\x85\x03\x12\x15a(\xFAW__\xFD[a)\x03\x83a%\xFBV[\x91Pa)\x11` \x84\x01a%\xFBV[\x90P\x92P\x92\x90PV[_____a\x01`\x86\x88\x03\x12\x15a)/W__\xFD[a)9\x87\x87a&\xAAV[\x94Pa)H\x87`\x80\x88\x01a'\nV[\x93Pa)W\x87`\xC0\x88\x01a'\nV[\x92Pa)g\x87a\x01\0\x88\x01a'\nV[\x91Pa)va\x01@\x87\x01a'9V[\x90P\x92\x95P\x92\x95\x90\x93PV[` \x81R_\x82Q\x80` \x84\x01R\x80` \x85\x01`@\x85\x01^_`@\x82\x85\x01\x01R`@`\x1F\x19`\x1F\x83\x01\x16\x84\x01\x01\x91PP\x92\x91PPV[_` \x82\x84\x03\x12\x15a)\xC7W__\xFD[P5\x91\x90PV[____`\x80\x85\x87\x03\x12\x15a)\xE1W__\xFD[a)\xEA\x85a%\xFBV[\x93Pa)\xF8` \x86\x01a%\xFBV[\x92P`@\x85\x015\x91Pa'\x95``\x86\x01a%\xFBV[____a\x01@\x85\x87\x03\x12\x15a*!W__\xFD[a*+\x86\x86a&\xAAV[\x93Pa*:\x86`\x80\x87\x01a'\nV[\x92Pa*I\x86`\xC0\x87\x01a'\nV[\x91Pa'\x95\x86a\x01\0\x87\x01a'\nV[cNH{q`\xE0\x1B_R`!`\x04R`$_\xFD[\x82\x81R`@\x81\x01`\x03\x83\x10a*\x90WcNH{q`\xE0\x1B_R`!`\x04R`$_\xFD[\x82` \x83\x01R\x93\x92PPPV[_` \x82\x84\x03\x12\x15a*\xADW__\xFD[PQ\x91\x90PV[cNH{q`\xE0\x1B_R`\x11`\x04R`$_\xFD[\x80\x82\x01\x80\x82\x11\x15a\x19\xD2Wa\x19\xD2a*\xB4V[_` \x82\x84\x03\x12\x15a*\xEBW__\xFD[\x81Qa\"\x19\x81a'\xA0V[`\x01`\x01`@\x1B\x03\x81\x81\x16\x83\x82\x16\x02\x90\x81\x16\x90\x81\x81\x14a%\xCBWa%\xCBa*\xB4V[\x81\x81\x03\x81\x81\x11\x15a\x19\xD2Wa\x19\xD2a*\xB4V[_\x81Q\x80` \x84\x01\x85^_\x93\x01\x92\x83RP\x90\x91\x90PV[_a+Va+P\x83\x86a++V[\x84a++V[\x94\x93PPPPV[cNH{q`\xE0\x1B_R`\x12`\x04R`$_\xFD[_\x82a+\x8CWcNH{q`\xE0\x1B_R`\x12`\x04R`$_\xFD[P\x06\x90V[_a\x19\xCF\x82\x84a++V[cNH{q`\xE0\x1B_R`\x01`\x04R`$_\xFD[cNH{q`\xE0\x1B_R`2`\x04R`$_\xFD[_a+\xCF\x82\x85a++V[_\x81R`\x01`\x01`\xF8\x1B\x03\x19\x93\x90\x93\x16`\x01\x84\x01RPP`\x02\x01\x91\x90PV[_a+\xF9\x82\x84a++V[_\x81R`\x01\x01\x93\x92PPPV[_a,\x11\x82\x85a++V[`\x01`\x01`\xF0\x1B\x03\x19\x93\x90\x93\x16\x83RPP`\x02\x01\x91\x90PV[_a,5\x82\x85a++V[`\x01`\x01`\xF8\x1B\x03\x19\x93\x90\x93\x16\x83RPP`\x01\x01\x91\x90PV[_a,Y\x82\x86a++V[`\x01`\x01`\xF8\x1B\x03\x19\x94\x90\x94\x16\x84RPP`\x01`\x01`\xF0\x1B\x03\x19\x16`\x01\x82\x01R`\x03\x01\x91\x90PV[\x80\x82\x02\x81\x15\x82\x82\x04\x84\x14\x17a\x19\xD2Wa\x19\xD2a*\xB4V[`\x01\x81[`\x01\x84\x11\x15a,\xD3W\x80\x85\x04\x81\x11\x15a,\xB7Wa,\xB7a*\xB4V[`\x01\x84\x16\x15a,\xC5W\x90\x81\x02\x90[`\x01\x93\x90\x93\x1C\x92\x80\x02a,\x9CV[\x93P\x93\x91PPV[_\x82a,\xE9WP`\x01a\x19\xD2V[\x81a,\xF5WP_a\x19\xD2V[\x81`\x01\x81\x14a-\x0BW`\x02\x81\x14a-\x15Wa-1V[`\x01\x91PPa\x19\xD2V[`\xFF\x84\x11\x15a-&Wa-&a*\xB4V[PP`\x01\x82\x1Ba\x19\xD2V[P` \x83\x10a\x013\x83\x10\x16`N\x84\x10`\x0B\x84\x10\x16\x17\x15a-TWP\x81\x81\na\x19\xD2V[a-`_\x19\x84\x84a,\x98V[\x80_\x19\x04\x82\x11\x15a-sWa-sa*\xB4V[\x02\x93\x92PPPV[_a\x19\xCF\x83\x83a,\xDBV\xFEBLS_SIG_BN254G1_XMD:KECCAK_NCTH_NUL_0dNr\xE11\xA0)\xB8PE\xB6\x81\x81X]\x97\x81j\x91hq\xCA\x8D< \x8C\x16\xD8|\xFDG6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\xA1dsolcC\0\x08\x1C\0\n", + b"`\xA0`@R0`\x80R4\x80\x15a\0\x13W__\xFD[Pa\0\x1Ca\x001V[a\0$a\x001V[a\0,a\x001V[a\0\xE3V[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0\x80Th\x01\0\0\0\0\0\0\0\0\x90\x04`\xFF\x16\x15a\0\x81W`@Qc\xF9.\xE8\xA9`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x80T`\x01`\x01`@\x1B\x03\x90\x81\x16\x14a\0\xE0W\x80T`\x01`\x01`@\x1B\x03\x19\x16`\x01`\x01`@\x1B\x03\x90\x81\x17\x82U`@Q\x90\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1[PV[`\x80Qa.\x82a\x01\t_9_\x81\x81a\x14\xD3\x01R\x81\x81a\x14\xFC\x01Ra\x16\x7F\x01Ra.\x82_\xF3\xFE`\x80`@R`\x046\x10a\x01\xAFW_5`\xE0\x1C\x80c\x9B0\xA5\xE6\x11a\0\xE7W\x80c\xB5p\x0Eh\x11a\0\x87W\x80c\xC6H\x14\xDD\x11a\0bW\x80c\xC6H\x14\xDD\x14a\x05\"W\x80c\xF2\xFD\xE3\x8B\x14a\x05XW\x80c\xFAR\xC7\xD8\x14a\x05wW\x80c\xFC\x0CTj\x14a\x05\xBAW__\xFD[\x80c\xB5p\x0Eh\x14a\x04\xB9W\x80c\xB5\xEC\xB3D\x14a\x04\xD8W\x80c\xBE 0\x94\x14a\x05\x03W__\xFD[\x80c\xA3\x06j\xAB\x11a\0\xC2W\x80c\xA3\x06j\xAB\x14a\x04\0W\x80c\xAC\\*\xD0\x14a\x04\x1FW\x80c\xAD<\xB1\xCC\x14a\x04>W\x80c\xB3\xE6\xEB\xD5\x14a\x04{W__\xFD[\x80c\x9B0\xA5\xE6\x14a\x03zW\x80c\x9E\x9A\x8F1\x14a\x03\x99W\x80c\xA2\xD7\x8D\xD5\x14a\x03\xAEW__\xFD[\x80cM\x99\xDD\x16\x11a\x01RW\x80cUD\xC2\xF1\x11a\x01-W\x80cUD\xC2\xF1\x14a\x02\xE8W\x80cj\x91\x1C\xCF\x14a\x03\x02W\x80cqP\x18\xA6\x14a\x03\x16W\x80c\x8D\xA5\xCB[\x14a\x03*W__\xFD[\x80cM\x99\xDD\x16\x14a\x02\xA2W\x80cO\x1E\xF2\x86\x14a\x02\xC1W\x80cR\xD1\x90-\x14a\x02\xD4W__\xFD[\x80c\x1A \xCDc\x11a\x01\x8DW\x80c\x1A \xCDc\x14a\x02#W\x80c!@\xFE\xCD\x14a\x02BW\x80c0B@\xBF\x14a\x02aW\x80c>\x9D\xF9\xB5\x14a\x02\x80W__\xFD[\x80c\x02n@+\x14a\x01\xB3W\x80c\r\x8En,\x14a\x01\xD4W\x80c\x13\xB9\x05z\x14a\x02\x04W[__\xFD[4\x80\x15a\x01\xBEW__\xFD[Pa\x01\xD2a\x01\xCD6`\x04a%\x83V[a\x05\xD9V[\0[4\x80\x15a\x01\xDFW__\xFD[P`@\x80Q`\x02\x81R_` \x82\x01\x81\x90R\x91\x81\x01\x91\x90\x91R``\x01[`@Q\x80\x91\x03\x90\xF3[4\x80\x15a\x02\x0FW__\xFD[Pa\x01\xD2a\x02\x1E6`\x04a&\x87V[a\x07|V[4\x80\x15a\x02.W__\xFD[Pa\x01\xD2a\x02=6`\x04a&\xF1V[a\x07\x95V[4\x80\x15a\x02MW__\xFD[Pa\x01\xD2a\x02\\6`\x04a'\x0CV[a\x08\xA9V[4\x80\x15a\x02lW__\xFD[Pa\x01\xD2a\x02{6`\x04a'\xAEV[a\t\xCAV[4\x80\x15a\x02\x8BW__\xFD[Pa\x02\x94_T\x81V[`@Q\x90\x81R` \x01a\x01\xFBV[4\x80\x15a\x02\xADW__\xFD[Pa\x01\xD2a\x02\xBC6`\x04a%\x83V[a\x0B4V[a\x01\xD2a\x02\xCF6`\x04a(.V[a\x0C\xE6V[4\x80\x15a\x02\xDFW__\xFD[Pa\x02\x94a\r\x05V[4\x80\x15a\x02\xF3W__\xFD[Pa\x01\xD2a\x02\x1E6`\x04a(xV[4\x80\x15a\x03\rW__\xFD[Pa\x01\xD2a\r V[4\x80\x15a\x03!W__\xFD[Pa\x01\xD2a\r\xAEV[4\x80\x15a\x035W__\xFD[P\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0T`\x01`\x01`\xA0\x1B\x03\x16[`@Q`\x01`\x01`\xA0\x1B\x03\x90\x91\x16\x81R` \x01a\x01\xFBV[4\x80\x15a\x03\x85W__\xFD[Pa\x02\x94a\x03\x946`\x04a(\xBCV[a\r\xC1V[4\x80\x15a\x03\xA4W__\xFD[Pa\x02\x94`\x08T\x81V[4\x80\x15a\x03\xB9W__\xFD[Pa\x03\xEBa\x03\xC86`\x04a(\xD6V[`\x07` \x90\x81R_\x92\x83R`@\x80\x84 \x90\x91R\x90\x82R\x90 \x80T`\x01\x90\x91\x01T\x82V[`@\x80Q\x92\x83R` \x83\x01\x91\x90\x91R\x01a\x01\xFBV[4\x80\x15a\x04\x0BW__\xFD[Pa\x01\xD2a\x04\x1A6`\x04a'\x0CV[a\x0E\x1BV[4\x80\x15a\x04*W__\xFD[Pa\x01\xD2a\x0496`\x04a)\x07V[a\x0F+V[4\x80\x15a\x04IW__\xFD[Pa\x04n`@Q\x80`@\x01`@R\x80`\x05\x81R` \x01d\x03R\xE3\x02\xE3`\xDC\x1B\x81RP\x81V[`@Qa\x01\xFB\x91\x90a)\xA4V[4\x80\x15a\x04\x86W__\xFD[Pa\x04\xA9a\x04\x956`\x04a)\xB6V[`\x04` R_\x90\x81R`@\x90 T`\xFF\x16\x81V[`@Q\x90\x15\x15\x81R` \x01a\x01\xFBV[4\x80\x15a\x04\xC4W__\xFD[P`\x01Ta\x03b\x90`\x01`\x01`\xA0\x1B\x03\x16\x81V[4\x80\x15a\x04\xE3W__\xFD[Pa\x02\x94a\x04\xF26`\x04a'\x0CV[`\x05` R_\x90\x81R`@\x90 T\x81V[4\x80\x15a\x05\x0EW__\xFD[Pa\x01\xD2a\x05\x1D6`\x04a)\xCDV[a\x0F\xF9V[4\x80\x15a\x05-W__\xFD[Pa\x02\x94a\x05<6`\x04a(\xD6V[`\x06` \x90\x81R_\x92\x83R`@\x80\x84 \x90\x91R\x90\x82R\x90 T\x81V[4\x80\x15a\x05cW__\xFD[Pa\x01\xD2a\x05r6`\x04a'\x0CV[a\x11#V[4\x80\x15a\x05\x82W__\xFD[Pa\x05\xACa\x05\x916`\x04a'\x0CV[`\x03` R_\x90\x81R`@\x90 \x80T`\x01\x90\x91\x01T`\xFF\x16\x82V[`@Qa\x01\xFB\x92\x91\x90a* V[4\x80\x15a\x05\xC5W__\xFD[P`\x02Ta\x03b\x90`\x01`\x01`\xA0\x1B\x03\x16\x81V[a\x05\xE2\x82a\x11`V[3_\x82\x90\x03a\x06\x04W`@Qc\x1F* \x05`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02T`@Qcn\xB1v\x9F`\xE1\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x83\x81\x16`\x04\x83\x01R0`$\x83\x01R_\x92\x16\x90c\xDDb\xED>\x90`D\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x06RW=__>=_\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x06v\x91\x90a*PV[\x90P\x82\x81\x10\x15a\x06\xA8W`@Qc\x05Ce\xBB`\xE3\x1B\x81R`\x04\x81\x01\x82\x90R`$\x81\x01\x84\x90R`D\x01[`@Q\x80\x91\x03\x90\xFD[`\x02Ta\x06\xC0\x90`\x01`\x01`\xA0\x1B\x03\x16\x830\x86a\x11\xE1V[`\x01`\x01`\xA0\x1B\x03\x84\x16_\x90\x81R`\x03` R`@\x81 \x80T\x85\x92\x90a\x06\xE7\x90\x84\x90a*{V[\x90\x91UPP`\x01`\x01`\xA0\x1B\x03\x80\x85\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R\x90\x81 \x80T\x85\x92\x90a\x07\"\x90\x84\x90a*{V[\x92PP\x81\x90UP\x83`\x01`\x01`\xA0\x1B\x03\x16\x82`\x01`\x01`\xA0\x1B\x03\x16\x7F\xE5T\x1Aka\x03\xD4\xFA~\x02\x1E\xD5O\xAD9\xC6o'\xA7k\xD1=7L\xF6$\n\xE6\xBD\x0B\xB7+\x85`@Qa\x07n\x91\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA3PPPPV[`@Qc\xC2\xD7\xF8\x13`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x07\x9Da\x12\x85V[`\x01T`@\x80Qc<\x1A\x08\x15`\xE2\x1B\x81R\x90Q_\x92`\x01`\x01`\xA0\x1B\x03\x16\x91c\xF0h T\x91`\x04\x80\x83\x01\x92` \x92\x91\x90\x82\x90\x03\x01\x81\x86Z\xFA\x15\x80\x15a\x07\xE4W=__>=_\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x08\x08\x91\x90a*\x8EV[a\x08\x13\x90`\x0Fa*\xA9V[\x90Pb\x12u\0`\x01`\x01`@\x1B\x03\x80\x83\x16\x90\x84\x16\x10\x80a\x08DWP\x80`\x01`\x01`@\x1B\x03\x16\x83`\x01`\x01`@\x1B\x03\x16\x11[\x15a\x08bW`@Qc\xB5~!\xDF`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`@\x1B\x03\x83\x16`\x08\x81\x90U`@Q\x90\x81R\x7Fy>;\x1E\x1B\xCDg{\xB1\x19\0\xC81$\xD3\xC4L\x99F\xEA\x8D\xDF\x97\x8A\x0C\xA2P\xB04\xEC\x9D\xDE\x90` \x01`@Q\x80\x91\x03\x90\xA1PPPV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x05` R`@\x81 T3\x91\x81\x90\x03a\x08\xE3W`@Qcy)\x8AS`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x80B\x10\x15a\t\x04W`@QcZwCW`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R\x90\x81 T\x90\x81\x90\x03a\tLW`@Qc\x06\x86\x82{`\xE5\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x85\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x87\x85\x16\x84R\x90\x91R\x81 U`\x02Ta\t\x81\x91\x16\x84\x83a\x12\xE0V[\x82`\x01`\x01`\xA0\x1B\x03\x16\x7F\x7F\xCFS,\x15\xF0\xA6\xDB\x0B\xD6\xD0\xE08\xBE\xA7\x1D0\xD8\x08\xC7\xD9\x8C\xB3\xBFrh\xA9[\xF5\x08\x1Be\x82`@Qa\t\xBC\x91\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA2PPPPV[3a\t\xD4\x81a\x13oV[a\t\xDD\x85a\x13\xBCV[a\t\xE6\x86a\x13\xF7V[`@\x80Q`\x01`\x01`\xA0\x1B\x03\x83\x16` \x82\x01R_\x91\x01`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90Pa\n\x18\x81\x86\x89a\x143V[a'\x10\x83a\xFF\xFF\x16\x11\x15a\n?W`@Qc\xDC\x81\xDB\x85`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x04_a\nM\x8Aa\r\xC1V[\x81R` \x01\x90\x81R` \x01_ _a\x01\0\n\x81T\x81`\xFF\x02\x19\x16\x90\x83\x15\x15\x02\x17\x90UP`@Q\x80`@\x01`@R\x80_\x81R` \x01`\x01`\x02\x81\x11\x15a\n\x94Wa\n\x94a*\x0CV[\x90R`\x01`\x01`\xA0\x1B\x03\x83\x16_\x90\x81R`\x03` \x90\x81R`@\x90\x91 \x82Q\x81U\x90\x82\x01Q`\x01\x80\x83\x01\x80T\x90\x91`\xFF\x19\x90\x91\x16\x90\x83`\x02\x81\x11\x15a\n\xDAWa\n\xDAa*\x0CV[\x02\x17\x90UP\x90PP\x81`\x01`\x01`\xA0\x1B\x03\x16\x7F\xF0W\xD4\xEA\x81\xE9\x86(e:\x8F\x90x\x85A\x97 x\x13s4\xA9+B4~\xAC\xCD\xA8\x0F\xC4\n\x88\x88\x86\x89\x89`@Qa\x0B#\x95\x94\x93\x92\x91\x90a*\xCBV[`@Q\x80\x91\x03\x90\xA2PPPPPPPV[a\x0B=\x82a\x11`V[3_\x82\x90\x03a\x0B_W`@Qc\x1F* \x05`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 \x93\x85\x16\x83R\x92\x90R T\x15a\x0B\xA2W`@Qc\xD4#\xA4\xF1`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x85\x16\x83R\x92\x90R T\x82\x81\x10\x15a\x0B\xEBW`@Qc\x92fSQ`\xE0\x1B\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\x9FV[`\x01`\x01`\xA0\x1B\x03\x80\x85\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R\x90\x81 \x80T\x85\x92\x90a\x0C!\x90\x84\x90a+=V[\x92PP\x81\x90UP`@Q\x80`@\x01`@R\x80\x84\x81R` \x01`\x08TBa\x0CG\x91\x90a*{V[\x90R`\x01`\x01`\xA0\x1B\x03\x80\x86\x16_\x81\x81R`\x07` \x90\x81R`@\x80\x83 \x94\x88\x16\x83R\x93\x81R\x83\x82 \x85Q\x81U\x94\x81\x01Q`\x01\x90\x95\x01\x94\x90\x94U\x90\x81R`\x03\x90\x92R\x81 \x80T\x85\x92\x90a\x0C\x9A\x90\x84\x90a+=V[\x92PP\x81\x90UP\x83`\x01`\x01`\xA0\x1B\x03\x16\x82`\x01`\x01`\xA0\x1B\x03\x16\x7FM\x10\xBD\x04\x97u\xC7{\xD7\xF2U\x19Z\xFB\xA5\x08\x80(\xEC\xB3\xC7\xC2w\xD3\x93\xCC\xFFy4\xF2\xF9,\x85`@Qa\x07n\x91\x81R` \x01\x90V[a\x0C\xEEa\x14\xC8V[a\x0C\xF7\x82a\x15lV[a\r\x01\x82\x82a\x15\xB3V[PPV[_a\r\x0Ea\x16tV[P_Q` a.V_9_Q\x90_R\x90V[3a\r*\x81a\x11`V[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x03` R`@\x90 `\x01\x01\x80T`\xFF\x19\x16`\x02\x17\x90U`\x08Ta\r\\\x90Ba*{V[`\x01`\x01`\xA0\x1B\x03\x82\x16_\x81\x81R`\x05` \x90\x81R`@\x80\x83 \x94\x90\x94U`\x03\x90R\x82\x81 \x81\x90U\x91Q\x90\x91\x7F\xFB$0ST\xC8wb\xD5WHz\xE4\xA5d\xE8\xD0>\xCB\xB9\xA9}\xD8\xAF\xFF\x8E\x1Fo\xCA\xF0\xDD\x16\x91\xA2PV[a\r\xB6a\x12\x85V[a\r\xBF_a\x16\xBDV[V[_\x81_\x01Q\x82` \x01Q\x83`@\x01Q\x84``\x01Q`@Q` \x01a\r\xFE\x94\x93\x92\x91\x90\x93\x84R` \x84\x01\x92\x90\x92R`@\x83\x01R``\x82\x01R`\x80\x01\x90V[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x80Q\x90` \x01 \x90P\x91\x90PV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 3\x80\x85R\x92R\x82 T\x90\x91\x81\x90\x03a\x0E`W`@Qc\x06\x86\x82{`\xE5\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R `\x01\x01TB\x10\x15a\x0E\xA8W`@QcZwCW`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 \x86\x85\x16\x84R\x90\x91R\x81 \x81\x81U`\x01\x01U`\x02Ta\x0E\xE3\x91\x16\x83\x83a\x12\xE0V[\x81`\x01`\x01`\xA0\x1B\x03\x16\x7F\x7F\xCFS,\x15\xF0\xA6\xDB\x0B\xD6\xD0\xE08\xBE\xA7\x1D0\xD8\x08\xC7\xD9\x8C\xB3\xBFrh\xA9[\xF5\x08\x1Be\x82`@Qa\x0F\x1E\x91\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA2PPPV[3a\x0F5\x81a\x11`V[a\x0F>\x84a\x13\xBCV[a\x0FG\x85a\x13\xF7V[`@\x80Q`\x01`\x01`\xA0\x1B\x03\x83\x16` \x82\x01R_\x91\x01`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90Pa\x0Fy\x81\x85\x88a\x143V[`\x01`\x04_a\x0F\x87\x89a\r\xC1V[\x81R` \x01\x90\x81R` \x01_ _a\x01\0\n\x81T\x81`\xFF\x02\x19\x16\x90\x83\x15\x15\x02\x17\x90UP\x81`\x01`\x01`\xA0\x1B\x03\x16\x7F\xC8\xC5\xB3z\xEC\x7F-\xDB\xD3\xA1#\xA9f.\xFC\x9C\"\x9Cj\0\x80T`\x01`@\x1B\x81\x04`\xFF\x16\x15\x90`\x01`\x01`@\x1B\x03\x16_\x81\x15\x80\x15a\x10=WP\x82[\x90P_\x82`\x01`\x01`@\x1B\x03\x16`\x01\x14\x80\x15a\x10XWP0;\x15[\x90P\x81\x15\x80\x15a\x10fWP\x80\x15[\x15a\x10\x84W`@Qc\xF9.\xE8\xA9`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x84Tg\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16`\x01\x17\x85U\x83\x15a\x10\xAEW\x84T`\xFF`@\x1B\x19\x16`\x01`@\x1B\x17\x85U[a\x10\xB7\x86a\x17-V[a\x10\xBFa\x17>V[a\x10\xC7a\x17FV[a\x10\xD2\x89\x89\x89a\x18JV[\x83\x15a\x11\x18W\x84T`\xFF`@\x1B\x19\x16\x85U`@Q`\x01\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1[PPPPPPPPPV[a\x11+a\x12\x85V[`\x01`\x01`\xA0\x1B\x03\x81\x16a\x11TW`@Qc\x1EO\xBD\xF7`\xE0\x1B\x81R_`\x04\x82\x01R`$\x01a\x06\x9FV[a\x11]\x81a\x16\xBDV[PV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x03` R`@\x81 `\x01\x01T`\xFF\x16\x90\x81`\x02\x81\x11\x15a\x11\x91Wa\x11\x91a*\x0CV[\x03a\x11\xAFW`@QcP\x8Ay?`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02\x81`\x02\x81\x11\x15a\x11\xC3Wa\x11\xC3a*\x0CV[\x03a\r\x01W`@Qc\xEA\xB4\xA9c`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[_`@Qc#\xB8r\xDD`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x85\x16`\x04\x82\x01R`\x01`\x01`\xA0\x1B\x03\x84\x16`$\x82\x01R\x82`D\x82\x01R` _`d\x83_\x8AZ\xF1\x91PP\x80`\x1F=\x11`\x01_Q\x14\x16\x15\x16\x15a\x12:WP\x83;\x15=\x17\x15[\x80a\x12~W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x14`$\x82\x01Rs\x15\x14\x90S\x94\xD1\x91T\x97\xD1\x94\x93\xD3W\xD1\x90RS\x11Q`b\x1B`D\x82\x01R`d\x01a\x06\x9FV[PPPPPV[3a\x12\xB7\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0T`\x01`\x01`\xA0\x1B\x03\x16\x90V[`\x01`\x01`\xA0\x1B\x03\x16\x14a\r\xBFW`@Qc\x11\x8C\xDA\xA7`\xE0\x1B\x81R3`\x04\x82\x01R`$\x01a\x06\x9FV[_`@Qc\xA9\x05\x9C\xBB`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x84\x16`\x04\x82\x01R\x82`$\x82\x01R` _`D\x83_\x89Z\xF1\x91PP\x80`\x1F=\x11`\x01_Q\x14\x16\x15\x16\x15a\x13*WP\x82;\x15=\x17\x15[\x80a\x13iW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x0F`$\x82\x01Rn\x15\x14\x90S\x94\xD1\x91T\x97\xD1\x90RS\x11Q`\x8A\x1B`D\x82\x01R`d\x01a\x06\x9FV[PPPPV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x03` R`@\x81 `\x01\x01T`\xFF\x16`\x02\x81\x11\x15a\x13\x9EWa\x13\x9Ea*\x0CV[\x14a\x11]W`@Qc\x13.~\xFB`\xE3\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`@\x80Q\x80\x82\x01\x90\x91R_\x80\x82R` \x82\x01Ra\x13\xD9\x82\x82a\x18\xCDV[\x15a\r\x01W`@Qc\x06\xCFC\x8F`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x04_a\x14\x03\x83a\r\xC1V[\x81R` \x81\x01\x91\x90\x91R`@\x01_ T`\xFF\x16\x15a\x11]W`@Qb\xDA\x8AW`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x14<\x82a\x18\xF0V[_`@Q\x80``\x01`@R\x80`$\x81R` \x01a.\x12`$\x919\x90P_\x84\x82`@Q` \x01a\x14l\x92\x91\x90a+\xCDV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P_a\x14\x87\x82a\x19\x86V[\x90Pa\x14\xA4\x81\x85a\x14\x97\x88a\x1AsV[a\x14\x9Fa\x1A\xEAV[a\x1B\xB7V[a\x14\xC0W`@Qb\xCE\xD3\xE5`\xE4\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[PPPPPPV[0`\x01`\x01`\xA0\x1B\x03\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14\x80a\x15NWP\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x01`\x01`\xA0\x1B\x03\x16a\x15B_Q` a.V_9_Q\x90_RT`\x01`\x01`\xA0\x1B\x03\x16\x90V[`\x01`\x01`\xA0\x1B\x03\x16\x14\x15[\x15a\r\xBFW`@Qcp>F\xDD`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x15ta\x12\x85V[`@Q`\x01`\x01`\xA0\x1B\x03\x82\x16\x81R\x7F\xF7\x87!\"n\xFE\x9A\x1B\xB6x\x18\x9A\x16\xD1UI(\xB9\xF2\x19.,\xB9>\xED\xA8;y\xFA@\0}\x90` \x01`@Q\x80\x91\x03\x90\xA1PV[\x81`\x01`\x01`\xA0\x1B\x03\x16cR\xD1\x90-`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x92PPP\x80\x15a\x16\rWP`@\x80Q`\x1F=\x90\x81\x01`\x1F\x19\x16\x82\x01\x90\x92Ra\x16\n\x91\x81\x01\x90a*PV[`\x01[a\x165W`@QcL\x9C\x8C\xE3`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x83\x16`\x04\x82\x01R`$\x01a\x06\x9FV[_Q` a.V_9_Q\x90_R\x81\x14a\x16eW`@Qc*\x87Ri`\xE2\x1B\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\x9FV[a\x16o\x83\x83a\x1C\x95V[PPPV[0`\x01`\x01`\xA0\x1B\x03\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14a\r\xBFW`@Qcp>F\xDD`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0\x80T`\x01`\x01`\xA0\x1B\x03\x19\x81\x16`\x01`\x01`\xA0\x1B\x03\x84\x81\x16\x91\x82\x17\x84U`@Q\x92\x16\x91\x82\x90\x7F\x8B\xE0\x07\x9CS\x16Y\x14\x13D\xCD\x1F\xD0\xA4\xF2\x84\x19I\x7F\x97\"\xA3\xDA\xAF\xE3\xB4\x18okdW\xE0\x90_\x90\xA3PPPV[a\x175a\x1C\xEAV[a\x11]\x81a\x1D3V[a\r\xBFa\x1C\xEAV[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0\x80T`\x01`@\x1B\x81\x04`\xFF\x16\x15\x90`\x01`\x01`@\x1B\x03\x16_\x81\x15\x80\x15a\x17\x8AWP\x82[\x90P_\x82`\x01`\x01`@\x1B\x03\x16`\x01\x14\x80\x15a\x17\xA5WP0;\x15[\x90P\x81\x15\x80\x15a\x17\xB3WP\x80\x15[\x15a\x17\xD1W`@Qc\xF9.\xE8\xA9`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x84Tg\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16`\x01\x17\x85U\x83\x15a\x17\xFBW\x84T`\xFF`@\x1B\x19\x16`\x01`@\x1B\x17\x85U[C_U\x83\x15a\x12~W\x84T`\xFF`@\x1B\x19\x16\x85U`@Q`\x01\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1PPPPPV[`\x01`\x01`\xA0\x1B\x03\x83\x16a\x18qW`@Qc\xD9.#=`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x82\x16a\x18\x98W`@Qc\xD9.#=`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02\x80T`\x01`\x01`\xA0\x1B\x03\x94\x85\x16`\x01`\x01`\xA0\x1B\x03\x19\x91\x82\x16\x17\x90\x91U`\x01\x80T\x93\x90\x94\x16\x92\x16\x91\x90\x91\x17\x90\x91U`\x08UV[\x80Q\x82Q_\x91\x14\x80\x15a\x18\xE7WP\x81` \x01Q\x83` \x01Q\x14[\x90P[\x92\x91PPV[\x80Q` \x82\x01Q_\x91_Q` a.6_9_Q\x90_R\x91\x15\x90\x15\x16\x15a\x19\x16WPPPV[\x82Q` \x84\x01Q\x82`\x03\x84\x85\x85\x86\t\x85\t\x08\x83\x82\x83\t\x14\x83\x82\x10\x84\x84\x10\x16\x16\x93PPP\x81a\x16oW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7FBn254: invalid G1 point\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\x9FV[`@\x80Q\x80\x82\x01\x90\x91R_\x80\x82R` \x82\x01R_a\x19\xA3\x83a\x1D;V[\x90P_Q` a.6_9_Q\x90_R`\x03_\x82\x84\x85\t\x90P\x82\x80a\x19\xCAWa\x19\xCAa+\xE9V[\x84\x82\t\x90P\x82\x80a\x19\xDDWa\x19\xDDa+\xE9V[\x82\x82\x08\x90P__a\x19\xED\x83a\x1FCV[\x92P\x90P[\x80a\x1AVW\x84\x80a\x1A\x05Wa\x1A\x05a+\xE9V[`\x01\x87\x08\x95P\x84\x80a\x1A\x19Wa\x1A\x19a+\xE9V[\x86\x87\t\x92P\x84\x80a\x1A,Wa\x1A,a+\xE9V[\x86\x84\t\x92P\x84\x80a\x1A?Wa\x1A?a+\xE9V[\x84\x84\x08\x92Pa\x1AM\x83a\x1FCV[\x92P\x90Pa\x19\xF2V[P`@\x80Q\x80\x82\x01\x90\x91R\x94\x85R` \x85\x01RP\x91\x94\x93PPPPV[`@\x80Q\x80\x82\x01\x90\x91R_\x80\x82R` \x82\x01R\x81Q` \x83\x01Q\x15\x90\x15\x16\x15a\x1A\x9AWP\x90V[`@Q\x80`@\x01`@R\x80\x83_\x01Q\x81R` \x01_Q` a.6_9_Q\x90_R\x84` \x01Qa\x1A\xCB\x91\x90a+\xFDV[a\x1A\xE2\x90_Q` a.6_9_Q\x90_Ra+=V[\x90R\x92\x91PPV[a\x1B\x11`@Q\x80`\x80\x01`@R\x80_\x81R` \x01_\x81R` \x01_\x81R` \x01_\x81RP\x90V[`@Q\x80`\x80\x01`@R\x80\x7F\x18\0\xDE\xEF\x12\x1F\x1EvBj\0f^\\DygC\"\xD4\xF7^\xDA\xDDF\xDE\xBD\\\xD9\x92\xF6\xED\x81R` \x01\x7F\x19\x8E\x93\x93\x92\rH:r`\xBF\xB71\xFB]%\xF1\xAAI35\xA9\xE7\x12\x97\xE4\x85\xB7\xAE\xF3\x12\xC2\x81R` \x01\x7F\x12\xC8^\xA5\xDB\x8Cm\xEBJ\xABq\x80\x8D\xCB@\x8F\xE3\xD1\xE7i\x0CC\xD3{L\xE6\xCC\x01f\xFA}\xAA\x81R` \x01\x7F\t\x06\x89\xD0X_\xF0u\xEC\x9E\x99\xADi\x0C3\x95\xBCK13p\xB3\x8E\xF3U\xAC\xDA\xDC\xD1\"\x97[\x81RP\x90P\x90V[___`@Q\x87Q\x81R` \x88\x01Q` \x82\x01R` \x87\x01Q`@\x82\x01R\x86Q``\x82\x01R``\x87\x01Q`\x80\x82\x01R`@\x87\x01Q`\xA0\x82\x01R\x85Q`\xC0\x82\x01R` \x86\x01Q`\xE0\x82\x01R` \x85\x01Qa\x01\0\x82\x01R\x84Qa\x01 \x82\x01R``\x85\x01Qa\x01@\x82\x01R`@\x85\x01Qa\x01`\x82\x01R` _a\x01\x80\x83`\x08Z\xFA\x91PP_Q\x91P\x80a\x1C\x89W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1C`$\x82\x01R\x7FBn254: Pairing check failed!\0\0\0\0`D\x82\x01R`d\x01a\x06\x9FV[P\x15\x15\x95\x94PPPPPV[a\x1C\x9E\x82a :V[`@Q`\x01`\x01`\xA0\x1B\x03\x83\x16\x90\x7F\xBC|\xD7Z \xEE'\xFD\x9A\xDE\xBA\xB3 A\xF7U!M\xBCk\xFF\xA9\x0C\xC0\"[9\xDA.\\-;\x90_\x90\xA2\x80Q\x15a\x1C\xE2Wa\x16o\x82\x82a \x9DV[a\r\x01a!\x0FV[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0T`\x01`@\x1B\x90\x04`\xFF\x16a\r\xBFW`@Qc\x1A\xFC\xD7\x9F`\xE3\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x11+a\x1C\xEAV[__a\x1DF\x83a!.V[\x80Q\x90\x91P`0\x81\x14a\x1D[Wa\x1D[a,\x1CV[_\x81`\x01`\x01`@\x1B\x03\x81\x11\x15a\x1DtWa\x1Dta%\xABV[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a\x1D\x9EW` \x82\x01\x81\x806\x837\x01\x90P[P\x90P_[\x82\x81\x10\x15a\x1E\rW\x83`\x01a\x1D\xB8\x83\x86a+=V[a\x1D\xC2\x91\x90a+=V[\x81Q\x81\x10a\x1D\xD2Wa\x1D\xD2a,0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x82\x82\x81Q\x81\x10a\x1D\xEFWa\x1D\xEFa,0V[` \x01\x01\x90`\x01`\x01`\xF8\x1B\x03\x19\x16\x90\x81_\x1A\x90SP`\x01\x01a\x1D\xA3V[P`@\x80Q`\x1F\x80\x82Ra\x04\0\x82\x01\x90\x92R_\x90\x82` \x82\x01a\x03\xE0\x806\x837\x01\x90PP\x90P_[\x82\x81\x10\x15a\x1E\x9DW\x83\x81a\x1EI\x85\x88a+=V[a\x1ES\x91\x90a*{V[\x81Q\x81\x10a\x1EcWa\x1Eca,0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B`\xF8\x1C\x82\x82\x81Q\x81\x10a\x1E\x83Wa\x1E\x83a,0V[`\xFF\x90\x92\x16` \x92\x83\x02\x91\x90\x91\x01\x90\x91\x01R`\x01\x01a\x1E5V[P_a\x1E\xA8\x82a$yV[\x90Pa\x01\0_Q` a.6_9_Q\x90_R_a\x1E\xC6\x86\x89a+=V[\x90P_[\x81\x81\x10\x15a\x1F3W_\x88`\x01a\x1E\xE0\x84\x86a+=V[a\x1E\xEA\x91\x90a+=V[\x81Q\x81\x10a\x1E\xFAWa\x1E\xFAa,0V[\x01` \x01Q`\xF8\x1C\x90P\x83\x80a\x1F\x12Wa\x1F\x12a+\xE9V[\x85\x87\t\x95P\x83\x80a\x1F%Wa\x1F%a+\xE9V[\x81\x87\x08\x95PP`\x01\x01a\x1E\xCAV[P\x92\x9A\x99PPPPPPPPPPV[_____\x7F\x0C\x19\x13\x9C\xB8Lh\nn\x14\x11m\xA0`V\x17e\xE0Z\xA4Z\x1Cr\xA3O\x08#\x05\xB6\x1F?R\x90P__Q` a.6_9_Q\x90_R\x90P`@Q` \x81R` \x80\x82\x01R` `@\x82\x01R\x87``\x82\x01R\x82`\x80\x82\x01R\x81`\xA0\x82\x01R` _`\xC0\x83`\x05Z\xFA\x94PP_Q\x92P\x83a \0W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1B`$\x82\x01R\x7Fpow precompile call failed!\0\0\0\0\0`D\x82\x01R`d\x01a\x06\x9FV[\x80`\x01\x84\x90\x1B\x11\x15a \x19Wa \x16\x83\x82a+=V[\x92P[\x80\x80a 'Wa 'a+\xE9V[\x83\x84\t\x96\x90\x96\x14\x96\x91\x95P\x90\x93PPPPV[\x80`\x01`\x01`\xA0\x1B\x03\x16;_\x03a oW`@QcL\x9C\x8C\xE3`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x82\x16`\x04\x82\x01R`$\x01a\x06\x9FV[_Q` a.V_9_Q\x90_R\x80T`\x01`\x01`\xA0\x1B\x03\x19\x16`\x01`\x01`\xA0\x1B\x03\x92\x90\x92\x16\x91\x90\x91\x17\x90UV[``__\x84`\x01`\x01`\xA0\x1B\x03\x16\x84`@Qa \xB9\x91\x90a,DV[_`@Q\x80\x83\x03\x81\x85Z\xF4\x91PP=\x80_\x81\x14a \xF1W`@Q\x91P`\x1F\x19`?=\x01\x16\x82\x01`@R=\x82R=_` \x84\x01>a \xF6V[``\x91P[P\x91P\x91Pa!\x06\x85\x83\x83a$\xE0V[\x95\x94PPPPPV[4\x15a\r\xBFW`@Qc\xB3\x98\x97\x9F`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`@\x80Q`0\x80\x82R``\x82\x81\x01\x90\x93R\x90` \x90`\x01`\xF9\x1B\x90_\x90\x84` \x82\x01\x81\x806\x837\x01\x90PP\x90P\x80\x86`@Q` \x01a!n\x92\x91\x90a+\xCDV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P\x80\x84`\xF8\x1B`@Q` \x01a!\x95\x92\x91\x90a,OV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P\x80`@Q` \x01a!\xB7\x91\x90a,yV[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x90\x82\x90R\x91Pa\x01\x01`\xF0\x1B\x90a!\xE1\x90\x83\x90\x83\x90` \x01a,\x91V[`@\x80Q\x80\x83\x03`\x1F\x19\x01\x81R\x82\x82R\x80Q` \x91\x82\x01 \x81\x84\x01\x81\x90R`\x01`\xF8\x1B\x84\x84\x01R`\x01`\x01`\xF0\x1B\x03\x19\x85\x16`A\x85\x01R\x82Q`#\x81\x86\x03\x01\x81R`C\x90\x94\x01\x90\x92R\x82Q\x90\x83\x01 \x91\x93P\x90_`\xFF\x88\x16`\x01`\x01`@\x1B\x03\x81\x11\x15a\"PWa\"Pa%\xABV[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a\"zW` \x82\x01\x81\x806\x837\x01\x90P[P\x90P_\x82`@Q` \x01a\"\x91\x91\x81R` \x01\x90V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x91\x90R\x90P_[\x81Q\x81\x10\x15a\"\xFBW\x81\x81\x81Q\x81\x10a\"\xC0Wa\"\xC0a,0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x83\x82\x81Q\x81\x10a\"\xDDWa\"\xDDa,0V[` \x01\x01\x90`\x01`\x01`\xF8\x1B\x03\x19\x16\x90\x81_\x1A\x90SP`\x01\x01a\"\xA5V[P_\x84`@Q` \x01a#\x10\x91\x81R` \x01\x90V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R` \x83\x01\x90\x91R_\x80\x83R\x91\x98P\x91P[\x89\x81\x10\x15a#\xA2W_\x83\x82\x81Q\x81\x10a#IWa#Ia,0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x83\x83\x81Q\x81\x10a#fWa#fa,0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x18\x90P\x88\x81`@Q` \x01a#\x87\x92\x91\x90a,\xB5V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x91\x90R\x98PP`\x01\x01a#.V[P\x86\x88\x87`@Q` \x01a#\xB8\x93\x92\x91\x90a,\xD9V[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x96P\x86\x80Q\x90` \x01 \x93P\x83`@Q` \x01a#\xE6\x91\x81R` \x01\x90V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x91\x90R\x91P_[a$\x07\x8A`\xFF\x8D\x16a+=V[\x81\x10\x15a$hW\x82\x81\x81Q\x81\x10a$ Wa$ a,0V[\x01` \x01Q`\x01`\x01`\xF8\x1B\x03\x19\x16\x84a$:\x83\x8Da*{V[\x81Q\x81\x10a$JWa$Ja,0V[` \x01\x01\x90`\x01`\x01`\xF8\x1B\x03\x19\x16\x90\x81_\x1A\x90SP`\x01\x01a#\xFAV[P\x91\x9B\x9APPPPPPPPPPPV[_\x80\x80[\x83Q\x81\x10\x15a$\xD9W\x83\x81\x81Q\x81\x10a$\x98Wa$\x98a,0V[` \x02` \x01\x01Q`\xFF\x16\x81`\x08a$\xB0\x91\x90a-\x0CV[a$\xBB\x90`\x02a.\x06V[a$\xC5\x91\x90a-\x0CV[a$\xCF\x90\x83a*{V[\x91P`\x01\x01a$}V[P\x92\x91PPV[``\x82a$\xF5Wa$\xF0\x82a%?V[a%8V[\x81Q\x15\x80\x15a%\x0CWP`\x01`\x01`\xA0\x1B\x03\x84\x16;\x15[\x15a%5W`@Qc\x99\x96\xB3\x15`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x85\x16`\x04\x82\x01R`$\x01a\x06\x9FV[P\x80[\x93\x92PPPV[\x80Q\x15a%OW\x80Q\x80\x82` \x01\xFD[`@Qc\n\x12\xF5!`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x805`\x01`\x01`\xA0\x1B\x03\x81\x16\x81\x14a%~W__\xFD[\x91\x90PV[__`@\x83\x85\x03\x12\x15a%\x94W__\xFD[a%\x9D\x83a%hV[\x94` \x93\x90\x93\x015\x93PPPV[cNH{q`\xE0\x1B_R`A`\x04R`$_\xFD[`@\x80Q\x90\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a%\xE1Wa%\xE1a%\xABV[`@R\x90V[_`\x80\x82\x84\x03\x12\x15a%\xF7W__\xFD[`@Q`\x80\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a&\x19Wa&\x19a%\xABV[`@\x90\x81R\x835\x82R` \x80\x85\x015\x90\x83\x01R\x83\x81\x015\x90\x82\x01R``\x92\x83\x015\x92\x81\x01\x92\x90\x92RP\x91\x90PV[_`@\x82\x84\x03\x12\x15a&WW__\xFD[a&_a%\xBFV[\x825\x81R` \x92\x83\x015\x92\x81\x01\x92\x90\x92RP\x91\x90PV[\x805a\xFF\xFF\x81\x16\x81\x14a%~W__\xFD[____a\x01 \x85\x87\x03\x12\x15a&\x9BW__\xFD[a&\xA5\x86\x86a%\xE7V[\x93Pa&\xB4\x86`\x80\x87\x01a&GV[\x92Pa&\xC3\x86`\xC0\x87\x01a&GV[\x91Pa&\xD2a\x01\0\x86\x01a&vV[\x90P\x92\x95\x91\x94P\x92PV[`\x01`\x01`@\x1B\x03\x81\x16\x81\x14a\x11]W__\xFD[_` \x82\x84\x03\x12\x15a'\x01W__\xFD[\x815a%8\x81a&\xDDV[_` \x82\x84\x03\x12\x15a'\x1CW__\xFD[a\x18\xE7\x82a%hV[_\x82`\x1F\x83\x01\x12a'4W__\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a'MWa'Ma%\xABV[`@Q`\x1F\x82\x01`\x1F\x19\x90\x81\x16`?\x01\x16\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a'{Wa'{a%\xABV[`@R\x81\x81R\x83\x82\x01` \x01\x85\x10\x15a'\x92W__\xFD[\x81` \x85\x01` \x83\x017_\x91\x81\x01` \x01\x91\x90\x91R\x93\x92PPPV[_____a\x01@\x86\x88\x03\x12\x15a'\xC3W__\xFD[a'\xCD\x87\x87a%\xE7V[\x94Pa'\xDC\x87`\x80\x88\x01a&GV[\x93Pa'\xEB\x87`\xC0\x88\x01a&GV[\x92Pa\x01\0\x86\x015`\x01`\x01`@\x1B\x03\x81\x11\x15a(\x06W__\xFD[a(\x12\x88\x82\x89\x01a'%V[\x92PPa(\"a\x01 \x87\x01a&vV[\x90P\x92\x95P\x92\x95\x90\x93PV[__`@\x83\x85\x03\x12\x15a(?W__\xFD[a(H\x83a%hV[\x91P` \x83\x015`\x01`\x01`@\x1B\x03\x81\x11\x15a(bW__\xFD[a(n\x85\x82\x86\x01a'%V[\x91PP\x92P\x92\x90PV[___a\x01\0\x84\x86\x03\x12\x15a(\x8BW__\xFD[a(\x95\x85\x85a%\xE7V[\x92Pa(\xA4\x85`\x80\x86\x01a&GV[\x91Pa(\xB3\x85`\xC0\x86\x01a&GV[\x90P\x92P\x92P\x92V[_`\x80\x82\x84\x03\x12\x15a(\xCCW__\xFD[a\x18\xE7\x83\x83a%\xE7V[__`@\x83\x85\x03\x12\x15a(\xE7W__\xFD[a(\xF0\x83a%hV[\x91Pa(\xFE` \x84\x01a%hV[\x90P\x92P\x92\x90PV[____a\x01 \x85\x87\x03\x12\x15a)\x1BW__\xFD[a)%\x86\x86a%\xE7V[\x93Pa)4\x86`\x80\x87\x01a&GV[\x92Pa)C\x86`\xC0\x87\x01a&GV[\x91Pa\x01\0\x85\x015`\x01`\x01`@\x1B\x03\x81\x11\x15a)^W__\xFD[a)j\x87\x82\x88\x01a'%V[\x91PP\x92\x95\x91\x94P\x92PV[_\x81Q\x80\x84R\x80` \x84\x01` \x86\x01^_` \x82\x86\x01\x01R` `\x1F\x19`\x1F\x83\x01\x16\x85\x01\x01\x91PP\x92\x91PPV[` \x81R_a\x18\xE7` \x83\x01\x84a)vV[_` \x82\x84\x03\x12\x15a)\xC6W__\xFD[P5\x91\x90PV[____`\x80\x85\x87\x03\x12\x15a)\xE0W__\xFD[a)\xE9\x85a%hV[\x93Pa)\xF7` \x86\x01a%hV[\x92P`@\x85\x015\x91Pa&\xD2``\x86\x01a%hV[cNH{q`\xE0\x1B_R`!`\x04R`$_\xFD[\x82\x81R`@\x81\x01`\x03\x83\x10a*CWcNH{q`\xE0\x1B_R`!`\x04R`$_\xFD[\x82` \x83\x01R\x93\x92PPPV[_` \x82\x84\x03\x12\x15a*`W__\xFD[PQ\x91\x90PV[cNH{q`\xE0\x1B_R`\x11`\x04R`$_\xFD[\x80\x82\x01\x80\x82\x11\x15a\x18\xEAWa\x18\xEAa*gV[_` \x82\x84\x03\x12\x15a*\x9EW__\xFD[\x81Qa%8\x81a&\xDDV[`\x01`\x01`@\x1B\x03\x81\x81\x16\x83\x82\x16\x02\x90\x81\x16\x90\x81\x81\x14a$\xD9Wa$\xD9a*gV[\x85Q\x81R` \x80\x87\x01Q\x90\x82\x01R`@\x80\x87\x01Q\x90\x82\x01R``\x80\x87\x01Q\x90\x82\x01R\x84Q`\x80\x82\x01R` \x85\x01Q`\xA0\x82\x01Ra\xFF\xFF\x84\x16`\xC0\x82\x01R\x82Q`\xE0\x82\x01R` \x83\x01Qa\x01\0\x82\x01Ra\x01@a\x01 \x82\x01R_a+2a\x01@\x83\x01\x84a)vV[\x97\x96PPPPPPPV[\x81\x81\x03\x81\x81\x11\x15a\x18\xEAWa\x18\xEAa*gV[\x84Q\x81R` \x80\x86\x01Q\x90\x82\x01R`@\x80\x86\x01Q\x90\x82\x01R``\x80\x86\x01Q\x90\x82\x01R\x83Q`\x80\x82\x01R` \x84\x01Q`\xA0\x82\x01R\x82Q`\xC0\x82\x01R` \x83\x01Q`\xE0\x82\x01Ra\x01 a\x01\0\x82\x01R_a+\xACa\x01 \x83\x01\x84a)vV[\x96\x95PPPPPPV[_\x81Q\x80` \x84\x01\x85^_\x93\x01\x92\x83RP\x90\x91\x90PV[_a+\xE1a+\xDB\x83\x86a+\xB6V[\x84a+\xB6V[\x94\x93PPPPV[cNH{q`\xE0\x1B_R`\x12`\x04R`$_\xFD[_\x82a,\x17WcNH{q`\xE0\x1B_R`\x12`\x04R`$_\xFD[P\x06\x90V[cNH{q`\xE0\x1B_R`\x01`\x04R`$_\xFD[cNH{q`\xE0\x1B_R`2`\x04R`$_\xFD[_a\x18\xE7\x82\x84a+\xB6V[_a,Z\x82\x85a+\xB6V[_\x81R`\x01`\x01`\xF8\x1B\x03\x19\x93\x90\x93\x16`\x01\x84\x01RPP`\x02\x01\x91\x90PV[_a,\x84\x82\x84a+\xB6V[_\x81R`\x01\x01\x93\x92PPPV[_a,\x9C\x82\x85a+\xB6V[`\x01`\x01`\xF0\x1B\x03\x19\x93\x90\x93\x16\x83RPP`\x02\x01\x91\x90PV[_a,\xC0\x82\x85a+\xB6V[`\x01`\x01`\xF8\x1B\x03\x19\x93\x90\x93\x16\x83RPP`\x01\x01\x91\x90PV[_a,\xE4\x82\x86a+\xB6V[`\x01`\x01`\xF8\x1B\x03\x19\x94\x90\x94\x16\x84RPP`\x01`\x01`\xF0\x1B\x03\x19\x16`\x01\x82\x01R`\x03\x01\x91\x90PV[\x80\x82\x02\x81\x15\x82\x82\x04\x84\x14\x17a\x18\xEAWa\x18\xEAa*gV[`\x01\x81[`\x01\x84\x11\x15a-^W\x80\x85\x04\x81\x11\x15a-BWa-Ba*gV[`\x01\x84\x16\x15a-PW\x90\x81\x02\x90[`\x01\x93\x90\x93\x1C\x92\x80\x02a-'V[\x93P\x93\x91PPV[_\x82a-tWP`\x01a\x18\xEAV[\x81a-\x80WP_a\x18\xEAV[\x81`\x01\x81\x14a-\x96W`\x02\x81\x14a-\xA0Wa-\xBCV[`\x01\x91PPa\x18\xEAV[`\xFF\x84\x11\x15a-\xB1Wa-\xB1a*gV[PP`\x01\x82\x1Ba\x18\xEAV[P` \x83\x10a\x013\x83\x10\x16`N\x84\x10`\x0B\x84\x10\x16\x17\x15a-\xDFWP\x81\x81\na\x18\xEAV[a-\xEB_\x19\x84\x84a-#V[\x80_\x19\x04\x82\x11\x15a-\xFEWa-\xFEa*gV[\x02\x93\x92PPPV[_a\x18\xE7\x83\x83a-fV\xFEBLS_SIG_BN254G1_XMD:KECCAK_NCTH_NUL_0dNr\xE11\xA0)\xB8PE\xB6\x81\x81X]\x97\x81j\x91hq\xCA\x8D< \x8C\x16\xD8|\xFDG6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\xA1dsolcC\0\x08\x1C\0\n", ); /// The runtime bytecode of the contract, as deployed on the network. /// /// ```text - ///0x6080604052600436106101af575f3560e01c80639e9a8f31116100e7578063b5ecb34411610087578063e53b2a7411610062578063e53b2a7414610539578063f2fde38b14610558578063fa52c7d814610577578063fc0c546a146105ba575f5ffd5b8063b5ecb344146104b9578063be203094146104e4578063c64814dd14610503575f5ffd5b8063a5857ff3116100c2578063a5857ff314610400578063ad3cb1cc1461041f578063b3e6ebd51461045c578063b5700e681461049a575f5ffd5b80639e9a8f311461037a578063a2d78dd51461038f578063a3066aab146103e1575f5ffd5b80634f1ef286116101525780636a911ccf1161012d5780636a911ccf146102e3578063715018a6146102f75780638da5cb5b1461030b5780639b30a5e61461035b575f5ffd5b80634f1ef286146102a257806352d1902d146102b55780635544c2f1146102c9575f5ffd5b80631a20cd631161018d5780631a20cd63146102235780632140fecd146102425780633e9df9b5146102615780634d99dd1614610283575f5ffd5b8063026e402b146101b35780630d8e6e2c146101d457806313b9057a14610204575b5f5ffd5b3480156101be575f5ffd5b506101d26101cd366004612616565b6105d9565b005b3480156101df575f5ffd5b5060408051600281525f60208201819052918101919091526060015b60405180910390f35b34801561020f575f5ffd5b506101d261021e36600461274a565b61077c565b34801561022e575f5ffd5b506101d261023d3660046127b4565b610795565b34801561024d575f5ffd5b506101d261025c3660046127cf565b6108a9565b34801561026c575f5ffd5b506102755f5481565b6040519081526020016101fb565b34801561028e575f5ffd5b506101d261029d366004612616565b6109ca565b6101d26102b03660046127e8565b610b7c565b3480156102c0575f5ffd5b50610275610b9b565b3480156102d4575f5ffd5b506101d261021e36600461288b565b3480156102ee575f5ffd5b506101d2610bb6565b348015610302575f5ffd5b506101d2610c44565b348015610316575f5ffd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03165b6040516001600160a01b0390911681526020016101fb565b348015610366575f5ffd5b506102756103753660046128cf565b610c57565b348015610385575f5ffd5b5061027560085481565b34801561039a575f5ffd5b506103cc6103a93660046128e9565b600760209081525f92835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101fb565b3480156103ec575f5ffd5b506101d26103fb3660046127cf565b610cb1565b34801561040b575f5ffd5b506101d261041a36600461291a565b610dc1565b34801561042a575f5ffd5b5061044f604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516101fb9190612982565b348015610467575f5ffd5b5061048a6104763660046129b7565b60046020525f908152604090205460ff1681565b60405190151581526020016101fb565b3480156104a5575f5ffd5b50600154610343906001600160a01b031681565b3480156104c4575f5ffd5b506102756104d33660046127cf565b60056020525f908152604090205481565b3480156104ef575f5ffd5b506101d26104fe3660046129ce565b610f79565b34801561050e575f5ffd5b5061027561051d3660046128e9565b600660209081525f928352604080842090915290825290205481565b348015610544575f5ffd5b506101d2610553366004612a0d565b6110a3565b348015610563575f5ffd5b506101d26105723660046127cf565b6111b6565b348015610582575f5ffd5b506105ac6105913660046127cf565b60036020525f90815260409020805460019091015460ff1682565b6040516101fb929190612a6d565b3480156105c5575f5ffd5b50600254610343906001600160a01b031681565b6105e2826111f3565b335f82900361060457604051631f2a200560e01b815260040160405180910390fd5b600254604051636eb1769f60e11b81526001600160a01b0383811660048301523060248301525f92169063dd62ed3e90604401602060405180830381865afa158015610652573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106769190612a9d565b9050828110156106a85760405163054365bb60e31b815260048101829052602481018490526044015b60405180910390fd5b6002546106c0906001600160a01b0316833086611274565b6001600160a01b0384165f90815260036020526040812080548592906106e7908490612ac8565b90915550506001600160a01b038085165f90815260066020908152604080832093861683529290529081208054859290610722908490612ac8565b92505081905550836001600160a01b0316826001600160a01b03167fe5541a6b6103d4fa7e021ed54fad39c66f27a76bd13d374cf6240ae6bd0bb72b8560405161076e91815260200190565b60405180910390a350505050565b60405163c2d7f81360e01b815260040160405180910390fd5b61079d611318565b60015460408051633c1a081560e21b815290515f926001600160a01b03169163f06820549160048083019260209291908290030181865afa1580156107e4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108089190612adb565b61081390600f612af6565b9050621275006001600160401b0380831690841610806108445750806001600160401b0316836001600160401b0316115b156108625760405163b57e21df60e01b815260040160405180910390fd5b6001600160401b03831660088190556040519081527f793e3b1e1bcd677bb11900c83124d3c44c9946ea8ddf978a0ca250b034ec9dde9060200160405180910390a1505050565b6001600160a01b0381165f9081526005602052604081205433918190036108e3576040516379298a5360e11b815260040160405180910390fd5b8042101561090457604051635a77435760e01b815260040160405180910390fd5b6001600160a01b038084165f9081526006602090815260408083209386168352929052908120549081900361094c57604051630686827b60e51b815260040160405180910390fd5b6001600160a01b038085165f908152600660209081526040808320878516845290915281205560025461098191168483611373565b826001600160a01b03167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040516109bc91815260200190565b60405180910390a250505050565b6109d3826111f3565b335f8290036109f557604051631f2a200560e01b815260040160405180910390fd5b6001600160a01b038084165f9081526007602090815260408083209385168352929052205415610a385760405163d423a4f160e01b815260040160405180910390fd5b6001600160a01b038084165f9081526006602090815260408083209385168352929052205482811015610a8157604051639266535160e01b81526004810182905260240161069f565b6001600160a01b038085165f90815260066020908152604080832093861683529290529081208054859290610ab7908490612b18565b92505081905550604051806040016040528084815260200160085442610add9190612ac8565b90526001600160a01b038086165f81815260076020908152604080832094881683529381528382208551815594810151600190950194909455908152600390925281208054859290610b30908490612b18565b92505081905550836001600160a01b0316826001600160a01b03167f4d10bd049775c77bd7f255195afba5088028ecb3c7c277d393ccff7934f2f92c8560405161076e91815260200190565b610b84611402565b610b8d826114a6565b610b9782826114ed565b5050565b5f610ba46115ae565b505f516020612dcb5f395f51905f5290565b33610bc0816111f3565b6001600160a01b0381165f908152600360205260409020600101805460ff19166002179055600854610bf29042612ac8565b6001600160a01b0382165f8181526005602090815260408083209490945560039052828120819055915190917ffb24305354c87762d557487ae4a564e8d03ecbb9a97dd8afff8e1f6fcaf0dd1691a250565b610c4c611318565b610c555f6115f7565b565b5f815f0151826020015183604001518460600151604051602001610c94949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b6001600160a01b0381165f9081526007602090815260408083203380855292528220549091819003610cf657604051630686827b60e51b815260040160405180910390fd5b6001600160a01b038084165f90815260076020908152604080832093861683529290522060010154421015610d3e57604051635a77435760e01b815260040160405180910390fd5b6001600160a01b038084165f9081526007602090815260408083208685168452909152812081815560010155600254610d7991168383611373565b816001600160a01b03167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6582604051610db491815260200190565b60405180910390a2505050565b33610dcb81611667565b610dd4856116b4565b610ddd866116ef565b604080516001600160a01b03831660208201525f91016040516020818303038152906040529050610e0f81868961172b565b6127108361ffff161115610e365760405163dc81db8560e01b815260040160405180910390fd5b600160045f610e448a610c57565b81526020019081526020015f205f6101000a81548160ff02191690831515021790555060405180604001604052805f815260200160016002811115610e8b57610e8b612a59565b90526001600160a01b0383165f908152600360209081526040909120825181559082015160018083018054909160ff1990911690836002811115610ed157610ed1612a59565b02179055505060408051895181526020808b0151818301528a830151828401526060808c015190830152895160808301528981015160a083015261ffff871660c0830152885160e083015288810151610100830152875161012083015287015161014082015290516001600160a01b03851692507f8e1c394d8f3c83d8e24d20790bd0586fe71354810a93c2ee368b418745553b2e918190036101600190a250505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f81158015610fbd5750825b90505f826001600160401b03166001148015610fd85750303b155b905081158015610fe6575080155b156110045760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561102e57845460ff60401b1916600160401b1785555b611037866117c0565b61103f6117d1565b6110476117d9565b6110528989896118dd565b831561109857845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b336110ad816111f3565b6110b6846116b4565b6110bf856116ef565b604080516001600160a01b03831660208201525f910160405160208183030381529060405290506110f181858861172b565b600160045f6110ff89610c57565b815260208082019290925260409081015f20805460ff1916931515939093179092558151885181528882015181830152888301519281019290925260608089015190830152865160808301528681015160a0830152855160c08301528581015160e083015284516101008301528401516101208201526001600160a01b038316907f04cf8cf47a6bf2ea5f71b8eebdec9de2117f47d2b67bc608338f81acb1a466d5906101400160405180910390a2505050505050565b6111be611318565b6001600160a01b0381166111e757604051631e4fbdf760e01b81525f600482015260240161069f565b6111f0816115f7565b50565b6001600160a01b0381165f9081526003602052604081206001015460ff169081600281111561122457611224612a59565b036112425760405163508a793f60e01b815260040160405180910390fd5b600281600281111561125657611256612a59565b03610b975760405163eab4a96360e01b815260040160405180910390fd5b5f6040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260205f6064835f8a5af191505080601f3d1160015f5114161516156112cd5750833b153d17155b806113115760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b604482015260640161069f565b5050505050565b3361134a7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b031614610c555760405163118cdaa760e01b815233600482015260240161069f565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af191505080601f3d1160015f5114161516156113bd5750823b153d17155b806113fc5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015260640161069f565b50505050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061148857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661147c5f516020612dcb5f395f51905f52546001600160a01b031690565b6001600160a01b031614155b15610c555760405163703e46dd60e11b815260040160405180910390fd5b6114ae611318565b6040516001600160a01b03821681527ff78721226efe9a1bb678189a16d1554928b9f2192e2cb93eeda83b79fa40007d9060200160405180910390a150565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611547575060408051601f3d908101601f1916820190925261154491810190612a9d565b60015b61156f57604051634c9c8ce360e01b81526001600160a01b038316600482015260240161069f565b5f516020612dcb5f395f51905f52811461159f57604051632a87526960e21b81526004810182905260240161069f565b6115a98383611960565b505050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c555760405163703e46dd60e11b815260040160405180910390fd5b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b6001600160a01b0381165f9081526003602052604081206001015460ff16600281111561169657611696612a59565b146111f05760405163132e7efb60e31b815260040160405180910390fd5b604080518082019091525f80825260208201526116d182826119b5565b15610b97576040516306cf438f60e01b815260040160405180910390fd5b60045f6116fb83610c57565b815260208101919091526040015f205460ff16156111f05760405162da8a5760e11b815260040160405180910390fd5b611734826119d8565b5f604051806060016040528060248152602001612d876024913990505f8482604051602001611764929190612b42565b60405160208183030381529060405290505f61177f82611a6e565b905061179c818561178f88611b5b565b611797611bd2565b611c9f565b6117b85760405162ced3e560e41b815260040160405180910390fd5b505050505050565b6117c8611d7d565b6111f081611dc6565b610c55611d7d565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f8115801561181d5750825b90505f826001600160401b031660011480156118385750303b155b905081158015611846575080155b156118645760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561188e57845460ff60401b1916600160401b1785555b435f55831561131157845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050565b6001600160a01b0383166119045760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03821661192b5760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b039485166001600160a01b0319918216179091556001805493909416921691909117909155600855565b61196982611dce565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a28051156119ad576115a98282611e31565b610b97611ea3565b805182515f911480156119cf575081602001518360200151145b90505b92915050565b805160208201515f915f516020612dab5f395f51905f529115901516156119fe57505050565b8251602084015182600384858586098509088382830914838210848410161693505050816115a95760405162461bcd60e51b815260206004820152601760248201527f426e3235343a20696e76616c696420473120706f696e74000000000000000000604482015260640161069f565b604080518082019091525f80825260208201525f611a8b83611ec2565b90505f516020612dab5f395f51905f5260035f8284850990508280611ab257611ab2612b5e565b84820990508280611ac557611ac5612b5e565b82820890505f5f611ad5836120ca565b925090505b80611b3e578480611aed57611aed612b5e565b6001870895508480611b0157611b01612b5e565b86870992508480611b1457611b14612b5e565b86840992508480611b2757611b27612b5e565b8484089250611b35836120ca565b92509050611ada565b506040805180820190915294855260208501525091949350505050565b604080518082019091525f8082526020820152815160208301511590151615611b82575090565b6040518060400160405280835f015181526020015f516020612dab5f395f51905f528460200151611bb39190612b72565b611bca905f516020612dab5f395f51905f52612b18565b905292915050565b611bf960405180608001604052805f81526020015f81526020015f81526020015f81525090565b60405180608001604052807f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed81526020017f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa81526020017f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b815250905090565b5f5f5f6040518751815260208801516020820152602087015160408201528651606082015260608701516080820152604087015160a0820152855160c0820152602086015160e0820152602085015161010082015284516101208201526060850151610140820152604085015161016082015260205f6101808360085afa9150505f51915080611d715760405162461bcd60e51b815260206004820152601c60248201527f426e3235343a2050616972696e6720636865636b206661696c65642100000000604482015260640161069f565b50151595945050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16610c5557604051631afcd79f60e31b815260040160405180910390fd5b6111be611d7d565b806001600160a01b03163b5f03611e0357604051634c9c8ce360e01b81526001600160a01b038216600482015260240161069f565b5f516020612dcb5f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b031684604051611e4d9190612b91565b5f60405180830381855af49150503d805f8114611e85576040519150601f19603f3d011682016040523d82523d5f602084013e611e8a565b606091505b5091509150611e9a8583836121c1565b95945050505050565b3415610c555760405163b398979f60e01b815260040160405180910390fd5b5f5f611ecd83612220565b805190915060308114611ee257611ee2612b9c565b5f816001600160401b03811115611efb57611efb61263e565b6040519080825280601f01601f191660200182016040528015611f25576020820181803683370190505b5090505f5b82811015611f9457836001611f3f8386612b18565b611f499190612b18565b81518110611f5957611f59612bb0565b602001015160f81c60f81b828281518110611f7657611f76612bb0565b60200101906001600160f81b03191690815f1a905350600101611f2a565b5060408051601f80825261040082019092525f9082602082016103e0803683370190505090505f5b82811015612024578381611fd08588612b18565b611fda9190612ac8565b81518110611fea57611fea612bb0565b602001015160f81c60f81b60f81c82828151811061200a5761200a612bb0565b60ff90921660209283029190910190910152600101611fbc565b505f61202f8261256b565b90506101005f516020612dab5f395f51905f525f61204d8689612b18565b90505f5b818110156120ba575f8860016120678486612b18565b6120719190612b18565b8151811061208157612081612bb0565b016020015160f81c9050838061209957612099612b5e565b858709955083806120ac576120ac612b5e565b818708955050600101612051565b50929a9950505050505050505050565b5f5f5f5f5f7f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f5290505f5f516020612dab5f395f51905f52905060405160208152602080820152602060408201528760608201528260808201528160a082015260205f60c08360055afa9450505f519250836121875760405162461bcd60e51b815260206004820152601b60248201527f706f7720707265636f6d70696c652063616c6c206661696c6564210000000000604482015260640161069f565b80600184901b11156121a05761219d8382612b18565b92505b80806121ae576121ae612b5e565b8384099690961496919550909350505050565b6060826121d6576121d1826125d2565b612219565b81511580156121ed57506001600160a01b0384163b155b1561221657604051639996b31560e01b81526001600160a01b038516600482015260240161069f565b50805b9392505050565b604080516030808252606082810190935290602090600160f91b905f90846020820181803683370190505090508086604051602001612260929190612b42565b6040516020818303038152906040529050808460f81b604051602001612287929190612bc4565b6040516020818303038152906040529050806040516020016122a99190612bee565b60408051601f1981840301815290829052915061010160f01b906122d39083908390602001612c06565b60408051808303601f190181528282528051602091820120818401819052600160f81b848401526001600160f01b031985166041850152825160238186030181526043909401909252825190830120919350905f60ff88166001600160401b038111156123425761234261263e565b6040519080825280601f01601f19166020018201604052801561236c576020820181803683370190505b5090505f8260405160200161238391815260200190565b60408051601f1981840301815291905290505f5b81518110156123ed578181815181106123b2576123b2612bb0565b602001015160f81c60f81b8382815181106123cf576123cf612bb0565b60200101906001600160f81b03191690815f1a905350600101612397565b505f8460405160200161240291815260200190565b60408051601f19818403018152602083019091525f80835291985091505b89811015612494575f83828151811061243b5761243b612bb0565b602001015160f81c60f81b83838151811061245857612458612bb0565b602001015160f81c60f81b1890508881604051602001612479929190612c2a565b60408051601f19818403018152919052985050600101612420565b508688876040516020016124aa93929190612c4e565b604051602081830303815290604052965086805190602001209350836040516020016124d891815260200190565b60408051601f1981840301815291905291505f5b6124f98a60ff8d16612b18565b81101561255a5782818151811061251257612512612bb0565b01602001516001600160f81b0319168461252c838d612ac8565b8151811061253c5761253c612bb0565b60200101906001600160f81b03191690815f1a9053506001016124ec565b50919b9a5050505050505050505050565b5f80805b83518110156125cb5783818151811061258a5761258a612bb0565b602002602001015160ff168160086125a29190612c81565b6125ad906002612d7b565b6125b79190612c81565b6125c19083612ac8565b915060010161256f565b5092915050565b8051156125e25780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b80356001600160a01b0381168114612611575f5ffd5b919050565b5f5f60408385031215612627575f5ffd5b612630836125fb565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156126745761267461263e565b60405290565b604051601f8201601f191681016001600160401b03811182821017156126a2576126a261263e565b604052919050565b5f608082840312156126ba575f5ffd5b604051608081016001600160401b03811182821017156126dc576126dc61263e565b6040908152833582526020808501359083015283810135908201526060928301359281019290925250919050565b5f6040828403121561271a575f5ffd5b612722612652565b823581526020928301359281019290925250919050565b803561ffff81168114612611575f5ffd5b5f5f5f5f610120858703121561275e575f5ffd5b61276886866126aa565b9350612777866080870161270a565b92506127868660c0870161270a565b91506127956101008601612739565b905092959194509250565b6001600160401b03811681146111f0575f5ffd5b5f602082840312156127c4575f5ffd5b8135612219816127a0565b5f602082840312156127df575f5ffd5b6119cf826125fb565b5f5f604083850312156127f9575f5ffd5b612802836125fb565b915060208301356001600160401b0381111561281c575f5ffd5b8301601f8101851361282c575f5ffd5b80356001600160401b038111156128455761284561263e565b612858601f8201601f191660200161267a565b81815286602083850101111561286c575f5ffd5b816020840160208301375f602083830101528093505050509250929050565b5f5f5f610100848603121561289e575f5ffd5b6128a885856126aa565b92506128b7856080860161270a565b91506128c68560c0860161270a565b90509250925092565b5f608082840312156128df575f5ffd5b6119cf83836126aa565b5f5f604083850312156128fa575f5ffd5b612903836125fb565b9150612911602084016125fb565b90509250929050565b5f5f5f5f5f610160868803121561292f575f5ffd5b61293987876126aa565b9450612948876080880161270a565b93506129578760c0880161270a565b925061296787610100880161270a565b91506129766101408701612739565b90509295509295909350565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156129c7575f5ffd5b5035919050565b5f5f5f5f608085870312156129e1575f5ffd5b6129ea856125fb565b93506129f8602086016125fb565b925060408501359150612795606086016125fb565b5f5f5f5f6101408587031215612a21575f5ffd5b612a2b86866126aa565b9350612a3a866080870161270a565b9250612a498660c0870161270a565b915061279586610100870161270a565b634e487b7160e01b5f52602160045260245ffd5b8281526040810160038310612a9057634e487b7160e01b5f52602160045260245ffd5b8260208301529392505050565b5f60208284031215612aad575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156119d2576119d2612ab4565b5f60208284031215612aeb575f5ffd5b8151612219816127a0565b6001600160401b0381811683821602908116908181146125cb576125cb612ab4565b818103818111156119d2576119d2612ab4565b5f81518060208401855e5f93019283525090919050565b5f612b56612b508386612b2b565b84612b2b565b949350505050565b634e487b7160e01b5f52601260045260245ffd5b5f82612b8c57634e487b7160e01b5f52601260045260245ffd5b500690565b5f6119cf8284612b2b565b634e487b7160e01b5f52600160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f612bcf8285612b2b565b5f81526001600160f81b03199390931660018401525050600201919050565b5f612bf98284612b2b565b5f81526001019392505050565b5f612c118285612b2b565b6001600160f01b03199390931683525050600201919050565b5f612c358285612b2b565b6001600160f81b03199390931683525050600101919050565b5f612c598286612b2b565b6001600160f81b031994909416845250506001600160f01b0319166001820152600301919050565b80820281158282048414176119d2576119d2612ab4565b6001815b6001841115612cd357808504811115612cb757612cb7612ab4565b6001841615612cc557908102905b60019390931c928002612c9c565b935093915050565b5f82612ce9575060016119d2565b81612cf557505f6119d2565b8160018114612d0b5760028114612d1557612d31565b60019150506119d2565b60ff841115612d2657612d26612ab4565b50506001821b6119d2565b5060208310610133831016604e8410600b8410161715612d54575081810a6119d2565b612d605f198484612c98565b805f1904821115612d7357612d73612ab4565b029392505050565b5f6119cf8383612cdb56fe424c535f5349475f424e32353447315f584d443a4b454343414b5f4e4354485f4e554c5f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca164736f6c634300081c000a + ///0x6080604052600436106101af575f3560e01c80639b30a5e6116100e7578063b5700e6811610087578063c64814dd11610062578063c64814dd14610522578063f2fde38b14610558578063fa52c7d814610577578063fc0c546a146105ba575f5ffd5b8063b5700e68146104b9578063b5ecb344146104d8578063be20309414610503575f5ffd5b8063a3066aab116100c2578063a3066aab14610400578063ac5c2ad01461041f578063ad3cb1cc1461043e578063b3e6ebd51461047b575f5ffd5b80639b30a5e61461037a5780639e9a8f3114610399578063a2d78dd5146103ae575f5ffd5b80634d99dd16116101525780635544c2f11161012d5780635544c2f1146102e85780636a911ccf14610302578063715018a6146103165780638da5cb5b1461032a575f5ffd5b80634d99dd16146102a25780634f1ef286146102c157806352d1902d146102d4575f5ffd5b80631a20cd631161018d5780631a20cd63146102235780632140fecd14610242578063304240bf146102615780633e9df9b514610280575f5ffd5b8063026e402b146101b35780630d8e6e2c146101d457806313b9057a14610204575b5f5ffd5b3480156101be575f5ffd5b506101d26101cd366004612583565b6105d9565b005b3480156101df575f5ffd5b5060408051600281525f60208201819052918101919091526060015b60405180910390f35b34801561020f575f5ffd5b506101d261021e366004612687565b61077c565b34801561022e575f5ffd5b506101d261023d3660046126f1565b610795565b34801561024d575f5ffd5b506101d261025c36600461270c565b6108a9565b34801561026c575f5ffd5b506101d261027b3660046127ae565b6109ca565b34801561028b575f5ffd5b506102945f5481565b6040519081526020016101fb565b3480156102ad575f5ffd5b506101d26102bc366004612583565b610b34565b6101d26102cf36600461282e565b610ce6565b3480156102df575f5ffd5b50610294610d05565b3480156102f3575f5ffd5b506101d261021e366004612878565b34801561030d575f5ffd5b506101d2610d20565b348015610321575f5ffd5b506101d2610dae565b348015610335575f5ffd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b03165b6040516001600160a01b0390911681526020016101fb565b348015610385575f5ffd5b506102946103943660046128bc565b610dc1565b3480156103a4575f5ffd5b5061029460085481565b3480156103b9575f5ffd5b506103eb6103c83660046128d6565b600760209081525f92835260408084209091529082529020805460019091015482565b604080519283526020830191909152016101fb565b34801561040b575f5ffd5b506101d261041a36600461270c565b610e1b565b34801561042a575f5ffd5b506101d2610439366004612907565b610f2b565b348015610449575f5ffd5b5061046e604051806040016040528060058152602001640352e302e360dc1b81525081565b6040516101fb91906129a4565b348015610486575f5ffd5b506104a96104953660046129b6565b60046020525f908152604090205460ff1681565b60405190151581526020016101fb565b3480156104c4575f5ffd5b50600154610362906001600160a01b031681565b3480156104e3575f5ffd5b506102946104f236600461270c565b60056020525f908152604090205481565b34801561050e575f5ffd5b506101d261051d3660046129cd565b610ff9565b34801561052d575f5ffd5b5061029461053c3660046128d6565b600660209081525f928352604080842090915290825290205481565b348015610563575f5ffd5b506101d261057236600461270c565b611123565b348015610582575f5ffd5b506105ac61059136600461270c565b60036020525f90815260409020805460019091015460ff1682565b6040516101fb929190612a20565b3480156105c5575f5ffd5b50600254610362906001600160a01b031681565b6105e282611160565b335f82900361060457604051631f2a200560e01b815260040160405180910390fd5b600254604051636eb1769f60e11b81526001600160a01b0383811660048301523060248301525f92169063dd62ed3e90604401602060405180830381865afa158015610652573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106769190612a50565b9050828110156106a85760405163054365bb60e31b815260048101829052602481018490526044015b60405180910390fd5b6002546106c0906001600160a01b03168330866111e1565b6001600160a01b0384165f90815260036020526040812080548592906106e7908490612a7b565b90915550506001600160a01b038085165f90815260066020908152604080832093861683529290529081208054859290610722908490612a7b565b92505081905550836001600160a01b0316826001600160a01b03167fe5541a6b6103d4fa7e021ed54fad39c66f27a76bd13d374cf6240ae6bd0bb72b8560405161076e91815260200190565b60405180910390a350505050565b60405163c2d7f81360e01b815260040160405180910390fd5b61079d611285565b60015460408051633c1a081560e21b815290515f926001600160a01b03169163f06820549160048083019260209291908290030181865afa1580156107e4573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108089190612a8e565b61081390600f612aa9565b9050621275006001600160401b0380831690841610806108445750806001600160401b0316836001600160401b0316115b156108625760405163b57e21df60e01b815260040160405180910390fd5b6001600160401b03831660088190556040519081527f793e3b1e1bcd677bb11900c83124d3c44c9946ea8ddf978a0ca250b034ec9dde9060200160405180910390a1505050565b6001600160a01b0381165f9081526005602052604081205433918190036108e3576040516379298a5360e11b815260040160405180910390fd5b8042101561090457604051635a77435760e01b815260040160405180910390fd5b6001600160a01b038084165f9081526006602090815260408083209386168352929052908120549081900361094c57604051630686827b60e51b815260040160405180910390fd5b6001600160a01b038085165f9081526006602090815260408083208785168452909152812055600254610981911684836112e0565b826001600160a01b03167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040516109bc91815260200190565b60405180910390a250505050565b336109d48161136f565b6109dd856113bc565b6109e6866113f7565b604080516001600160a01b03831660208201525f91016040516020818303038152906040529050610a18818689611433565b6127108361ffff161115610a3f5760405163dc81db8560e01b815260040160405180910390fd5b600160045f610a4d8a610dc1565b81526020019081526020015f205f6101000a81548160ff02191690831515021790555060405180604001604052805f815260200160016002811115610a9457610a94612a0c565b90526001600160a01b0383165f908152600360209081526040909120825181559082015160018083018054909160ff1990911690836002811115610ada57610ada612a0c565b0217905550905050816001600160a01b03167ff057d4ea81e98628653a8f90788541972078137334a92b42347eaccda80fc40a8888868989604051610b23959493929190612acb565b60405180910390a250505050505050565b610b3d82611160565b335f829003610b5f57604051631f2a200560e01b815260040160405180910390fd5b6001600160a01b038084165f9081526007602090815260408083209385168352929052205415610ba25760405163d423a4f160e01b815260040160405180910390fd5b6001600160a01b038084165f9081526006602090815260408083209385168352929052205482811015610beb57604051639266535160e01b81526004810182905260240161069f565b6001600160a01b038085165f90815260066020908152604080832093861683529290529081208054859290610c21908490612b3d565b92505081905550604051806040016040528084815260200160085442610c479190612a7b565b90526001600160a01b038086165f81815260076020908152604080832094881683529381528382208551815594810151600190950194909455908152600390925281208054859290610c9a908490612b3d565b92505081905550836001600160a01b0316826001600160a01b03167f4d10bd049775c77bd7f255195afba5088028ecb3c7c277d393ccff7934f2f92c8560405161076e91815260200190565b610cee6114c8565b610cf78261156c565b610d0182826115b3565b5050565b5f610d0e611674565b505f516020612e565f395f51905f5290565b33610d2a81611160565b6001600160a01b0381165f908152600360205260409020600101805460ff19166002179055600854610d5c9042612a7b565b6001600160a01b0382165f8181526005602090815260408083209490945560039052828120819055915190917ffb24305354c87762d557487ae4a564e8d03ecbb9a97dd8afff8e1f6fcaf0dd1691a250565b610db6611285565b610dbf5f6116bd565b565b5f815f0151826020015183604001518460600151604051602001610dfe949392919093845260208401929092526040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b6001600160a01b0381165f9081526007602090815260408083203380855292528220549091819003610e6057604051630686827b60e51b815260040160405180910390fd5b6001600160a01b038084165f90815260076020908152604080832093861683529290522060010154421015610ea857604051635a77435760e01b815260040160405180910390fd5b6001600160a01b038084165f9081526007602090815260408083208685168452909152812081815560010155600254610ee3911683836112e0565b816001600160a01b03167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6582604051610f1e91815260200190565b60405180910390a2505050565b33610f3581611160565b610f3e846113bc565b610f47856113f7565b604080516001600160a01b03831660208201525f91016040516020818303038152906040529050610f79818588611433565b600160045f610f8789610dc1565b81526020019081526020015f205f6101000a81548160ff021916908315150217905550816001600160a01b03167fc8c5b37aec7f2ddbd3a13c51361e54a0a8df3bca256ab758a77f5ad741d281e587878787604051610fe99493929190612b50565b60405180910390a2505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f8115801561103d5750825b90505f826001600160401b031660011480156110585750303b155b905081158015611066575080155b156110845760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156110ae57845460ff60401b1916600160401b1785555b6110b78661172d565b6110bf61173e565b6110c7611746565b6110d289898961184a565b831561111857845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050505050565b61112b611285565b6001600160a01b03811661115457604051631e4fbdf760e01b81525f600482015260240161069f565b61115d816116bd565b50565b6001600160a01b0381165f9081526003602052604081206001015460ff169081600281111561119157611191612a0c565b036111af5760405163508a793f60e01b815260040160405180910390fd5b60028160028111156111c3576111c3612a0c565b03610d015760405163eab4a96360e01b815260040160405180910390fd5b5f6040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260205f6064835f8a5af191505080601f3d1160015f51141615161561123a5750833b153d17155b8061127e5760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b604482015260640161069f565b5050505050565b336112b77f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b031614610dbf5760405163118cdaa760e01b815233600482015260240161069f565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af191505080601f3d1160015f51141615161561132a5750823b153d17155b806113695760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015260640161069f565b50505050565b6001600160a01b0381165f9081526003602052604081206001015460ff16600281111561139e5761139e612a0c565b1461115d5760405163132e7efb60e31b815260040160405180910390fd5b604080518082019091525f80825260208201526113d982826118cd565b15610d01576040516306cf438f60e01b815260040160405180910390fd5b60045f61140383610dc1565b815260208101919091526040015f205460ff161561115d5760405162da8a5760e11b815260040160405180910390fd5b61143c826118f0565b5f604051806060016040528060248152602001612e126024913990505f848260405160200161146c929190612bcd565b60405160208183030381529060405290505f61148782611986565b90506114a4818561149788611a73565b61149f611aea565b611bb7565b6114c05760405162ced3e560e41b815260040160405180910390fd5b505050505050565b306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148061154e57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166115425f516020612e565f395f51905f52546001600160a01b031690565b6001600160a01b031614155b15610dbf5760405163703e46dd60e11b815260040160405180910390fd5b611574611285565b6040516001600160a01b03821681527ff78721226efe9a1bb678189a16d1554928b9f2192e2cb93eeda83b79fa40007d9060200160405180910390a150565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561160d575060408051601f3d908101601f1916820190925261160a91810190612a50565b60015b61163557604051634c9c8ce360e01b81526001600160a01b038316600482015260240161069f565b5f516020612e565f395f51905f52811461166557604051632a87526960e21b81526004810182905260240161069f565b61166f8383611c95565b505050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610dbf5760405163703e46dd60e11b815260040160405180910390fd5b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b611735611cea565b61115d81611d33565b610dbf611cea565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f8115801561178a5750825b90505f826001600160401b031660011480156117a55750303b155b9050811580156117b3575080155b156117d15760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff1916600117855583156117fb57845460ff60401b1916600160401b1785555b435f55831561127e57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15050505050565b6001600160a01b0383166118715760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0382166118985760405163d92e233d60e01b815260040160405180910390fd5b600280546001600160a01b039485166001600160a01b0319918216179091556001805493909416921691909117909155600855565b805182515f911480156118e7575081602001518360200151145b90505b92915050565b805160208201515f915f516020612e365f395f51905f5291159015161561191657505050565b82516020840151826003848585860985090883828309148382108484101616935050508161166f5760405162461bcd60e51b815260206004820152601760248201527f426e3235343a20696e76616c696420473120706f696e74000000000000000000604482015260640161069f565b604080518082019091525f80825260208201525f6119a383611d3b565b90505f516020612e365f395f51905f5260035f82848509905082806119ca576119ca612be9565b848209905082806119dd576119dd612be9565b82820890505f5f6119ed83611f43565b925090505b80611a56578480611a0557611a05612be9565b6001870895508480611a1957611a19612be9565b86870992508480611a2c57611a2c612be9565b86840992508480611a3f57611a3f612be9565b8484089250611a4d83611f43565b925090506119f2565b506040805180820190915294855260208501525091949350505050565b604080518082019091525f8082526020820152815160208301511590151615611a9a575090565b6040518060400160405280835f015181526020015f516020612e365f395f51905f528460200151611acb9190612bfd565b611ae2905f516020612e365f395f51905f52612b3d565b905292915050565b611b1160405180608001604052805f81526020015f81526020015f81526020015f81525090565b60405180608001604052807f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed81526020017f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa81526020017f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b815250905090565b5f5f5f6040518751815260208801516020820152602087015160408201528651606082015260608701516080820152604087015160a0820152855160c0820152602086015160e0820152602085015161010082015284516101208201526060850151610140820152604085015161016082015260205f6101808360085afa9150505f51915080611c895760405162461bcd60e51b815260206004820152601c60248201527f426e3235343a2050616972696e6720636865636b206661696c65642100000000604482015260640161069f565b50151595945050505050565b611c9e8261203a565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2805115611ce25761166f828261209d565b610d0161210f565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16610dbf57604051631afcd79f60e31b815260040160405180910390fd5b61112b611cea565b5f5f611d468361212e565b805190915060308114611d5b57611d5b612c1c565b5f816001600160401b03811115611d7457611d746125ab565b6040519080825280601f01601f191660200182016040528015611d9e576020820181803683370190505b5090505f5b82811015611e0d57836001611db88386612b3d565b611dc29190612b3d565b81518110611dd257611dd2612c30565b602001015160f81c60f81b828281518110611def57611def612c30565b60200101906001600160f81b03191690815f1a905350600101611da3565b5060408051601f80825261040082019092525f9082602082016103e0803683370190505090505f5b82811015611e9d578381611e498588612b3d565b611e539190612a7b565b81518110611e6357611e63612c30565b602001015160f81c60f81b60f81c828281518110611e8357611e83612c30565b60ff90921660209283029190910190910152600101611e35565b505f611ea882612479565b90506101005f516020612e365f395f51905f525f611ec68689612b3d565b90505f5b81811015611f33575f886001611ee08486612b3d565b611eea9190612b3d565b81518110611efa57611efa612c30565b016020015160f81c90508380611f1257611f12612be9565b85870995508380611f2557611f25612be9565b818708955050600101611eca565b50929a9950505050505050505050565b5f5f5f5f5f7f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f5290505f5f516020612e365f395f51905f52905060405160208152602080820152602060408201528760608201528260808201528160a082015260205f60c08360055afa9450505f519250836120005760405162461bcd60e51b815260206004820152601b60248201527f706f7720707265636f6d70696c652063616c6c206661696c6564210000000000604482015260640161069f565b80600184901b1115612019576120168382612b3d565b92505b808061202757612027612be9565b8384099690961496919550909350505050565b806001600160a01b03163b5f0361206f57604051634c9c8ce360e01b81526001600160a01b038216600482015260240161069f565b5f516020612e565f395f51905f5280546001600160a01b0319166001600160a01b0392909216919091179055565b60605f5f846001600160a01b0316846040516120b99190612c44565b5f60405180830381855af49150503d805f81146120f1576040519150601f19603f3d011682016040523d82523d5f602084013e6120f6565b606091505b50915091506121068583836124e0565b95945050505050565b3415610dbf5760405163b398979f60e01b815260040160405180910390fd5b604080516030808252606082810190935290602090600160f91b905f9084602082018180368337019050509050808660405160200161216e929190612bcd565b6040516020818303038152906040529050808460f81b604051602001612195929190612c4f565b6040516020818303038152906040529050806040516020016121b79190612c79565b60408051601f1981840301815290829052915061010160f01b906121e19083908390602001612c91565b60408051808303601f190181528282528051602091820120818401819052600160f81b848401526001600160f01b031985166041850152825160238186030181526043909401909252825190830120919350905f60ff88166001600160401b03811115612250576122506125ab565b6040519080825280601f01601f19166020018201604052801561227a576020820181803683370190505b5090505f8260405160200161229191815260200190565b60408051601f1981840301815291905290505f5b81518110156122fb578181815181106122c0576122c0612c30565b602001015160f81c60f81b8382815181106122dd576122dd612c30565b60200101906001600160f81b03191690815f1a9053506001016122a5565b505f8460405160200161231091815260200190565b60408051601f19818403018152602083019091525f80835291985091505b898110156123a2575f83828151811061234957612349612c30565b602001015160f81c60f81b83838151811061236657612366612c30565b602001015160f81c60f81b1890508881604051602001612387929190612cb5565b60408051601f1981840301815291905298505060010161232e565b508688876040516020016123b893929190612cd9565b604051602081830303815290604052965086805190602001209350836040516020016123e691815260200190565b60408051601f1981840301815291905291505f5b6124078a60ff8d16612b3d565b8110156124685782818151811061242057612420612c30565b01602001516001600160f81b0319168461243a838d612a7b565b8151811061244a5761244a612c30565b60200101906001600160f81b03191690815f1a9053506001016123fa565b50919b9a5050505050505050505050565b5f80805b83518110156124d95783818151811061249857612498612c30565b602002602001015160ff168160086124b09190612d0c565b6124bb906002612e06565b6124c59190612d0c565b6124cf9083612a7b565b915060010161247d565b5092915050565b6060826124f5576124f08261253f565b612538565b815115801561250c57506001600160a01b0384163b155b1561253557604051639996b31560e01b81526001600160a01b038516600482015260240161069f565b50805b9392505050565b80511561254f5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b80356001600160a01b038116811461257e575f5ffd5b919050565b5f5f60408385031215612594575f5ffd5b61259d83612568565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b03811182821017156125e1576125e16125ab565b60405290565b5f608082840312156125f7575f5ffd5b604051608081016001600160401b0381118282101715612619576126196125ab565b6040908152833582526020808501359083015283810135908201526060928301359281019290925250919050565b5f60408284031215612657575f5ffd5b61265f6125bf565b823581526020928301359281019290925250919050565b803561ffff8116811461257e575f5ffd5b5f5f5f5f610120858703121561269b575f5ffd5b6126a586866125e7565b93506126b48660808701612647565b92506126c38660c08701612647565b91506126d26101008601612676565b905092959194509250565b6001600160401b038116811461115d575f5ffd5b5f60208284031215612701575f5ffd5b8135612538816126dd565b5f6020828403121561271c575f5ffd5b6118e782612568565b5f82601f830112612734575f5ffd5b81356001600160401b0381111561274d5761274d6125ab565b604051601f8201601f19908116603f011681016001600160401b038111828210171561277b5761277b6125ab565b604052818152838201602001851015612792575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f5f5f5f61014086880312156127c3575f5ffd5b6127cd87876125e7565b94506127dc8760808801612647565b93506127eb8760c08801612647565b92506101008601356001600160401b03811115612806575f5ffd5b61281288828901612725565b9250506128226101208701612676565b90509295509295909350565b5f5f6040838503121561283f575f5ffd5b61284883612568565b915060208301356001600160401b03811115612862575f5ffd5b61286e85828601612725565b9150509250929050565b5f5f5f610100848603121561288b575f5ffd5b61289585856125e7565b92506128a48560808601612647565b91506128b38560c08601612647565b90509250925092565b5f608082840312156128cc575f5ffd5b6118e783836125e7565b5f5f604083850312156128e7575f5ffd5b6128f083612568565b91506128fe60208401612568565b90509250929050565b5f5f5f5f610120858703121561291b575f5ffd5b61292586866125e7565b93506129348660808701612647565b92506129438660c08701612647565b91506101008501356001600160401b0381111561295e575f5ffd5b61296a87828801612725565b91505092959194509250565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6118e76020830184612976565b5f602082840312156129c6575f5ffd5b5035919050565b5f5f5f5f608085870312156129e0575f5ffd5b6129e985612568565b93506129f760208601612568565b9250604085013591506126d260608601612568565b634e487b7160e01b5f52602160045260245ffd5b8281526040810160038310612a4357634e487b7160e01b5f52602160045260245ffd5b8260208301529392505050565b5f60208284031215612a60575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156118ea576118ea612a67565b5f60208284031215612a9e575f5ffd5b8151612538816126dd565b6001600160401b0381811683821602908116908181146124d9576124d9612a67565b8551815260208087015190820152604080870151908201526060808701519082015284516080820152602085015160a082015261ffff841660c0820152825160e082015260208301516101008201526101406101208201525f612b32610140830184612976565b979650505050505050565b818103818111156118ea576118ea612a67565b8451815260208086015190820152604080860151908201526060808601519082015283516080820152602084015160a0820152825160c0820152602083015160e08201526101206101008201525f612bac610120830184612976565b9695505050505050565b5f81518060208401855e5f93019283525090919050565b5f612be1612bdb8386612bb6565b84612bb6565b949350505050565b634e487b7160e01b5f52601260045260245ffd5b5f82612c1757634e487b7160e01b5f52601260045260245ffd5b500690565b634e487b7160e01b5f52600160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f6118e78284612bb6565b5f612c5a8285612bb6565b5f81526001600160f81b03199390931660018401525050600201919050565b5f612c848284612bb6565b5f81526001019392505050565b5f612c9c8285612bb6565b6001600160f01b03199390931683525050600201919050565b5f612cc08285612bb6565b6001600160f81b03199390931683525050600101919050565b5f612ce48286612bb6565b6001600160f81b031994909416845250506001600160f01b0319166001820152600301919050565b80820281158282048414176118ea576118ea612a67565b6001815b6001841115612d5e57808504811115612d4257612d42612a67565b6001841615612d5057908102905b60019390931c928002612d27565b935093915050565b5f82612d74575060016118ea565b81612d8057505f6118ea565b8160018114612d965760028114612da057612dbc565b60019150506118ea565b60ff841115612db157612db1612a67565b50506001821b6118ea565b5060208310610133831016604e8410600b8410161715612ddf575081810a6118ea565b612deb5f198484612d23565b805f1904821115612dfe57612dfe612a67565b029392505050565b5f6118e78383612d6656fe424c535f5349475f424e32353447315f584d443a4b454343414b5f4e4354485f4e554c5f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca164736f6c634300081c000a /// ``` #[rustfmt::skip] #[allow(clippy::all)] pub static DEPLOYED_BYTECODE: alloy_sol_types::private::Bytes = alloy_sol_types::private::Bytes::from_static( - b"`\x80`@R`\x046\x10a\x01\xAFW_5`\xE0\x1C\x80c\x9E\x9A\x8F1\x11a\0\xE7W\x80c\xB5\xEC\xB3D\x11a\0\x87W\x80c\xE5;*t\x11a\0bW\x80c\xE5;*t\x14a\x059W\x80c\xF2\xFD\xE3\x8B\x14a\x05XW\x80c\xFAR\xC7\xD8\x14a\x05wW\x80c\xFC\x0CTj\x14a\x05\xBAW__\xFD[\x80c\xB5\xEC\xB3D\x14a\x04\xB9W\x80c\xBE 0\x94\x14a\x04\xE4W\x80c\xC6H\x14\xDD\x14a\x05\x03W__\xFD[\x80c\xA5\x85\x7F\xF3\x11a\0\xC2W\x80c\xA5\x85\x7F\xF3\x14a\x04\0W\x80c\xAD<\xB1\xCC\x14a\x04\x1FW\x80c\xB3\xE6\xEB\xD5\x14a\x04\\W\x80c\xB5p\x0Eh\x14a\x04\x9AW__\xFD[\x80c\x9E\x9A\x8F1\x14a\x03zW\x80c\xA2\xD7\x8D\xD5\x14a\x03\x8FW\x80c\xA3\x06j\xAB\x14a\x03\xE1W__\xFD[\x80cO\x1E\xF2\x86\x11a\x01RW\x80cj\x91\x1C\xCF\x11a\x01-W\x80cj\x91\x1C\xCF\x14a\x02\xE3W\x80cqP\x18\xA6\x14a\x02\xF7W\x80c\x8D\xA5\xCB[\x14a\x03\x0BW\x80c\x9B0\xA5\xE6\x14a\x03[W__\xFD[\x80cO\x1E\xF2\x86\x14a\x02\xA2W\x80cR\xD1\x90-\x14a\x02\xB5W\x80cUD\xC2\xF1\x14a\x02\xC9W__\xFD[\x80c\x1A \xCDc\x11a\x01\x8DW\x80c\x1A \xCDc\x14a\x02#W\x80c!@\xFE\xCD\x14a\x02BW\x80c>\x9D\xF9\xB5\x14a\x02aW\x80cM\x99\xDD\x16\x14a\x02\x83W__\xFD[\x80c\x02n@+\x14a\x01\xB3W\x80c\r\x8En,\x14a\x01\xD4W\x80c\x13\xB9\x05z\x14a\x02\x04W[__\xFD[4\x80\x15a\x01\xBEW__\xFD[Pa\x01\xD2a\x01\xCD6`\x04a&\x16V[a\x05\xD9V[\0[4\x80\x15a\x01\xDFW__\xFD[P`@\x80Q`\x02\x81R_` \x82\x01\x81\x90R\x91\x81\x01\x91\x90\x91R``\x01[`@Q\x80\x91\x03\x90\xF3[4\x80\x15a\x02\x0FW__\xFD[Pa\x01\xD2a\x02\x1E6`\x04a'JV[a\x07|V[4\x80\x15a\x02.W__\xFD[Pa\x01\xD2a\x02=6`\x04a'\xB4V[a\x07\x95V[4\x80\x15a\x02MW__\xFD[Pa\x01\xD2a\x02\\6`\x04a'\xCFV[a\x08\xA9V[4\x80\x15a\x02lW__\xFD[Pa\x02u_T\x81V[`@Q\x90\x81R` \x01a\x01\xFBV[4\x80\x15a\x02\x8EW__\xFD[Pa\x01\xD2a\x02\x9D6`\x04a&\x16V[a\t\xCAV[a\x01\xD2a\x02\xB06`\x04a'\xE8V[a\x0B|V[4\x80\x15a\x02\xC0W__\xFD[Pa\x02ua\x0B\x9BV[4\x80\x15a\x02\xD4W__\xFD[Pa\x01\xD2a\x02\x1E6`\x04a(\x8BV[4\x80\x15a\x02\xEEW__\xFD[Pa\x01\xD2a\x0B\xB6V[4\x80\x15a\x03\x02W__\xFD[Pa\x01\xD2a\x0CDV[4\x80\x15a\x03\x16W__\xFD[P\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0T`\x01`\x01`\xA0\x1B\x03\x16[`@Q`\x01`\x01`\xA0\x1B\x03\x90\x91\x16\x81R` \x01a\x01\xFBV[4\x80\x15a\x03fW__\xFD[Pa\x02ua\x03u6`\x04a(\xCFV[a\x0CWV[4\x80\x15a\x03\x85W__\xFD[Pa\x02u`\x08T\x81V[4\x80\x15a\x03\x9AW__\xFD[Pa\x03\xCCa\x03\xA96`\x04a(\xE9V[`\x07` \x90\x81R_\x92\x83R`@\x80\x84 \x90\x91R\x90\x82R\x90 \x80T`\x01\x90\x91\x01T\x82V[`@\x80Q\x92\x83R` \x83\x01\x91\x90\x91R\x01a\x01\xFBV[4\x80\x15a\x03\xECW__\xFD[Pa\x01\xD2a\x03\xFB6`\x04a'\xCFV[a\x0C\xB1V[4\x80\x15a\x04\x0BW__\xFD[Pa\x01\xD2a\x04\x1A6`\x04a)\x1AV[a\r\xC1V[4\x80\x15a\x04*W__\xFD[Pa\x04O`@Q\x80`@\x01`@R\x80`\x05\x81R` \x01d\x03R\xE3\x02\xE3`\xDC\x1B\x81RP\x81V[`@Qa\x01\xFB\x91\x90a)\x82V[4\x80\x15a\x04gW__\xFD[Pa\x04\x8Aa\x04v6`\x04a)\xB7V[`\x04` R_\x90\x81R`@\x90 T`\xFF\x16\x81V[`@Q\x90\x15\x15\x81R` \x01a\x01\xFBV[4\x80\x15a\x04\xA5W__\xFD[P`\x01Ta\x03C\x90`\x01`\x01`\xA0\x1B\x03\x16\x81V[4\x80\x15a\x04\xC4W__\xFD[Pa\x02ua\x04\xD36`\x04a'\xCFV[`\x05` R_\x90\x81R`@\x90 T\x81V[4\x80\x15a\x04\xEFW__\xFD[Pa\x01\xD2a\x04\xFE6`\x04a)\xCEV[a\x0FyV[4\x80\x15a\x05\x0EW__\xFD[Pa\x02ua\x05\x1D6`\x04a(\xE9V[`\x06` \x90\x81R_\x92\x83R`@\x80\x84 \x90\x91R\x90\x82R\x90 T\x81V[4\x80\x15a\x05DW__\xFD[Pa\x01\xD2a\x05S6`\x04a*\rV[a\x10\xA3V[4\x80\x15a\x05cW__\xFD[Pa\x01\xD2a\x05r6`\x04a'\xCFV[a\x11\xB6V[4\x80\x15a\x05\x82W__\xFD[Pa\x05\xACa\x05\x916`\x04a'\xCFV[`\x03` R_\x90\x81R`@\x90 \x80T`\x01\x90\x91\x01T`\xFF\x16\x82V[`@Qa\x01\xFB\x92\x91\x90a*mV[4\x80\x15a\x05\xC5W__\xFD[P`\x02Ta\x03C\x90`\x01`\x01`\xA0\x1B\x03\x16\x81V[a\x05\xE2\x82a\x11\xF3V[3_\x82\x90\x03a\x06\x04W`@Qc\x1F* \x05`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02T`@Qcn\xB1v\x9F`\xE1\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x83\x81\x16`\x04\x83\x01R0`$\x83\x01R_\x92\x16\x90c\xDDb\xED>\x90`D\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x06RW=__>=_\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x06v\x91\x90a*\x9DV[\x90P\x82\x81\x10\x15a\x06\xA8W`@Qc\x05Ce\xBB`\xE3\x1B\x81R`\x04\x81\x01\x82\x90R`$\x81\x01\x84\x90R`D\x01[`@Q\x80\x91\x03\x90\xFD[`\x02Ta\x06\xC0\x90`\x01`\x01`\xA0\x1B\x03\x16\x830\x86a\x12tV[`\x01`\x01`\xA0\x1B\x03\x84\x16_\x90\x81R`\x03` R`@\x81 \x80T\x85\x92\x90a\x06\xE7\x90\x84\x90a*\xC8V[\x90\x91UPP`\x01`\x01`\xA0\x1B\x03\x80\x85\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R\x90\x81 \x80T\x85\x92\x90a\x07\"\x90\x84\x90a*\xC8V[\x92PP\x81\x90UP\x83`\x01`\x01`\xA0\x1B\x03\x16\x82`\x01`\x01`\xA0\x1B\x03\x16\x7F\xE5T\x1Aka\x03\xD4\xFA~\x02\x1E\xD5O\xAD9\xC6o'\xA7k\xD1=7L\xF6$\n\xE6\xBD\x0B\xB7+\x85`@Qa\x07n\x91\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA3PPPPV[`@Qc\xC2\xD7\xF8\x13`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x07\x9Da\x13\x18V[`\x01T`@\x80Qc<\x1A\x08\x15`\xE2\x1B\x81R\x90Q_\x92`\x01`\x01`\xA0\x1B\x03\x16\x91c\xF0h T\x91`\x04\x80\x83\x01\x92` \x92\x91\x90\x82\x90\x03\x01\x81\x86Z\xFA\x15\x80\x15a\x07\xE4W=__>=_\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x08\x08\x91\x90a*\xDBV[a\x08\x13\x90`\x0Fa*\xF6V[\x90Pb\x12u\0`\x01`\x01`@\x1B\x03\x80\x83\x16\x90\x84\x16\x10\x80a\x08DWP\x80`\x01`\x01`@\x1B\x03\x16\x83`\x01`\x01`@\x1B\x03\x16\x11[\x15a\x08bW`@Qc\xB5~!\xDF`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`@\x1B\x03\x83\x16`\x08\x81\x90U`@Q\x90\x81R\x7Fy>;\x1E\x1B\xCDg{\xB1\x19\0\xC81$\xD3\xC4L\x99F\xEA\x8D\xDF\x97\x8A\x0C\xA2P\xB04\xEC\x9D\xDE\x90` \x01`@Q\x80\x91\x03\x90\xA1PPPV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x05` R`@\x81 T3\x91\x81\x90\x03a\x08\xE3W`@Qcy)\x8AS`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x80B\x10\x15a\t\x04W`@QcZwCW`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R\x90\x81 T\x90\x81\x90\x03a\tLW`@Qc\x06\x86\x82{`\xE5\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x85\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x87\x85\x16\x84R\x90\x91R\x81 U`\x02Ta\t\x81\x91\x16\x84\x83a\x13sV[\x82`\x01`\x01`\xA0\x1B\x03\x16\x7F\x7F\xCFS,\x15\xF0\xA6\xDB\x0B\xD6\xD0\xE08\xBE\xA7\x1D0\xD8\x08\xC7\xD9\x8C\xB3\xBFrh\xA9[\xF5\x08\x1Be\x82`@Qa\t\xBC\x91\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA2PPPPV[a\t\xD3\x82a\x11\xF3V[3_\x82\x90\x03a\t\xF5W`@Qc\x1F* \x05`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 \x93\x85\x16\x83R\x92\x90R T\x15a\n8W`@Qc\xD4#\xA4\xF1`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x85\x16\x83R\x92\x90R T\x82\x81\x10\x15a\n\x81W`@Qc\x92fSQ`\xE0\x1B\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\x9FV[`\x01`\x01`\xA0\x1B\x03\x80\x85\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R\x90\x81 \x80T\x85\x92\x90a\n\xB7\x90\x84\x90a+\x18V[\x92PP\x81\x90UP`@Q\x80`@\x01`@R\x80\x84\x81R` \x01`\x08TBa\n\xDD\x91\x90a*\xC8V[\x90R`\x01`\x01`\xA0\x1B\x03\x80\x86\x16_\x81\x81R`\x07` \x90\x81R`@\x80\x83 \x94\x88\x16\x83R\x93\x81R\x83\x82 \x85Q\x81U\x94\x81\x01Q`\x01\x90\x95\x01\x94\x90\x94U\x90\x81R`\x03\x90\x92R\x81 \x80T\x85\x92\x90a\x0B0\x90\x84\x90a+\x18V[\x92PP\x81\x90UP\x83`\x01`\x01`\xA0\x1B\x03\x16\x82`\x01`\x01`\xA0\x1B\x03\x16\x7FM\x10\xBD\x04\x97u\xC7{\xD7\xF2U\x19Z\xFB\xA5\x08\x80(\xEC\xB3\xC7\xC2w\xD3\x93\xCC\xFFy4\xF2\xF9,\x85`@Qa\x07n\x91\x81R` \x01\x90V[a\x0B\x84a\x14\x02V[a\x0B\x8D\x82a\x14\xA6V[a\x0B\x97\x82\x82a\x14\xEDV[PPV[_a\x0B\xA4a\x15\xAEV[P_Q` a-\xCB_9_Q\x90_R\x90V[3a\x0B\xC0\x81a\x11\xF3V[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x03` R`@\x90 `\x01\x01\x80T`\xFF\x19\x16`\x02\x17\x90U`\x08Ta\x0B\xF2\x90Ba*\xC8V[`\x01`\x01`\xA0\x1B\x03\x82\x16_\x81\x81R`\x05` \x90\x81R`@\x80\x83 \x94\x90\x94U`\x03\x90R\x82\x81 \x81\x90U\x91Q\x90\x91\x7F\xFB$0ST\xC8wb\xD5WHz\xE4\xA5d\xE8\xD0>\xCB\xB9\xA9}\xD8\xAF\xFF\x8E\x1Fo\xCA\xF0\xDD\x16\x91\xA2PV[a\x0CLa\x13\x18V[a\x0CU_a\x15\xF7V[V[_\x81_\x01Q\x82` \x01Q\x83`@\x01Q\x84``\x01Q`@Q` \x01a\x0C\x94\x94\x93\x92\x91\x90\x93\x84R` \x84\x01\x92\x90\x92R`@\x83\x01R``\x82\x01R`\x80\x01\x90V[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x80Q\x90` \x01 \x90P\x91\x90PV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 3\x80\x85R\x92R\x82 T\x90\x91\x81\x90\x03a\x0C\xF6W`@Qc\x06\x86\x82{`\xE5\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R `\x01\x01TB\x10\x15a\r>W`@QcZwCW`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 \x86\x85\x16\x84R\x90\x91R\x81 \x81\x81U`\x01\x01U`\x02Ta\ry\x91\x16\x83\x83a\x13sV[\x81`\x01`\x01`\xA0\x1B\x03\x16\x7F\x7F\xCFS,\x15\xF0\xA6\xDB\x0B\xD6\xD0\xE08\xBE\xA7\x1D0\xD8\x08\xC7\xD9\x8C\xB3\xBFrh\xA9[\xF5\x08\x1Be\x82`@Qa\r\xB4\x91\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA2PPPV[3a\r\xCB\x81a\x16gV[a\r\xD4\x85a\x16\xB4V[a\r\xDD\x86a\x16\xEFV[`@\x80Q`\x01`\x01`\xA0\x1B\x03\x83\x16` \x82\x01R_\x91\x01`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90Pa\x0E\x0F\x81\x86\x89a\x17+V[a'\x10\x83a\xFF\xFF\x16\x11\x15a\x0E6W`@Qc\xDC\x81\xDB\x85`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x04_a\x0ED\x8Aa\x0CWV[\x81R` \x01\x90\x81R` \x01_ _a\x01\0\n\x81T\x81`\xFF\x02\x19\x16\x90\x83\x15\x15\x02\x17\x90UP`@Q\x80`@\x01`@R\x80_\x81R` \x01`\x01`\x02\x81\x11\x15a\x0E\x8BWa\x0E\x8Ba*YV[\x90R`\x01`\x01`\xA0\x1B\x03\x83\x16_\x90\x81R`\x03` \x90\x81R`@\x90\x91 \x82Q\x81U\x90\x82\x01Q`\x01\x80\x83\x01\x80T\x90\x91`\xFF\x19\x90\x91\x16\x90\x83`\x02\x81\x11\x15a\x0E\xD1Wa\x0E\xD1a*YV[\x02\x17\x90UPP`@\x80Q\x89Q\x81R` \x80\x8B\x01Q\x81\x83\x01R\x8A\x83\x01Q\x82\x84\x01R``\x80\x8C\x01Q\x90\x83\x01R\x89Q`\x80\x83\x01R\x89\x81\x01Q`\xA0\x83\x01Ra\xFF\xFF\x87\x16`\xC0\x83\x01R\x88Q`\xE0\x83\x01R\x88\x81\x01Qa\x01\0\x83\x01R\x87Qa\x01 \x83\x01R\x87\x01Qa\x01@\x82\x01R\x90Q`\x01`\x01`\xA0\x1B\x03\x85\x16\x92P\x7F\x8E\x1C9M\x8F<\x83\xD8\xE2M y\x0B\xD0Xo\xE7\x13T\x81\n\x93\xC2\xEE6\x8BA\x87EU;.\x91\x81\x90\x03a\x01`\x01\x90\xA2PPPPPPPV[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0\x80T`\x01`@\x1B\x81\x04`\xFF\x16\x15\x90`\x01`\x01`@\x1B\x03\x16_\x81\x15\x80\x15a\x0F\xBDWP\x82[\x90P_\x82`\x01`\x01`@\x1B\x03\x16`\x01\x14\x80\x15a\x0F\xD8WP0;\x15[\x90P\x81\x15\x80\x15a\x0F\xE6WP\x80\x15[\x15a\x10\x04W`@Qc\xF9.\xE8\xA9`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x84Tg\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16`\x01\x17\x85U\x83\x15a\x10.W\x84T`\xFF`@\x1B\x19\x16`\x01`@\x1B\x17\x85U[a\x107\x86a\x17\xC0V[a\x10?a\x17\xD1V[a\x10Ga\x17\xD9V[a\x10R\x89\x89\x89a\x18\xDDV[\x83\x15a\x10\x98W\x84T`\xFF`@\x1B\x19\x16\x85U`@Q`\x01\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1[PPPPPPPPPV[3a\x10\xAD\x81a\x11\xF3V[a\x10\xB6\x84a\x16\xB4V[a\x10\xBF\x85a\x16\xEFV[`@\x80Q`\x01`\x01`\xA0\x1B\x03\x83\x16` \x82\x01R_\x91\x01`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90Pa\x10\xF1\x81\x85\x88a\x17+V[`\x01`\x04_a\x10\xFF\x89a\x0CWV[\x81R` \x80\x82\x01\x92\x90\x92R`@\x90\x81\x01_ \x80T`\xFF\x19\x16\x93\x15\x15\x93\x90\x93\x17\x90\x92U\x81Q\x88Q\x81R\x88\x82\x01Q\x81\x83\x01R\x88\x83\x01Q\x92\x81\x01\x92\x90\x92R``\x80\x89\x01Q\x90\x83\x01R\x86Q`\x80\x83\x01R\x86\x81\x01Q`\xA0\x83\x01R\x85Q`\xC0\x83\x01R\x85\x81\x01Q`\xE0\x83\x01R\x84Qa\x01\0\x83\x01R\x84\x01Qa\x01 \x82\x01R`\x01`\x01`\xA0\x1B\x03\x83\x16\x90\x7F\x04\xCF\x8C\xF4zk\xF2\xEA_q\xB8\xEE\xBD\xEC\x9D\xE2\x11\x7FG\xD2\xB6{\xC6\x083\x8F\x81\xAC\xB1\xA4f\xD5\x90a\x01@\x01`@Q\x80\x91\x03\x90\xA2PPPPPPV[a\x11\xBEa\x13\x18V[`\x01`\x01`\xA0\x1B\x03\x81\x16a\x11\xE7W`@Qc\x1EO\xBD\xF7`\xE0\x1B\x81R_`\x04\x82\x01R`$\x01a\x06\x9FV[a\x11\xF0\x81a\x15\xF7V[PV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x03` R`@\x81 `\x01\x01T`\xFF\x16\x90\x81`\x02\x81\x11\x15a\x12$Wa\x12$a*YV[\x03a\x12BW`@QcP\x8Ay?`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02\x81`\x02\x81\x11\x15a\x12VWa\x12Va*YV[\x03a\x0B\x97W`@Qc\xEA\xB4\xA9c`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[_`@Qc#\xB8r\xDD`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x85\x16`\x04\x82\x01R`\x01`\x01`\xA0\x1B\x03\x84\x16`$\x82\x01R\x82`D\x82\x01R` _`d\x83_\x8AZ\xF1\x91PP\x80`\x1F=\x11`\x01_Q\x14\x16\x15\x16\x15a\x12\xCDWP\x83;\x15=\x17\x15[\x80a\x13\x11W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x14`$\x82\x01Rs\x15\x14\x90S\x94\xD1\x91T\x97\xD1\x94\x93\xD3W\xD1\x90RS\x11Q`b\x1B`D\x82\x01R`d\x01a\x06\x9FV[PPPPPV[3a\x13J\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0T`\x01`\x01`\xA0\x1B\x03\x16\x90V[`\x01`\x01`\xA0\x1B\x03\x16\x14a\x0CUW`@Qc\x11\x8C\xDA\xA7`\xE0\x1B\x81R3`\x04\x82\x01R`$\x01a\x06\x9FV[_`@Qc\xA9\x05\x9C\xBB`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x84\x16`\x04\x82\x01R\x82`$\x82\x01R` _`D\x83_\x89Z\xF1\x91PP\x80`\x1F=\x11`\x01_Q\x14\x16\x15\x16\x15a\x13\xBDWP\x82;\x15=\x17\x15[\x80a\x13\xFCW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x0F`$\x82\x01Rn\x15\x14\x90S\x94\xD1\x91T\x97\xD1\x90RS\x11Q`\x8A\x1B`D\x82\x01R`d\x01a\x06\x9FV[PPPPV[0`\x01`\x01`\xA0\x1B\x03\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14\x80a\x14\x88WP\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x01`\x01`\xA0\x1B\x03\x16a\x14|_Q` a-\xCB_9_Q\x90_RT`\x01`\x01`\xA0\x1B\x03\x16\x90V[`\x01`\x01`\xA0\x1B\x03\x16\x14\x15[\x15a\x0CUW`@Qcp>F\xDD`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x14\xAEa\x13\x18V[`@Q`\x01`\x01`\xA0\x1B\x03\x82\x16\x81R\x7F\xF7\x87!\"n\xFE\x9A\x1B\xB6x\x18\x9A\x16\xD1UI(\xB9\xF2\x19.,\xB9>\xED\xA8;y\xFA@\0}\x90` \x01`@Q\x80\x91\x03\x90\xA1PV[\x81`\x01`\x01`\xA0\x1B\x03\x16cR\xD1\x90-`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x92PPP\x80\x15a\x15GWP`@\x80Q`\x1F=\x90\x81\x01`\x1F\x19\x16\x82\x01\x90\x92Ra\x15D\x91\x81\x01\x90a*\x9DV[`\x01[a\x15oW`@QcL\x9C\x8C\xE3`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x83\x16`\x04\x82\x01R`$\x01a\x06\x9FV[_Q` a-\xCB_9_Q\x90_R\x81\x14a\x15\x9FW`@Qc*\x87Ri`\xE2\x1B\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\x9FV[a\x15\xA9\x83\x83a\x19`V[PPPV[0`\x01`\x01`\xA0\x1B\x03\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14a\x0CUW`@Qcp>F\xDD`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0\x80T`\x01`\x01`\xA0\x1B\x03\x19\x81\x16`\x01`\x01`\xA0\x1B\x03\x84\x81\x16\x91\x82\x17\x84U`@Q\x92\x16\x91\x82\x90\x7F\x8B\xE0\x07\x9CS\x16Y\x14\x13D\xCD\x1F\xD0\xA4\xF2\x84\x19I\x7F\x97\"\xA3\xDA\xAF\xE3\xB4\x18okdW\xE0\x90_\x90\xA3PPPV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x03` R`@\x81 `\x01\x01T`\xFF\x16`\x02\x81\x11\x15a\x16\x96Wa\x16\x96a*YV[\x14a\x11\xF0W`@Qc\x13.~\xFB`\xE3\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`@\x80Q\x80\x82\x01\x90\x91R_\x80\x82R` \x82\x01Ra\x16\xD1\x82\x82a\x19\xB5V[\x15a\x0B\x97W`@Qc\x06\xCFC\x8F`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x04_a\x16\xFB\x83a\x0CWV[\x81R` \x81\x01\x91\x90\x91R`@\x01_ T`\xFF\x16\x15a\x11\xF0W`@Qb\xDA\x8AW`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x174\x82a\x19\xD8V[_`@Q\x80``\x01`@R\x80`$\x81R` \x01a-\x87`$\x919\x90P_\x84\x82`@Q` \x01a\x17d\x92\x91\x90a+BV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P_a\x17\x7F\x82a\x1AnV[\x90Pa\x17\x9C\x81\x85a\x17\x8F\x88a\x1B[V[a\x17\x97a\x1B\xD2V[a\x1C\x9FV[a\x17\xB8W`@Qb\xCE\xD3\xE5`\xE4\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[PPPPPPV[a\x17\xC8a\x1D}V[a\x11\xF0\x81a\x1D\xC6V[a\x0CUa\x1D}V[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0\x80T`\x01`@\x1B\x81\x04`\xFF\x16\x15\x90`\x01`\x01`@\x1B\x03\x16_\x81\x15\x80\x15a\x18\x1DWP\x82[\x90P_\x82`\x01`\x01`@\x1B\x03\x16`\x01\x14\x80\x15a\x188WP0;\x15[\x90P\x81\x15\x80\x15a\x18FWP\x80\x15[\x15a\x18dW`@Qc\xF9.\xE8\xA9`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x84Tg\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16`\x01\x17\x85U\x83\x15a\x18\x8EW\x84T`\xFF`@\x1B\x19\x16`\x01`@\x1B\x17\x85U[C_U\x83\x15a\x13\x11W\x84T`\xFF`@\x1B\x19\x16\x85U`@Q`\x01\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1PPPPPV[`\x01`\x01`\xA0\x1B\x03\x83\x16a\x19\x04W`@Qc\xD9.#=`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x82\x16a\x19+W`@Qc\xD9.#=`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02\x80T`\x01`\x01`\xA0\x1B\x03\x94\x85\x16`\x01`\x01`\xA0\x1B\x03\x19\x91\x82\x16\x17\x90\x91U`\x01\x80T\x93\x90\x94\x16\x92\x16\x91\x90\x91\x17\x90\x91U`\x08UV[a\x19i\x82a\x1D\xCEV[`@Q`\x01`\x01`\xA0\x1B\x03\x83\x16\x90\x7F\xBC|\xD7Z \xEE'\xFD\x9A\xDE\xBA\xB3 A\xF7U!M\xBCk\xFF\xA9\x0C\xC0\"[9\xDA.\\-;\x90_\x90\xA2\x80Q\x15a\x19\xADWa\x15\xA9\x82\x82a\x1E1V[a\x0B\x97a\x1E\xA3V[\x80Q\x82Q_\x91\x14\x80\x15a\x19\xCFWP\x81` \x01Q\x83` \x01Q\x14[\x90P[\x92\x91PPV[\x80Q` \x82\x01Q_\x91_Q` a-\xAB_9_Q\x90_R\x91\x15\x90\x15\x16\x15a\x19\xFEWPPPV[\x82Q` \x84\x01Q\x82`\x03\x84\x85\x85\x86\t\x85\t\x08\x83\x82\x83\t\x14\x83\x82\x10\x84\x84\x10\x16\x16\x93PPP\x81a\x15\xA9W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7FBn254: invalid G1 point\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\x9FV[`@\x80Q\x80\x82\x01\x90\x91R_\x80\x82R` \x82\x01R_a\x1A\x8B\x83a\x1E\xC2V[\x90P_Q` a-\xAB_9_Q\x90_R`\x03_\x82\x84\x85\t\x90P\x82\x80a\x1A\xB2Wa\x1A\xB2a+^V[\x84\x82\t\x90P\x82\x80a\x1A\xC5Wa\x1A\xC5a+^V[\x82\x82\x08\x90P__a\x1A\xD5\x83a \xCAV[\x92P\x90P[\x80a\x1B>W\x84\x80a\x1A\xEDWa\x1A\xEDa+^V[`\x01\x87\x08\x95P\x84\x80a\x1B\x01Wa\x1B\x01a+^V[\x86\x87\t\x92P\x84\x80a\x1B\x14Wa\x1B\x14a+^V[\x86\x84\t\x92P\x84\x80a\x1B'Wa\x1B'a+^V[\x84\x84\x08\x92Pa\x1B5\x83a \xCAV[\x92P\x90Pa\x1A\xDAV[P`@\x80Q\x80\x82\x01\x90\x91R\x94\x85R` \x85\x01RP\x91\x94\x93PPPPV[`@\x80Q\x80\x82\x01\x90\x91R_\x80\x82R` \x82\x01R\x81Q` \x83\x01Q\x15\x90\x15\x16\x15a\x1B\x82WP\x90V[`@Q\x80`@\x01`@R\x80\x83_\x01Q\x81R` \x01_Q` a-\xAB_9_Q\x90_R\x84` \x01Qa\x1B\xB3\x91\x90a+rV[a\x1B\xCA\x90_Q` a-\xAB_9_Q\x90_Ra+\x18V[\x90R\x92\x91PPV[a\x1B\xF9`@Q\x80`\x80\x01`@R\x80_\x81R` \x01_\x81R` \x01_\x81R` \x01_\x81RP\x90V[`@Q\x80`\x80\x01`@R\x80\x7F\x18\0\xDE\xEF\x12\x1F\x1EvBj\0f^\\DygC\"\xD4\xF7^\xDA\xDDF\xDE\xBD\\\xD9\x92\xF6\xED\x81R` \x01\x7F\x19\x8E\x93\x93\x92\rH:r`\xBF\xB71\xFB]%\xF1\xAAI35\xA9\xE7\x12\x97\xE4\x85\xB7\xAE\xF3\x12\xC2\x81R` \x01\x7F\x12\xC8^\xA5\xDB\x8Cm\xEBJ\xABq\x80\x8D\xCB@\x8F\xE3\xD1\xE7i\x0CC\xD3{L\xE6\xCC\x01f\xFA}\xAA\x81R` \x01\x7F\t\x06\x89\xD0X_\xF0u\xEC\x9E\x99\xADi\x0C3\x95\xBCK13p\xB3\x8E\xF3U\xAC\xDA\xDC\xD1\"\x97[\x81RP\x90P\x90V[___`@Q\x87Q\x81R` \x88\x01Q` \x82\x01R` \x87\x01Q`@\x82\x01R\x86Q``\x82\x01R``\x87\x01Q`\x80\x82\x01R`@\x87\x01Q`\xA0\x82\x01R\x85Q`\xC0\x82\x01R` \x86\x01Q`\xE0\x82\x01R` \x85\x01Qa\x01\0\x82\x01R\x84Qa\x01 \x82\x01R``\x85\x01Qa\x01@\x82\x01R`@\x85\x01Qa\x01`\x82\x01R` _a\x01\x80\x83`\x08Z\xFA\x91PP_Q\x91P\x80a\x1DqW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1C`$\x82\x01R\x7FBn254: Pairing check failed!\0\0\0\0`D\x82\x01R`d\x01a\x06\x9FV[P\x15\x15\x95\x94PPPPPV[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0T`\x01`@\x1B\x90\x04`\xFF\x16a\x0CUW`@Qc\x1A\xFC\xD7\x9F`\xE3\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x11\xBEa\x1D}V[\x80`\x01`\x01`\xA0\x1B\x03\x16;_\x03a\x1E\x03W`@QcL\x9C\x8C\xE3`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x82\x16`\x04\x82\x01R`$\x01a\x06\x9FV[_Q` a-\xCB_9_Q\x90_R\x80T`\x01`\x01`\xA0\x1B\x03\x19\x16`\x01`\x01`\xA0\x1B\x03\x92\x90\x92\x16\x91\x90\x91\x17\x90UV[``__\x84`\x01`\x01`\xA0\x1B\x03\x16\x84`@Qa\x1EM\x91\x90a+\x91V[_`@Q\x80\x83\x03\x81\x85Z\xF4\x91PP=\x80_\x81\x14a\x1E\x85W`@Q\x91P`\x1F\x19`?=\x01\x16\x82\x01`@R=\x82R=_` \x84\x01>a\x1E\x8AV[``\x91P[P\x91P\x91Pa\x1E\x9A\x85\x83\x83a!\xC1V[\x95\x94PPPPPV[4\x15a\x0CUW`@Qc\xB3\x98\x97\x9F`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[__a\x1E\xCD\x83a\" V[\x80Q\x90\x91P`0\x81\x14a\x1E\xE2Wa\x1E\xE2a+\x9CV[_\x81`\x01`\x01`@\x1B\x03\x81\x11\x15a\x1E\xFBWa\x1E\xFBa&>V[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a\x1F%W` \x82\x01\x81\x806\x837\x01\x90P[P\x90P_[\x82\x81\x10\x15a\x1F\x94W\x83`\x01a\x1F?\x83\x86a+\x18V[a\x1FI\x91\x90a+\x18V[\x81Q\x81\x10a\x1FYWa\x1FYa+\xB0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x82\x82\x81Q\x81\x10a\x1FvWa\x1Fva+\xB0V[` \x01\x01\x90`\x01`\x01`\xF8\x1B\x03\x19\x16\x90\x81_\x1A\x90SP`\x01\x01a\x1F*V[P`@\x80Q`\x1F\x80\x82Ra\x04\0\x82\x01\x90\x92R_\x90\x82` \x82\x01a\x03\xE0\x806\x837\x01\x90PP\x90P_[\x82\x81\x10\x15a $W\x83\x81a\x1F\xD0\x85\x88a+\x18V[a\x1F\xDA\x91\x90a*\xC8V[\x81Q\x81\x10a\x1F\xEAWa\x1F\xEAa+\xB0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B`\xF8\x1C\x82\x82\x81Q\x81\x10a \nWa \na+\xB0V[`\xFF\x90\x92\x16` \x92\x83\x02\x91\x90\x91\x01\x90\x91\x01R`\x01\x01a\x1F\xBCV[P_a /\x82a%kV[\x90Pa\x01\0_Q` a-\xAB_9_Q\x90_R_a M\x86\x89a+\x18V[\x90P_[\x81\x81\x10\x15a \xBAW_\x88`\x01a g\x84\x86a+\x18V[a q\x91\x90a+\x18V[\x81Q\x81\x10a \x81Wa \x81a+\xB0V[\x01` \x01Q`\xF8\x1C\x90P\x83\x80a \x99Wa \x99a+^V[\x85\x87\t\x95P\x83\x80a \xACWa \xACa+^V[\x81\x87\x08\x95PP`\x01\x01a QV[P\x92\x9A\x99PPPPPPPPPPV[_____\x7F\x0C\x19\x13\x9C\xB8Lh\nn\x14\x11m\xA0`V\x17e\xE0Z\xA4Z\x1Cr\xA3O\x08#\x05\xB6\x1F?R\x90P__Q` a-\xAB_9_Q\x90_R\x90P`@Q` \x81R` \x80\x82\x01R` `@\x82\x01R\x87``\x82\x01R\x82`\x80\x82\x01R\x81`\xA0\x82\x01R` _`\xC0\x83`\x05Z\xFA\x94PP_Q\x92P\x83a!\x87W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1B`$\x82\x01R\x7Fpow precompile call failed!\0\0\0\0\0`D\x82\x01R`d\x01a\x06\x9FV[\x80`\x01\x84\x90\x1B\x11\x15a!\xA0Wa!\x9D\x83\x82a+\x18V[\x92P[\x80\x80a!\xAEWa!\xAEa+^V[\x83\x84\t\x96\x90\x96\x14\x96\x91\x95P\x90\x93PPPPV[``\x82a!\xD6Wa!\xD1\x82a%\xD2V[a\"\x19V[\x81Q\x15\x80\x15a!\xEDWP`\x01`\x01`\xA0\x1B\x03\x84\x16;\x15[\x15a\"\x16W`@Qc\x99\x96\xB3\x15`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x85\x16`\x04\x82\x01R`$\x01a\x06\x9FV[P\x80[\x93\x92PPPV[`@\x80Q`0\x80\x82R``\x82\x81\x01\x90\x93R\x90` \x90`\x01`\xF9\x1B\x90_\x90\x84` \x82\x01\x81\x806\x837\x01\x90PP\x90P\x80\x86`@Q` \x01a\"`\x92\x91\x90a+BV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P\x80\x84`\xF8\x1B`@Q` \x01a\"\x87\x92\x91\x90a+\xC4V[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P\x80`@Q` \x01a\"\xA9\x91\x90a+\xEEV[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x90\x82\x90R\x91Pa\x01\x01`\xF0\x1B\x90a\"\xD3\x90\x83\x90\x83\x90` \x01a,\x06V[`@\x80Q\x80\x83\x03`\x1F\x19\x01\x81R\x82\x82R\x80Q` \x91\x82\x01 \x81\x84\x01\x81\x90R`\x01`\xF8\x1B\x84\x84\x01R`\x01`\x01`\xF0\x1B\x03\x19\x85\x16`A\x85\x01R\x82Q`#\x81\x86\x03\x01\x81R`C\x90\x94\x01\x90\x92R\x82Q\x90\x83\x01 \x91\x93P\x90_`\xFF\x88\x16`\x01`\x01`@\x1B\x03\x81\x11\x15a#BWa#Ba&>V[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a#lW` \x82\x01\x81\x806\x837\x01\x90P[P\x90P_\x82`@Q` \x01a#\x83\x91\x81R` \x01\x90V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x91\x90R\x90P_[\x81Q\x81\x10\x15a#\xEDW\x81\x81\x81Q\x81\x10a#\xB2Wa#\xB2a+\xB0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x83\x82\x81Q\x81\x10a#\xCFWa#\xCFa+\xB0V[` \x01\x01\x90`\x01`\x01`\xF8\x1B\x03\x19\x16\x90\x81_\x1A\x90SP`\x01\x01a#\x97V[P_\x84`@Q` \x01a$\x02\x91\x81R` \x01\x90V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R` \x83\x01\x90\x91R_\x80\x83R\x91\x98P\x91P[\x89\x81\x10\x15a$\x94W_\x83\x82\x81Q\x81\x10a$;Wa$;a+\xB0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x83\x83\x81Q\x81\x10a$XWa$Xa+\xB0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x18\x90P\x88\x81`@Q` \x01a$y\x92\x91\x90a,*V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x91\x90R\x98PP`\x01\x01a$ V[P\x86\x88\x87`@Q` \x01a$\xAA\x93\x92\x91\x90a,NV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x96P\x86\x80Q\x90` \x01 \x93P\x83`@Q` \x01a$\xD8\x91\x81R` \x01\x90V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x91\x90R\x91P_[a$\xF9\x8A`\xFF\x8D\x16a+\x18V[\x81\x10\x15a%ZW\x82\x81\x81Q\x81\x10a%\x12Wa%\x12a+\xB0V[\x01` \x01Q`\x01`\x01`\xF8\x1B\x03\x19\x16\x84a%,\x83\x8Da*\xC8V[\x81Q\x81\x10a%V[`@R\x90V[`@Q`\x1F\x82\x01`\x1F\x19\x16\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a&\xA2Wa&\xA2a&>V[`@R\x91\x90PV[_`\x80\x82\x84\x03\x12\x15a&\xBAW__\xFD[`@Q`\x80\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a&\xDCWa&\xDCa&>V[`@\x90\x81R\x835\x82R` \x80\x85\x015\x90\x83\x01R\x83\x81\x015\x90\x82\x01R``\x92\x83\x015\x92\x81\x01\x92\x90\x92RP\x91\x90PV[_`@\x82\x84\x03\x12\x15a'\x1AW__\xFD[a'\"a&RV[\x825\x81R` \x92\x83\x015\x92\x81\x01\x92\x90\x92RP\x91\x90PV[\x805a\xFF\xFF\x81\x16\x81\x14a&\x11W__\xFD[____a\x01 \x85\x87\x03\x12\x15a'^W__\xFD[a'h\x86\x86a&\xAAV[\x93Pa'w\x86`\x80\x87\x01a'\nV[\x92Pa'\x86\x86`\xC0\x87\x01a'\nV[\x91Pa'\x95a\x01\0\x86\x01a'9V[\x90P\x92\x95\x91\x94P\x92PV[`\x01`\x01`@\x1B\x03\x81\x16\x81\x14a\x11\xF0W__\xFD[_` \x82\x84\x03\x12\x15a'\xC4W__\xFD[\x815a\"\x19\x81a'\xA0V[_` \x82\x84\x03\x12\x15a'\xDFW__\xFD[a\x19\xCF\x82a%\xFBV[__`@\x83\x85\x03\x12\x15a'\xF9W__\xFD[a(\x02\x83a%\xFBV[\x91P` \x83\x015`\x01`\x01`@\x1B\x03\x81\x11\x15a(\x1CW__\xFD[\x83\x01`\x1F\x81\x01\x85\x13a(,W__\xFD[\x805`\x01`\x01`@\x1B\x03\x81\x11\x15a(EWa(Ea&>V[a(X`\x1F\x82\x01`\x1F\x19\x16` \x01a&zV[\x81\x81R\x86` \x83\x85\x01\x01\x11\x15a(lW__\xFD[\x81` \x84\x01` \x83\x017_` \x83\x83\x01\x01R\x80\x93PPPP\x92P\x92\x90PV[___a\x01\0\x84\x86\x03\x12\x15a(\x9EW__\xFD[a(\xA8\x85\x85a&\xAAV[\x92Pa(\xB7\x85`\x80\x86\x01a'\nV[\x91Pa(\xC6\x85`\xC0\x86\x01a'\nV[\x90P\x92P\x92P\x92V[_`\x80\x82\x84\x03\x12\x15a(\xDFW__\xFD[a\x19\xCF\x83\x83a&\xAAV[__`@\x83\x85\x03\x12\x15a(\xFAW__\xFD[a)\x03\x83a%\xFBV[\x91Pa)\x11` \x84\x01a%\xFBV[\x90P\x92P\x92\x90PV[_____a\x01`\x86\x88\x03\x12\x15a)/W__\xFD[a)9\x87\x87a&\xAAV[\x94Pa)H\x87`\x80\x88\x01a'\nV[\x93Pa)W\x87`\xC0\x88\x01a'\nV[\x92Pa)g\x87a\x01\0\x88\x01a'\nV[\x91Pa)va\x01@\x87\x01a'9V[\x90P\x92\x95P\x92\x95\x90\x93PV[` \x81R_\x82Q\x80` \x84\x01R\x80` \x85\x01`@\x85\x01^_`@\x82\x85\x01\x01R`@`\x1F\x19`\x1F\x83\x01\x16\x84\x01\x01\x91PP\x92\x91PPV[_` \x82\x84\x03\x12\x15a)\xC7W__\xFD[P5\x91\x90PV[____`\x80\x85\x87\x03\x12\x15a)\xE1W__\xFD[a)\xEA\x85a%\xFBV[\x93Pa)\xF8` \x86\x01a%\xFBV[\x92P`@\x85\x015\x91Pa'\x95``\x86\x01a%\xFBV[____a\x01@\x85\x87\x03\x12\x15a*!W__\xFD[a*+\x86\x86a&\xAAV[\x93Pa*:\x86`\x80\x87\x01a'\nV[\x92Pa*I\x86`\xC0\x87\x01a'\nV[\x91Pa'\x95\x86a\x01\0\x87\x01a'\nV[cNH{q`\xE0\x1B_R`!`\x04R`$_\xFD[\x82\x81R`@\x81\x01`\x03\x83\x10a*\x90WcNH{q`\xE0\x1B_R`!`\x04R`$_\xFD[\x82` \x83\x01R\x93\x92PPPV[_` \x82\x84\x03\x12\x15a*\xADW__\xFD[PQ\x91\x90PV[cNH{q`\xE0\x1B_R`\x11`\x04R`$_\xFD[\x80\x82\x01\x80\x82\x11\x15a\x19\xD2Wa\x19\xD2a*\xB4V[_` \x82\x84\x03\x12\x15a*\xEBW__\xFD[\x81Qa\"\x19\x81a'\xA0V[`\x01`\x01`@\x1B\x03\x81\x81\x16\x83\x82\x16\x02\x90\x81\x16\x90\x81\x81\x14a%\xCBWa%\xCBa*\xB4V[\x81\x81\x03\x81\x81\x11\x15a\x19\xD2Wa\x19\xD2a*\xB4V[_\x81Q\x80` \x84\x01\x85^_\x93\x01\x92\x83RP\x90\x91\x90PV[_a+Va+P\x83\x86a++V[\x84a++V[\x94\x93PPPPV[cNH{q`\xE0\x1B_R`\x12`\x04R`$_\xFD[_\x82a+\x8CWcNH{q`\xE0\x1B_R`\x12`\x04R`$_\xFD[P\x06\x90V[_a\x19\xCF\x82\x84a++V[cNH{q`\xE0\x1B_R`\x01`\x04R`$_\xFD[cNH{q`\xE0\x1B_R`2`\x04R`$_\xFD[_a+\xCF\x82\x85a++V[_\x81R`\x01`\x01`\xF8\x1B\x03\x19\x93\x90\x93\x16`\x01\x84\x01RPP`\x02\x01\x91\x90PV[_a+\xF9\x82\x84a++V[_\x81R`\x01\x01\x93\x92PPPV[_a,\x11\x82\x85a++V[`\x01`\x01`\xF0\x1B\x03\x19\x93\x90\x93\x16\x83RPP`\x02\x01\x91\x90PV[_a,5\x82\x85a++V[`\x01`\x01`\xF8\x1B\x03\x19\x93\x90\x93\x16\x83RPP`\x01\x01\x91\x90PV[_a,Y\x82\x86a++V[`\x01`\x01`\xF8\x1B\x03\x19\x94\x90\x94\x16\x84RPP`\x01`\x01`\xF0\x1B\x03\x19\x16`\x01\x82\x01R`\x03\x01\x91\x90PV[\x80\x82\x02\x81\x15\x82\x82\x04\x84\x14\x17a\x19\xD2Wa\x19\xD2a*\xB4V[`\x01\x81[`\x01\x84\x11\x15a,\xD3W\x80\x85\x04\x81\x11\x15a,\xB7Wa,\xB7a*\xB4V[`\x01\x84\x16\x15a,\xC5W\x90\x81\x02\x90[`\x01\x93\x90\x93\x1C\x92\x80\x02a,\x9CV[\x93P\x93\x91PPV[_\x82a,\xE9WP`\x01a\x19\xD2V[\x81a,\xF5WP_a\x19\xD2V[\x81`\x01\x81\x14a-\x0BW`\x02\x81\x14a-\x15Wa-1V[`\x01\x91PPa\x19\xD2V[`\xFF\x84\x11\x15a-&Wa-&a*\xB4V[PP`\x01\x82\x1Ba\x19\xD2V[P` \x83\x10a\x013\x83\x10\x16`N\x84\x10`\x0B\x84\x10\x16\x17\x15a-TWP\x81\x81\na\x19\xD2V[a-`_\x19\x84\x84a,\x98V[\x80_\x19\x04\x82\x11\x15a-sWa-sa*\xB4V[\x02\x93\x92PPPV[_a\x19\xCF\x83\x83a,\xDBV\xFEBLS_SIG_BN254G1_XMD:KECCAK_NCTH_NUL_0dNr\xE11\xA0)\xB8PE\xB6\x81\x81X]\x97\x81j\x91hq\xCA\x8D< \x8C\x16\xD8|\xFDG6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\xA1dsolcC\0\x08\x1C\0\n", + b"`\x80`@R`\x046\x10a\x01\xAFW_5`\xE0\x1C\x80c\x9B0\xA5\xE6\x11a\0\xE7W\x80c\xB5p\x0Eh\x11a\0\x87W\x80c\xC6H\x14\xDD\x11a\0bW\x80c\xC6H\x14\xDD\x14a\x05\"W\x80c\xF2\xFD\xE3\x8B\x14a\x05XW\x80c\xFAR\xC7\xD8\x14a\x05wW\x80c\xFC\x0CTj\x14a\x05\xBAW__\xFD[\x80c\xB5p\x0Eh\x14a\x04\xB9W\x80c\xB5\xEC\xB3D\x14a\x04\xD8W\x80c\xBE 0\x94\x14a\x05\x03W__\xFD[\x80c\xA3\x06j\xAB\x11a\0\xC2W\x80c\xA3\x06j\xAB\x14a\x04\0W\x80c\xAC\\*\xD0\x14a\x04\x1FW\x80c\xAD<\xB1\xCC\x14a\x04>W\x80c\xB3\xE6\xEB\xD5\x14a\x04{W__\xFD[\x80c\x9B0\xA5\xE6\x14a\x03zW\x80c\x9E\x9A\x8F1\x14a\x03\x99W\x80c\xA2\xD7\x8D\xD5\x14a\x03\xAEW__\xFD[\x80cM\x99\xDD\x16\x11a\x01RW\x80cUD\xC2\xF1\x11a\x01-W\x80cUD\xC2\xF1\x14a\x02\xE8W\x80cj\x91\x1C\xCF\x14a\x03\x02W\x80cqP\x18\xA6\x14a\x03\x16W\x80c\x8D\xA5\xCB[\x14a\x03*W__\xFD[\x80cM\x99\xDD\x16\x14a\x02\xA2W\x80cO\x1E\xF2\x86\x14a\x02\xC1W\x80cR\xD1\x90-\x14a\x02\xD4W__\xFD[\x80c\x1A \xCDc\x11a\x01\x8DW\x80c\x1A \xCDc\x14a\x02#W\x80c!@\xFE\xCD\x14a\x02BW\x80c0B@\xBF\x14a\x02aW\x80c>\x9D\xF9\xB5\x14a\x02\x80W__\xFD[\x80c\x02n@+\x14a\x01\xB3W\x80c\r\x8En,\x14a\x01\xD4W\x80c\x13\xB9\x05z\x14a\x02\x04W[__\xFD[4\x80\x15a\x01\xBEW__\xFD[Pa\x01\xD2a\x01\xCD6`\x04a%\x83V[a\x05\xD9V[\0[4\x80\x15a\x01\xDFW__\xFD[P`@\x80Q`\x02\x81R_` \x82\x01\x81\x90R\x91\x81\x01\x91\x90\x91R``\x01[`@Q\x80\x91\x03\x90\xF3[4\x80\x15a\x02\x0FW__\xFD[Pa\x01\xD2a\x02\x1E6`\x04a&\x87V[a\x07|V[4\x80\x15a\x02.W__\xFD[Pa\x01\xD2a\x02=6`\x04a&\xF1V[a\x07\x95V[4\x80\x15a\x02MW__\xFD[Pa\x01\xD2a\x02\\6`\x04a'\x0CV[a\x08\xA9V[4\x80\x15a\x02lW__\xFD[Pa\x01\xD2a\x02{6`\x04a'\xAEV[a\t\xCAV[4\x80\x15a\x02\x8BW__\xFD[Pa\x02\x94_T\x81V[`@Q\x90\x81R` \x01a\x01\xFBV[4\x80\x15a\x02\xADW__\xFD[Pa\x01\xD2a\x02\xBC6`\x04a%\x83V[a\x0B4V[a\x01\xD2a\x02\xCF6`\x04a(.V[a\x0C\xE6V[4\x80\x15a\x02\xDFW__\xFD[Pa\x02\x94a\r\x05V[4\x80\x15a\x02\xF3W__\xFD[Pa\x01\xD2a\x02\x1E6`\x04a(xV[4\x80\x15a\x03\rW__\xFD[Pa\x01\xD2a\r V[4\x80\x15a\x03!W__\xFD[Pa\x01\xD2a\r\xAEV[4\x80\x15a\x035W__\xFD[P\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0T`\x01`\x01`\xA0\x1B\x03\x16[`@Q`\x01`\x01`\xA0\x1B\x03\x90\x91\x16\x81R` \x01a\x01\xFBV[4\x80\x15a\x03\x85W__\xFD[Pa\x02\x94a\x03\x946`\x04a(\xBCV[a\r\xC1V[4\x80\x15a\x03\xA4W__\xFD[Pa\x02\x94`\x08T\x81V[4\x80\x15a\x03\xB9W__\xFD[Pa\x03\xEBa\x03\xC86`\x04a(\xD6V[`\x07` \x90\x81R_\x92\x83R`@\x80\x84 \x90\x91R\x90\x82R\x90 \x80T`\x01\x90\x91\x01T\x82V[`@\x80Q\x92\x83R` \x83\x01\x91\x90\x91R\x01a\x01\xFBV[4\x80\x15a\x04\x0BW__\xFD[Pa\x01\xD2a\x04\x1A6`\x04a'\x0CV[a\x0E\x1BV[4\x80\x15a\x04*W__\xFD[Pa\x01\xD2a\x0496`\x04a)\x07V[a\x0F+V[4\x80\x15a\x04IW__\xFD[Pa\x04n`@Q\x80`@\x01`@R\x80`\x05\x81R` \x01d\x03R\xE3\x02\xE3`\xDC\x1B\x81RP\x81V[`@Qa\x01\xFB\x91\x90a)\xA4V[4\x80\x15a\x04\x86W__\xFD[Pa\x04\xA9a\x04\x956`\x04a)\xB6V[`\x04` R_\x90\x81R`@\x90 T`\xFF\x16\x81V[`@Q\x90\x15\x15\x81R` \x01a\x01\xFBV[4\x80\x15a\x04\xC4W__\xFD[P`\x01Ta\x03b\x90`\x01`\x01`\xA0\x1B\x03\x16\x81V[4\x80\x15a\x04\xE3W__\xFD[Pa\x02\x94a\x04\xF26`\x04a'\x0CV[`\x05` R_\x90\x81R`@\x90 T\x81V[4\x80\x15a\x05\x0EW__\xFD[Pa\x01\xD2a\x05\x1D6`\x04a)\xCDV[a\x0F\xF9V[4\x80\x15a\x05-W__\xFD[Pa\x02\x94a\x05<6`\x04a(\xD6V[`\x06` \x90\x81R_\x92\x83R`@\x80\x84 \x90\x91R\x90\x82R\x90 T\x81V[4\x80\x15a\x05cW__\xFD[Pa\x01\xD2a\x05r6`\x04a'\x0CV[a\x11#V[4\x80\x15a\x05\x82W__\xFD[Pa\x05\xACa\x05\x916`\x04a'\x0CV[`\x03` R_\x90\x81R`@\x90 \x80T`\x01\x90\x91\x01T`\xFF\x16\x82V[`@Qa\x01\xFB\x92\x91\x90a* V[4\x80\x15a\x05\xC5W__\xFD[P`\x02Ta\x03b\x90`\x01`\x01`\xA0\x1B\x03\x16\x81V[a\x05\xE2\x82a\x11`V[3_\x82\x90\x03a\x06\x04W`@Qc\x1F* \x05`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02T`@Qcn\xB1v\x9F`\xE1\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x83\x81\x16`\x04\x83\x01R0`$\x83\x01R_\x92\x16\x90c\xDDb\xED>\x90`D\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x15\x80\x15a\x06RW=__>=_\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x06v\x91\x90a*PV[\x90P\x82\x81\x10\x15a\x06\xA8W`@Qc\x05Ce\xBB`\xE3\x1B\x81R`\x04\x81\x01\x82\x90R`$\x81\x01\x84\x90R`D\x01[`@Q\x80\x91\x03\x90\xFD[`\x02Ta\x06\xC0\x90`\x01`\x01`\xA0\x1B\x03\x16\x830\x86a\x11\xE1V[`\x01`\x01`\xA0\x1B\x03\x84\x16_\x90\x81R`\x03` R`@\x81 \x80T\x85\x92\x90a\x06\xE7\x90\x84\x90a*{V[\x90\x91UPP`\x01`\x01`\xA0\x1B\x03\x80\x85\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R\x90\x81 \x80T\x85\x92\x90a\x07\"\x90\x84\x90a*{V[\x92PP\x81\x90UP\x83`\x01`\x01`\xA0\x1B\x03\x16\x82`\x01`\x01`\xA0\x1B\x03\x16\x7F\xE5T\x1Aka\x03\xD4\xFA~\x02\x1E\xD5O\xAD9\xC6o'\xA7k\xD1=7L\xF6$\n\xE6\xBD\x0B\xB7+\x85`@Qa\x07n\x91\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA3PPPPV[`@Qc\xC2\xD7\xF8\x13`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x07\x9Da\x12\x85V[`\x01T`@\x80Qc<\x1A\x08\x15`\xE2\x1B\x81R\x90Q_\x92`\x01`\x01`\xA0\x1B\x03\x16\x91c\xF0h T\x91`\x04\x80\x83\x01\x92` \x92\x91\x90\x82\x90\x03\x01\x81\x86Z\xFA\x15\x80\x15a\x07\xE4W=__>=_\xFD[PPPP`@Q=`\x1F\x19`\x1F\x82\x01\x16\x82\x01\x80`@RP\x81\x01\x90a\x08\x08\x91\x90a*\x8EV[a\x08\x13\x90`\x0Fa*\xA9V[\x90Pb\x12u\0`\x01`\x01`@\x1B\x03\x80\x83\x16\x90\x84\x16\x10\x80a\x08DWP\x80`\x01`\x01`@\x1B\x03\x16\x83`\x01`\x01`@\x1B\x03\x16\x11[\x15a\x08bW`@Qc\xB5~!\xDF`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`@\x1B\x03\x83\x16`\x08\x81\x90U`@Q\x90\x81R\x7Fy>;\x1E\x1B\xCDg{\xB1\x19\0\xC81$\xD3\xC4L\x99F\xEA\x8D\xDF\x97\x8A\x0C\xA2P\xB04\xEC\x9D\xDE\x90` \x01`@Q\x80\x91\x03\x90\xA1PPPV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x05` R`@\x81 T3\x91\x81\x90\x03a\x08\xE3W`@Qcy)\x8AS`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x80B\x10\x15a\t\x04W`@QcZwCW`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R\x90\x81 T\x90\x81\x90\x03a\tLW`@Qc\x06\x86\x82{`\xE5\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x85\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x87\x85\x16\x84R\x90\x91R\x81 U`\x02Ta\t\x81\x91\x16\x84\x83a\x12\xE0V[\x82`\x01`\x01`\xA0\x1B\x03\x16\x7F\x7F\xCFS,\x15\xF0\xA6\xDB\x0B\xD6\xD0\xE08\xBE\xA7\x1D0\xD8\x08\xC7\xD9\x8C\xB3\xBFrh\xA9[\xF5\x08\x1Be\x82`@Qa\t\xBC\x91\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA2PPPPV[3a\t\xD4\x81a\x13oV[a\t\xDD\x85a\x13\xBCV[a\t\xE6\x86a\x13\xF7V[`@\x80Q`\x01`\x01`\xA0\x1B\x03\x83\x16` \x82\x01R_\x91\x01`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90Pa\n\x18\x81\x86\x89a\x143V[a'\x10\x83a\xFF\xFF\x16\x11\x15a\n?W`@Qc\xDC\x81\xDB\x85`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x04_a\nM\x8Aa\r\xC1V[\x81R` \x01\x90\x81R` \x01_ _a\x01\0\n\x81T\x81`\xFF\x02\x19\x16\x90\x83\x15\x15\x02\x17\x90UP`@Q\x80`@\x01`@R\x80_\x81R` \x01`\x01`\x02\x81\x11\x15a\n\x94Wa\n\x94a*\x0CV[\x90R`\x01`\x01`\xA0\x1B\x03\x83\x16_\x90\x81R`\x03` \x90\x81R`@\x90\x91 \x82Q\x81U\x90\x82\x01Q`\x01\x80\x83\x01\x80T\x90\x91`\xFF\x19\x90\x91\x16\x90\x83`\x02\x81\x11\x15a\n\xDAWa\n\xDAa*\x0CV[\x02\x17\x90UP\x90PP\x81`\x01`\x01`\xA0\x1B\x03\x16\x7F\xF0W\xD4\xEA\x81\xE9\x86(e:\x8F\x90x\x85A\x97 x\x13s4\xA9+B4~\xAC\xCD\xA8\x0F\xC4\n\x88\x88\x86\x89\x89`@Qa\x0B#\x95\x94\x93\x92\x91\x90a*\xCBV[`@Q\x80\x91\x03\x90\xA2PPPPPPPV[a\x0B=\x82a\x11`V[3_\x82\x90\x03a\x0B_W`@Qc\x1F* \x05`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 \x93\x85\x16\x83R\x92\x90R T\x15a\x0B\xA2W`@Qc\xD4#\xA4\xF1`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x85\x16\x83R\x92\x90R T\x82\x81\x10\x15a\x0B\xEBW`@Qc\x92fSQ`\xE0\x1B\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\x9FV[`\x01`\x01`\xA0\x1B\x03\x80\x85\x16_\x90\x81R`\x06` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R\x90\x81 \x80T\x85\x92\x90a\x0C!\x90\x84\x90a+=V[\x92PP\x81\x90UP`@Q\x80`@\x01`@R\x80\x84\x81R` \x01`\x08TBa\x0CG\x91\x90a*{V[\x90R`\x01`\x01`\xA0\x1B\x03\x80\x86\x16_\x81\x81R`\x07` \x90\x81R`@\x80\x83 \x94\x88\x16\x83R\x93\x81R\x83\x82 \x85Q\x81U\x94\x81\x01Q`\x01\x90\x95\x01\x94\x90\x94U\x90\x81R`\x03\x90\x92R\x81 \x80T\x85\x92\x90a\x0C\x9A\x90\x84\x90a+=V[\x92PP\x81\x90UP\x83`\x01`\x01`\xA0\x1B\x03\x16\x82`\x01`\x01`\xA0\x1B\x03\x16\x7FM\x10\xBD\x04\x97u\xC7{\xD7\xF2U\x19Z\xFB\xA5\x08\x80(\xEC\xB3\xC7\xC2w\xD3\x93\xCC\xFFy4\xF2\xF9,\x85`@Qa\x07n\x91\x81R` \x01\x90V[a\x0C\xEEa\x14\xC8V[a\x0C\xF7\x82a\x15lV[a\r\x01\x82\x82a\x15\xB3V[PPV[_a\r\x0Ea\x16tV[P_Q` a.V_9_Q\x90_R\x90V[3a\r*\x81a\x11`V[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x03` R`@\x90 `\x01\x01\x80T`\xFF\x19\x16`\x02\x17\x90U`\x08Ta\r\\\x90Ba*{V[`\x01`\x01`\xA0\x1B\x03\x82\x16_\x81\x81R`\x05` \x90\x81R`@\x80\x83 \x94\x90\x94U`\x03\x90R\x82\x81 \x81\x90U\x91Q\x90\x91\x7F\xFB$0ST\xC8wb\xD5WHz\xE4\xA5d\xE8\xD0>\xCB\xB9\xA9}\xD8\xAF\xFF\x8E\x1Fo\xCA\xF0\xDD\x16\x91\xA2PV[a\r\xB6a\x12\x85V[a\r\xBF_a\x16\xBDV[V[_\x81_\x01Q\x82` \x01Q\x83`@\x01Q\x84``\x01Q`@Q` \x01a\r\xFE\x94\x93\x92\x91\x90\x93\x84R` \x84\x01\x92\x90\x92R`@\x83\x01R``\x82\x01R`\x80\x01\x90V[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x80Q\x90` \x01 \x90P\x91\x90PV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 3\x80\x85R\x92R\x82 T\x90\x91\x81\x90\x03a\x0E`W`@Qc\x06\x86\x82{`\xE5\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 \x93\x86\x16\x83R\x92\x90R `\x01\x01TB\x10\x15a\x0E\xA8W`@QcZwCW`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x80\x84\x16_\x90\x81R`\x07` \x90\x81R`@\x80\x83 \x86\x85\x16\x84R\x90\x91R\x81 \x81\x81U`\x01\x01U`\x02Ta\x0E\xE3\x91\x16\x83\x83a\x12\xE0V[\x81`\x01`\x01`\xA0\x1B\x03\x16\x7F\x7F\xCFS,\x15\xF0\xA6\xDB\x0B\xD6\xD0\xE08\xBE\xA7\x1D0\xD8\x08\xC7\xD9\x8C\xB3\xBFrh\xA9[\xF5\x08\x1Be\x82`@Qa\x0F\x1E\x91\x81R` \x01\x90V[`@Q\x80\x91\x03\x90\xA2PPPV[3a\x0F5\x81a\x11`V[a\x0F>\x84a\x13\xBCV[a\x0FG\x85a\x13\xF7V[`@\x80Q`\x01`\x01`\xA0\x1B\x03\x83\x16` \x82\x01R_\x91\x01`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90Pa\x0Fy\x81\x85\x88a\x143V[`\x01`\x04_a\x0F\x87\x89a\r\xC1V[\x81R` \x01\x90\x81R` \x01_ _a\x01\0\n\x81T\x81`\xFF\x02\x19\x16\x90\x83\x15\x15\x02\x17\x90UP\x81`\x01`\x01`\xA0\x1B\x03\x16\x7F\xC8\xC5\xB3z\xEC\x7F-\xDB\xD3\xA1#\xA9f.\xFC\x9C\"\x9Cj\0\x80T`\x01`@\x1B\x81\x04`\xFF\x16\x15\x90`\x01`\x01`@\x1B\x03\x16_\x81\x15\x80\x15a\x10=WP\x82[\x90P_\x82`\x01`\x01`@\x1B\x03\x16`\x01\x14\x80\x15a\x10XWP0;\x15[\x90P\x81\x15\x80\x15a\x10fWP\x80\x15[\x15a\x10\x84W`@Qc\xF9.\xE8\xA9`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x84Tg\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16`\x01\x17\x85U\x83\x15a\x10\xAEW\x84T`\xFF`@\x1B\x19\x16`\x01`@\x1B\x17\x85U[a\x10\xB7\x86a\x17-V[a\x10\xBFa\x17>V[a\x10\xC7a\x17FV[a\x10\xD2\x89\x89\x89a\x18JV[\x83\x15a\x11\x18W\x84T`\xFF`@\x1B\x19\x16\x85U`@Q`\x01\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1[PPPPPPPPPV[a\x11+a\x12\x85V[`\x01`\x01`\xA0\x1B\x03\x81\x16a\x11TW`@Qc\x1EO\xBD\xF7`\xE0\x1B\x81R_`\x04\x82\x01R`$\x01a\x06\x9FV[a\x11]\x81a\x16\xBDV[PV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x03` R`@\x81 `\x01\x01T`\xFF\x16\x90\x81`\x02\x81\x11\x15a\x11\x91Wa\x11\x91a*\x0CV[\x03a\x11\xAFW`@QcP\x8Ay?`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02\x81`\x02\x81\x11\x15a\x11\xC3Wa\x11\xC3a*\x0CV[\x03a\r\x01W`@Qc\xEA\xB4\xA9c`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[_`@Qc#\xB8r\xDD`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x85\x16`\x04\x82\x01R`\x01`\x01`\xA0\x1B\x03\x84\x16`$\x82\x01R\x82`D\x82\x01R` _`d\x83_\x8AZ\xF1\x91PP\x80`\x1F=\x11`\x01_Q\x14\x16\x15\x16\x15a\x12:WP\x83;\x15=\x17\x15[\x80a\x12~W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x14`$\x82\x01Rs\x15\x14\x90S\x94\xD1\x91T\x97\xD1\x94\x93\xD3W\xD1\x90RS\x11Q`b\x1B`D\x82\x01R`d\x01a\x06\x9FV[PPPPPV[3a\x12\xB7\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0T`\x01`\x01`\xA0\x1B\x03\x16\x90V[`\x01`\x01`\xA0\x1B\x03\x16\x14a\r\xBFW`@Qc\x11\x8C\xDA\xA7`\xE0\x1B\x81R3`\x04\x82\x01R`$\x01a\x06\x9FV[_`@Qc\xA9\x05\x9C\xBB`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x84\x16`\x04\x82\x01R\x82`$\x82\x01R` _`D\x83_\x89Z\xF1\x91PP\x80`\x1F=\x11`\x01_Q\x14\x16\x15\x16\x15a\x13*WP\x82;\x15=\x17\x15[\x80a\x13iW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x0F`$\x82\x01Rn\x15\x14\x90S\x94\xD1\x91T\x97\xD1\x90RS\x11Q`\x8A\x1B`D\x82\x01R`d\x01a\x06\x9FV[PPPPV[`\x01`\x01`\xA0\x1B\x03\x81\x16_\x90\x81R`\x03` R`@\x81 `\x01\x01T`\xFF\x16`\x02\x81\x11\x15a\x13\x9EWa\x13\x9Ea*\x0CV[\x14a\x11]W`@Qc\x13.~\xFB`\xE3\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`@\x80Q\x80\x82\x01\x90\x91R_\x80\x82R` \x82\x01Ra\x13\xD9\x82\x82a\x18\xCDV[\x15a\r\x01W`@Qc\x06\xCFC\x8F`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x04_a\x14\x03\x83a\r\xC1V[\x81R` \x81\x01\x91\x90\x91R`@\x01_ T`\xFF\x16\x15a\x11]W`@Qb\xDA\x8AW`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x14<\x82a\x18\xF0V[_`@Q\x80``\x01`@R\x80`$\x81R` \x01a.\x12`$\x919\x90P_\x84\x82`@Q` \x01a\x14l\x92\x91\x90a+\xCDV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P_a\x14\x87\x82a\x19\x86V[\x90Pa\x14\xA4\x81\x85a\x14\x97\x88a\x1AsV[a\x14\x9Fa\x1A\xEAV[a\x1B\xB7V[a\x14\xC0W`@Qb\xCE\xD3\xE5`\xE4\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[PPPPPPV[0`\x01`\x01`\xA0\x1B\x03\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14\x80a\x15NWP\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\x01`\x01`\xA0\x1B\x03\x16a\x15B_Q` a.V_9_Q\x90_RT`\x01`\x01`\xA0\x1B\x03\x16\x90V[`\x01`\x01`\xA0\x1B\x03\x16\x14\x15[\x15a\r\xBFW`@Qcp>F\xDD`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x15ta\x12\x85V[`@Q`\x01`\x01`\xA0\x1B\x03\x82\x16\x81R\x7F\xF7\x87!\"n\xFE\x9A\x1B\xB6x\x18\x9A\x16\xD1UI(\xB9\xF2\x19.,\xB9>\xED\xA8;y\xFA@\0}\x90` \x01`@Q\x80\x91\x03\x90\xA1PV[\x81`\x01`\x01`\xA0\x1B\x03\x16cR\xD1\x90-`@Q\x81c\xFF\xFF\xFF\xFF\x16`\xE0\x1B\x81R`\x04\x01` `@Q\x80\x83\x03\x81\x86Z\xFA\x92PPP\x80\x15a\x16\rWP`@\x80Q`\x1F=\x90\x81\x01`\x1F\x19\x16\x82\x01\x90\x92Ra\x16\n\x91\x81\x01\x90a*PV[`\x01[a\x165W`@QcL\x9C\x8C\xE3`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x83\x16`\x04\x82\x01R`$\x01a\x06\x9FV[_Q` a.V_9_Q\x90_R\x81\x14a\x16eW`@Qc*\x87Ri`\xE2\x1B\x81R`\x04\x81\x01\x82\x90R`$\x01a\x06\x9FV[a\x16o\x83\x83a\x1C\x95V[PPPV[0`\x01`\x01`\xA0\x1B\x03\x7F\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x14a\r\xBFW`@Qcp>F\xDD`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x7F\x90\x16\xD0\x9Dr\xD4\x0F\xDA\xE2\xFD\x8C\xEA\xC6\xB6#Lw\x06!O\xD3\x9C\x1C\xD1\xE6\t\xA0R\x8C\x19\x93\0\x80T`\x01`\x01`\xA0\x1B\x03\x19\x81\x16`\x01`\x01`\xA0\x1B\x03\x84\x81\x16\x91\x82\x17\x84U`@Q\x92\x16\x91\x82\x90\x7F\x8B\xE0\x07\x9CS\x16Y\x14\x13D\xCD\x1F\xD0\xA4\xF2\x84\x19I\x7F\x97\"\xA3\xDA\xAF\xE3\xB4\x18okdW\xE0\x90_\x90\xA3PPPV[a\x175a\x1C\xEAV[a\x11]\x81a\x1D3V[a\r\xBFa\x1C\xEAV[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0\x80T`\x01`@\x1B\x81\x04`\xFF\x16\x15\x90`\x01`\x01`@\x1B\x03\x16_\x81\x15\x80\x15a\x17\x8AWP\x82[\x90P_\x82`\x01`\x01`@\x1B\x03\x16`\x01\x14\x80\x15a\x17\xA5WP0;\x15[\x90P\x81\x15\x80\x15a\x17\xB3WP\x80\x15[\x15a\x17\xD1W`@Qc\xF9.\xE8\xA9`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x84Tg\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x19\x16`\x01\x17\x85U\x83\x15a\x17\xFBW\x84T`\xFF`@\x1B\x19\x16`\x01`@\x1B\x17\x85U[C_U\x83\x15a\x12~W\x84T`\xFF`@\x1B\x19\x16\x85U`@Q`\x01\x81R\x7F\xC7\xF5\x05\xB2\xF3q\xAE!u\xEEI\x13\xF4I\x9E\x1F&3\xA7\xB5\x93c!\xEE\xD1\xCD\xAE\xB6\x11Q\x81\xD2\x90` \x01`@Q\x80\x91\x03\x90\xA1PPPPPV[`\x01`\x01`\xA0\x1B\x03\x83\x16a\x18qW`@Qc\xD9.#=`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x01`\x01`\xA0\x1B\x03\x82\x16a\x18\x98W`@Qc\xD9.#=`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`\x02\x80T`\x01`\x01`\xA0\x1B\x03\x94\x85\x16`\x01`\x01`\xA0\x1B\x03\x19\x91\x82\x16\x17\x90\x91U`\x01\x80T\x93\x90\x94\x16\x92\x16\x91\x90\x91\x17\x90\x91U`\x08UV[\x80Q\x82Q_\x91\x14\x80\x15a\x18\xE7WP\x81` \x01Q\x83` \x01Q\x14[\x90P[\x92\x91PPV[\x80Q` \x82\x01Q_\x91_Q` a.6_9_Q\x90_R\x91\x15\x90\x15\x16\x15a\x19\x16WPPPV[\x82Q` \x84\x01Q\x82`\x03\x84\x85\x85\x86\t\x85\t\x08\x83\x82\x83\t\x14\x83\x82\x10\x84\x84\x10\x16\x16\x93PPP\x81a\x16oW`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x17`$\x82\x01R\x7FBn254: invalid G1 point\0\0\0\0\0\0\0\0\0`D\x82\x01R`d\x01a\x06\x9FV[`@\x80Q\x80\x82\x01\x90\x91R_\x80\x82R` \x82\x01R_a\x19\xA3\x83a\x1D;V[\x90P_Q` a.6_9_Q\x90_R`\x03_\x82\x84\x85\t\x90P\x82\x80a\x19\xCAWa\x19\xCAa+\xE9V[\x84\x82\t\x90P\x82\x80a\x19\xDDWa\x19\xDDa+\xE9V[\x82\x82\x08\x90P__a\x19\xED\x83a\x1FCV[\x92P\x90P[\x80a\x1AVW\x84\x80a\x1A\x05Wa\x1A\x05a+\xE9V[`\x01\x87\x08\x95P\x84\x80a\x1A\x19Wa\x1A\x19a+\xE9V[\x86\x87\t\x92P\x84\x80a\x1A,Wa\x1A,a+\xE9V[\x86\x84\t\x92P\x84\x80a\x1A?Wa\x1A?a+\xE9V[\x84\x84\x08\x92Pa\x1AM\x83a\x1FCV[\x92P\x90Pa\x19\xF2V[P`@\x80Q\x80\x82\x01\x90\x91R\x94\x85R` \x85\x01RP\x91\x94\x93PPPPV[`@\x80Q\x80\x82\x01\x90\x91R_\x80\x82R` \x82\x01R\x81Q` \x83\x01Q\x15\x90\x15\x16\x15a\x1A\x9AWP\x90V[`@Q\x80`@\x01`@R\x80\x83_\x01Q\x81R` \x01_Q` a.6_9_Q\x90_R\x84` \x01Qa\x1A\xCB\x91\x90a+\xFDV[a\x1A\xE2\x90_Q` a.6_9_Q\x90_Ra+=V[\x90R\x92\x91PPV[a\x1B\x11`@Q\x80`\x80\x01`@R\x80_\x81R` \x01_\x81R` \x01_\x81R` \x01_\x81RP\x90V[`@Q\x80`\x80\x01`@R\x80\x7F\x18\0\xDE\xEF\x12\x1F\x1EvBj\0f^\\DygC\"\xD4\xF7^\xDA\xDDF\xDE\xBD\\\xD9\x92\xF6\xED\x81R` \x01\x7F\x19\x8E\x93\x93\x92\rH:r`\xBF\xB71\xFB]%\xF1\xAAI35\xA9\xE7\x12\x97\xE4\x85\xB7\xAE\xF3\x12\xC2\x81R` \x01\x7F\x12\xC8^\xA5\xDB\x8Cm\xEBJ\xABq\x80\x8D\xCB@\x8F\xE3\xD1\xE7i\x0CC\xD3{L\xE6\xCC\x01f\xFA}\xAA\x81R` \x01\x7F\t\x06\x89\xD0X_\xF0u\xEC\x9E\x99\xADi\x0C3\x95\xBCK13p\xB3\x8E\xF3U\xAC\xDA\xDC\xD1\"\x97[\x81RP\x90P\x90V[___`@Q\x87Q\x81R` \x88\x01Q` \x82\x01R` \x87\x01Q`@\x82\x01R\x86Q``\x82\x01R``\x87\x01Q`\x80\x82\x01R`@\x87\x01Q`\xA0\x82\x01R\x85Q`\xC0\x82\x01R` \x86\x01Q`\xE0\x82\x01R` \x85\x01Qa\x01\0\x82\x01R\x84Qa\x01 \x82\x01R``\x85\x01Qa\x01@\x82\x01R`@\x85\x01Qa\x01`\x82\x01R` _a\x01\x80\x83`\x08Z\xFA\x91PP_Q\x91P\x80a\x1C\x89W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1C`$\x82\x01R\x7FBn254: Pairing check failed!\0\0\0\0`D\x82\x01R`d\x01a\x06\x9FV[P\x15\x15\x95\x94PPPPPV[a\x1C\x9E\x82a :V[`@Q`\x01`\x01`\xA0\x1B\x03\x83\x16\x90\x7F\xBC|\xD7Z \xEE'\xFD\x9A\xDE\xBA\xB3 A\xF7U!M\xBCk\xFF\xA9\x0C\xC0\"[9\xDA.\\-;\x90_\x90\xA2\x80Q\x15a\x1C\xE2Wa\x16o\x82\x82a \x9DV[a\r\x01a!\x0FV[\x7F\xF0\xC5~\x16\x84\r\xF0@\xF1P\x88\xDC/\x81\xFE9\x1C9#\xBE\xC7>#\xA9f.\xFC\x9C\"\x9Cj\0T`\x01`@\x1B\x90\x04`\xFF\x16a\r\xBFW`@Qc\x1A\xFC\xD7\x9F`\xE3\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[a\x11+a\x1C\xEAV[__a\x1DF\x83a!.V[\x80Q\x90\x91P`0\x81\x14a\x1D[Wa\x1D[a,\x1CV[_\x81`\x01`\x01`@\x1B\x03\x81\x11\x15a\x1DtWa\x1Dta%\xABV[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a\x1D\x9EW` \x82\x01\x81\x806\x837\x01\x90P[P\x90P_[\x82\x81\x10\x15a\x1E\rW\x83`\x01a\x1D\xB8\x83\x86a+=V[a\x1D\xC2\x91\x90a+=V[\x81Q\x81\x10a\x1D\xD2Wa\x1D\xD2a,0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x82\x82\x81Q\x81\x10a\x1D\xEFWa\x1D\xEFa,0V[` \x01\x01\x90`\x01`\x01`\xF8\x1B\x03\x19\x16\x90\x81_\x1A\x90SP`\x01\x01a\x1D\xA3V[P`@\x80Q`\x1F\x80\x82Ra\x04\0\x82\x01\x90\x92R_\x90\x82` \x82\x01a\x03\xE0\x806\x837\x01\x90PP\x90P_[\x82\x81\x10\x15a\x1E\x9DW\x83\x81a\x1EI\x85\x88a+=V[a\x1ES\x91\x90a*{V[\x81Q\x81\x10a\x1EcWa\x1Eca,0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B`\xF8\x1C\x82\x82\x81Q\x81\x10a\x1E\x83Wa\x1E\x83a,0V[`\xFF\x90\x92\x16` \x92\x83\x02\x91\x90\x91\x01\x90\x91\x01R`\x01\x01a\x1E5V[P_a\x1E\xA8\x82a$yV[\x90Pa\x01\0_Q` a.6_9_Q\x90_R_a\x1E\xC6\x86\x89a+=V[\x90P_[\x81\x81\x10\x15a\x1F3W_\x88`\x01a\x1E\xE0\x84\x86a+=V[a\x1E\xEA\x91\x90a+=V[\x81Q\x81\x10a\x1E\xFAWa\x1E\xFAa,0V[\x01` \x01Q`\xF8\x1C\x90P\x83\x80a\x1F\x12Wa\x1F\x12a+\xE9V[\x85\x87\t\x95P\x83\x80a\x1F%Wa\x1F%a+\xE9V[\x81\x87\x08\x95PP`\x01\x01a\x1E\xCAV[P\x92\x9A\x99PPPPPPPPPPV[_____\x7F\x0C\x19\x13\x9C\xB8Lh\nn\x14\x11m\xA0`V\x17e\xE0Z\xA4Z\x1Cr\xA3O\x08#\x05\xB6\x1F?R\x90P__Q` a.6_9_Q\x90_R\x90P`@Q` \x81R` \x80\x82\x01R` `@\x82\x01R\x87``\x82\x01R\x82`\x80\x82\x01R\x81`\xA0\x82\x01R` _`\xC0\x83`\x05Z\xFA\x94PP_Q\x92P\x83a \0W`@QbF\x1B\xCD`\xE5\x1B\x81R` `\x04\x82\x01R`\x1B`$\x82\x01R\x7Fpow precompile call failed!\0\0\0\0\0`D\x82\x01R`d\x01a\x06\x9FV[\x80`\x01\x84\x90\x1B\x11\x15a \x19Wa \x16\x83\x82a+=V[\x92P[\x80\x80a 'Wa 'a+\xE9V[\x83\x84\t\x96\x90\x96\x14\x96\x91\x95P\x90\x93PPPPV[\x80`\x01`\x01`\xA0\x1B\x03\x16;_\x03a oW`@QcL\x9C\x8C\xE3`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x82\x16`\x04\x82\x01R`$\x01a\x06\x9FV[_Q` a.V_9_Q\x90_R\x80T`\x01`\x01`\xA0\x1B\x03\x19\x16`\x01`\x01`\xA0\x1B\x03\x92\x90\x92\x16\x91\x90\x91\x17\x90UV[``__\x84`\x01`\x01`\xA0\x1B\x03\x16\x84`@Qa \xB9\x91\x90a,DV[_`@Q\x80\x83\x03\x81\x85Z\xF4\x91PP=\x80_\x81\x14a \xF1W`@Q\x91P`\x1F\x19`?=\x01\x16\x82\x01`@R=\x82R=_` \x84\x01>a \xF6V[``\x91P[P\x91P\x91Pa!\x06\x85\x83\x83a$\xE0V[\x95\x94PPPPPV[4\x15a\r\xBFW`@Qc\xB3\x98\x97\x9F`\xE0\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[`@\x80Q`0\x80\x82R``\x82\x81\x01\x90\x93R\x90` \x90`\x01`\xF9\x1B\x90_\x90\x84` \x82\x01\x81\x806\x837\x01\x90PP\x90P\x80\x86`@Q` \x01a!n\x92\x91\x90a+\xCDV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P\x80\x84`\xF8\x1B`@Q` \x01a!\x95\x92\x91\x90a,OV[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x90P\x80`@Q` \x01a!\xB7\x91\x90a,yV[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x90\x82\x90R\x91Pa\x01\x01`\xF0\x1B\x90a!\xE1\x90\x83\x90\x83\x90` \x01a,\x91V[`@\x80Q\x80\x83\x03`\x1F\x19\x01\x81R\x82\x82R\x80Q` \x91\x82\x01 \x81\x84\x01\x81\x90R`\x01`\xF8\x1B\x84\x84\x01R`\x01`\x01`\xF0\x1B\x03\x19\x85\x16`A\x85\x01R\x82Q`#\x81\x86\x03\x01\x81R`C\x90\x94\x01\x90\x92R\x82Q\x90\x83\x01 \x91\x93P\x90_`\xFF\x88\x16`\x01`\x01`@\x1B\x03\x81\x11\x15a\"PWa\"Pa%\xABV[`@Q\x90\x80\x82R\x80`\x1F\x01`\x1F\x19\x16` \x01\x82\x01`@R\x80\x15a\"zW` \x82\x01\x81\x806\x837\x01\x90P[P\x90P_\x82`@Q` \x01a\"\x91\x91\x81R` \x01\x90V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x91\x90R\x90P_[\x81Q\x81\x10\x15a\"\xFBW\x81\x81\x81Q\x81\x10a\"\xC0Wa\"\xC0a,0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x83\x82\x81Q\x81\x10a\"\xDDWa\"\xDDa,0V[` \x01\x01\x90`\x01`\x01`\xF8\x1B\x03\x19\x16\x90\x81_\x1A\x90SP`\x01\x01a\"\xA5V[P_\x84`@Q` \x01a#\x10\x91\x81R` \x01\x90V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R` \x83\x01\x90\x91R_\x80\x83R\x91\x98P\x91P[\x89\x81\x10\x15a#\xA2W_\x83\x82\x81Q\x81\x10a#IWa#Ia,0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x83\x83\x81Q\x81\x10a#fWa#fa,0V[` \x01\x01Q`\xF8\x1C`\xF8\x1B\x18\x90P\x88\x81`@Q` \x01a#\x87\x92\x91\x90a,\xB5V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x91\x90R\x98PP`\x01\x01a#.V[P\x86\x88\x87`@Q` \x01a#\xB8\x93\x92\x91\x90a,\xD9V[`@Q` \x81\x83\x03\x03\x81R\x90`@R\x96P\x86\x80Q\x90` \x01 \x93P\x83`@Q` \x01a#\xE6\x91\x81R` \x01\x90V[`@\x80Q`\x1F\x19\x81\x84\x03\x01\x81R\x91\x90R\x91P_[a$\x07\x8A`\xFF\x8D\x16a+=V[\x81\x10\x15a$hW\x82\x81\x81Q\x81\x10a$ Wa$ a,0V[\x01` \x01Q`\x01`\x01`\xF8\x1B\x03\x19\x16\x84a$:\x83\x8Da*{V[\x81Q\x81\x10a$JWa$Ja,0V[` \x01\x01\x90`\x01`\x01`\xF8\x1B\x03\x19\x16\x90\x81_\x1A\x90SP`\x01\x01a#\xFAV[P\x91\x9B\x9APPPPPPPPPPPV[_\x80\x80[\x83Q\x81\x10\x15a$\xD9W\x83\x81\x81Q\x81\x10a$\x98Wa$\x98a,0V[` \x02` \x01\x01Q`\xFF\x16\x81`\x08a$\xB0\x91\x90a-\x0CV[a$\xBB\x90`\x02a.\x06V[a$\xC5\x91\x90a-\x0CV[a$\xCF\x90\x83a*{V[\x91P`\x01\x01a$}V[P\x92\x91PPV[``\x82a$\xF5Wa$\xF0\x82a%?V[a%8V[\x81Q\x15\x80\x15a%\x0CWP`\x01`\x01`\xA0\x1B\x03\x84\x16;\x15[\x15a%5W`@Qc\x99\x96\xB3\x15`\xE0\x1B\x81R`\x01`\x01`\xA0\x1B\x03\x85\x16`\x04\x82\x01R`$\x01a\x06\x9FV[P\x80[\x93\x92PPPV[\x80Q\x15a%OW\x80Q\x80\x82` \x01\xFD[`@Qc\n\x12\xF5!`\xE1\x1B\x81R`\x04\x01`@Q\x80\x91\x03\x90\xFD[\x805`\x01`\x01`\xA0\x1B\x03\x81\x16\x81\x14a%~W__\xFD[\x91\x90PV[__`@\x83\x85\x03\x12\x15a%\x94W__\xFD[a%\x9D\x83a%hV[\x94` \x93\x90\x93\x015\x93PPPV[cNH{q`\xE0\x1B_R`A`\x04R`$_\xFD[`@\x80Q\x90\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a%\xE1Wa%\xE1a%\xABV[`@R\x90V[_`\x80\x82\x84\x03\x12\x15a%\xF7W__\xFD[`@Q`\x80\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a&\x19Wa&\x19a%\xABV[`@\x90\x81R\x835\x82R` \x80\x85\x015\x90\x83\x01R\x83\x81\x015\x90\x82\x01R``\x92\x83\x015\x92\x81\x01\x92\x90\x92RP\x91\x90PV[_`@\x82\x84\x03\x12\x15a&WW__\xFD[a&_a%\xBFV[\x825\x81R` \x92\x83\x015\x92\x81\x01\x92\x90\x92RP\x91\x90PV[\x805a\xFF\xFF\x81\x16\x81\x14a%~W__\xFD[____a\x01 \x85\x87\x03\x12\x15a&\x9BW__\xFD[a&\xA5\x86\x86a%\xE7V[\x93Pa&\xB4\x86`\x80\x87\x01a&GV[\x92Pa&\xC3\x86`\xC0\x87\x01a&GV[\x91Pa&\xD2a\x01\0\x86\x01a&vV[\x90P\x92\x95\x91\x94P\x92PV[`\x01`\x01`@\x1B\x03\x81\x16\x81\x14a\x11]W__\xFD[_` \x82\x84\x03\x12\x15a'\x01W__\xFD[\x815a%8\x81a&\xDDV[_` \x82\x84\x03\x12\x15a'\x1CW__\xFD[a\x18\xE7\x82a%hV[_\x82`\x1F\x83\x01\x12a'4W__\xFD[\x815`\x01`\x01`@\x1B\x03\x81\x11\x15a'MWa'Ma%\xABV[`@Q`\x1F\x82\x01`\x1F\x19\x90\x81\x16`?\x01\x16\x81\x01`\x01`\x01`@\x1B\x03\x81\x11\x82\x82\x10\x17\x15a'{Wa'{a%\xABV[`@R\x81\x81R\x83\x82\x01` \x01\x85\x10\x15a'\x92W__\xFD[\x81` \x85\x01` \x83\x017_\x91\x81\x01` \x01\x91\x90\x91R\x93\x92PPPV[_____a\x01@\x86\x88\x03\x12\x15a'\xC3W__\xFD[a'\xCD\x87\x87a%\xE7V[\x94Pa'\xDC\x87`\x80\x88\x01a&GV[\x93Pa'\xEB\x87`\xC0\x88\x01a&GV[\x92Pa\x01\0\x86\x015`\x01`\x01`@\x1B\x03\x81\x11\x15a(\x06W__\xFD[a(\x12\x88\x82\x89\x01a'%V[\x92PPa(\"a\x01 \x87\x01a&vV[\x90P\x92\x95P\x92\x95\x90\x93PV[__`@\x83\x85\x03\x12\x15a(?W__\xFD[a(H\x83a%hV[\x91P` \x83\x015`\x01`\x01`@\x1B\x03\x81\x11\x15a(bW__\xFD[a(n\x85\x82\x86\x01a'%V[\x91PP\x92P\x92\x90PV[___a\x01\0\x84\x86\x03\x12\x15a(\x8BW__\xFD[a(\x95\x85\x85a%\xE7V[\x92Pa(\xA4\x85`\x80\x86\x01a&GV[\x91Pa(\xB3\x85`\xC0\x86\x01a&GV[\x90P\x92P\x92P\x92V[_`\x80\x82\x84\x03\x12\x15a(\xCCW__\xFD[a\x18\xE7\x83\x83a%\xE7V[__`@\x83\x85\x03\x12\x15a(\xE7W__\xFD[a(\xF0\x83a%hV[\x91Pa(\xFE` \x84\x01a%hV[\x90P\x92P\x92\x90PV[____a\x01 \x85\x87\x03\x12\x15a)\x1BW__\xFD[a)%\x86\x86a%\xE7V[\x93Pa)4\x86`\x80\x87\x01a&GV[\x92Pa)C\x86`\xC0\x87\x01a&GV[\x91Pa\x01\0\x85\x015`\x01`\x01`@\x1B\x03\x81\x11\x15a)^W__\xFD[a)j\x87\x82\x88\x01a'%V[\x91PP\x92\x95\x91\x94P\x92PV[_\x81Q\x80\x84R\x80` \x84\x01` \x86\x01^_` \x82\x86\x01\x01R` `\x1F\x19`\x1F\x83\x01\x16\x85\x01\x01\x91PP\x92\x91PPV[` \x81R_a\x18\xE7` \x83\x01\x84a)vV[_` \x82\x84\x03\x12\x15a)\xC6W__\xFD[P5\x91\x90PV[____`\x80\x85\x87\x03\x12\x15a)\xE0W__\xFD[a)\xE9\x85a%hV[\x93Pa)\xF7` \x86\x01a%hV[\x92P`@\x85\x015\x91Pa&\xD2``\x86\x01a%hV[cNH{q`\xE0\x1B_R`!`\x04R`$_\xFD[\x82\x81R`@\x81\x01`\x03\x83\x10a*CWcNH{q`\xE0\x1B_R`!`\x04R`$_\xFD[\x82` \x83\x01R\x93\x92PPPV[_` \x82\x84\x03\x12\x15a*`W__\xFD[PQ\x91\x90PV[cNH{q`\xE0\x1B_R`\x11`\x04R`$_\xFD[\x80\x82\x01\x80\x82\x11\x15a\x18\xEAWa\x18\xEAa*gV[_` \x82\x84\x03\x12\x15a*\x9EW__\xFD[\x81Qa%8\x81a&\xDDV[`\x01`\x01`@\x1B\x03\x81\x81\x16\x83\x82\x16\x02\x90\x81\x16\x90\x81\x81\x14a$\xD9Wa$\xD9a*gV[\x85Q\x81R` \x80\x87\x01Q\x90\x82\x01R`@\x80\x87\x01Q\x90\x82\x01R``\x80\x87\x01Q\x90\x82\x01R\x84Q`\x80\x82\x01R` \x85\x01Q`\xA0\x82\x01Ra\xFF\xFF\x84\x16`\xC0\x82\x01R\x82Q`\xE0\x82\x01R` \x83\x01Qa\x01\0\x82\x01Ra\x01@a\x01 \x82\x01R_a+2a\x01@\x83\x01\x84a)vV[\x97\x96PPPPPPPV[\x81\x81\x03\x81\x81\x11\x15a\x18\xEAWa\x18\xEAa*gV[\x84Q\x81R` \x80\x86\x01Q\x90\x82\x01R`@\x80\x86\x01Q\x90\x82\x01R``\x80\x86\x01Q\x90\x82\x01R\x83Q`\x80\x82\x01R` \x84\x01Q`\xA0\x82\x01R\x82Q`\xC0\x82\x01R` \x83\x01Q`\xE0\x82\x01Ra\x01 a\x01\0\x82\x01R_a+\xACa\x01 \x83\x01\x84a)vV[\x96\x95PPPPPPV[_\x81Q\x80` \x84\x01\x85^_\x93\x01\x92\x83RP\x90\x91\x90PV[_a+\xE1a+\xDB\x83\x86a+\xB6V[\x84a+\xB6V[\x94\x93PPPPV[cNH{q`\xE0\x1B_R`\x12`\x04R`$_\xFD[_\x82a,\x17WcNH{q`\xE0\x1B_R`\x12`\x04R`$_\xFD[P\x06\x90V[cNH{q`\xE0\x1B_R`\x01`\x04R`$_\xFD[cNH{q`\xE0\x1B_R`2`\x04R`$_\xFD[_a\x18\xE7\x82\x84a+\xB6V[_a,Z\x82\x85a+\xB6V[_\x81R`\x01`\x01`\xF8\x1B\x03\x19\x93\x90\x93\x16`\x01\x84\x01RPP`\x02\x01\x91\x90PV[_a,\x84\x82\x84a+\xB6V[_\x81R`\x01\x01\x93\x92PPPV[_a,\x9C\x82\x85a+\xB6V[`\x01`\x01`\xF0\x1B\x03\x19\x93\x90\x93\x16\x83RPP`\x02\x01\x91\x90PV[_a,\xC0\x82\x85a+\xB6V[`\x01`\x01`\xF8\x1B\x03\x19\x93\x90\x93\x16\x83RPP`\x01\x01\x91\x90PV[_a,\xE4\x82\x86a+\xB6V[`\x01`\x01`\xF8\x1B\x03\x19\x94\x90\x94\x16\x84RPP`\x01`\x01`\xF0\x1B\x03\x19\x16`\x01\x82\x01R`\x03\x01\x91\x90PV[\x80\x82\x02\x81\x15\x82\x82\x04\x84\x14\x17a\x18\xEAWa\x18\xEAa*gV[`\x01\x81[`\x01\x84\x11\x15a-^W\x80\x85\x04\x81\x11\x15a-BWa-Ba*gV[`\x01\x84\x16\x15a-PW\x90\x81\x02\x90[`\x01\x93\x90\x93\x1C\x92\x80\x02a-'V[\x93P\x93\x91PPV[_\x82a-tWP`\x01a\x18\xEAV[\x81a-\x80WP_a\x18\xEAV[\x81`\x01\x81\x14a-\x96W`\x02\x81\x14a-\xA0Wa-\xBCV[`\x01\x91PPa\x18\xEAV[`\xFF\x84\x11\x15a-\xB1Wa-\xB1a*gV[PP`\x01\x82\x1Ba\x18\xEAV[P` \x83\x10a\x013\x83\x10\x16`N\x84\x10`\x0B\x84\x10\x16\x17\x15a-\xDFWP\x81\x81\na\x18\xEAV[a-\xEB_\x19\x84\x84a-#V[\x80_\x19\x04\x82\x11\x15a-\xFEWa-\xFEa*gV[\x02\x93\x92PPPV[_a\x18\xE7\x83\x83a-fV\xFEBLS_SIG_BN254G1_XMD:KECCAK_NCTH_NUL_0dNr\xE11\xA0)\xB8PE\xB6\x81\x81X]\x97\x81j\x91hq\xCA\x8D< \x8C\x16\xD8|\xFDG6\x08\x94\xA1;\xA1\xA3!\x06g\xC8(I-\xB9\x8D\xCA> v\xCC75\xA9 \xA3\xCAP]8+\xBC\xA1dsolcC\0\x08\x1C\0\n", ); #[derive(Default, Debug, PartialEq, Eq, Hash)] /**Custom error with signature `AddressEmptyCode(address)` and selector `0x9996b315`. @@ -4585,9 +4537,9 @@ pub mod StakeTableV2 { } }; #[derive()] - /**Event with signature `ConsensusKeysUpdatedV2(address,(uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),(uint256,uint256))` and selector `0x04cf8cf47a6bf2ea5f71b8eebdec9de2117f47d2b67bc608338f81acb1a466d5`. + /**Event with signature `ConsensusKeysUpdatedV2(address,(uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),bytes)` and selector `0xc8c5b37aec7f2ddbd3a13c51361e54a0a8df3bca256ab758a77f5ad741d281e5`. ```solidity - event ConsensusKeysUpdatedV2(address indexed account, BN254.G2Point blsVK, EdOnBN254.EdOnBN254Point schnorrVK, BN254.G1Point blsSig, EdOnBN254.EdOnBN254Point schnorrSig); + event ConsensusKeysUpdatedV2(address indexed account, BN254.G2Point blsVK, EdOnBN254.EdOnBN254Point schnorrVK, BN254.G1Point blsSig, bytes schnorrSig); ```*/ #[allow( non_camel_case_types, @@ -4606,7 +4558,7 @@ pub mod StakeTableV2 { #[allow(missing_docs)] pub blsSig: ::RustType, #[allow(missing_docs)] - pub schnorrSig: ::RustType, + pub schnorrSig: alloy::sol_types::private::Bytes, } #[allow( non_camel_case_types, @@ -4622,19 +4574,19 @@ pub mod StakeTableV2 { BN254::G2Point, EdOnBN254::EdOnBN254Point, BN254::G1Point, - EdOnBN254::EdOnBN254Point, + alloy::sol_types::sol_data::Bytes, ); type DataToken<'a> = as alloy_sol_types::SolType>::Token<'a>; type TopicList = ( alloy_sol_types::sol_data::FixedBytes<32>, alloy::sol_types::sol_data::Address, ); - const SIGNATURE: &'static str = "ConsensusKeysUpdatedV2(address,(uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),(uint256,uint256))"; + const SIGNATURE: &'static str = "ConsensusKeysUpdatedV2(address,(uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),bytes)"; const SIGNATURE_HASH: alloy_sol_types::private::B256 = alloy_sol_types::private::B256::new([ - 4u8, 207u8, 140u8, 244u8, 122u8, 107u8, 242u8, 234u8, 95u8, 113u8, 184u8, - 238u8, 189u8, 236u8, 157u8, 226u8, 17u8, 127u8, 71u8, 210u8, 182u8, 123u8, - 198u8, 8u8, 51u8, 143u8, 129u8, 172u8, 177u8, 164u8, 102u8, 213u8, + 200u8, 197u8, 179u8, 122u8, 236u8, 127u8, 45u8, 219u8, 211u8, 161u8, 60u8, + 81u8, 54u8, 30u8, 84u8, 160u8, 168u8, 223u8, 59u8, 202u8, 37u8, 106u8, 183u8, + 88u8, 167u8, 127u8, 90u8, 215u8, 65u8, 210u8, 129u8, 229u8, ]); const ANONYMOUS: bool = false; #[allow(unused_variables)] @@ -4672,7 +4624,7 @@ pub mod StakeTableV2 { &self.schnorrVK, ), ::tokenize(&self.blsSig), - ::tokenize( + ::tokenize( &self.schnorrSig, ), ) @@ -5701,9 +5653,9 @@ pub mod StakeTableV2 { } }; #[derive()] - /**Event with signature `ValidatorRegisteredV2(address,(uint256,uint256,uint256,uint256),(uint256,uint256),uint16,(uint256,uint256),(uint256,uint256))` and selector `0x8e1c394d8f3c83d8e24d20790bd0586fe71354810a93c2ee368b418745553b2e`. + /**Event with signature `ValidatorRegisteredV2(address,(uint256,uint256,uint256,uint256),(uint256,uint256),uint16,(uint256,uint256),bytes)` and selector `0xf057d4ea81e98628653a8f90788541972078137334a92b42347eaccda80fc40a`. ```solidity - event ValidatorRegisteredV2(address indexed account, BN254.G2Point blsVk, EdOnBN254.EdOnBN254Point schnorrVk, uint16 commission, BN254.G1Point blsSig, EdOnBN254.EdOnBN254Point schnorrSig); + event ValidatorRegisteredV2(address indexed account, BN254.G2Point blsVK, EdOnBN254.EdOnBN254Point schnorrVK, uint16 commission, BN254.G1Point blsSig, bytes schnorrSig); ```*/ #[allow( non_camel_case_types, @@ -5716,15 +5668,15 @@ pub mod StakeTableV2 { #[allow(missing_docs)] pub account: alloy::sol_types::private::Address, #[allow(missing_docs)] - pub blsVk: ::RustType, + pub blsVK: ::RustType, #[allow(missing_docs)] - pub schnorrVk: ::RustType, + pub schnorrVK: ::RustType, #[allow(missing_docs)] pub commission: u16, #[allow(missing_docs)] pub blsSig: ::RustType, #[allow(missing_docs)] - pub schnorrSig: ::RustType, + pub schnorrSig: alloy::sol_types::private::Bytes, } #[allow( non_camel_case_types, @@ -5741,19 +5693,19 @@ pub mod StakeTableV2 { EdOnBN254::EdOnBN254Point, alloy::sol_types::sol_data::Uint<16>, BN254::G1Point, - EdOnBN254::EdOnBN254Point, + alloy::sol_types::sol_data::Bytes, ); type DataToken<'a> = as alloy_sol_types::SolType>::Token<'a>; type TopicList = ( alloy_sol_types::sol_data::FixedBytes<32>, alloy::sol_types::sol_data::Address, ); - const SIGNATURE: &'static str = "ValidatorRegisteredV2(address,(uint256,uint256,uint256,uint256),(uint256,uint256),uint16,(uint256,uint256),(uint256,uint256))"; + const SIGNATURE: &'static str = "ValidatorRegisteredV2(address,(uint256,uint256,uint256,uint256),(uint256,uint256),uint16,(uint256,uint256),bytes)"; const SIGNATURE_HASH: alloy_sol_types::private::B256 = alloy_sol_types::private::B256::new([ - 142u8, 28u8, 57u8, 77u8, 143u8, 60u8, 131u8, 216u8, 226u8, 77u8, 32u8, 121u8, - 11u8, 208u8, 88u8, 111u8, 231u8, 19u8, 84u8, 129u8, 10u8, 147u8, 194u8, 238u8, - 54u8, 139u8, 65u8, 135u8, 69u8, 85u8, 59u8, 46u8, + 240u8, 87u8, 212u8, 234u8, 129u8, 233u8, 134u8, 40u8, 101u8, 58u8, 143u8, + 144u8, 120u8, 133u8, 65u8, 151u8, 32u8, 120u8, 19u8, 115u8, 52u8, 169u8, 43u8, + 66u8, 52u8, 126u8, 172u8, 205u8, 168u8, 15u8, 196u8, 10u8, ]); const ANONYMOUS: bool = false; #[allow(unused_variables)] @@ -5764,8 +5716,8 @@ pub mod StakeTableV2 { ) -> Self { Self { account: topics.1, - blsVk: data.0, - schnorrVk: data.1, + blsVK: data.0, + schnorrVK: data.1, commission: data.2, blsSig: data.3, schnorrSig: data.4, @@ -5787,15 +5739,15 @@ pub mod StakeTableV2 { #[inline] fn tokenize_body(&self) -> Self::DataToken<'_> { ( - ::tokenize(&self.blsVk), + ::tokenize(&self.blsVK), ::tokenize( - &self.schnorrVk, + &self.schnorrVK, ), as alloy_sol_types::SolType>::tokenize( &self.commission, ), ::tokenize(&self.blsSig), - ::tokenize( + ::tokenize( &self.schnorrSig, ), ) @@ -7822,7 +7774,7 @@ pub mod StakeTableV2 { ```*/ #[allow(non_camel_case_types, non_snake_case, clippy::pub_underscore_fields)] #[derive(Clone)] - pub struct registerValidator_0Call { + pub struct registerValidatorCall { #[allow(missing_docs)] pub _0: ::RustType, #[allow(missing_docs)] @@ -7832,10 +7784,10 @@ pub mod StakeTableV2 { #[allow(missing_docs)] pub _3: u16, } - ///Container type for the return parameters of the [`registerValidator((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),uint16)`](registerValidator_0Call) function. + ///Container type for the return parameters of the [`registerValidator((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),uint16)`](registerValidatorCall) function. #[allow(non_camel_case_types, non_snake_case, clippy::pub_underscore_fields)] #[derive(Clone)] - pub struct registerValidator_0Return {} + pub struct registerValidatorReturn {} #[allow( non_camel_case_types, non_snake_case, @@ -7870,14 +7822,14 @@ pub mod StakeTableV2 { } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From for UnderlyingRustTuple<'_> { - fn from(value: registerValidator_0Call) -> Self { + impl ::core::convert::From for UnderlyingRustTuple<'_> { + fn from(value: registerValidatorCall) -> Self { (value._0, value._1, value._2, value._3) } } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From> for registerValidator_0Call { + impl ::core::convert::From> for registerValidatorCall { fn from(tuple: UnderlyingRustTuple<'_>) -> Self { Self { _0: tuple.0, @@ -7904,21 +7856,21 @@ pub mod StakeTableV2 { } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From for UnderlyingRustTuple<'_> { - fn from(value: registerValidator_0Return) -> Self { + impl ::core::convert::From for UnderlyingRustTuple<'_> { + fn from(value: registerValidatorReturn) -> Self { () } } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From> for registerValidator_0Return { + impl ::core::convert::From> for registerValidatorReturn { fn from(tuple: UnderlyingRustTuple<'_>) -> Self { Self {} } } } #[automatically_derived] - impl alloy_sol_types::SolCall for registerValidator_0Call { + impl alloy_sol_types::SolCall for registerValidatorCall { type Parameters<'a> = ( BN254::G2Point, EdOnBN254::EdOnBN254Point, @@ -7926,7 +7878,7 @@ pub mod StakeTableV2 { alloy::sol_types::sol_data::Uint<16>, ); type Token<'a> = as alloy_sol_types::SolType>::Token<'a>; - type Return = registerValidator_0Return; + type Return = registerValidatorReturn; type ReturnTuple<'a> = (); type ReturnToken<'a> = as alloy_sol_types::SolType>::Token<'a>; const SIGNATURE: &'static str = "registerValidator((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),uint16)"; @@ -7961,13 +7913,13 @@ pub mod StakeTableV2 { } }; #[derive()] - /**Function with signature `registerValidator((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),(uint256,uint256),uint16)` and selector `0xa5857ff3`. + /**Function with signature `registerValidatorV2((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),bytes,uint16)` and selector `0x304240bf`. ```solidity - function registerValidator(BN254.G2Point memory blsVK, EdOnBN254.EdOnBN254Point memory schnorrVK, BN254.G1Point memory blsSig, EdOnBN254.EdOnBN254Point memory schnorrSig, uint16 commission) external; + function registerValidatorV2(BN254.G2Point memory blsVK, EdOnBN254.EdOnBN254Point memory schnorrVK, BN254.G1Point memory blsSig, bytes memory schnorrSig, uint16 commission) external; ```*/ #[allow(non_camel_case_types, non_snake_case, clippy::pub_underscore_fields)] #[derive(Clone)] - pub struct registerValidator_1Call { + pub struct registerValidatorV2Call { #[allow(missing_docs)] pub blsVK: ::RustType, #[allow(missing_docs)] @@ -7975,14 +7927,14 @@ pub mod StakeTableV2 { #[allow(missing_docs)] pub blsSig: ::RustType, #[allow(missing_docs)] - pub schnorrSig: ::RustType, + pub schnorrSig: alloy::sol_types::private::Bytes, #[allow(missing_docs)] pub commission: u16, } - ///Container type for the return parameters of the [`registerValidator((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),(uint256,uint256),uint16)`](registerValidator_1Call) function. + ///Container type for the return parameters of the [`registerValidatorV2((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),bytes,uint16)`](registerValidatorV2Call) function. #[allow(non_camel_case_types, non_snake_case, clippy::pub_underscore_fields)] #[derive(Clone)] - pub struct registerValidator_1Return {} + pub struct registerValidatorV2Return {} #[allow( non_camel_case_types, non_snake_case, @@ -7997,7 +7949,7 @@ pub mod StakeTableV2 { BN254::G2Point, EdOnBN254::EdOnBN254Point, BN254::G1Point, - EdOnBN254::EdOnBN254Point, + alloy::sol_types::sol_data::Bytes, alloy::sol_types::sol_data::Uint<16>, ); #[doc(hidden)] @@ -8005,7 +7957,7 @@ pub mod StakeTableV2 { ::RustType, ::RustType, ::RustType, - ::RustType, + alloy::sol_types::private::Bytes, u16, ); #[cfg(test)] @@ -8019,8 +7971,8 @@ pub mod StakeTableV2 { } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From for UnderlyingRustTuple<'_> { - fn from(value: registerValidator_1Call) -> Self { + impl ::core::convert::From for UnderlyingRustTuple<'_> { + fn from(value: registerValidatorV2Call) -> Self { ( value.blsVK, value.schnorrVK, @@ -8032,7 +7984,7 @@ pub mod StakeTableV2 { } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From> for registerValidator_1Call { + impl ::core::convert::From> for registerValidatorV2Call { fn from(tuple: UnderlyingRustTuple<'_>) -> Self { Self { blsVK: tuple.0, @@ -8060,34 +8012,34 @@ pub mod StakeTableV2 { } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From for UnderlyingRustTuple<'_> { - fn from(value: registerValidator_1Return) -> Self { + impl ::core::convert::From for UnderlyingRustTuple<'_> { + fn from(value: registerValidatorV2Return) -> Self { () } } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From> for registerValidator_1Return { + impl ::core::convert::From> for registerValidatorV2Return { fn from(tuple: UnderlyingRustTuple<'_>) -> Self { Self {} } } } #[automatically_derived] - impl alloy_sol_types::SolCall for registerValidator_1Call { + impl alloy_sol_types::SolCall for registerValidatorV2Call { type Parameters<'a> = ( BN254::G2Point, EdOnBN254::EdOnBN254Point, BN254::G1Point, - EdOnBN254::EdOnBN254Point, + alloy::sol_types::sol_data::Bytes, alloy::sol_types::sol_data::Uint<16>, ); type Token<'a> = as alloy_sol_types::SolType>::Token<'a>; - type Return = registerValidator_1Return; + type Return = registerValidatorV2Return; type ReturnTuple<'a> = (); type ReturnToken<'a> = as alloy_sol_types::SolType>::Token<'a>; - const SIGNATURE: &'static str = "registerValidator((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),(uint256,uint256),uint16)"; - const SELECTOR: [u8; 4] = [165u8, 133u8, 127u8, 243u8]; + const SIGNATURE: &'static str = "registerValidatorV2((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),bytes,uint16)"; + const SELECTOR: [u8; 4] = [48u8, 66u8, 64u8, 191u8]; #[inline] fn new<'a>( tuple: as alloy_sol_types::SolType>::RustType, @@ -8102,7 +8054,7 @@ pub mod StakeTableV2 { &self.schnorrVK, ), ::tokenize(&self.blsSig), - ::tokenize( + ::tokenize( &self.schnorrSig, ), as alloy_sol_types::SolType>::tokenize( @@ -8751,7 +8703,7 @@ pub mod StakeTableV2 { ```*/ #[allow(non_camel_case_types, non_snake_case, clippy::pub_underscore_fields)] #[derive(Clone)] - pub struct updateConsensusKeys_0Call { + pub struct updateConsensusKeysCall { #[allow(missing_docs)] pub _0: ::RustType, #[allow(missing_docs)] @@ -8759,10 +8711,10 @@ pub mod StakeTableV2 { #[allow(missing_docs)] pub _2: ::RustType, } - ///Container type for the return parameters of the [`updateConsensusKeys((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256))`](updateConsensusKeys_0Call) function. + ///Container type for the return parameters of the [`updateConsensusKeys((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256))`](updateConsensusKeysCall) function. #[allow(non_camel_case_types, non_snake_case, clippy::pub_underscore_fields)] #[derive(Clone)] - pub struct updateConsensusKeys_0Return {} + pub struct updateConsensusKeysReturn {} #[allow( non_camel_case_types, non_snake_case, @@ -8792,14 +8744,14 @@ pub mod StakeTableV2 { } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From for UnderlyingRustTuple<'_> { - fn from(value: updateConsensusKeys_0Call) -> Self { + impl ::core::convert::From for UnderlyingRustTuple<'_> { + fn from(value: updateConsensusKeysCall) -> Self { (value._0, value._1, value._2) } } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From> for updateConsensusKeys_0Call { + impl ::core::convert::From> for updateConsensusKeysCall { fn from(tuple: UnderlyingRustTuple<'_>) -> Self { Self { _0: tuple.0, @@ -8825,24 +8777,24 @@ pub mod StakeTableV2 { } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From for UnderlyingRustTuple<'_> { - fn from(value: updateConsensusKeys_0Return) -> Self { + impl ::core::convert::From for UnderlyingRustTuple<'_> { + fn from(value: updateConsensusKeysReturn) -> Self { () } } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From> for updateConsensusKeys_0Return { + impl ::core::convert::From> for updateConsensusKeysReturn { fn from(tuple: UnderlyingRustTuple<'_>) -> Self { Self {} } } } #[automatically_derived] - impl alloy_sol_types::SolCall for updateConsensusKeys_0Call { + impl alloy_sol_types::SolCall for updateConsensusKeysCall { type Parameters<'a> = (BN254::G2Point, EdOnBN254::EdOnBN254Point, BN254::G1Point); type Token<'a> = as alloy_sol_types::SolType>::Token<'a>; - type Return = updateConsensusKeys_0Return; + type Return = updateConsensusKeysReturn; type ReturnTuple<'a> = (); type ReturnToken<'a> = as alloy_sol_types::SolType>::Token<'a>; const SIGNATURE: &'static str = "updateConsensusKeys((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256))"; @@ -8874,13 +8826,13 @@ pub mod StakeTableV2 { } }; #[derive()] - /**Function with signature `updateConsensusKeys((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),(uint256,uint256))` and selector `0xe53b2a74`. + /**Function with signature `updateConsensusKeysV2((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),bytes)` and selector `0xac5c2ad0`. ```solidity - function updateConsensusKeys(BN254.G2Point memory blsVK, EdOnBN254.EdOnBN254Point memory schnorrVK, BN254.G1Point memory blsSig, EdOnBN254.EdOnBN254Point memory schnorrSig) external; + function updateConsensusKeysV2(BN254.G2Point memory blsVK, EdOnBN254.EdOnBN254Point memory schnorrVK, BN254.G1Point memory blsSig, bytes memory schnorrSig) external; ```*/ #[allow(non_camel_case_types, non_snake_case, clippy::pub_underscore_fields)] #[derive(Clone)] - pub struct updateConsensusKeys_1Call { + pub struct updateConsensusKeysV2Call { #[allow(missing_docs)] pub blsVK: ::RustType, #[allow(missing_docs)] @@ -8888,12 +8840,12 @@ pub mod StakeTableV2 { #[allow(missing_docs)] pub blsSig: ::RustType, #[allow(missing_docs)] - pub schnorrSig: ::RustType, + pub schnorrSig: alloy::sol_types::private::Bytes, } - ///Container type for the return parameters of the [`updateConsensusKeys((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),(uint256,uint256))`](updateConsensusKeys_1Call) function. + ///Container type for the return parameters of the [`updateConsensusKeysV2((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),bytes)`](updateConsensusKeysV2Call) function. #[allow(non_camel_case_types, non_snake_case, clippy::pub_underscore_fields)] #[derive(Clone)] - pub struct updateConsensusKeys_1Return {} + pub struct updateConsensusKeysV2Return {} #[allow( non_camel_case_types, non_snake_case, @@ -8908,14 +8860,14 @@ pub mod StakeTableV2 { BN254::G2Point, EdOnBN254::EdOnBN254Point, BN254::G1Point, - EdOnBN254::EdOnBN254Point, + alloy::sol_types::sol_data::Bytes, ); #[doc(hidden)] type UnderlyingRustTuple<'a> = ( ::RustType, ::RustType, ::RustType, - ::RustType, + alloy::sol_types::private::Bytes, ); #[cfg(test)] #[allow(dead_code, unreachable_patterns)] @@ -8928,14 +8880,14 @@ pub mod StakeTableV2 { } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From for UnderlyingRustTuple<'_> { - fn from(value: updateConsensusKeys_1Call) -> Self { + impl ::core::convert::From for UnderlyingRustTuple<'_> { + fn from(value: updateConsensusKeysV2Call) -> Self { (value.blsVK, value.schnorrVK, value.blsSig, value.schnorrSig) } } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From> for updateConsensusKeys_1Call { + impl ::core::convert::From> for updateConsensusKeysV2Call { fn from(tuple: UnderlyingRustTuple<'_>) -> Self { Self { blsVK: tuple.0, @@ -8962,33 +8914,33 @@ pub mod StakeTableV2 { } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From for UnderlyingRustTuple<'_> { - fn from(value: updateConsensusKeys_1Return) -> Self { + impl ::core::convert::From for UnderlyingRustTuple<'_> { + fn from(value: updateConsensusKeysV2Return) -> Self { () } } #[automatically_derived] #[doc(hidden)] - impl ::core::convert::From> for updateConsensusKeys_1Return { + impl ::core::convert::From> for updateConsensusKeysV2Return { fn from(tuple: UnderlyingRustTuple<'_>) -> Self { Self {} } } } #[automatically_derived] - impl alloy_sol_types::SolCall for updateConsensusKeys_1Call { + impl alloy_sol_types::SolCall for updateConsensusKeysV2Call { type Parameters<'a> = ( BN254::G2Point, EdOnBN254::EdOnBN254Point, BN254::G1Point, - EdOnBN254::EdOnBN254Point, + alloy::sol_types::sol_data::Bytes, ); type Token<'a> = as alloy_sol_types::SolType>::Token<'a>; - type Return = updateConsensusKeys_1Return; + type Return = updateConsensusKeysV2Return; type ReturnTuple<'a> = (); type ReturnToken<'a> = as alloy_sol_types::SolType>::Token<'a>; - const SIGNATURE: &'static str = "updateConsensusKeys((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),(uint256,uint256))"; - const SELECTOR: [u8; 4] = [229u8, 59u8, 42u8, 116u8]; + const SIGNATURE: &'static str = "updateConsensusKeysV2((uint256,uint256,uint256,uint256),(uint256,uint256),(uint256,uint256),bytes)"; + const SELECTOR: [u8; 4] = [172u8, 92u8, 42u8, 208u8]; #[inline] fn new<'a>( tuple: as alloy_sol_types::SolType>::RustType, @@ -9003,7 +8955,7 @@ pub mod StakeTableV2 { &self.schnorrVK, ), ::tokenize(&self.blsSig), - ::tokenize( + ::tokenize( &self.schnorrSig, ), ) @@ -9559,9 +9511,9 @@ pub mod StakeTableV2 { #[allow(missing_docs)] proxiableUUID(proxiableUUIDCall), #[allow(missing_docs)] - registerValidator_0(registerValidator_0Call), + registerValidator(registerValidatorCall), #[allow(missing_docs)] - registerValidator_1(registerValidator_1Call), + registerValidatorV2(registerValidatorV2Call), #[allow(missing_docs)] renounceOwnership(renounceOwnershipCall), #[allow(missing_docs)] @@ -9573,9 +9525,9 @@ pub mod StakeTableV2 { #[allow(missing_docs)] undelegations(undelegationsCall), #[allow(missing_docs)] - updateConsensusKeys_0(updateConsensusKeys_0Call), + updateConsensusKeys(updateConsensusKeysCall), #[allow(missing_docs)] - updateConsensusKeys_1(updateConsensusKeys_1Call), + updateConsensusKeysV2(updateConsensusKeysV2Call), #[allow(missing_docs)] updateExitEscrowPeriod(updateExitEscrowPeriodCall), #[allow(missing_docs)] @@ -9599,6 +9551,7 @@ pub mod StakeTableV2 { [19u8, 185u8, 5u8, 122u8], [26u8, 32u8, 205u8, 99u8], [33u8, 64u8, 254u8, 205u8], + [48u8, 66u8, 64u8, 191u8], [62u8, 157u8, 249u8, 181u8], [77u8, 153u8, 221u8, 22u8], [79u8, 30u8, 242u8, 134u8], @@ -9611,14 +9564,13 @@ pub mod StakeTableV2 { [158u8, 154u8, 143u8, 49u8], [162u8, 215u8, 141u8, 213u8], [163u8, 6u8, 106u8, 171u8], - [165u8, 133u8, 127u8, 243u8], + [172u8, 92u8, 42u8, 208u8], [173u8, 60u8, 177u8, 204u8], [179u8, 230u8, 235u8, 213u8], [181u8, 112u8, 14u8, 104u8], [181u8, 236u8, 179u8, 68u8], [190u8, 32u8, 48u8, 148u8], [198u8, 72u8, 20u8, 221u8], - [229u8, 59u8, 42u8, 116u8], [242u8, 253u8, 227u8, 139u8], [250u8, 82u8, 199u8, 216u8], [252u8, 12u8, 84u8, 106u8], @@ -9659,11 +9611,11 @@ pub mod StakeTableV2 { Self::lightClient(_) => ::SELECTOR, Self::owner(_) => ::SELECTOR, Self::proxiableUUID(_) => ::SELECTOR, - Self::registerValidator_0(_) => { - ::SELECTOR + Self::registerValidator(_) => { + ::SELECTOR }, - Self::registerValidator_1(_) => { - ::SELECTOR + Self::registerValidatorV2(_) => { + ::SELECTOR }, Self::renounceOwnership(_) => { ::SELECTOR @@ -9674,11 +9626,11 @@ pub mod StakeTableV2 { }, Self::undelegate(_) => ::SELECTOR, Self::undelegations(_) => ::SELECTOR, - Self::updateConsensusKeys_0(_) => { - ::SELECTOR + Self::updateConsensusKeys(_) => { + ::SELECTOR }, - Self::updateConsensusKeys_1(_) => { - ::SELECTOR + Self::updateConsensusKeysV2(_) => { + ::SELECTOR }, Self::updateExitEscrowPeriod(_) => { ::SELECTOR @@ -9733,16 +9685,16 @@ pub mod StakeTableV2 { getVersion }, { - fn registerValidator_0( + fn registerValidator( data: &[u8], validate: bool, ) -> alloy_sol_types::Result { - ::abi_decode_raw( + ::abi_decode_raw( data, validate, ) - .map(StakeTableV2Calls::registerValidator_0) + .map(StakeTableV2Calls::registerValidator) } - registerValidator_0 + registerValidator }, { fn updateExitEscrowPeriod( @@ -9768,6 +9720,18 @@ pub mod StakeTableV2 { } claimValidatorExit }, + { + fn registerValidatorV2( + data: &[u8], + validate: bool, + ) -> alloy_sol_types::Result { + ::abi_decode_raw( + data, validate, + ) + .map(StakeTableV2Calls::registerValidatorV2) + } + registerValidatorV2 + }, { fn initializedAtBlock( data: &[u8], @@ -9815,16 +9779,16 @@ pub mod StakeTableV2 { proxiableUUID }, { - fn updateConsensusKeys_0( + fn updateConsensusKeys( data: &[u8], validate: bool, ) -> alloy_sol_types::Result { - ::abi_decode_raw( + ::abi_decode_raw( data, validate, ) - .map(StakeTableV2Calls::updateConsensusKeys_0) + .map(StakeTableV2Calls::updateConsensusKeys) } - updateConsensusKeys_0 + updateConsensusKeys }, { fn deregisterValidator( @@ -9909,16 +9873,16 @@ pub mod StakeTableV2 { claimWithdrawal }, { - fn registerValidator_1( + fn updateConsensusKeysV2( data: &[u8], validate: bool, ) -> alloy_sol_types::Result { - ::abi_decode_raw( + ::abi_decode_raw( data, validate, ) - .map(StakeTableV2Calls::registerValidator_1) + .map(StakeTableV2Calls::updateConsensusKeysV2) } - registerValidator_1 + updateConsensusKeysV2 }, { fn UPGRADE_INTERFACE_VERSION( @@ -9988,18 +9952,6 @@ pub mod StakeTableV2 { } delegations }, - { - fn updateConsensusKeys_1( - data: &[u8], - validate: bool, - ) -> alloy_sol_types::Result { - ::abi_decode_raw( - data, validate, - ) - .map(StakeTableV2Calls::updateConsensusKeys_1) - } - updateConsensusKeys_1 - }, { fn transferOwnership( data: &[u8], @@ -10091,11 +10043,11 @@ pub mod StakeTableV2 { Self::proxiableUUID(inner) => { ::abi_encoded_size(inner) }, - Self::registerValidator_0(inner) => { - ::abi_encoded_size(inner) + Self::registerValidator(inner) => { + ::abi_encoded_size(inner) }, - Self::registerValidator_1(inner) => { - ::abi_encoded_size(inner) + Self::registerValidatorV2(inner) => { + ::abi_encoded_size(inner) }, Self::renounceOwnership(inner) => { ::abi_encoded_size(inner) @@ -10112,11 +10064,11 @@ pub mod StakeTableV2 { Self::undelegations(inner) => { ::abi_encoded_size(inner) }, - Self::updateConsensusKeys_0(inner) => { - ::abi_encoded_size(inner) + Self::updateConsensusKeys(inner) => { + ::abi_encoded_size(inner) }, - Self::updateConsensusKeys_1(inner) => { - ::abi_encoded_size(inner) + Self::updateConsensusKeysV2(inner) => { + ::abi_encoded_size(inner) }, Self::updateExitEscrowPeriod(inner) => { ::abi_encoded_size( @@ -10186,13 +10138,11 @@ pub mod StakeTableV2 { Self::proxiableUUID(inner) => { ::abi_encode_raw(inner, out) }, - Self::registerValidator_0(inner) => { - ::abi_encode_raw( - inner, out, - ) + Self::registerValidator(inner) => { + ::abi_encode_raw(inner, out) }, - Self::registerValidator_1(inner) => { - ::abi_encode_raw( + Self::registerValidatorV2(inner) => { + ::abi_encode_raw( inner, out, ) }, @@ -10211,13 +10161,13 @@ pub mod StakeTableV2 { Self::undelegations(inner) => { ::abi_encode_raw(inner, out) }, - Self::updateConsensusKeys_0(inner) => { - ::abi_encode_raw( + Self::updateConsensusKeys(inner) => { + ::abi_encode_raw( inner, out, ) }, - Self::updateConsensusKeys_1(inner) => { - ::abi_encode_raw( + Self::updateConsensusKeysV2(inner) => { + ::abi_encode_raw( inner, out, ) }, @@ -11012,11 +10962,6 @@ pub mod StakeTableV2 { /// /// Prefer using `SolInterface` methods instead. pub const SELECTORS: &'static [[u8; 32usize]] = &[ - [ - 4u8, 207u8, 140u8, 244u8, 122u8, 107u8, 242u8, 234u8, 95u8, 113u8, 184u8, 238u8, - 189u8, 236u8, 157u8, 226u8, 17u8, 127u8, 71u8, 210u8, 182u8, 123u8, 198u8, 8u8, - 51u8, 143u8, 129u8, 172u8, 177u8, 164u8, 102u8, 213u8, - ], [ 77u8, 16u8, 189u8, 4u8, 151u8, 117u8, 199u8, 123u8, 215u8, 242u8, 85u8, 25u8, 90u8, 251u8, 165u8, 8u8, 128u8, 40u8, 236u8, 179u8, 199u8, 194u8, 119u8, 211u8, 147u8, @@ -11042,11 +10987,6 @@ pub mod StakeTableV2 { 164u8, 242u8, 132u8, 25u8, 73u8, 127u8, 151u8, 34u8, 163u8, 218u8, 175u8, 227u8, 180u8, 24u8, 111u8, 107u8, 100u8, 87u8, 224u8, ], - [ - 142u8, 28u8, 57u8, 77u8, 143u8, 60u8, 131u8, 216u8, 226u8, 77u8, 32u8, 121u8, 11u8, - 208u8, 88u8, 111u8, 231u8, 19u8, 84u8, 129u8, 10u8, 147u8, 194u8, 238u8, 54u8, - 139u8, 65u8, 135u8, 69u8, 85u8, 59u8, 46u8, - ], [ 188u8, 124u8, 215u8, 90u8, 32u8, 238u8, 39u8, 253u8, 154u8, 222u8, 186u8, 179u8, 32u8, 65u8, 247u8, 85u8, 33u8, 77u8, 188u8, 107u8, 255u8, 169u8, 12u8, 192u8, 34u8, @@ -11057,11 +10997,21 @@ pub mod StakeTableV2 { 244u8, 73u8, 158u8, 31u8, 38u8, 51u8, 167u8, 181u8, 147u8, 99u8, 33u8, 238u8, 209u8, 205u8, 174u8, 182u8, 17u8, 81u8, 129u8, 210u8, ], + [ + 200u8, 197u8, 179u8, 122u8, 236u8, 127u8, 45u8, 219u8, 211u8, 161u8, 60u8, 81u8, + 54u8, 30u8, 84u8, 160u8, 168u8, 223u8, 59u8, 202u8, 37u8, 106u8, 183u8, 88u8, + 167u8, 127u8, 90u8, 215u8, 65u8, 210u8, 129u8, 229u8, + ], [ 229u8, 84u8, 26u8, 107u8, 97u8, 3u8, 212u8, 250u8, 126u8, 2u8, 30u8, 213u8, 79u8, 173u8, 57u8, 198u8, 111u8, 39u8, 167u8, 107u8, 209u8, 61u8, 55u8, 76u8, 246u8, 36u8, 10u8, 230u8, 189u8, 11u8, 183u8, 43u8, ], + [ + 240u8, 87u8, 212u8, 234u8, 129u8, 233u8, 134u8, 40u8, 101u8, 58u8, 143u8, 144u8, + 120u8, 133u8, 65u8, 151u8, 32u8, 120u8, 19u8, 115u8, 52u8, 169u8, 43u8, 66u8, 52u8, + 126u8, 172u8, 205u8, 168u8, 15u8, 196u8, 10u8, + ], [ 246u8, 232u8, 53u8, 156u8, 87u8, 82u8, 11u8, 70u8, 150u8, 52u8, 115u8, 107u8, 252u8, 59u8, 183u8, 236u8, 92u8, 189u8, 26u8, 11u8, 210u8, 139u8, 16u8, 168u8, @@ -11520,26 +11470,26 @@ pub mod StakeTableV2 { pub fn proxiableUUID(&self) -> alloy_contract::SolCallBuilder { self.call_builder(&proxiableUUIDCall {}) } - ///Creates a new call builder for the [`registerValidator_0`] function. - pub fn registerValidator_0( + ///Creates a new call builder for the [`registerValidator`] function. + pub fn registerValidator( &self, _0: ::RustType, _1: ::RustType, _2: ::RustType, _3: u16, - ) -> alloy_contract::SolCallBuilder { - self.call_builder(®isterValidator_0Call { _0, _1, _2, _3 }) + ) -> alloy_contract::SolCallBuilder { + self.call_builder(®isterValidatorCall { _0, _1, _2, _3 }) } - ///Creates a new call builder for the [`registerValidator_1`] function. - pub fn registerValidator_1( + ///Creates a new call builder for the [`registerValidatorV2`] function. + pub fn registerValidatorV2( &self, blsVK: ::RustType, schnorrVK: ::RustType, blsSig: ::RustType, - schnorrSig: ::RustType, + schnorrSig: alloy::sol_types::private::Bytes, commission: u16, - ) -> alloy_contract::SolCallBuilder { - self.call_builder(®isterValidator_1Call { + ) -> alloy_contract::SolCallBuilder { + self.call_builder(®isterValidatorV2Call { blsVK, schnorrVK, blsSig, @@ -11583,24 +11533,24 @@ pub mod StakeTableV2 { delegator, }) } - ///Creates a new call builder for the [`updateConsensusKeys_0`] function. - pub fn updateConsensusKeys_0( + ///Creates a new call builder for the [`updateConsensusKeys`] function. + pub fn updateConsensusKeys( &self, _0: ::RustType, _1: ::RustType, _2: ::RustType, - ) -> alloy_contract::SolCallBuilder { - self.call_builder(&updateConsensusKeys_0Call { _0, _1, _2 }) + ) -> alloy_contract::SolCallBuilder { + self.call_builder(&updateConsensusKeysCall { _0, _1, _2 }) } - ///Creates a new call builder for the [`updateConsensusKeys_1`] function. - pub fn updateConsensusKeys_1( + ///Creates a new call builder for the [`updateConsensusKeysV2`] function. + pub fn updateConsensusKeysV2( &self, blsVK: ::RustType, schnorrVK: ::RustType, blsSig: ::RustType, - schnorrSig: ::RustType, - ) -> alloy_contract::SolCallBuilder { - self.call_builder(&updateConsensusKeys_1Call { + schnorrSig: alloy::sol_types::private::Bytes, + ) -> alloy_contract::SolCallBuilder { + self.call_builder(&updateConsensusKeysV2Call { blsVK, schnorrVK, blsSig, diff --git a/contracts/rust/adapter/src/copy.rs b/contracts/rust/adapter/src/copy.rs new file mode 100644 index 0000000000..593cc98787 --- /dev/null +++ b/contracts/rust/adapter/src/copy.rs @@ -0,0 +1,13 @@ +// The bindings types are small and pure data, there is no reason they +// shouldn't be Copy. However some of them do have a bytes field which cannot be Copy. +impl Copy for crate::sol_types::G1PointSol {} +impl Copy for crate::sol_types::G2PointSol {} +impl Copy for crate::sol_types::EdOnBN254PointSol {} +impl Copy for crate::sol_types::StakeTableV2::ValidatorRegistered {} +// schnorr sig in ValidatorRegisteredV2 uses Bytes, cannot implement copy +impl Copy for crate::sol_types::StakeTableV2::ValidatorExit {} +impl Copy for crate::sol_types::StakeTableV2::ConsensusKeysUpdated {} +// schnorr sig in ConsensusKeysUpdatedV2 Bytes, cannot implement copy +impl Copy for crate::sol_types::StakeTableV2::Delegated {} +impl Copy for crate::sol_types::StakeTableV2::Undelegated {} +impl Copy for crate::sol_types::staketablev2::BN254::G1Point {} diff --git a/contracts/rust/adapter/src/lib.rs b/contracts/rust/adapter/src/lib.rs index e68f8c3c34..1839a542e2 100644 --- a/contracts/rust/adapter/src/lib.rs +++ b/contracts/rust/adapter/src/lib.rs @@ -5,6 +5,7 @@ use ark_ff::{BigInteger, PrimeField}; #[allow(dead_code)] pub(crate) mod bindings; +mod copy; pub mod evm; pub mod jellyfish; pub mod light_client; diff --git a/contracts/rust/adapter/src/sol_types.rs b/contracts/rust/adapter/src/sol_types.rs index 09acc04150..e81bb26256 100644 --- a/contracts/rust/adapter/src/sol_types.rs +++ b/contracts/rust/adapter/src/sol_types.rs @@ -39,8 +39,9 @@ pub use crate::bindings::{ lightclientv2mock::{self, LightClientV2Mock}, plonkverifier::PlonkVerifier, plonkverifierv2::PlonkVerifierV2, - staketable::{ - self, EdOnBN254::EdOnBN254Point as EdOnBN254PointSol, StakeTable, + staketable::StakeTable, + staketablev2::{ + self, EdOnBN254::EdOnBN254Point as EdOnBN254PointSol, StakeTableV2, BN254::G2Point as G2PointSol, }, timelock::Timelock, @@ -173,18 +174,25 @@ impl From for StakeTableStateSol } } -impl From for staketable::BN254::G1Point { +impl From for staketablev2::BN254::G1Point { fn from(v: G1PointSol) -> Self { unsafe { std::mem::transmute(v) } } } +impl From for G1PointSol { + fn from(v: staketablev2::BN254::G1Point) -> Self { + unsafe { std::mem::transmute(v) } + } +} + use serde::{Deserialize, Deserializer, Serialize, Serializer}; use self::{ - staketable::{EdOnBN254::EdOnBN254Point, BN254::G2Point}, - StakeTable::{ - ConsensusKeysUpdated, Delegated, Undelegated, ValidatorExit, ValidatorRegistered, + staketablev2::{EdOnBN254::EdOnBN254Point, BN254::G2Point}, + StakeTableV2::{ + ConsensusKeysUpdated, ConsensusKeysUpdatedV2, Delegated, Undelegated, ValidatorExit, + ValidatorRegistered, ValidatorRegisteredV2, }, }; @@ -197,6 +205,17 @@ impl PartialEq for ValidatorRegistered { } } +impl PartialEq for ValidatorRegisteredV2 { + fn eq(&self, other: &Self) -> bool { + self.account == other.account + && self.blsVK == other.blsVK + && self.schnorrVK == other.schnorrVK + && self.commission == other.commission + && self.blsSig == other.blsSig + && self.schnorrSig == other.schnorrSig + } +} + impl PartialEq for ConsensusKeysUpdated { fn eq(&self, other: &Self) -> bool { self.account == other.account @@ -205,6 +224,16 @@ impl PartialEq for ConsensusKeysUpdated { } } +impl PartialEq for ConsensusKeysUpdatedV2 { + fn eq(&self, other: &Self) -> bool { + self.account == other.account + && self.blsVK == other.blsVK + && self.schnorrVK == other.schnorrVK + && self.blsSig == other.blsSig + && self.schnorrSig == other.schnorrSig + } +} + impl Serialize for ValidatorRegistered { fn serialize(&self, serializer: S) -> Result where @@ -221,7 +250,7 @@ impl<'de> Deserialize<'de> for ValidatorRegistered { D: Deserializer<'de>, { let (account, blsVk, schnorrVk, commission) = <(_, _, _, u16)>::deserialize(deserializer)?; - Ok(ValidatorRegistered { + Ok(Self { account, blsVk, schnorrVk, @@ -230,6 +259,42 @@ impl<'de> Deserialize<'de> for ValidatorRegistered { } } +impl Serialize for ValidatorRegisteredV2 { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + ( + &self.account, + &self.blsVK, + &self.schnorrVK, + self.commission, + &self.blsSig, + &self.schnorrSig, + ) + .serialize(serializer) + } +} + +#[allow(non_snake_case)] +impl<'de> Deserialize<'de> for ValidatorRegisteredV2 { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let (account, blsVK, schnorrVK, commission, blsSig, schnorrSig) = + <(_, _, _, u16, _, _)>::deserialize(deserializer)?; + Ok(ValidatorRegisteredV2 { + account, + blsVK, + schnorrVK, + commission, + blsSig, + schnorrSig, + }) + } +} + impl Serialize for EdOnBN254Point { fn serialize(&self, serializer: S) -> Result where @@ -245,7 +310,7 @@ impl<'de> Deserialize<'de> for EdOnBN254Point { D: Deserializer<'de>, { let (x, y) = Deserialize::deserialize(deserializer)?; - Ok(EdOnBN254Point { x, y }) + Ok(Self { x, y }) } } @@ -259,13 +324,32 @@ impl Serialize for G2Point { } impl<'de> Deserialize<'de> for G2Point { - fn deserialize(deserializer: D) -> Result + fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { let (x0, x1, y0, y1) = Deserialize::deserialize(deserializer)?; - Ok(G2Point { x0, x1, y0, y1 }) + Ok(Self { x0, x1, y0, y1 }) + } +} + +impl Serialize for staketablev2::BN254::G1Point { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + (&self.x, &self.y).serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for staketablev2::BN254::G1Point { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let (x, y) = Deserialize::deserialize(deserializer)?; + Ok(Self { x, y }) } } @@ -361,3 +445,38 @@ impl<'de> Deserialize<'de> for ConsensusKeysUpdated { }) } } + +impl Serialize for ConsensusKeysUpdatedV2 { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + ( + &self.account, + &self.blsVK, + &self.schnorrVK, + &self.blsSig, + &self.schnorrSig, + ) + .serialize(serializer) + } +} + +#[allow(non_snake_case)] +impl<'de> Deserialize<'de> for ConsensusKeysUpdatedV2 { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let (account, blsVK, schnorrVK, blsSig, schnorrSig) = + Deserialize::deserialize(deserializer)?; + + Ok(ConsensusKeysUpdatedV2 { + account, + blsVK, + schnorrVK, + blsSig, + schnorrSig, + }) + } +} diff --git a/contracts/rust/adapter/src/stake_table.rs b/contracts/rust/adapter/src/stake_table.rs index 52dc7090a4..d38580e950 100644 --- a/contracts/rust/adapter/src/stake_table.rs +++ b/contracts/rust/adapter/src/stake_table.rs @@ -1,9 +1,44 @@ +use alloy::{ + primitives::{Address, Bytes}, + sol_types::SolValue, +}; use ark_bn254::G2Affine; -use ark_ec::AffineRepr; +use ark_ec::{AffineRepr, CurveGroup as _}; +use ark_ed_on_bn254::EdwardsConfig; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use hotshot_types::{light_client::StateVerKey, signature_key::BLSPubKey}; +use hotshot_types::{ + light_client::{hash_bytes_to_field, StateKeyPair, StateVerKey}, + signature_key::{BLSKeyPair, BLSPubKey, BLSSignature}, + traits::signature_key::SignatureKey, +}; +use jf_signature::{ + constants::{CS_ID_BLS_BN254, CS_ID_SCHNORR}, + schnorr, +}; -use crate::sol_types::*; +use crate::sol_types::{ + StakeTableV2::{getVersionReturn, ConsensusKeysUpdatedV2, ValidatorRegisteredV2}, + *, +}; + +#[derive(Debug, Clone, Copy, Default)] +pub enum StakeTableContractVersion { + V1, + #[default] + V2, +} + +impl TryFrom for StakeTableContractVersion { + type Error = anyhow::Error; + + fn try_from(value: getVersionReturn) -> anyhow::Result { + match value.majorVersion { + 1 => Ok(StakeTableContractVersion::V1), + 2 => Ok(StakeTableContractVersion::V2), + _ => anyhow::bail!("Unsupported stake table contract version: {:?}", value), + } + } +} impl From for BLSPubKey { fn from(value: G2PointSol) -> Self { @@ -24,10 +59,129 @@ impl From for StateVerKey { } } +pub fn sign_address_bls(bls_key_pair: &BLSKeyPair, address: Address) -> G1PointSol { + bls_key_pair + .sign(&address.abi_encode(), CS_ID_BLS_BN254) + .sigma + .into_affine() + .into() +} + +pub fn sign_address_schnorr(schnorr_key_pair: &StateKeyPair, address: Address) -> Bytes { + let msg = [hash_bytes_to_field(&address.abi_encode()).expect("hash to field works")]; + let mut buf = vec![]; + schnorr_key_pair + .sign(&msg, CS_ID_SCHNORR) + .serialize_compressed(&mut buf) + .expect("serialize works"); + buf.into() +} + +// Helper function useful for unit tests. +fn authenticate_schnorr_sig( + schnorr_vk: &StateVerKey, + address: Address, + schnorr_sig: &[u8], +) -> Result<(), StakeTableSolError> { + let msg = [hash_bytes_to_field(&address.abi_encode()).expect("hash to field works")]; + let sig = schnorr::Signature::::deserialize_compressed(schnorr_sig)?; + schnorr_vk.verify(&msg, &sig, CS_ID_SCHNORR)?; + Ok(()) +} + +// Helper function useful for unit tests. +fn authenticate_bls_sig( + bls_vk: &BLSPubKey, + address: Address, + bls_sig: &G1PointSol, +) -> Result<(), StakeTableSolError> { + let msg = address.abi_encode(); + let sig = { + let sigma_affine: ark_bn254::G1Affine = (*bls_sig).into(); + BLSSignature { + sigma: sigma_affine.into_group(), + } + }; + if !bls_vk.validate(&sig, &msg) { + return Err(StakeTableSolError::InvalidBlsSignature); + } + Ok(()) +} + +fn authenticate_stake_table_validator_event( + account: Address, + bls_vk: G2PointSol, + schnorr_vk: EdOnBN254PointSol, + bls_sig: G1PointSol, + schnorr_sig: &[u8], +) -> Result<(), StakeTableSolError> { + // TODO(alex): simplify this once jellyfish has `VerKey::from_affine()` + let bls_vk = { + let bls_vk_inner: ark_bn254::G2Affine = bls_vk.into(); + let bls_vk_inner = bls_vk_inner.into_group(); + + // the two unwrap are safe since it's BLSPubKey is just a wrapper around G2Projective + let mut ser_bytes: Vec = Vec::new(); + bls_vk_inner.serialize_uncompressed(&mut ser_bytes).unwrap(); + BLSPubKey::deserialize_uncompressed(&ser_bytes[..]).unwrap() + }; + authenticate_bls_sig(&bls_vk, account, &bls_sig)?; + + let schnorr_vk: StateVerKey = schnorr_vk.into(); + authenticate_schnorr_sig(&schnorr_vk, account, schnorr_sig)?; + Ok(()) +} + +/// Errors encountered when processing stake table events +#[derive(Debug, thiserror::Error)] +pub enum StakeTableSolError { + #[error("Failed to deserialize Schnorr signature")] + SchnorrSigDeserializationError(#[from] ark_serialize::SerializationError), + #[error("BLS signature invalid")] + InvalidBlsSignature, + #[error("Schnorr signature invalid")] + InvalidSchnorrSignature(#[from] jf_signature::SignatureError), +} + +impl ValidatorRegisteredV2 { + /// verified the BLS and Schnorr signatures in the event + pub fn authenticate(&self) -> Result<(), StakeTableSolError> { + authenticate_stake_table_validator_event( + self.account, + self.blsVK, + self.schnorrVK, + self.blsSig.into(), + &self.schnorrSig, + )?; + Ok(()) + } +} + +impl ConsensusKeysUpdatedV2 { + /// verified the BLS and Schnorr signatures in the event + pub fn authenticate(&self) -> Result<(), StakeTableSolError> { + authenticate_stake_table_validator_event( + self.account, + self.blsVK, + self.schnorrVK, + self.blsSig.into(), + &self.schnorrSig, + )?; + Ok(()) + } +} + #[cfg(test)] mod test { - use hotshot_types::signature_key::{BLSPrivKey, BLSPubKey}; + use alloy::primitives::{Address, U256}; + use hotshot_types::{ + light_client::StateKeyPair, + signature_key::{BLSKeyPair, BLSPrivKey, BLSPubKey}, + }; + use super::{ + authenticate_bls_sig, authenticate_schnorr_sig, sign_address_bls, sign_address_schnorr, + }; use crate::sol_types::G2PointSol; fn check_round_trip(pk: BLSPubKey) { @@ -52,4 +206,44 @@ mod test { let pk: BLSPubKey = s.parse().unwrap(); check_round_trip(pk); } + + #[test] + fn test_schnorr_sigs() { + for _ in 0..10 { + let key_pair = StateKeyPair::generate(); + let address = Address::random(); + let sig = sign_address_schnorr(&key_pair, address); + authenticate_schnorr_sig(key_pair.ver_key_ref(), address, &sig).unwrap(); + + // signed with wrong key + let sig = sign_address_schnorr(&StateKeyPair::generate(), address); + assert!(authenticate_schnorr_sig(key_pair.ver_key_ref(), address, &sig).is_err()); + + // manipulate one byte + let mut bad_sig: Vec = sig.to_vec(); + bad_sig[0] = bad_sig[0].wrapping_add(1); + assert!(authenticate_schnorr_sig(key_pair.ver_key_ref(), address, &bad_sig).is_err()); + } + } + + #[test] + fn test_bls_sigs() { + let key_pair = BLSKeyPair::generate(&mut rand::thread_rng()); + let address = Address::random(); + let sig = sign_address_bls(&key_pair, address); + authenticate_bls_sig(key_pair.ver_key_ref(), address, &sig).unwrap(); + + // signed with wrong key + assert!(authenticate_bls_sig( + key_pair.ver_key_ref(), + address, + &sign_address_bls(&BLSKeyPair::generate(&mut rand::thread_rng()), address) + ) + .is_err()); + + // tamper with the signature + let mut sig = sig; + sig.x = sig.x.wrapping_add(U256::from(1)); + assert!(authenticate_bls_sig(key_pair.ver_key_ref(), address, &sig).is_err()); + } } diff --git a/contracts/rust/deployer/Cargo.toml b/contracts/rust/deployer/Cargo.toml index 84c9342100..f2277bfa35 100644 --- a/contracts/rust/deployer/Cargo.toml +++ b/contracts/rust/deployer/Cargo.toml @@ -19,3 +19,6 @@ tide-disco = { workspace = true } tokio = { workspace = true } tracing = "0.1.37" vbs = { workspace = true } + +[dev-dependencies] +sequencer-utils = { version = "0.1.0", path = "../../../utils" } diff --git a/contracts/rust/deployer/src/builder.rs b/contracts/rust/deployer/src/builder.rs index e0bee42f97..08504eeebb 100644 --- a/contracts/rust/deployer/src/builder.rs +++ b/contracts/rust/deployer/src/builder.rs @@ -2,13 +2,13 @@ use alloy::{ primitives::{Address, U256}, - providers::WalletProvider, + providers::{Provider, WalletProvider}, }; use anyhow::{Context, Result}; use derive_builder::Builder; use hotshot_contract_adapter::sol_types::{LightClientStateSol, StakeTableStateSol}; -use crate::{Contract, Contracts, HttpProviderWithWallet}; +use crate::{Contract, Contracts}; /// Convenient handler that builds all the input arguments ready to be deployed. /// - `deployer`: deployer's wallet provider @@ -26,8 +26,8 @@ use crate::{Contract, Contracts, HttpProviderWithWallet}; /// - `token_symbol`: symbol of the token #[derive(Builder, Clone)] #[builder(setter(strip_option))] -pub struct DeployerArgs { - deployer: HttpProviderWithWallet, +pub struct DeployerArgs { + deployer: P, #[builder(default)] token_recipient: Option
, #[builder(default)] @@ -54,11 +54,11 @@ pub struct DeployerArgs { token_symbol: Option, } -impl DeployerArgs { +impl DeployerArgs

{ /// deploy target contracts pub async fn deploy(&self, contracts: &mut Contracts, target: Contract) -> Result<()> { let provider = &self.deployer; - let admin = ::default_signer_address(provider); + let admin = provider.default_signer_address(); match target { Contract::FeeContractProxy => { let addr = crate::deploy_fee_contract_proxy(provider, contracts, admin).await?; @@ -162,7 +162,7 @@ impl DeployerArgs { .address(Contract::LightClientProxy) .context("no LightClient proxy address")?; let escrow_period = self.exit_escrow_period.unwrap_or(U256::from(300)); - let addr = crate::deploy_stake_table_proxy( + crate::deploy_stake_table_proxy( provider, contracts, token_addr, @@ -172,8 +172,22 @@ impl DeployerArgs { ) .await?; + // NOTE: we don't transfer ownership to multisig, we only do so after V2 upgrade + }, + Contract::StakeTableV2 => { + crate::upgrade_stake_table_v2(provider, contracts).await?; + if let Some(multisig) = self.multisig { - crate::transfer_ownership(provider, target, addr, multisig).await?; + let stake_table_proxy = contracts + .address(Contract::StakeTableProxy) + .expect("fail to get StakeTableProxy address"); + crate::transfer_ownership( + provider, + Contract::StakeTableProxy, + stake_table_proxy, + multisig, + ) + .await?; } }, _ => { @@ -183,8 +197,8 @@ impl DeployerArgs { Ok(()) } - /// Deploy all contracts - pub async fn deploy_all(&self, contracts: &mut Contracts) -> Result<()> { + /// Deploy all contracts up to and including stake table v1 + pub async fn deploy_to_stake_table_v1(&self, contracts: &mut Contracts) -> Result<()> { self.deploy(contracts, Contract::FeeContractProxy).await?; self.deploy(contracts, Contract::EspTokenProxy).await?; self.deploy(contracts, Contract::LightClientProxy).await?; @@ -192,4 +206,11 @@ impl DeployerArgs { self.deploy(contracts, Contract::StakeTableProxy).await?; Ok(()) } + + /// Deploy all contracts + pub async fn deploy_all(&self, contracts: &mut Contracts) -> Result<()> { + self.deploy_to_stake_table_v1(contracts).await?; + self.deploy(contracts, Contract::StakeTableV2).await?; + Ok(()) + } } diff --git a/contracts/rust/deployer/src/lib.rs b/contracts/rust/deployer/src/lib.rs index d13b408dad..5c122bab34 100644 --- a/contracts/rust/deployer/src/lib.rs +++ b/contracts/rust/deployer/src/lib.rs @@ -106,6 +106,10 @@ pub struct DeployedContracts { #[clap(long, env = Contract::StakeTable)] stake_table: Option

, + /// Use an already-deployed StakeTableV2.sol instead of deploying a new one. + #[clap(long, env = Contract::StakeTableV2)] + stake_table_v2: Option
, + /// Use an already-deployed StakeTable.sol proxy instead of deploying a new one. #[clap(long, env = Contract::StakeTableProxy)] stake_table_proxy: Option
, @@ -136,6 +140,8 @@ pub enum Contract { EspTokenProxy, #[display("ESPRESSO_SEQUENCER_STAKE_TABLE_ADDRESS")] StakeTable, + #[display("ESPRESSO_SEQUENCER_STAKE_TABLE_V2_ADDRESS")] + StakeTableV2, #[display("ESPRESSO_SEQUENCER_STAKE_TABLE_PROXY_ADDRESS")] StakeTableProxy, } @@ -186,6 +192,9 @@ impl From for Contracts { if let Some(addr) = deployed.stake_table { m.insert(Contract::StakeTable, addr); } + if let Some(addr) = deployed.stake_table_v2 { + m.insert(Contract::StakeTableV2, addr); + } if let Some(addr) = deployed.stake_table_proxy { m.insert(Contract::StakeTableProxy, addr); } @@ -634,6 +643,46 @@ pub async fn deploy_stake_table_proxy( Ok(st_proxy_addr) } +/// Upgrade the stake table proxy to use StakeTableV2. +async fn upgrade_stake_table_v2( + provider: impl Provider, + contracts: &mut Contracts, +) -> Result { + let Some(proxy_addr) = contracts.address(Contract::StakeTableProxy) else { + anyhow::bail!("StakeTableProxy not found, can't upgrade") + }; + + let proxy = StakeTable::new(proxy_addr, &provider); + // Deploy the new implementation + let v2_addr = contracts + .deploy( + Contract::StakeTableV2, + StakeTableV2::deploy_builder(&provider), + ) + .await?; + + assert!(is_contract(&provider, v2_addr).await?); + + // invoke upgrade on proxy + let receipt = proxy + .upgradeToAndCall(v2_addr, vec![].into() /* no new init data for V2 */) + .send() + .await? + .get_receipt() + .await?; + + if receipt.inner.is_success() { + // post deploy verification checks + let proxy_as_v2 = StakeTableV2::new(proxy_addr, &provider); + assert_eq!(proxy_as_v2.getVersion().call().await?.majorVersion, 2); + tracing::info!(%v2_addr, "StakeTable successfully upgraded to") + } else { + anyhow::bail!("StakeTable upgrade failed: {:?}", receipt); + } + + Ok(receipt) +} + /// Common logic for any Ownable contract to transfer ownership pub async fn transfer_ownership( provider: impl Provider, @@ -777,11 +826,13 @@ pub async fn deploy_timelock( #[cfg(test)] mod tests { use alloy::{primitives::utils::parse_ether, providers::ProviderBuilder, sol_types::SolValue}; + use sequencer_utils::test_utils::setup_test; use super::*; #[tokio::test] async fn test_is_contract() -> Result<(), anyhow::Error> { + setup_test(); let provider = ProviderBuilder::new().on_anvil_with_wallet(); // test with zero address returns false @@ -802,6 +853,7 @@ mod tests { #[tokio::test] async fn test_is_proxy_contract() -> Result<()> { + setup_test(); let provider = ProviderBuilder::new().on_anvil_with_wallet(); let deployer = provider.get_accounts().await?[0]; @@ -816,6 +868,7 @@ mod tests { #[tokio::test] async fn test_deploy_light_client() -> Result<()> { + setup_test(); let provider = ProviderBuilder::new().on_anvil_with_wallet(); let mut contracts = Contracts::new(); @@ -833,6 +886,7 @@ mod tests { #[tokio::test] async fn test_deploy_mock_light_client_proxy() -> Result<()> { + setup_test(); let provider = ProviderBuilder::new().on_anvil_with_wallet(); let mut contracts = Contracts::new(); @@ -882,6 +936,7 @@ mod tests { #[tokio::test] async fn test_deploy_light_client_proxy() -> Result<()> { + setup_test(); let provider = ProviderBuilder::new().on_anvil_with_wallet(); let mut contracts = Contracts::new(); @@ -934,6 +989,7 @@ mod tests { #[tokio::test] async fn test_deploy_fee_contract_proxy() -> Result<()> { + setup_test(); let provider = ProviderBuilder::new().on_anvil_with_wallet(); let mut contracts = Contracts::new(); let admin = provider.get_accounts().await?[0]; @@ -966,6 +1022,7 @@ mod tests { } async fn test_upgrade_light_client_to_v2_helper(is_mock: bool) -> Result<()> { + setup_test(); let provider = ProviderBuilder::new().on_anvil_with_wallet(); let mut contracts = Contracts::new(); let blocks_per_epoch = 10; // for test @@ -1047,16 +1104,19 @@ mod tests { #[tokio::test] async fn test_upgrade_light_client_to_v2() -> Result<()> { + setup_test(); test_upgrade_light_client_to_v2_helper(false).await } #[tokio::test] async fn test_upgrade_mock_light_client_v2() -> Result<()> { + setup_test(); test_upgrade_light_client_to_v2_helper(true).await } #[tokio::test] async fn test_deploy_token_proxy() -> Result<()> { + setup_test(); let provider = ProviderBuilder::new().on_anvil_with_wallet(); let mut contracts = Contracts::new(); @@ -1096,6 +1156,7 @@ mod tests { #[tokio::test] async fn test_deploy_stake_table_proxy() -> Result<()> { + setup_test(); let provider = ProviderBuilder::new().on_anvil_with_wallet(); let mut contracts = Contracts::new(); @@ -1143,8 +1204,60 @@ mod tests { Ok(()) } + #[tokio::test] + async fn test_upgrade_stake_table_v2() -> Result<()> { + setup_test(); + setup_test(); + let provider = ProviderBuilder::new().on_anvil_with_wallet(); + let mut contracts = Contracts::new(); + + // deploy token + let init_recipient = provider.get_accounts().await?[0]; + let token_owner = Address::random(); + let token_name = "Espresso"; + let token_symbol = "ESP"; + let initial_supply = U256::from(3590000000u64); + let token_addr = deploy_token_proxy( + &provider, + &mut contracts, + token_owner, + init_recipient, + initial_supply, + token_name, + token_symbol, + ) + .await?; + + // deploy light client + let lc_addr = deploy_light_client_contract(&provider, &mut contracts, false).await?; + + // deploy stake table + let exit_escrow_period = U256::from(1000); + let owner = init_recipient; + let stake_table_addr = deploy_stake_table_proxy( + &provider, + &mut contracts, + token_addr, + lc_addr, + exit_escrow_period, + owner, + ) + .await?; + let stake_table = StakeTable::new(stake_table_addr, &provider); + + // upgrade to v2 + upgrade_stake_table_v2(&provider, &mut contracts).await?; + + assert_eq!(stake_table.getVersion().call().await?, (2, 0, 0).into()); + assert_eq!(stake_table.owner().call().await?._0, owner); + assert_eq!(stake_table.token().call().await?._0, token_addr); + assert_eq!(stake_table.lightClient().call().await?._0, lc_addr); + Ok(()) + } + #[tokio::test] async fn test_deploy_timelock() -> Result<()> { + setup_test(); let provider = ProviderBuilder::new().on_anvil_with_wallet(); let mut contracts = Contracts::new(); diff --git a/contracts/src/StakeTableV2.sol b/contracts/src/StakeTableV2.sol index 5fc19443fb..d6f0e8fd5d 100644 --- a/contracts/src/StakeTableV2.sol +++ b/contracts/src/StakeTableV2.sol @@ -9,6 +9,26 @@ import { EdOnBN254 } from "./libraries/EdOnBn254.sol"; import { BN254 } from "bn254/BN254.sol"; import { BLSSig } from "./libraries/BLSSig.sol"; +/// @title Ethereum L1 component of the Espresso Global Confirmation Layer (GCL) stake table. +/// +/// @dev All functions are marked as virtual so that future upgrades can override them. +/// +/// @notice This contract is an upgrade to the original StakeTable contract. On Espresso mainnet we +/// will only use the V2 contract. On decaf the V2 is used to upgrade the V1 that was first deployed +/// with the original proof of stake release. +/// +/// @notice The V2 contract contains the following changes: +/// +/// 1. The functions to register validators and update consensus keys are updated to require both a +/// BLS signature and a Schnorr signature and emit the signatures via events so that the GCL can +/// verify them. The new functions and events have a V2 postfix. After the upgrade components that +/// support registration and key updates must use the V2 functions and listen to the V2 events. The +/// original functions revert with a `DeprecatedFunction` error in V2. +/// +/// 2. The exit escrow period can be updated by the owner of the contract. +/// +/// @notice The StakeTableV2 contract ABI is a superset of the original ABI. Consumers of the +/// contract can use the V2 ABI, even if they would like to maintain backwards compatibility. contract StakeTableV2 is StakeTable { // === Events === @@ -16,11 +36,11 @@ contract StakeTableV2 is StakeTable { /// @notice the blsSig and schnorrSig are validated by the Espresso Network event ValidatorRegisteredV2( address indexed account, - BN254.G2Point blsVk, - EdOnBN254.EdOnBN254Point schnorrVk, + BN254.G2Point blsVK, + EdOnBN254.EdOnBN254Point schnorrVK, uint16 commission, BN254.G1Point blsSig, - EdOnBN254.EdOnBN254Point schnorrSig + bytes schnorrSig ); /// @notice A validator updates their consensus keys @@ -30,7 +50,7 @@ contract StakeTableV2 is StakeTable { BN254.G2Point blsVK, EdOnBN254.EdOnBN254Point schnorrVK, BN254.G1Point blsSig, - EdOnBN254.EdOnBN254Point schnorrSig + bytes schnorrSig ); /// @notice The exit escrow period is updated @@ -65,11 +85,11 @@ contract StakeTableV2 is StakeTable { /// @param blsSig The BLS signature that authenticates the BLS VK /// @param schnorrSig The Schnorr signature that authenticates the Schnorr VK /// @param commission in % with 2 decimals, from 0.00% (value 0) to 100% (value 10_000) - function registerValidator( + function registerValidatorV2( BN254.G2Point memory blsVK, EdOnBN254.EdOnBN254Point memory schnorrVK, BN254.G1Point memory blsSig, - EdOnBN254.EdOnBN254Point memory schnorrSig, + bytes memory schnorrSig, uint16 commission ) external virtual { address validator = msg.sender; @@ -99,11 +119,11 @@ contract StakeTableV2 is StakeTable { /// @param schnorrVK The new Schnorr verification key /// @param blsSig The BLS signature that authenticates the blsVK /// @param schnorrSig The Schnorr signature that authenticates the schnorrVK - function updateConsensusKeys( + function updateConsensusKeysV2( BN254.G2Point memory blsVK, EdOnBN254.EdOnBN254Point memory schnorrVK, BN254.G1Point memory blsSig, - EdOnBN254.EdOnBN254Point memory schnorrSig + bytes memory schnorrSig ) external virtual { address validator = msg.sender; diff --git a/crates/hotshot/types/src/signature_key.rs b/crates/hotshot/types/src/signature_key.rs index bd102ed3e1..e2cf4546c0 100644 --- a/crates/hotshot/types/src/signature_key.rs +++ b/crates/hotshot/types/src/signature_key.rs @@ -38,6 +38,8 @@ pub type BLSPubKey = VerKey; pub type BLSKeyPair = KeyPair; /// Public parameters for BLS signature scheme pub type BLSPublicParam = (); +/// BLS signature type for consensus votes +pub type BLSSignature = jf_signature::bls_over_bn254::Signature; impl PrivateSignatureKey for BLSPrivKey { fn to_bytes(&self) -> Vec { diff --git a/docker-compose.yaml b/docker-compose.yaml index 3c1a4952f8..af0e1ef3ee 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -15,7 +15,7 @@ services: deploy-sequencer-contracts: image: ghcr.io/espressosystems/espresso-sequencer/deploy:${DOCKER_TAG:-main} - command: deploy --deploy-fee --deploy-esp-token --deploy-stake-table + command: deploy --deploy-fee --deploy-esp-token --deploy-stake-table --upgrade-stake-table-v2 environment: - ESPRESSO_SEQUENCER_ETH_MULTISIG_ADDRESS - ESPRESSO_SEQUENCER_L1_PROVIDER diff --git a/justfile b/justfile index 60a69d81ee..845ad232ef 100644 --- a/justfile +++ b/justfile @@ -15,14 +15,20 @@ demo-native *args: (build "test") fmt: cargo fmt --all -lint: +fix *args: + just clippy --fix {{args}} + +lint *args: + just clippy -- -D warnings + +clippy *args: #!/usr/bin/env bash set -euxo pipefail # Use the same target dir for both `clippy` invocations export CARGO_TARGET_DIR=${CARGO_TARGET_DIR:-target} - cargo clippy --workspace --features testing --all-targets -- -D warnings - cargo clippy --workspace --features "embedded-db testing" --all-targets -- -D warnings - cargo clippy --workspace --all-targets --manifest-path sequencer-sqlite/Cargo.toml -- -D warnings + cargo clippy --workspace --features testing --all-targets {{args}} + cargo clippy --workspace --features "embedded-db testing" --all-targets {{args}} + cargo clippy --workspace --all-targets --manifest-path sequencer-sqlite/Cargo.toml {{args}} build profile="dev" features="": #!/usr/bin/env bash @@ -84,11 +90,6 @@ test-all: test-integration: (build "test" "--features fee") INTEGRATION_TEST_SEQUENCER_VERSION=2 cargo nextest run -p tests --nocapture --profile integration test_native_demo_basic -clippy: - @echo 'features: "embedded-db"' - cargo clippy --workspace --features embedded-db --all-targets -- -D warnings - cargo clippy --workspace -- -D warnings - check-features *args: cargo hack check --each-feature {{args}} diff --git a/process-compose.yaml b/process-compose.yaml index 621e9eb1fe..b3fbd2bb19 100644 --- a/process-compose.yaml +++ b/process-compose.yaml @@ -43,7 +43,7 @@ processes: ESPRESSO_SEQUENCER_FEE_CONTRACT_PROXY_ADDRESS ESPRESSO_SEQUENCER_ESP_TOKEN_PROXY_ADDRESS ESPRESSO_SEQUENCER_STAKE_TABLE_PROXY_ADDRESS - && deploy --deploy-fee --deploy-esp-token --deploy-stake-table + && deploy --deploy-fee --deploy-esp-token --deploy-stake-table --upgrade-stake-table-v2 namespace: setup depends_on: demo-l1-network: diff --git a/sequencer-sqlite/Cargo.lock b/sequencer-sqlite/Cargo.lock index 337ac2d253..06838fefd6 100644 --- a/sequencer-sqlite/Cargo.lock +++ b/sequencer-sqlite/Cargo.lock @@ -4189,6 +4189,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "generic-tests" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9ff6d6584f4f6fa911d5e07856abf1a48dc5599b3734f2eaea130f2c3baa989" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -4684,11 +4695,13 @@ dependencies = [ "hotshot-types", "jf-pcs", "jf-plonk", + "jf-signature 0.2.0", "jf-utils", "num-bigint", "num-traits", "rand 0.8.5", "serde", + "thiserror 1.0.69", ] [[package]] @@ -8451,6 +8464,12 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + [[package]] name = "rend" version = "0.4.2" @@ -8678,6 +8697,47 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rstest" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fc39292f8613e913f7df8fa892b8944ceb47c247b78e1b1ae2f09e019be789d" +dependencies = [ + "futures-timer", + "futures-util", + "rstest_macros", + "rustc_version 0.4.1", +] + +[[package]] +name = "rstest_macros" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f168d99749d307be9de54d23fd226628d99768225ef08f6ffb52e0182a27746" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version 0.4.1", + "syn 2.0.101", + "unicode-ident", +] + +[[package]] +name = "rstest_reuse" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a8fb4672e840a587a66fc577a5491375df51ddb88f2a2c2a792598c326fe14" +dependencies = [ + "quote", + "rand 0.8.5", + "syn 2.0.101", +] + [[package]] name = "rtnetlink" version = "0.13.1" @@ -9147,6 +9207,7 @@ dependencies = [ "espresso-contract-deployer", "espresso-types", "futures", + "generic-tests", "hotshot", "hotshot-builder-core-refactored", "hotshot-contract-adapter", @@ -9173,6 +9234,8 @@ dependencies = [ "rand_chacha 0.3.1", "rand_distr", "request-response", + "rstest", + "rstest_reuse", "semver 1.0.26", "sequencer-utils", "serde", @@ -9878,8 +9941,7 @@ version = "0.1.0" dependencies = [ "alloy", "anyhow", - "ark-ec", - "ark-ed-on-bn254", + "ark-serialize 0.4.2", "clap 4.5.37", "clap-serde", "clap-serde-derive", @@ -9897,6 +9959,8 @@ dependencies = [ "portpicker", "rand 0.8.5", "rand_chacha 0.3.1", + "rstest", + "rstest_reuse", "rust_decimal", "sequencer-utils", "serde", diff --git a/sequencer/Cargo.toml b/sequencer/Cargo.toml index 4f562b9e7a..cbfaffc8bb 100644 --- a/sequencer/Cargo.toml +++ b/sequencer/Cargo.toml @@ -72,6 +72,7 @@ dotenvy = { workspace = true } espresso-contract-deployer = { path = "../contracts/rust/deployer" } espresso-types = { path = "../types" } futures = { workspace = true } +generic-tests = "0.1.3" hotshot = { workspace = true } hotshot-builder-core-refactored = { path = "../hotshot-builder-core-refactored" } @@ -103,6 +104,8 @@ rand = { workspace = true } rand_chacha = { workspace = true } rand_distr = { workspace = true } request-response = { path = "../request-response" } +rstest = { workspace = true } +rstest_reuse = { workspace = true } semver = { workspace = true } sequencer-utils = { path = "../utils" } serde = { workspace = true } diff --git a/sequencer/src/api.rs b/sequencer/src/api.rs index 305167fc76..109844345f 100644 --- a/sequencer/src/api.rs +++ b/sequencer/src/api.rs @@ -809,6 +809,7 @@ pub mod test_helpers { stream::StreamExt, }; use hotshot::types::{Event, EventType}; + use hotshot_contract_adapter::stake_table::StakeTableContractVersion; use hotshot_types::{ event::LeafInfo, traits::{metrics::NoMetrics, node_implementation::ConsensusTime}, @@ -956,6 +957,7 @@ pub mod test_helpers { pub async fn pos_hook( self, delegation_config: DelegationConfig, + stake_table_version: StakeTableContractVersion, ) -> anyhow::Result { if ::Upgrade::VERSION < EpochVersion::VERSION && ::Base::VERSION < EpochVersion::VERSION @@ -992,9 +994,14 @@ pub mod test_helpers { .epoch_start_block(epoch_start_block) .build() .unwrap(); - args.deploy_all(&mut contracts) - .await - .expect("failed to deploy all contracts"); + + match stake_table_version { + StakeTableContractVersion::V1 => { + args.deploy_to_stake_table_v1(&mut contracts).await + }, + StakeTableContractVersion::V2 => args.deploy_all(&mut contracts).await, + } + .context("failed to deploy contracts")?; let stake_table_address = contracts .address(Contract::StakeTableProxy) @@ -3155,7 +3162,7 @@ mod test { let config = TestNetworkConfigBuilder::default() .api_config(options) .network_config(network_config.clone()) - .pos_hook::(DelegationConfig::VariableAmounts) + .pos_hook::(DelegationConfig::VariableAmounts, Default::default()) .await .expect("Pos Deployment") .build(); @@ -3254,7 +3261,7 @@ mod test { &NoMetrics, ) })) - .pos_hook::(DelegationConfig::VariableAmounts) + .pos_hook::(DelegationConfig::VariableAmounts, Default::default()) .await .unwrap() .build(); @@ -3346,7 +3353,7 @@ mod test { &NoMetrics, ) })) - .pos_hook::(DelegationConfig::MultipleDelegators) + .pos_hook::(DelegationConfig::MultipleDelegators, Default::default()) .await .unwrap() .build(); @@ -3465,7 +3472,7 @@ mod test { &NoMetrics, ) })) - .pos_hook::(DelegationConfig::MultipleDelegators) + .pos_hook::(DelegationConfig::MultipleDelegators, Default::default()) .await .unwrap() .build(); @@ -3578,7 +3585,7 @@ mod test { &NoMetrics, ) })) - .pos_hook::(DelegationConfig::MultipleDelegators) + .pos_hook::(DelegationConfig::MultipleDelegators, Default::default()) .await .unwrap() .build(); @@ -3789,7 +3796,7 @@ mod test { &NoMetrics, ) })) - .pos_hook::(DelegationConfig::MultipleDelegators) + .pos_hook::(DelegationConfig::MultipleDelegators, Default::default()) .await .unwrap() .build(); @@ -3866,7 +3873,7 @@ mod test { .network_config(network_config) .persistences(persistence_options.clone()) .catchups(catchup_peers) - .pos_hook::(DelegationConfig::MultipleDelegators) + .pos_hook::(DelegationConfig::MultipleDelegators, Default::default()) .await .unwrap() .build(); @@ -4005,7 +4012,7 @@ mod test { .network_config(network_config) .persistences(persistence_options.clone()) .catchups(catchup_peers) - .pos_hook::(DelegationConfig::MultipleDelegators) + .pos_hook::(DelegationConfig::MultipleDelegators, Default::default()) .await .unwrap() .build(); diff --git a/sequencer/src/bin/deploy.rs b/sequencer/src/bin/deploy.rs index 3d61e89fdd..a3783040e6 100644 --- a/sequencer/src/bin/deploy.rs +++ b/sequencer/src/bin/deploy.rs @@ -105,6 +105,8 @@ struct Options { deploy_esp_token: bool, #[clap(long, default_value = "false")] deploy_stake_table: bool, + #[clap(long, default_value = "false")] + upgrade_stake_table_v2: bool, /// Write deployment results to OUT as a .env file. /// @@ -245,6 +247,9 @@ async fn main() -> anyhow::Result<()> { args.deploy(&mut contracts, Contract::StakeTableProxy) .await?; } + if opt.upgrade_stake_table_v2 { + args.deploy(&mut contracts, Contract::StakeTableV2).await?; + } // finally print out or persist deployed addresses if let Some(out) = &opt.out { diff --git a/sequencer/src/persistence.rs b/sequencer/src/persistence.rs index 4dac4af18c..87b9268b92 100644 --- a/sequencer/src/persistence.rs +++ b/sequencer/src/persistence.rs @@ -20,32 +20,8 @@ pub trait ChainConfigPersistence: Sized + Send + Sync { async fn insert_chain_config(&mut self, chain_config: ChainConfig) -> anyhow::Result<()>; } -#[cfg(any(test, feature = "testing"))] -mod testing { - - use espresso_types::{ - traits::MembershipPersistence, - v0::traits::{PersistenceOptions, SequencerPersistence}, - }; - - use super::*; - #[allow(dead_code)] - #[async_trait] - pub trait TestablePersistence: SequencerPersistence + MembershipPersistence { - type Storage: Sync; - - async fn tmp_storage() -> Self::Storage; - fn options(storage: &Self::Storage) -> impl PersistenceOptions; - - async fn connect(storage: &Self::Storage) -> Self { - Self::options(storage).create().await.unwrap() - } - } -} - #[cfg(test)] -#[espresso_macros::generic_tests] -mod persistence_tests { +mod tests { use std::{collections::BTreeMap, marker::PhantomData, sync::Arc, time::Duration}; use alloy::{ @@ -55,13 +31,17 @@ mod persistence_tests { }; use anyhow::bail; use async_lock::{Mutex, RwLock}; + use async_trait::async_trait; use committable::{Commitment, Committable}; use espresso_contract_deployer::{ builder::DeployerArgsBuilder, network_config::light_client_genesis_from_stake_table, Contract, Contracts, }; use espresso_types::{ - traits::{EventConsumer, EventsPersistenceRead, NullEventConsumer, PersistenceOptions}, + traits::{ + EventConsumer, EventsPersistenceRead, MembershipPersistence, NullEventConsumer, + PersistenceOptions, SequencerPersistence, + }, v0_3::{StakeTableFetcher, Validator}, Event, L1Client, L1ClientOptions, Leaf, Leaf2, NodeState, PubKey, SeqTypes, SequencerVersions, ValidatedState, @@ -71,6 +51,7 @@ mod persistence_tests { types::{BLSPubKey, SignatureKey}, InitializerEpochInfo, }; + use hotshot_contract_adapter::stake_table::StakeTableContractVersion; use hotshot_example_types::node_types::TestVersions; use hotshot_query_service::{availability::BlockQueryData, testing::mocks::MockVersions}; use hotshot_types::{ @@ -100,12 +81,10 @@ mod persistence_tests { use sequencer_utils::test_utils::setup_test; use staking_cli::demo::{setup_stake_table_contract_for_test, DelegationConfig}; use surf_disco::Client; - use testing::TestablePersistence; use tide_disco::error::ServerError; use tokio::{spawn, time::sleep}; use vbs::version::{StaticVersion, StaticVersionType, Version}; - use super::*; use crate::{ api::{ test_helpers::{TestNetwork, TestNetworkConfigBuilder, STAKE_TABLE_CAPACITY_FOR_TEST}, @@ -116,6 +95,25 @@ mod persistence_tests { SequencerApiVersion, RECENT_STAKE_TABLES_LIMIT, }; + #[async_trait] + pub trait TestablePersistence: SequencerPersistence + MembershipPersistence { + type Storage: Sync; + + async fn tmp_storage() -> Self::Storage; + fn options(storage: &Self::Storage) -> impl PersistenceOptions; + + async fn connect(storage: &Self::Storage) -> Self { + Self::options(storage).create().await.unwrap() + } + } + + #[rstest_reuse::template] + #[rstest::rstest] + #[case(PhantomData::)] + #[case(PhantomData::)] + #[tokio::test(flavor = "multi_thread")] + pub fn persistence_types(#[case] _p: PhantomData

) {} + #[derive(Clone, Debug, Default)] struct EventCollector { events: Arc>>, @@ -145,8 +143,8 @@ mod persistence_tests { } } - #[tokio::test(flavor = "multi_thread")] - pub async fn test_voted_view() { + #[rstest_reuse::apply(persistence_types)] + pub async fn test_voted_view(_p: PhantomData

) { setup_test(); let tmp = P::tmp_storage().await; @@ -188,8 +186,8 @@ mod persistence_tests { ); } - #[tokio::test(flavor = "multi_thread")] - pub async fn test_restart_view() { + #[rstest_reuse::apply(persistence_types)] + pub async fn test_restart_view(_p: PhantomData

) { setup_test(); let tmp = P::tmp_storage().await; @@ -250,8 +248,9 @@ mod persistence_tests { view2 + 1 ); } - #[tokio::test(flavor = "multi_thread")] - pub async fn test_store_drb_input() { + + #[rstest_reuse::apply(persistence_types)] + pub async fn test_store_drb_input(_p: PhantomData

) { use hotshot_types::drb::DrbInput; setup_test(); @@ -295,8 +294,8 @@ mod persistence_tests { assert_eq!(storage.load_drb_input(10).await.unwrap(), drb_input_3); } - #[tokio::test(flavor = "multi_thread")] - pub async fn test_epoch_info() { + #[rstest_reuse::apply(persistence_types)] + pub async fn test_epoch_info(_p: PhantomData

) { setup_test(); let tmp = P::tmp_storage().await; let storage = P::connect(&tmp).await; @@ -408,8 +407,8 @@ mod persistence_tests { } } - #[tokio::test(flavor = "multi_thread")] - pub async fn test_append_and_decide() { + #[rstest_reuse::apply(persistence_types)] + pub async fn test_append_and_decide(_p: PhantomData

) { setup_test(); let tmp = P::tmp_storage().await; @@ -789,8 +788,8 @@ mod persistence_tests { ); } - #[tokio::test(flavor = "multi_thread")] - pub async fn test_upgrade_certificate() { + #[rstest_reuse::apply(persistence_types)] + pub async fn test_upgrade_certificate(_p: PhantomData

) { setup_test(); let tmp = P::tmp_storage().await; @@ -838,8 +837,8 @@ mod persistence_tests { assert_eq!(view_number, new_view_number_for_certificate); } - #[tokio::test(flavor = "multi_thread")] - pub async fn test_next_epoch_quorum_certificate() { + #[rstest_reuse::apply(persistence_types)] + pub async fn test_next_epoch_quorum_certificate(_p: PhantomData

) { setup_test(); let tmp = P::tmp_storage().await; @@ -900,8 +899,10 @@ mod persistence_tests { assert_eq!(view_number, new_view_number_for_qc); } - #[tokio::test(flavor = "multi_thread")] - pub async fn test_decide_with_failing_event_consumer() { + #[rstest_reuse::apply(persistence_types)] + pub async fn test_decide_with_failing_event_consumer( + _p: PhantomData

, + ) { #[derive(Clone, Copy, Debug)] struct FailConsumer; @@ -1119,8 +1120,8 @@ mod persistence_tests { } } - #[tokio::test(flavor = "multi_thread")] - pub async fn test_pruning() { + #[rstest_reuse::apply(persistence_types)] + pub async fn test_pruning(_p: PhantomData

) { setup_test(); let tmp = P::tmp_storage().await; @@ -1300,8 +1301,11 @@ mod persistence_tests { // test for validating stake table event fetching from persistence, // ensuring that persisted data matches the on-chain events and that event fetcher work correctly. - #[tokio::test(flavor = "multi_thread")] + #[rstest_reuse::apply(persistence_types)] pub async fn test_stake_table_fetching_from_persistence( + #[values(StakeTableContractVersion::V1, StakeTableContractVersion::V2)] + stake_table_version: StakeTableContractVersion, + _p: PhantomData

, ) -> anyhow::Result<()> { setup_test(); @@ -1336,7 +1340,7 @@ mod persistence_tests { .api_config(query_api_options) .network_config(network_config.clone()) .persistences(persistence_options.clone()) - .pos_hook::(DelegationConfig::MultipleDelegators) + .pos_hook::(DelegationConfig::MultipleDelegators, stake_table_version) .await .expect("Pos deployment failed") .build(); @@ -1425,9 +1429,15 @@ mod persistence_tests { Ok(()) } - #[tokio::test(flavor = "multi_thread")] - pub async fn test_stake_table_background_fetching() -> anyhow::Result<()> - { + #[rstest_reuse::apply(persistence_types)] + pub async fn test_stake_table_background_fetching( + #[values(StakeTableContractVersion::V1, StakeTableContractVersion::V2)] + stake_table_version: StakeTableContractVersion, + _p: PhantomData

, + ) -> anyhow::Result<()> { + use espresso_types::v0_3::ChainConfig; + use hotshot_contract_adapter::stake_table::StakeTableContractVersion; + setup_test(); let blocks_per_epoch = 10; @@ -1467,16 +1477,19 @@ mod persistence_tests { .epoch_start_block(1) .build() .unwrap(); - args.deploy_all(&mut contracts) - .await - .expect("failed to deploy all contracts"); + + match stake_table_version { + StakeTableContractVersion::V1 => args.deploy_to_stake_table_v1(&mut contracts).await, + StakeTableContractVersion::V2 => args.deploy_all(&mut contracts).await, + } + .expect("contracts deployed"); let st_addr = contracts .address(Contract::StakeTableProxy) - .expect("StakeTableProxy address not found"); + .expect("StakeTableProxy deployed"); let token_addr = contracts .address(Contract::EspTokenProxy) - .expect("EspTokenProxy address not found"); + .expect("EspTokenProxy deployed"); let l1_url = network_config.l1_url().clone(); // new block every 1s @@ -1575,8 +1588,10 @@ mod persistence_tests { Ok(()) } - #[tokio::test(flavor = "multi_thread")] - pub async fn test_membership_persistence() -> anyhow::Result<()> { + #[rstest_reuse::apply(persistence_types)] + pub async fn test_membership_persistence( + _p: PhantomData

, + ) -> anyhow::Result<()> { setup_test(); let tmp = P::tmp_storage().await; diff --git a/sequencer/src/persistence/fs.rs b/sequencer/src/persistence/fs.rs index 5cd91eedb8..cf406be546 100644 --- a/sequencer/src/persistence/fs.rs +++ b/sequencer/src/persistence/fs.rs @@ -1886,36 +1886,6 @@ fn epoch_files( })) } -#[cfg(test)] -mod testing { - use tempfile::TempDir; - - use super::{super::testing::TestablePersistence, *}; - - #[async_trait] - impl TestablePersistence for Persistence { - type Storage = TempDir; - - async fn tmp_storage() -> Self::Storage { - TempDir::new().unwrap() - } - - fn options(storage: &Self::Storage) -> impl PersistenceOptions { - Options::new(storage.path().into()) - } - } -} - -#[cfg(test)] -mod generic_tests { - use super::{super::persistence_tests, Persistence}; - // For some reason this is the only way to import the macro defined in another module of this - // crate. - use crate::*; - - instantiate_persistence_tests!(Persistence); -} - #[cfg(test)] mod test { use std::marker::PhantomData; @@ -1936,10 +1906,24 @@ mod test { use jf_vid::VidScheme; use sequencer_utils::test_utils::setup_test; use serde_json::json; + use tempfile::TempDir; use vbs::version::StaticVersionType; use super::*; - use crate::{persistence::testing::TestablePersistence, BLSPubKey}; + use crate::{persistence::tests::TestablePersistence, BLSPubKey}; + + #[async_trait] + impl TestablePersistence for Persistence { + type Storage = TempDir; + + async fn tmp_storage() -> Self::Storage { + TempDir::new().unwrap() + } + + fn options(storage: &Self::Storage) -> impl PersistenceOptions { + Options::new(storage.path().into()) + } + } #[test] fn test_config_migrations_add_builder_urls() { diff --git a/sequencer/src/persistence/sql.rs b/sequencer/src/persistence/sql.rs index c476ed75e7..b050f51d12 100644 --- a/sequencer/src/persistence/sql.rs +++ b/sequencer/src/persistence/sql.rs @@ -2520,7 +2520,8 @@ async fn fetch_leaf_from_proposals( mod testing { use hotshot_query_service::data_source::storage::sql::testing::TmpDb; - use super::{super::testing::TestablePersistence, *}; + use super::*; + use crate::persistence::tests::TestablePersistence; #[async_trait] impl TestablePersistence for Persistence { @@ -2555,16 +2556,6 @@ mod testing { } } -#[cfg(test)] -mod generic_tests { - use super::{super::persistence_tests, Persistence}; - // For some reason this is the only way to import the macro defined in another module of this - // crate. - use crate::*; - - instantiate_persistence_tests!(Persistence); -} - #[cfg(test)] mod test { @@ -2595,7 +2586,7 @@ mod test { use vbs::version::StaticVersionType; use super::*; - use crate::{persistence::testing::TestablePersistence, BLSPubKey, PubKey}; + use crate::{persistence::tests::TestablePersistence as _, BLSPubKey, PubKey}; #[tokio::test(flavor = "multi_thread")] async fn test_quorum_proposals_leaf_hash_migration() { diff --git a/staking-cli/Cargo.toml b/staking-cli/Cargo.toml index a13b2ed56f..ced6e166b8 100644 --- a/staking-cli/Cargo.toml +++ b/staking-cli/Cargo.toml @@ -8,8 +8,7 @@ description = "A CLI to interact with the Espresso stake table contract" [dependencies] alloy = { workspace = true } anyhow = { workspace = true } -ark-ec = { workspace = true } -ark-ed-on-bn254 = { workspace = true } +ark-serialize = { workspace = true } clap = { workspace = true } clap-serde = "0.5.1" clap-serde-derive = "0.2.1" @@ -27,6 +26,8 @@ jf-signature = { workspace = true, features = ["bls", "schnorr"] } portpicker = { workspace = true } rand = { workspace = true } rand_chacha = { workspace = true } +rstest = { workspace = true } +rstest_reuse = { workspace = true } rust_decimal = "1.36.0" sequencer-utils = { version = "0.1.0", path = "../utils" } serde = { workspace = true } diff --git a/staking-cli/src/demo.rs b/staking-cli/src/demo.rs index b013dd7cfc..8e79a18739 100644 --- a/staking-cli/src/demo.rs +++ b/staking-cli/src/demo.rs @@ -143,7 +143,7 @@ pub async fn setup_stake_table_contract_for_test( commission, validator_address, bls_key_pair, - state_key_pair.ver_key(), + state_key_pair, ) .await?; assert!(receipt.status()); diff --git a/staking-cli/src/deploy.rs b/staking-cli/src/deploy.rs index 23d29c16fe..946fd0627d 100644 --- a/staking-cli/src/deploy.rs +++ b/staking-cli/src/deploy.rs @@ -14,10 +14,20 @@ use alloy::{ signers::local::PrivateKeySigner, }; use anyhow::Result; -use espresso_contract_deployer::build_signer; -use hotshot_contract_adapter::sol_types::{ERC1967Proxy, EspToken, StakeTable}; +use espresso_contract_deployer::{ + build_signer, builder::DeployerArgsBuilder, + network_config::light_client_genesis_from_stake_table, Contract, Contracts, +}; +use hotshot_contract_adapter::{ + sol_types::{ + EspToken::{self, EspTokenInstance}, + StakeTable, + }, + stake_table::StakeTableContractVersion, +}; +use hotshot_state_prover::mock_ledger::STAKE_TABLE_CAPACITY_FOR_TEST; use hotshot_types::light_client::StateKeyPair; -use rand::{rngs::StdRng, CryptoRng, RngCore, SeedableRng as _}; +use rand::{rngs::StdRng, CryptoRng, Rng as _, RngCore, SeedableRng as _}; use url::Url; use crate::{parse::Commission, registration::register_validator, BLSKeyPair, DEV_MNEMONIC}; @@ -28,8 +38,6 @@ type TestProvider = FillProvider< Ethereum, >; -type SchnorrKeyPair = jf_signature::schnorr::KeyPair; - #[derive(Debug, Clone)] pub struct TestSystem { pub provider: TestProvider, @@ -47,6 +55,12 @@ pub struct TestSystem { impl TestSystem { pub async fn deploy() -> Result { + Self::deploy_version(StakeTableContractVersion::V2).await + } + + pub async fn deploy_version( + stake_table_contract_version: StakeTableContractVersion, + ) -> Result { let exit_escrow_period = Duration::from_secs(1); let port = portpicker::pick_unused_port().unwrap(); // Spawn anvil @@ -64,45 +78,45 @@ impl TestSystem { "Signer address mismatch" ); - // `EspToken.sol` - let token_impl = EspToken::deploy(provider.clone()).await?; - let initial_supply = U256::from(3590000000u64); - let token_name = "Espresso".to_string(); - let token_symbol = "ESP".to_string(); - let data = token_impl - .initialize( - deployer_address, - deployer_address, - initial_supply, - token_name, - token_symbol, - ) - .calldata() - .clone(); - - let token_proxy = - ERC1967Proxy::deploy(provider.clone(), *token_impl.address(), data).await?; - let token = EspToken::new(*token_proxy.address(), provider.clone()); - - // `StakeTable.sol` - let stake_table_impl = StakeTable::deploy(provider.clone()).await?; - let data = stake_table_impl - .initialize( - *token_proxy.address(), - "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF".parse()?, // fake LC address - U256::from(exit_escrow_period.as_secs()), - deployer_address, - ) - .calldata() - .clone(); - - let st_proxy = - ERC1967Proxy::deploy(provider.clone(), *stake_table_impl.address(), data).await?; + // Create a fake stake table to create a genesis state. This is fine because we don't + // currently use the light client contract. Will need to be updated once we implement + // slashing and call the light client contract from the stake table contract. + let blocks_per_epoch = 100; + let epoch_start_block = 1; + let (genesis_state, genesis_stake) = light_client_genesis_from_stake_table( + &Default::default(), + STAKE_TABLE_CAPACITY_FOR_TEST, + ) + .unwrap(); + + let mut contracts = Contracts::new(); + let args = DeployerArgsBuilder::default() + .deployer(provider.clone()) + .mock_light_client(true) + .genesis_lc_state(genesis_state) + .genesis_st_state(genesis_stake) + .blocks_per_epoch(blocks_per_epoch) + .epoch_start_block(epoch_start_block) + .exit_escrow_period(U256::from(exit_escrow_period.as_secs())) + .build() + .unwrap(); + + match stake_table_contract_version { + StakeTableContractVersion::V1 => args.deploy_to_stake_table_v1(&mut contracts).await?, + StakeTableContractVersion::V2 => args.deploy_all(&mut contracts).await?, + }; + + let stake_table = contracts + .address(Contract::StakeTableProxy) + .expect("StakeTableProxy deployed"); + let token = contracts + .address(Contract::EspTokenProxy) + .expect("EspTokenProxy deployed"); let approval_amount = parse_ether("1000000")?; // Approve the stake table contract so it can transfer tokens to itself - let receipt = token - .approve(*st_proxy.address(), approval_amount) + let receipt = EspTokenInstance::new(token, &provider) + .approve(stake_table, approval_amount) .send() .await? .get_receipt() @@ -116,8 +130,8 @@ impl TestSystem { provider, signer, deployer_address, - token: *token_proxy.address(), - stake_table: *st_proxy.address(), + token, + stake_table, exit_escrow_period, rpc_url, bls_key_pair, @@ -134,7 +148,7 @@ impl TestSystem { ( PrivateKeySigner::random_with(rng), BLSKeyPair::generate(rng), - SchnorrKeyPair::generate(rng).into(), + StateKeyPair::generate_from_seed(rng.gen()), ) } @@ -145,7 +159,7 @@ impl TestSystem { self.commission, self.deployer_address, self.bls_key_pair.clone(), - self.state_key_pair.ver_key(), + self.state_key_pair.clone(), ) .await?; assert!(receipt.status()); diff --git a/staking-cli/src/lib.rs b/staking-cli/src/lib.rs index bfd73fdff1..4aa3fe4d2b 100644 --- a/staking-cli/src/lib.rs +++ b/staking-cli/src/lib.rs @@ -11,10 +11,7 @@ use anyhow::{bail, Result}; use clap::{Parser, Subcommand}; use clap_serde_derive::ClapSerde; use demo::DelegationConfig; -pub(crate) use hotshot_types::{ - light_client::{StateSignKey, StateVerKey}, - signature_key::BLSPrivKey, -}; +pub(crate) use hotshot_types::{light_client::StateSignKey, signature_key::BLSPrivKey}; pub(crate) use jf_signature::bls_over_bn254::KeyPair as BLSKeyPair; use parse::Commission; use sequencer_utils::logging; diff --git a/staking-cli/src/main.rs b/staking-cli/src/main.rs index a728790c85..8b544e03dd 100644 --- a/staking-cli/src/main.rs +++ b/staking-cli/src/main.rs @@ -14,6 +14,7 @@ use hotshot_contract_adapter::{ evm::DecodeRevert as _, sol_types::EspToken::{self, EspTokenErrors}, }; +use hotshot_types::light_client::StateKeyPair; use staking_cli::{ claim::{claim_validator_exit, claim_withdrawal}, delegation::{approve, delegate, undelegate}, @@ -252,7 +253,7 @@ pub async fn main() -> Result<()> { commission, account, (consensus_private_key).into(), - (&state_private_key).into(), + StateKeyPair::from_sign_key(state_private_key), ) .await }, @@ -266,7 +267,7 @@ pub async fn main() -> Result<()> { stake_table_addr, account, (consensus_private_key).into(), - (&state_private_key).into(), + StateKeyPair::from_sign_key(state_private_key), ) .await }, diff --git a/staking-cli/src/registration.rs b/staking-cli/src/registration.rs index 360b7693c8..042df255cf 100644 --- a/staking-cli/src/registration.rs +++ b/staking-cli/src/registration.rs @@ -1,31 +1,40 @@ use alloy::{ - primitives::Address, providers::Provider, rpc::types::TransactionReceipt, - sol_types::SolValue as _, + primitives::{Address, Bytes}, + providers::Provider, + rpc::types::TransactionReceipt, }; use anyhow::Result; -use ark_ec::CurveGroup; use hotshot_contract_adapter::{ evm::DecodeRevert as _, sol_types::{ EdOnBN254PointSol, G1PointSol, G2PointSol, - StakeTable::{self, StakeTableErrors}, + StakeTableV2::{self, StakeTableV2Errors}, }, + stake_table::{sign_address_bls, sign_address_schnorr, StakeTableContractVersion}, }; -use jf_signature::constants::CS_ID_BLS_BN254; +use hotshot_types::{light_client::StateKeyPair, signature_key::BLSKeyPair}; -use crate::{parse::Commission, BLSKeyPair, StateVerKey}; +use crate::parse::Commission; +/// The ver_key and signature as types that contract bindings expect fn prepare_bls_payload( bls_key_pair: &BLSKeyPair, validator_address: Address, ) -> (G2PointSol, G1PointSol) { - let bls_vk_sol: G2PointSol = bls_key_pair.ver_key().to_affine().into(); - let sig_sol: G1PointSol = bls_key_pair - .sign(&validator_address.abi_encode(), CS_ID_BLS_BN254) - .sigma - .into_affine() - .into(); - (bls_vk_sol, sig_sol) + ( + bls_key_pair.ver_key().to_affine().into(), + sign_address_bls(bls_key_pair, validator_address), + ) +} + +// The ver_key and signature as types that contract bindings expect +fn prepare_schnorr_payload( + schnorr_key_pair: &StateKeyPair, + validator_address: Address, +) -> (EdOnBN254PointSol, Bytes) { + let schnorr_vk_sol: EdOnBN254PointSol = schnorr_key_pair.ver_key().to_affine().into(); + let sig = sign_address_schnorr(schnorr_key_pair, validator_address); + (schnorr_vk_sol, sig) } pub async fn register_validator( @@ -34,23 +43,45 @@ pub async fn register_validator( commission: Commission, validator_address: Address, bls_key_pair: BLSKeyPair, - schnorr_vk: StateVerKey, + schnorr_key_pair: StateKeyPair, ) -> Result { - let stake_table = StakeTable::new(stake_table_addr, &provider); - let (bls_vk_sol, sig_sol) = prepare_bls_payload(&bls_key_pair, validator_address); - let schnorr_vk_sol: EdOnBN254PointSol = schnorr_vk.to_affine().into(); - Ok(stake_table - .registerValidator( - bls_vk_sol, - schnorr_vk_sol, - sig_sol.into(), - commission.to_evm(), - ) - .send() - .await - .maybe_decode_revert::()? - .get_receipt() - .await?) + // NOTE: the StakeTableV2 ABI is a superset of the V1 ABI because the V2 inherits from V1 so we + // can always use the V2 bindings for calling functions and decoding events, even if we are + // connected to the V1 contract. + let stake_table = StakeTableV2::new(stake_table_addr, &provider); + let (bls_vk, bls_sig) = prepare_bls_payload(&bls_key_pair, validator_address); + let (schnorr_vk, schnorr_sig) = prepare_schnorr_payload(&schnorr_key_pair, validator_address); + + let version = stake_table.getVersion().call().await?.try_into()?; + // There is a race-condition here if the contract is upgraded while this transactions is waiting + // to be mined. We're very unlikely to hit this in practice, and since we only perform the + // upgrade on decaf this is acceptable. + Ok(match version { + StakeTableContractVersion::V1 => { + stake_table + .registerValidator(bls_vk, schnorr_vk, bls_sig.into(), commission.to_evm()) + .send() + .await + .maybe_decode_revert::()? + .get_receipt() + .await? + }, + StakeTableContractVersion::V2 => { + stake_table + .registerValidatorV2( + bls_vk, + schnorr_vk, + bls_sig.into(), + schnorr_sig, + commission.to_evm(), + ) + .send() + .await + .maybe_decode_revert::()? + .get_receipt() + .await? + }, + }) } pub async fn update_consensus_keys( @@ -58,36 +89,63 @@ pub async fn update_consensus_keys( stake_table_addr: Address, validator_address: Address, bls_key_pair: BLSKeyPair, - schnorr_vk: StateVerKey, + schnorr_key_pair: StateKeyPair, ) -> Result { - let stake_table = StakeTable::new(stake_table_addr, &provider); - let (bls_vk_sol, sig_sol) = prepare_bls_payload(&bls_key_pair, validator_address); - let schnorr_vk_sol: EdOnBN254PointSol = schnorr_vk.to_affine().into(); - Ok(stake_table - .updateConsensusKeys(bls_vk_sol, schnorr_vk_sol, sig_sol.into()) - .send() - .await - .maybe_decode_revert::()? - .get_receipt() - .await?) + // NOTE: the StakeTableV2 ABI is a superset of the V1 ABI because the V2 inherits from V1 so we + // can always use the V2 bindings for calling functions and decoding events, even if we are + // connected to the V1 contract. + let stake_table = StakeTableV2::new(stake_table_addr, &provider); + let (bls_vk, bls_sig) = prepare_bls_payload(&bls_key_pair, validator_address); + let (schnorr_vk, schnorr_sig) = prepare_schnorr_payload(&schnorr_key_pair, validator_address); + + // There is a race-condition here if the contract is upgraded while this transactions is waiting + // to be mined. We're very unlikely to hit this in practice, and since we only perform the + // upgrade on decaf this is acceptable. + let version = stake_table.getVersion().call().await?.try_into()?; + Ok(match version { + StakeTableContractVersion::V1 => { + stake_table + .updateConsensusKeys(bls_vk, schnorr_vk, bls_sig.into()) + .send() + .await + .maybe_decode_revert::()? + .get_receipt() + .await? + }, + StakeTableContractVersion::V2 => { + stake_table + .updateConsensusKeysV2(bls_vk, schnorr_vk, bls_sig.into(), schnorr_sig) + .send() + .await + .maybe_decode_revert::()? + .get_receipt() + .await? + }, + }) } pub async fn deregister_validator( provider: impl Provider, stake_table_addr: Address, ) -> Result { - let stake_table = StakeTable::new(stake_table_addr, &provider); + let stake_table = StakeTableV2::new(stake_table_addr, &provider); Ok(stake_table .deregisterValidator() .send() .await - .maybe_decode_revert::()? + .maybe_decode_revert::()? .get_receipt() .await?) } #[cfg(test)] mod test { + use alloy::providers::WalletProvider as _; + use espresso_contract_deployer::build_provider; + use espresso_types::{ + v0_3::{StakeTableEvent, StakeTableFetcher}, + L1Client, + }; use rand::{rngs::StdRng, SeedableRng as _}; use super::*; @@ -106,21 +164,21 @@ mod test { system.commission, validator_address, system.bls_key_pair, - system.state_key_pair.ver_key(), + system.state_key_pair, ) .await?; assert!(receipt.status()); let event = receipt - .decoded_log::() + .decoded_log::() .unwrap(); assert_eq!(event.account, validator_address); assert_eq!(event.commission, system.commission.to_evm()); - assert_eq!(event.blsVk, bls_vk_sol); - assert_eq!(event.schnorrVk, schnorr_vk_sol); + assert_eq!(event.blsVK, bls_vk_sol); + assert_eq!(event.schnorrVK, schnorr_vk_sol); - // TODO verify we can parse keys and verify signature + event.data.authenticate()?; Ok(()) } @@ -132,7 +190,9 @@ mod test { let receipt = deregister_validator(&system.provider, system.stake_table).await?; assert!(receipt.status()); - let event = receipt.decoded_log::().unwrap(); + let event = receipt + .decoded_log::() + .unwrap(); assert_eq!(event.validator, system.deployer_address); Ok(()) @@ -146,26 +206,158 @@ mod test { let mut rng = StdRng::from_seed([43u8; 32]); let (_, new_bls, new_schnorr) = TestSystem::gen_keys(&mut rng); let (bls_vk_sol, _) = prepare_bls_payload(&new_bls, validator_address); - let schnorr_vk_sol: EdOnBN254PointSol = new_schnorr.ver_key().to_affine().into(); + let (schnorr_vk_sol, _) = prepare_schnorr_payload(&new_schnorr, validator_address); let receipt = update_consensus_keys( &system.provider, system.stake_table, validator_address, new_bls, - new_schnorr.ver_key(), + new_schnorr, ) .await?; assert!(receipt.status()); let event = receipt - .decoded_log::() + .decoded_log::() .unwrap(); assert_eq!(event.account, system.deployer_address); assert_eq!(event.blsVK, bls_vk_sol); assert_eq!(event.schnorrVK, schnorr_vk_sol); + event.data.authenticate()?; + + Ok(()) + } + + /// The GCL must remove stake table events with incorrect signatures. This test verifies that a + /// validator registered event with incorrect schnorr signature is removed before the stake + /// table is computed. + #[tokio::test] + async fn test_integration_unauthenticated_validator_registered_events_removed() -> Result<()> { + let system = TestSystem::deploy().await?; + + // register a validator with correct signature + system.register_validator().await?; + + // NOTE: we can't register a validator with a bad BLS signature because the contract will revert + + let provider = build_provider( + "test test test test test test test test test test test junk".to_string(), + 1, + system.rpc_url.clone(), + ); + let validator_address = provider.default_signer_address(); + let (_, bls_key_pair, schnorr_key_pair) = + TestSystem::gen_keys(&mut StdRng::from_seed([1u8; 32])); + let (_, _, other_schnorr_key_pair) = + TestSystem::gen_keys(&mut StdRng::from_seed([2u8; 32])); + + let (bls_vk, bls_sig) = prepare_bls_payload(&bls_key_pair, validator_address); + let (schnorr_vk, _) = prepare_schnorr_payload(&schnorr_key_pair, validator_address); + + // create a valid schnorr signature with the *wrong* key + let (_, schnorr_sig_other_key) = + prepare_schnorr_payload(&other_schnorr_key_pair, validator_address); + + let stake_table = StakeTableV2::new(system.stake_table, provider); + + // register a validator with the schnorr sig from another key + let receipt = stake_table + .registerValidatorV2( + bls_vk, + schnorr_vk, + bls_sig.into(), + schnorr_sig_other_key.clone(), + Commission::try_from("12.34")?.to_evm(), + ) + .send() + .await + .maybe_decode_revert::()? + .get_receipt() + .await?; + assert!(receipt.status()); + + let l1 = L1Client::new(vec![system.rpc_url])?; + let events = StakeTableFetcher::fetch_events_from_contract( + l1, + system.stake_table, + Some(0), + receipt.block_number.unwrap(), + ) + .await? + .sort_events()?; + + // verify that we only have the first RegisterV2 event + assert_eq!(events.len(), 1); + match events[0].1.clone() { + StakeTableEvent::RegisterV2(event) => { + assert_eq!(event.account, system.deployer_address); + }, + _ => panic!("expected RegisterV2 event"), + } + Ok(()) + } + + /// The GCL must remove stake table events with incorrect signatures. This test verifies that a + /// consensus keys update event with incorrect schnorr signature is removed before the stake + /// table is computed. + #[tokio::test] + async fn test_integration_unauthenticated_update_consensus_keys_events_removed() -> Result<()> { + let system = TestSystem::deploy().await?; + + // register a validator with correct signature + system.register_validator().await?; + let validator_address = system.deployer_address; + + // NOTE: we can't register a validator with a bad BLS signature because the contract will revert + + let (_, new_bls_key_pair, new_schnorr_key_pair) = + TestSystem::gen_keys(&mut StdRng::from_seed([1u8; 32])); + let (_, _, other_schnorr_key_pair) = + TestSystem::gen_keys(&mut StdRng::from_seed([2u8; 32])); + + let (bls_vk, bls_sig) = prepare_bls_payload(&new_bls_key_pair, validator_address); + let (schnorr_vk, _) = prepare_schnorr_payload(&new_schnorr_key_pair, validator_address); + + // create a valid schnorr signature with the *wrong* key + let (_, schnorr_sig_other_key) = + prepare_schnorr_payload(&other_schnorr_key_pair, validator_address); + + let stake_table = StakeTableV2::new(system.stake_table, system.provider); + + // update consensus keys with the schnorr sig from another key + let receipt = stake_table + .updateConsensusKeysV2(bls_vk, schnorr_vk, bls_sig.into(), schnorr_sig_other_key) + .send() + .await + .maybe_decode_revert::()? + .get_receipt() + .await?; + assert!(receipt.status()); + + let l1 = L1Client::new(vec![system.rpc_url])?; + let events = StakeTableFetcher::fetch_events_from_contract( + l1, + system.stake_table, + Some(0), + receipt.block_number.unwrap(), + ) + .await? + .sort_events()?; + + // verify that we only have the RegisterV2 event + assert_eq!(events.len(), 1); + match events[0].1.clone() { + StakeTableEvent::RegisterV2(event) => { + assert_eq!(event.account, system.deployer_address); + }, + _ => panic!("expected RegisterV2 event"), + } + + println!("Events: {events:?}"); + Ok(()) } } diff --git a/staking-cli/tests/cli.rs b/staking-cli/tests/cli.rs index 8bc7eb5432..bd87dbc892 100644 --- a/staking-cli/tests/cli.rs +++ b/staking-cli/tests/cli.rs @@ -8,12 +8,20 @@ use alloy::primitives::{ Address, U256, }; use anyhow::Result; +use hotshot_contract_adapter::stake_table::StakeTableContractVersion; use rand::{rngs::StdRng, SeedableRng as _}; use sequencer_utils::test_utils::setup_test; -use staking_cli::{demo::DelegationConfig, deploy::Signer, *}; +use staking_cli::{demo::DelegationConfig, deploy, deploy::Signer, Config}; use crate::deploy::TestSystem; +#[rstest_reuse::template] +#[rstest::rstest] +#[case::v1(StakeTableContractVersion::V1)] +#[case::v2(StakeTableContractVersion::V2)] +#[tokio::test] +async fn stake_table_versions(#[case] _version: StakeTableContractVersion) {} + const TEST_MNEMONIC: &str = "wool upset allow cheap purity craft hat cute below useful reject door"; trait AssertSuccess { @@ -160,10 +168,10 @@ fn test_cli_create_file_ledger() -> anyhow::Result<()> { } // TODO: ideally we would test that the decoding works for all the commands -#[tokio::test] -async fn test_cli_contract_revert() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_contract_revert(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; let mut cmd = base_cmd(); system.args(&mut cmd, Signer::Mnemonic); @@ -180,10 +188,10 @@ async fn test_cli_contract_revert() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_register_validator() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_register_validator(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; let mut cmd = base_cmd(); system.args(&mut cmd, Signer::Mnemonic); cmd.arg("register-validator") @@ -210,9 +218,9 @@ async fn test_cli_register_validator() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_update_consensus_keys() -> Result<()> { - let system = TestSystem::deploy().await?; +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_update_consensus_keys(#[case] version: StakeTableContractVersion) -> Result<()> { + let system = TestSystem::deploy_version(version).await?; system.register_validator().await?; let mut rng = StdRng::from_seed([43u8; 32]); @@ -230,10 +238,10 @@ async fn test_cli_update_consensus_keys() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_delegate() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_delegate(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; system.register_validator().await?; let mut cmd = base_cmd(); @@ -248,10 +256,10 @@ async fn test_cli_delegate() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_deregister_validator() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_deregister_validator(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; system.register_validator().await?; let mut cmd = base_cmd(); @@ -260,10 +268,10 @@ async fn test_cli_deregister_validator() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_undelegate() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_undelegate(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; system.register_validator().await?; let amount = "123"; system.delegate(parse_ether(amount)?).await?; @@ -280,10 +288,10 @@ async fn test_cli_undelegate() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_claim_withdrawal() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_claim_withdrawal(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; let amount = U256::from(123); system.register_validator().await?; system.delegate(amount).await?; @@ -300,10 +308,10 @@ async fn test_cli_claim_withdrawal() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_claim_validator_exit() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_claim_validator_exit(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; let amount = U256::from(123); system.register_validator().await?; system.delegate(amount).await?; @@ -320,10 +328,12 @@ async fn test_cli_claim_validator_exit() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_stake_for_demo_default_num_validators() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_stake_for_demo_default_num_validators( + #[case] version: StakeTableContractVersion, +) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; let mut cmd = base_cmd(); system.args(&mut cmd, Signer::Mnemonic); @@ -331,10 +341,12 @@ async fn test_cli_stake_for_demo_default_num_validators() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_stake_for_demo_three_validators() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_stake_for_demo_three_validators( + #[case] version: StakeTableContractVersion, +) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; let mut cmd = base_cmd(); system.args(&mut cmd, Signer::Mnemonic); @@ -346,9 +358,20 @@ async fn test_cli_stake_for_demo_three_validators() -> Result<()> { Ok(()) } -async fn stake_for_demo_delegation_config_helper(config: DelegationConfig) -> Result<()> { +#[rstest::rstest] +#[tokio::test] +async fn stake_for_demo_delegation_config_helper( + #[values(StakeTableContractVersion::V1, StakeTableContractVersion::V2)] + version: StakeTableContractVersion, + #[values( + DelegationConfig::EqualAmounts, + DelegationConfig::VariableAmounts, + DelegationConfig::MultipleDelegators + )] + config: DelegationConfig, +) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; let mut cmd = base_cmd(); system.args(&mut cmd, Signer::Mnemonic); @@ -360,25 +383,10 @@ async fn stake_for_demo_delegation_config_helper(config: DelegationConfig) -> Re Ok(()) } -#[tokio::test] -async fn test_cli_stake_for_demo_delegation_config_equal_amounts() -> Result<()> { - stake_for_demo_delegation_config_helper(DelegationConfig::EqualAmounts).await -} - -#[tokio::test] -async fn test_cli_stake_for_demo_delegation_config_variable_amounts() -> Result<()> { - stake_for_demo_delegation_config_helper(DelegationConfig::VariableAmounts).await -} - -#[tokio::test] -async fn test_cli_stake_for_demo_delegation_config_multiple_delegators() -> Result<()> { - stake_for_demo_delegation_config_helper(DelegationConfig::MultipleDelegators).await -} - -#[tokio::test] -async fn test_cli_approve() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_approve(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; let amount = "123"; let mut cmd = base_cmd(); @@ -394,10 +402,10 @@ async fn test_cli_approve() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_balance() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_balance(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; // Check balance of account owner let mut cmd = base_cmd(); @@ -427,10 +435,10 @@ async fn test_cli_balance() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_allowance() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_allowance(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; // Check allowance of account owner let mut cmd = base_cmd(); @@ -458,10 +466,10 @@ async fn test_cli_allowance() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_transfer() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_transfer(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; let addr = "0x1111111111111111111111111111111111111111".parse::

()?; let amount = parse_ether("0.123")?; let mut cmd = base_cmd(); @@ -479,10 +487,10 @@ async fn test_cli_transfer() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_stake_table_full() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_stake_table_full(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; system.register_validator().await?; let amount = parse_ether("0.123")?; @@ -502,10 +510,10 @@ async fn test_cli_stake_table_full() -> Result<()> { Ok(()) } -#[tokio::test] -async fn test_cli_stake_table_compact() -> Result<()> { +#[rstest_reuse::apply(stake_table_versions)] +async fn test_cli_stake_table_compact(#[case] version: StakeTableContractVersion) -> Result<()> { setup_test(); - let system = TestSystem::deploy().await?; + let system = TestSystem::deploy_version(version).await?; system.register_validator().await?; let amount = parse_ether("0.123")?; diff --git a/types/Cargo.toml b/types/Cargo.toml index 4d36c95eba..b03658612a 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -65,6 +65,8 @@ vid = { workspace = true } espresso-contract-deployer = { path = "../contracts/rust/deployer" } espresso-types = { path = ".", features = [ "testing" ] } portpicker = { workspace = true } +rstest = { workspace = true } +rstest_reuse = { workspace = true } [package.metadata.cargo-machete] ignored = ["base64_bytes", "hotshot_testing"] diff --git a/types/src/v0/impls/stake_table.rs b/types/src/v0/impls/stake_table.rs index 728c3b59a9..d39c883bce 100644 --- a/types/src/v0/impls/stake_table.rs +++ b/types/src/v0/impls/stake_table.rs @@ -14,8 +14,9 @@ use async_lock::{Mutex, RwLock}; use committable::Committable; use futures::stream::{self, StreamExt}; use hotshot::types::{BLSPubKey, SchnorrPubKey, SignatureKey as _}; -use hotshot_contract_adapter::sol_types::StakeTable::{ - self, ConsensusKeysUpdated, Delegated, Undelegated, ValidatorExit, ValidatorRegistered, +use hotshot_contract_adapter::sol_types::StakeTableV2::{ + self, ConsensusKeysUpdated, ConsensusKeysUpdatedV2, Delegated, Undelegated, ValidatorExit, + ValidatorRegistered, ValidatorRegisteredV2, }; use hotshot_types::{ data::{vid_disperse::VID_TARGET_TOTAL_STAKE, EpochNumber}, @@ -49,24 +50,96 @@ use crate::traits::EventsPersistenceRead; type Epoch = ::Epoch; +/// Format the alloy Log RPC type in a way to make it easy to find the event in an explorer. +trait DisplayLog { + fn display(&self) -> String; +} + +impl DisplayLog for Log { + fn display(&self) -> String { + // These values are all unlikely to be missing because we only create Log variables by + // fetching them from the RPC, so for simplicity we use defaults if the any of the values + // are missing. + let block = self.block_number.unwrap_or_default(); + let index = self.log_index.unwrap_or_default(); + let hash = self.transaction_hash.unwrap_or_default(); + format!("Log(block={block},index={index},transaction_hash={hash})") + } +} + #[derive(Clone, PartialEq)] pub struct StakeTableEvents { registrations: Vec<(ValidatorRegistered, Log)>, + registrations_v2: Vec<(ValidatorRegisteredV2, Log)>, deregistrations: Vec<(ValidatorExit, Log)>, delegated: Vec<(Delegated, Log)>, undelegated: Vec<(Undelegated, Log)>, keys: Vec<(ConsensusKeysUpdated, Log)>, + keys_v2: Vec<(ConsensusKeysUpdatedV2, Log)>, } impl StakeTableEvents { + /// Creates a new instance of `StakeTableEvents` with the provided events. + /// + /// Remove unauthenticated registration and key update events + fn from_l1_logs( + registrations: Vec<(ValidatorRegistered, Log)>, + registrations_v2: Vec<(ValidatorRegisteredV2, Log)>, + deregistrations: Vec<(ValidatorExit, Log)>, + delegated: Vec<(Delegated, Log)>, + undelegated: Vec<(Undelegated, Log)>, + keys: Vec<(ConsensusKeysUpdated, Log)>, + keys_v2: Vec<(ConsensusKeysUpdatedV2, Log)>, + ) -> Self { + let registrations_v2 = registrations_v2 + .into_iter() + .filter(|(event, log)| { + event + .authenticate() + .map_err(|_| { + tracing::warn!( + "Failed to authenticate ValidatorRegisteredV2 event {}", + log.display() + ); + }) + .is_ok() + }) + .collect(); + let keys_v2 = keys_v2 + .into_iter() + .filter(|(event, log)| { + event + .authenticate() + .map_err(|_| { + tracing::warn!( + "Failed to authenticate ConsensusKeysUpdatedV2 event {}", + log.display() + ); + }) + .is_ok() + }) + .collect(); + Self { + registrations, + registrations_v2, + deregistrations, + delegated, + undelegated, + keys, + keys_v2, + } + } + pub fn sort_events(self) -> anyhow::Result> { let mut events: Vec<(EventKey, StakeTableEvent)> = Vec::new(); let Self { registrations, + registrations_v2, deregistrations, delegated, undelegated, keys, + keys_v2, } = self; for (registration, log) in registrations { @@ -78,6 +151,15 @@ impl StakeTableEvents { registration.into(), )); } + for (registration, log) in registrations_v2 { + events.push(( + ( + log.block_number.context("block number")?, + log.log_index.context("log index")?, + ), + registration.into(), + )); + } for (dereg, log) in deregistrations { events.push(( ( @@ -115,6 +197,15 @@ impl StakeTableEvents { update.into(), )); } + for (update, log) in keys_v2 { + events.push(( + ( + log.block_number.context("block number")?, + log.log_index.context("log index")?, + ), + update.into(), + )); + } events.sort_by_key(|(key, _)| *key); Ok(events) @@ -122,6 +213,9 @@ impl StakeTableEvents { } /// Extract all validators from L1 stake table events. +// TODO: MA we should reject ValidatorRegistered and ConsensusKeysUpdated events after the stake +// table contract has been updated to V2, this is currently however not a safety issue because the +// V2 contract will not generate the V1 events after the upgrade to V2. pub fn validators_from_l1_events>( events: I, ) -> anyhow::Result>> { @@ -137,19 +231,60 @@ pub fn validators_from_l1_events>( schnorrVk, commission, }) => { - // TODO(abdul): BLS and Schnorr signature keys verification - let stake_table_key: BLSPubKey = blsVk.clone().into(); - let state_ver_key: SchnorrPubKey = schnorrVk.clone().into(); - // TODO(MA): The stake table contract currently enforces that each bls key is only used once. We will - // move this check to the confirmation layer and remove it from the contract. Once we have the signature - // check in this functions we can skip if a BLS key, or Schnorr key was previously used. + let stake_table_key: BLSPubKey = blsVk.into(); + let state_ver_key: SchnorrPubKey = schnorrVk.into(); + // The stake table contract enforces that each bls key is only used once. + if bls_keys.contains(&stake_table_key) { + bail!("bls key already used: {}", stake_table_key.to_string()); + }; + + // The contract does *not* enforce that each schnorr key is only used once, + // therefore it's possible to have multiple validators with the same schnorr key. + if schnorr_keys.contains(&state_ver_key) { + tracing::warn!("schnorr key already used: {}", state_ver_key.to_string()); + }; + + bls_keys.insert(stake_table_key); + schnorr_keys.insert(state_ver_key.clone()); + + match validators.entry(account) { + indexmap::map::Entry::Occupied(_occupied_entry) => { + bail!("validator {:#x} already registered", *account) + }, + indexmap::map::Entry::Vacant(vacant_entry) => vacant_entry.insert(Validator { + account, + stake_table_key, + state_ver_key, + stake: U256::from(0_u64), + commission, + delegators: HashMap::default(), + }), + }; + }, + StakeTableEvent::RegisterV2(event) => { + // Signature authentication is performed right after fetching, if we get an + // unauthenticated event here, something went wrong, we abort early. + event + .authenticate() + .context("Failed to authenticate event: {event:?}")?; + let ValidatorRegisteredV2 { + account, + blsVK, + schnorrVK, + commission, + .. + } = event; + + let stake_table_key: BLSPubKey = blsVK.into(); + let state_ver_key: SchnorrPubKey = schnorrVK.into(); + // The stake table contract enforces that each bls key is only used once. if bls_keys.contains(&stake_table_key) { - bail!("bls key {} already used", stake_table_key.to_string()); + bail!("bls key already used: {}", stake_table_key.to_string()); }; // The contract does *not* enforce that each schnorr key is only used once. if schnorr_keys.contains(&state_ver_key) { - tracing::warn!("schnorr key {} already used", state_ver_key.to_string()); + tracing::warn!("schnorr key already used: {}", state_ver_key.to_string()); }; bls_keys.insert(stake_table_key); @@ -232,6 +367,56 @@ pub fn validators_from_l1_events>( blsVK, schnorrVK, } = update; + let validator = validators + .get_mut(&account) + .with_context(|| "validator {account:#x} not found")?; + let stake_table_key: BLSPubKey = blsVK.into(); + let state_ver_key: SchnorrPubKey = schnorrVK.into(); + // The stake table contract enforces that each bls key is only used once. + if bls_keys.contains(&stake_table_key) { + bail!("bls key already used: {}", stake_table_key.to_string()); + }; + + // The contract does *not* enforce that each schnorr key is only used once, + // therefore it's possible to have multiple validators with the same schnorr key. + if schnorr_keys.contains(&state_ver_key) { + tracing::warn!("schnorr key already used: {}", state_ver_key.to_string()); + }; + + let bls = blsVK.into(); + let state_ver_key = schnorrVK.into(); + + validator.stake_table_key = bls; + validator.state_ver_key = state_ver_key; + }, + StakeTableEvent::KeyUpdateV2(update) => { + // Signature authentication is performed right after fetching, if we get an + // unauthenticated event here, something went wrong, we abort early. + update + .authenticate() + .context("Failed to authenticate event: {event:?}")?; + + let ConsensusKeysUpdatedV2 { + account, + blsVK, + schnorrVK, + .. + } = update; + + // The stake table contract enforces that each bls key is only used once. + let stake_table_key: BLSPubKey = blsVK.into(); + let state_ver_key: SchnorrPubKey = schnorrVK.into(); + // The stake table contract enforces that each bls key is only used once. + if bls_keys.contains(&stake_table_key) { + bail!("bls key already used: {}", stake_table_key.to_string()); + }; + + // The contract does *not* enforce that each schnorr key is only used once, + // therefore it's possible to have multiple validators with the same schnorr key. + if schnorr_keys.contains(&state_ver_key) { + tracing::warn!("schnorr key already used: {}", state_ver_key.to_string()); + }; + let validator = validators .get_mut(&account) .with_context(|| "validator {account:#x} not found")?; @@ -318,10 +503,12 @@ impl std::fmt::Debug for StakeTableEvent { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { StakeTableEvent::Register(event) => write!(f, "Register({:?})", event.account), + StakeTableEvent::RegisterV2(event) => write!(f, "RegisterV2({:?})", event.account), StakeTableEvent::Deregister(event) => write!(f, "Deregister({:?})", event.validator), StakeTableEvent::Delegate(event) => write!(f, "Delegate({:?})", event.delegator), StakeTableEvent::Undelegate(event) => write!(f, "Undelegate({:?})", event.delegator), StakeTableEvent::KeyUpdate(event) => write!(f, "KeyUpdate({:?})", event.account), + StakeTableEvent::KeyUpdateV2(event) => write!(f, "KeyUpdateV2({:?})", event.account), } } } @@ -506,7 +693,7 @@ impl StakeTableFetcher { from_block: Option, to_block: u64, ) -> anyhow::Result { - let stake_table_contract = StakeTable::new(contract, l1_client.provider.clone()); + let stake_table_contract = StakeTableV2::new(contract, l1_client.provider.clone()); // get the block number when the contract was initialized // to avoid fetching events from block number 0 @@ -571,6 +758,40 @@ impl StakeTableFetcher { } }); + // fetch registered events v2 + // retry if the call to the provider to fetch the events fails + let registered_events_v2 = stream::iter(chunks.clone()).then(|(from, to)| { + let retry_delay = l1_client.options().l1_retry_delay; + let stake_table_contract = stake_table_contract.clone(); + async move { + tracing::debug!(from, to, "fetch ValidatorRegisteredV2 events in range"); + loop { + match stake_table_contract + .clone() + .ValidatorRegisteredV2_filter() + .from_block(from) + .to_block(to) + .query() + .await + { + Ok(events) => { + break stream::iter(events.into_iter().filter(|(event, log)| { + if let Err(e) = event.authenticate() { + tracing::warn!(%e, "Failed to authenticate ValidatorRegisteredV2 event: {}", log.display()); + return false; + } + true + })); + }, + Err(err) => { + tracing::warn!(from, to, %err, "ValidatorRegisteredV2 Error"); + sleep(retry_delay).await; + }, + } + } + } + }); + // fetch validator de registration events let deregistered_events = stream::iter(chunks.clone()).then(|(from, to)| { let retry_delay = l1_client.options().l1_retry_delay; @@ -643,7 +864,7 @@ impl StakeTableFetcher { }); // fetch consensus keys updated events - let keys_update_events = stream::iter(chunks).then(|(from, to)| { + let keys_update_events = stream::iter(chunks.clone()).then(|(from, to)| { let retry_delay = l1_client.options().l1_retry_delay; let stake_table_contract = stake_table_contract.clone(); async move { @@ -666,19 +887,55 @@ impl StakeTableFetcher { } }); + // fetch consensus keys updated v2 events + let keys_update_events_v2 = stream::iter(chunks).then(|(from, to)| { + let retry_delay = l1_client.options().l1_retry_delay; + let stake_table_contract = stake_table_contract.clone(); + async move { + tracing::debug!(from, to, "fetch ConsensusKeysUpdatedV2 events in range"); + loop { + match stake_table_contract + .ConsensusKeysUpdatedV2_filter() + .from_block(from) + .to_block(to) + .query() + .await + { + Ok(events) => { + break stream::iter(events.into_iter().filter(|(event, log)| { + if let Err(e) = event.authenticate() { + tracing::warn!(%e, "Failed to authenticate ConsensusKeysUpdatedV2 event {}", log.display()); + return false; + } + true + })); + }, + Err(err) => { + tracing::warn!(from, to, %err, "ConsensusKeysUpdatedV2 Error"); + sleep(retry_delay).await; + }, + } + } + } + }); + let registrations = registered_events.flatten().collect().await; + let registrations_v2 = registered_events_v2.flatten().collect().await; let deregistrations = deregistered_events.flatten().collect().await; let delegated = delegated_events.flatten().collect().await; let undelegated = undelegated_events.flatten().collect().await; let keys = keys_update_events.flatten().collect().await; + let keys_v2 = keys_update_events_v2.flatten().collect().await; - Ok(StakeTableEvents { + Ok(StakeTableEvents::from_l1_logs( registrations, + registrations_v2, deregistrations, delegated, undelegated, keys, - }) + keys_v2, + )) } /// Get `StakeTable` at specific l1 block height. @@ -1422,38 +1679,108 @@ impl DAMembers { #[cfg(any(test, feature = "testing"))] pub mod testing { - use hotshot_contract_adapter::sol_types::{EdOnBN254PointSol, G2PointSol}; - use hotshot_types::light_client::StateKeyPair; + use alloy::primitives::Bytes; + use hotshot_contract_adapter::{ + sol_types::{EdOnBN254PointSol, G1PointSol, G2PointSol}, + stake_table::{sign_address_bls, sign_address_schnorr}, + }; + use hotshot_types::{light_client::StateKeyPair, signature_key::BLSKeyPair}; use rand::{Rng as _, RngCore as _}; use super::*; // TODO: current tests are just sanity checks, we need more. + #[derive(Debug, Clone)] pub struct TestValidator { pub account: Address, pub bls_vk: G2PointSol, pub schnorr_vk: EdOnBN254PointSol, pub commission: u16, + pub bls_sig: G1PointSol, + pub schnorr_sig: Bytes, } impl TestValidator { pub fn random() -> Self { - let rng = &mut rand::thread_rng(); + let account = Address::random(); + let commission = rand::thread_rng().gen_range(0..10000); + Self::random_update_keys(account, commission) + } + + pub fn randomize_keys(&self) -> Self { + Self::random_update_keys(self.account, self.commission) + } + + fn random_update_keys(account: Address, commission: u16) -> Self { + let mut rng = &mut rand::thread_rng(); let mut seed = [0u8; 32]; rng.fill_bytes(&mut seed); + let bls_key_pair = BLSKeyPair::generate(&mut rng); + let bls_sig = sign_address_bls(&bls_key_pair, account); + let schnorr_key_pair = StateKeyPair::generate_from_seed_indexed(seed, 0); + let schnorr_sig = sign_address_schnorr(&schnorr_key_pair, account); + Self { + account, + bls_vk: bls_key_pair.ver_key().to_affine().into(), + schnorr_vk: schnorr_key_pair.ver_key().to_affine().into(), + commission, + bls_sig, + schnorr_sig, + } + } + } - let (bls_vk, _) = BLSPubKey::generated_from_seed_indexed(seed, 0); - let schnorr_vk: EdOnBN254PointSol = StateKeyPair::generate_from_seed_indexed(seed, 0) - .ver_key() - .to_affine() - .into(); + impl From<&TestValidator> for ValidatorRegistered { + fn from(value: &TestValidator) -> Self { + Self { + account: value.account, + blsVk: value.bls_vk, + schnorrVk: value.schnorr_vk, + commission: value.commission, + } + } + } + impl From<&TestValidator> for ValidatorRegisteredV2 { + fn from(value: &TestValidator) -> Self { Self { - account: Address::random(), - bls_vk: bls_vk.to_affine().into(), - schnorr_vk, - commission: rng.gen_range(0..10000), + account: value.account, + blsVK: value.bls_vk, + schnorrVK: value.schnorr_vk, + commission: value.commission, + blsSig: value.bls_sig.into(), + schnorrSig: value.schnorr_sig.clone(), + } + } + } + + impl From<&TestValidator> for ConsensusKeysUpdated { + fn from(value: &TestValidator) -> Self { + Self { + account: value.account, + blsVK: value.bls_vk, + schnorrVK: value.schnorr_vk, + } + } + } + + impl From<&TestValidator> for ConsensusKeysUpdatedV2 { + fn from(value: &TestValidator) -> Self { + Self { + account: value.account, + blsVK: value.bls_vk, + schnorrVK: value.schnorr_vk, + blsSig: value.bls_sig.into(), + schnorrSig: value.schnorr_sig.clone(), + } + } + } + + impl From<&TestValidator> for ValidatorExit { + fn from(value: &TestValidator) -> Self { + Self { + validator: value.account, } } } @@ -1472,8 +1799,8 @@ pub mod testing { validator_stake += alloy::primitives::U256::from(stake); } - let stake_table_key = val.bls_vk.clone().into(); - let state_ver_key = val.schnorr_vk.clone().into(); + let stake_table_key = val.bls_vk.into(); + let state_ver_key = val.schnorr_vk.into(); Validator { account: val.account, @@ -1489,7 +1816,8 @@ pub mod testing { #[cfg(test)] mod tests { - use alloy::primitives::Address; + use alloy::{primitives::Address, rpc::types::Log}; + use hotshot_contract_adapter::stake_table::StakeTableContractVersion; use sequencer_utils::test_utils::setup_test; use super::*; @@ -1499,60 +1827,73 @@ mod tests { fn test_from_l1_events() -> anyhow::Result<()> { setup_test(); // Build a stake table with one DA node and one consensus node. - let val = TestValidator::random(); - let val_new_keys = TestValidator::random(); + let val_1 = TestValidator::random(); + let val_1_new_keys = val_1.randomize_keys(); + let val_2 = TestValidator::random(); + let val_2_new_keys = val_2.randomize_keys(); let delegator = Address::random(); let mut events: Vec = [ - ValidatorRegistered { - account: val.account, - blsVk: val.bls_vk.clone(), - schnorrVk: val.schnorr_vk.clone(), - commission: val.commission, - } - .into(), + ValidatorRegistered::from(&val_1).into(), + ValidatorRegisteredV2::from(&val_2).into(), Delegated { delegator, - validator: val.account, + validator: val_1.account, amount: U256::from(10), } .into(), - ConsensusKeysUpdated { - account: val.account, - blsVK: val_new_keys.bls_vk.clone(), - schnorrVK: val_new_keys.schnorr_vk.clone(), - } - .into(), + ConsensusKeysUpdated::from(&val_1_new_keys).into(), + ConsensusKeysUpdatedV2::from(&val_2_new_keys).into(), Undelegated { delegator, - validator: val.account, + validator: val_1.account, amount: U256::from(7), } .into(), // delegate to the same validator again Delegated { delegator, - validator: val.account, + validator: val_1.account, amount: U256::from(5), } .into(), + // delegate to the second validator + Delegated { + delegator: Address::random(), + validator: val_2.account, + amount: U256::from(3), + } + .into(), ] .to_vec(); let st = active_validator_set_from_l1_events(events.iter().cloned())?; - let st_val = st.get(&val.account).unwrap(); + let st_val_1 = st.get(&val_1.account).unwrap(); // final staked amount should be 10 (delegated) - 7 (undelegated) + 5 (Delegated) - assert_eq!(st_val.stake, U256::from(8)); - assert_eq!(st_val.commission, val.commission); - assert_eq!(st_val.delegators.len(), 1); + assert_eq!(st_val_1.stake, U256::from(8)); + assert_eq!(st_val_1.commission, val_1.commission); + assert_eq!(st_val_1.delegators.len(), 1); // final delegated amount should be 10 (delegated) - 7 (undelegated) + 5 (Delegated) - assert_eq!(*st_val.delegators.get(&delegator).unwrap(), U256::from(8)); + assert_eq!(*st_val_1.delegators.get(&delegator).unwrap(), U256::from(8)); - events.push( - ValidatorExit { - validator: val.account, - } - .into(), - ); + let st_val_2 = st.get(&val_2.account).unwrap(); + assert_eq!(st_val_2.stake, U256::from(3)); + assert_eq!(st_val_2.commission, val_2.commission); + assert_eq!(st_val_2.delegators.len(), 1); + + events.push(ValidatorExit::from(&val_1).into()); + + let st = active_validator_set_from_l1_events(events.iter().cloned())?; + // The first validator should have been removed + assert_eq!(st.get(&val_1.account), None); + + // The second validator should be unchanged + let st_val_2 = st.get(&val_2.account).unwrap(); + assert_eq!(st_val_2.stake, U256::from(3)); + assert_eq!(st_val_2.commission, val_2.commission); + assert_eq!(st_val_2.delegators.len(), 1); + + // remove the 2nd validator + events.push(ValidatorExit::from(&val_2).into()); // This should fail because the validator has exited and no longer exists in the stake table. assert!(active_validator_set_from_l1_events(events.iter().cloned()).is_err()); @@ -1565,25 +1906,16 @@ mod tests { let val = TestValidator::random(); let delegator = Address::random(); - let register: StakeTableEvent = ValidatorRegistered { - account: val.account, - blsVk: val.bls_vk.clone(), - schnorrVk: val.schnorr_vk.clone(), - commission: val.commission, - } - .into(); + let register: StakeTableEvent = ValidatorRegistered::from(&val).into(); + let register_v2: StakeTableEvent = ValidatorRegisteredV2::from(&val).into(); let delegate: StakeTableEvent = Delegated { delegator, validator: val.account, amount: U256::from(10), } .into(); - let key_update: StakeTableEvent = ConsensusKeysUpdated { - account: val.account, - blsVK: val.bls_vk.clone(), - schnorrVK: val.schnorr_vk.clone(), - } - .into(); + let key_update: StakeTableEvent = ConsensusKeysUpdated::from(&val).into(); + let key_update_v2: StakeTableEvent = ConsensusKeysUpdatedV2::from(&val).into(); let undelegate: StakeTableEvent = Undelegated { delegator, validator: val.account, @@ -1591,25 +1923,35 @@ mod tests { } .into(); - let exit: StakeTableEvent = ValidatorExit { - validator: val.account, - } - .into(); + let exit: StakeTableEvent = ValidatorExit::from(&val).into(); let cases = [ vec![exit], vec![undelegate.clone()], vec![delegate.clone()], vec![key_update], + vec![key_update_v2], vec![register.clone(), register.clone()], - vec![register, delegate, undelegate.clone(), undelegate], + vec![register_v2.clone(), register_v2.clone()], + vec![register.clone(), register_v2.clone()], + vec![register_v2.clone(), register.clone()], + vec![ + register, + delegate.clone(), + undelegate.clone(), + undelegate.clone(), + ], + vec![register_v2, delegate, undelegate.clone(), undelegate], ]; for events in cases.iter() { - let res = active_validator_set_from_l1_events(events.iter().cloned()); + // NOTE: not selecting the active validator set because we care about wrong sequences of + // events being detected. If we compute the active set we will also get an error if the + // set is empty but that's not what we want to test here. + let res = validators_from_l1_events(events.iter().cloned()); assert!( res.is_err(), - "events {:?}, not a valid sequencer of events", + "events {:?}, not a valid sequence of events", res ); } @@ -1654,4 +1996,49 @@ mod tests { } } } + + // For a bug where the GCL did not match the stake table contract implementation and allowed + // duplicated BLS keys via the update keys events. + #[rstest::rstest] + fn test_regression_non_unique_bls_keys_not_discarded( + #[values(StakeTableContractVersion::V1, StakeTableContractVersion::V2)] + version: StakeTableContractVersion, + ) { + let val = TestValidator::random(); + let register: StakeTableEvent = match version { + StakeTableContractVersion::V1 => ValidatorRegistered::from(&val).into(), + StakeTableContractVersion::V2 => ValidatorRegisteredV2::from(&val).into(), + }; + let delegate: StakeTableEvent = Delegated { + delegator: Address::random(), + validator: val.account, + amount: U256::from(10), + } + .into(); + + // first ensure that wan build a valid stake table + assert!(active_validator_set_from_l1_events( + vec![register.clone(), delegate.clone()].into_iter() + ) + .is_ok()); + + // add the invalid key update (re-using the same consensus keys) + let key_update = ConsensusKeysUpdated::from(&val).into(); + assert!(active_validator_set_from_l1_events( + vec![register, delegate, key_update].into_iter() + ) + .unwrap_err() + .to_string() + .contains("bls key already used")); + } + + #[test] + fn test_display_log() { + let serialized = r#"{"address":"0x0000000000000000000000000000000000000069","topics":["0x0000000000000000000000000000000000000000000000000000000000000069"],"data":"0x69","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000069","blockNumber":"0x69","blockTimestamp":"0x69","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000069","transactionIndex":"0x69","logIndex":"0x70","removed":false}"#; + let log: Log = serde_json::from_str(serialized).unwrap(); + assert_eq!( + log.display(), + "Log(block=105,index=112,transaction_hash=0x0000000000000000000000000000000000000000000000000000000000000069)" + ) + } } diff --git a/types/src/v0/v0_3/stake_table.rs b/types/src/v0/v0_3/stake_table.rs index 30fe269b02..46f1b36919 100644 --- a/types/src/v0/v0_3/stake_table.rs +++ b/types/src/v0/v0_3/stake_table.rs @@ -4,8 +4,9 @@ use alloy::primitives::{Address, U256}; use async_lock::Mutex; use derive_more::derive::{From, Into}; use hotshot::types::{BLSPubKey, SignatureKey}; -use hotshot_contract_adapter::sol_types::StakeTable::{ - ConsensusKeysUpdated, Delegated, Undelegated, ValidatorExit, ValidatorRegistered, +use hotshot_contract_adapter::sol_types::StakeTableV2::{ + ConsensusKeysUpdated, ConsensusKeysUpdatedV2, Delegated, Undelegated, ValidatorExit, + ValidatorRegistered, ValidatorRegisteredV2, }; use hotshot_types::{ data::EpochNumber, light_client::StateVerKey, network::PeerConfigKeys, PeerConfig, @@ -95,8 +96,10 @@ pub type EventKey = (u64, u64); #[derive(Clone, derive_more::From, PartialEq, serde::Serialize, serde::Deserialize)] pub enum StakeTableEvent { Register(ValidatorRegistered), + RegisterV2(ValidatorRegisteredV2), Deregister(ValidatorExit), Delegate(Delegated), Undelegate(Undelegated), KeyUpdate(ConsensusKeysUpdated), + KeyUpdateV2(ConsensusKeysUpdatedV2), }