diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 475e2f265..3d35d68f8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,6 +15,9 @@ jobs: - name: Update rust toolchain from rust-toolchain file run: rustup update + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + - uses: Swatinem/rust-cache@v2 with: workspaces: | diff --git a/Cargo.lock b/Cargo.lock index 95b1bfbe0..6b2cd802b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -318,6 +318,15 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +dependencies = [ + "serde", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -2275,6 +2284,130 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonrpsee" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4b0e68d9af1f066c06d6e2397583795b912d78537d7d907c561e82c13d69fa1" +dependencies = [ + "jsonrpsee-core", + "jsonrpsee-proc-macros", + "jsonrpsee-server", + "jsonrpsee-types", + "jsonrpsee-ws-client", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92f254f56af1ae84815b9b1325094743dcf05b92abb5e94da2e81a35cff0cada" +dependencies = [ + "futures-util", + "http", + "jsonrpsee-core", + "pin-project", + "rustls-native-certs", + "rustls-pki-types", + "soketto", + "thiserror", + "tokio", + "tokio-rustls 0.25.0", + "tokio-util", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "274d68152c24aa78977243bb56f28d7946e6aa309945b37d33174a3f92d89a3a" +dependencies = [ + "anyhow", + "async-trait", + "beef", + "futures-timer", + "futures-util", + "hyper", + "jsonrpsee-types", + "parking_lot", + "pin-project", + "rand", + "rustc-hash", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "jsonrpsee-proc-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c326f9e95aeff7d707b2ffde72c22a52acc975ba1c48587776c02b90c4747a6" +dependencies = [ + "heck 0.4.1", + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "jsonrpsee-server" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b5bfbda5f8fb63f997102fd18f73e35e34c84c6dcdbdbbe72c6e48f6d2c959b" +dependencies = [ + "futures-util", + "http", + "hyper", + "jsonrpsee-core", + "jsonrpsee-types", + "pin-project", + "route-recognizer", + "serde", + "serde_json", + "soketto", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dc828e537868d6b12bbb07ec20324909a22ced6efca0057c825c3e1126b2c6d" +dependencies = [ + "anyhow", + "beef", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f00abe918bf34b785f87459b9205790e5361a3f7437adb50e928dc243f27eb" +dependencies = [ + "http", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", + "url", +] + [[package]] name = "jsonwebtoken" version = "8.3.0" @@ -3794,6 +3927,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "route-recognizer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" + [[package]] name = "rstest" version = "0.16.0" @@ -3837,6 +3976,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -4199,6 +4344,19 @@ dependencies = [ "serde", ] +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha1" version = "0.10.6" @@ -4326,6 +4484,22 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "futures", + "http", + "httparse", + "log", + "rand", + "sha-1", +] + [[package]] name = "solang-parser" version = "0.3.3" @@ -4826,6 +5000,20 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-test" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2468baabc3311435b55dd935f702f42cd1b8abb7e754fb7dfb16bd36aa88f9f7" +dependencies = [ + "async-stream", + "bytes", + "futures-core", + "tokio", + "tokio-stream", ] [[package]] @@ -4851,6 +5039,7 @@ checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", @@ -5786,20 +5975,30 @@ dependencies = [ name = "xmtp_id" version = "0.1.0" dependencies = [ + "anyhow", "async-trait", "chrono", + "ctor", "ethers", "futures", + "hex", + "jsonrpsee", "log", "openmls", "openmls_basic_credential", "openmls_rust_crypto", "openmls_traits", "prost 0.12.3", + "rand", + "regex", "serde", + "serde_json", + "sha2 0.10.8", "thiserror", "tokio", + "tokio-test", "tracing", + "tracing-subscriber", "xmtp_cryptography", "xmtp_mls", "xmtp_proto", diff --git a/Cargo.toml b/Cargo.toml index 20bed97a2..fb1b1d979 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,10 @@ tls_codec = "0.4.0" tokio = { version = "1.35.1", features = ["macros"] } tonic = "^0.11" tracing = "0.1" +anyhow = "1.0" +jsonrpsee = { version = "0.22", features = ["macros", "server", "client-core"] } +tracing-subscriber = { version = "0.3.18", features = ["fmt", "env-filter"] } +ctor = "0.2" # Internal Crate Dependencies xmtp_cryptography = { path = "xmtp_cryptography" } diff --git a/README.md b/README.md index 5450e9623..eaf3fc032 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ LibXMTP is a shared library encapsulating the core functionality of the XMTP mes - InstallĀ [Rustup](https://rustup.rs/) - Install [Docker](https://www.docker.com/get-started/) +- Install [Foundry](https://book.getfoundry.sh/getting-started/installation#using-foundryup) ## Development diff --git a/bindings_ffi/src/mls.rs b/bindings_ffi/src/mls.rs index b5944251c..221efcc8a 100644 --- a/bindings_ffi/src/mls.rs +++ b/bindings_ffi/src/mls.rs @@ -19,7 +19,8 @@ use xmtp_mls::{ client::Client as MlsClient, groups::MlsGroup, storage::{ - group_message::StoredGroupMessage, EncryptedMessageStore, EncryptionKey, StorageOption, + group_message::GroupMessageKind, group_message::StoredGroupMessage, EncryptedMessageStore, + EncryptionKey, StorageOption, }, types::Address, }; @@ -224,7 +225,10 @@ impl FfiConversations { Ok(out) } - pub fn process_streamed_welcome_message(&self, envelope_bytes: Vec) -> Result, GenericError> { + pub fn process_streamed_welcome_message( + &self, + envelope_bytes: Vec, + ) -> Result, GenericError> { let inner = self.inner_client.as_ref(); let group = inner.process_streamed_welcome_message(envelope_bytes)?; @@ -365,7 +369,13 @@ impl FfiGroup { ); let messages: Vec = group - .find_messages(None, opts.sent_before_ns, opts.sent_after_ns, None, opts.limit)? + .find_messages( + None, + opts.sent_before_ns, + opts.sent_after_ns, + None, + opts.limit, + )? .into_iter() .map(|msg| msg.into()) .collect(); @@ -373,7 +383,10 @@ impl FfiGroup { Ok(messages) } - pub async fn process_streamed_group_message(&self, envelope_bytes: Vec) -> Result { + pub async fn process_streamed_group_message( + &self, + envelope_bytes: Vec, + ) -> Result { let group = MlsGroup::new( self.inner_client.as_ref(), self.group_id.clone(), @@ -381,7 +394,7 @@ impl FfiGroup { ); let message = group.process_streamed_group_message(envelope_bytes).await?; let ffi_message = message.into(); - + Ok(ffi_message) } @@ -484,6 +497,21 @@ impl FfiGroup { } } +#[derive(uniffi::Enum)] +pub enum FfiGroupMessageKind { + Application, + MembershipChange, +} + +impl From for FfiGroupMessageKind { + fn from(kind: GroupMessageKind) -> Self { + match kind { + GroupMessageKind::Application => FfiGroupMessageKind::Application, + GroupMessageKind::MembershipChange => FfiGroupMessageKind::MembershipChange, + } + } +} + #[derive(uniffi::Record)] pub struct FfiMessage { pub id: Vec, @@ -491,6 +519,7 @@ pub struct FfiMessage { pub convo_id: Vec, pub addr_from: String, pub content: Vec, + pub kind: FfiGroupMessageKind, } impl From for FfiMessage { @@ -501,6 +530,7 @@ impl From for FfiMessage { convo_id: msg.group_id, addr_from: msg.sender_account_address, content: msg.decrypted_message_bytes, + kind: msg.kind.into(), } } } diff --git a/dev/up b/dev/up index 217727f0f..7af7bf3d7 100755 --- a/dev/up +++ b/dev/up @@ -12,6 +12,13 @@ if [[ "${OSTYPE}" == "darwin"* ]]; then fi if ! kotlinc -version &>/dev/null; then brew install kotlin; fi if ! swiftformat -version &>/dev/null; then brew install swiftformat; fi + if ! foundryup -version &>/dev/null; then + # install foundry for tests that require mocking blockchain + curl -L https://foundry.paradigm.xyz | bash + # you may need to adjust this depending on which $SHELL you use + source $HOME/.zshenv + foundryup + fi fi rustup update diff --git a/diagrams/HLSDK.mermaid b/diagrams/HLSDK.mermaid new file mode 100644 index 000000000..5cd8926b7 --- /dev/null +++ b/diagrams/HLSDK.mermaid @@ -0,0 +1,24 @@ +block-beta + columns 4 + block:group1:2 + columns 2 + Android LibXMTP + end + space:2 + + block:group3:2 + columns 2 + React C["LibXMTP"] + end + space + Node["XMTP Node"] + block:group2:2 + columns 2 + iOS B["LibXMTP"] + end + group1-->Node + Node-->group1 + group2-->Node + Node-->group2 + group3-->Node + Node-->group3 \ No newline at end of file diff --git a/diagrams/add-remove.mermaid b/diagrams/add-remove.mermaid index f0d8cca15..6199a07d7 100644 --- a/diagrams/add-remove.mermaid +++ b/diagrams/add-remove.mermaid @@ -4,36 +4,37 @@ sequenceDiagram participant Charlie participant LibXMTP participant Node - + Note left of Alice: Remove Charlie - Alice->>LibXMTP: group.removeMembers(Charlie) + Alice->>LibXMTP: group.remove_members(Charlie) + LibXMTP->>+Node: get-identity-updates(Charlie) + Node-->>-LibXMTP: installation_key:Charlie + credential_identity:Charlie LibXMTP->>Node: send-group-message(REMOVE_MEMBER:installation_key:Charlie) - Alice->>+LibXMTP: group.messages() + Alice->>+LibXMTP: group.sync() LibXMTP->>+Node: query-group-messages(group_id) Node->>-LibXMTP: REMOVE_MEMBER:Charlie LibXMTP-->>-Alice: "Charlie has been removed from the group" - Bob->>+LibXMTP: group.messages() + Bob->>+LibXMTP: group.sync() LibXMTP->>+Node: query-group-messages(group_id) Node->>-LibXMTP: REMOVE_MEMBER:Charlie LibXMTP-->>-Bob: "Charlie has been removed from the group" Note left of Alice: Add Charlie - Bob->>LibXMTP: addMembers(Charlie) + Alice->>LibXMTP: addMembers(Charlie) LibXMTP->>+Node: get-identity-updates(Charlie) Node-->>-LibXMTP: installation_key:Charlie + credential_identity:Charlie LibXMTP->>Node: send-group-message(ADD_MEMBER:installation_key:Charlie) - Bob->>+LibXMTP: group.messages() + Alice->>+LibXMTP: group.sync() LibXMTP->>+Node: query-group-messages(group_id) Node->>-LibXMTP: ADD_MEMBER:Charlie - LibXMTP-->>-Bob: "Charlie has been added to the group" - Alice->>+LibXMTP: group.messages() + LibXMTP-->>-Alice: "Charlie has been added to the group" + Bob->>+LibXMTP: group.sync() LibXMTP->>+Node: query-group-messages(group_id) Node->>-LibXMTP: ADD_MEMBER:Charlie - LibXMTP-->>-Alice: "Charlie has been added to the group" - Charlie->>+LibXMTP: syncGroups() + LibXMTP-->>-Bob: "Charlie has been added to the group" + Charlie->>+LibXMTP: conversations.sync() LibXMTP->>+Node: query-welcome-messages(installation_key:Charlie) Node-->>-LibXMTP: WelcomeMessages() - LibXMTP-->>-Charlie: "Alice has added you to a group" - Charlie->>LibXMTP: rotate_key_packages() - LibXMTP->>Node: upload-key-package() \ No newline at end of file + Charlie->>+LibXMTP: conversations.list() + LibXMTP-->>-Charlie: List of groups including new group \ No newline at end of file diff --git a/diagrams/create-client.mermaid b/diagrams/create-client.mermaid new file mode 100644 index 000000000..c122d9ae6 --- /dev/null +++ b/diagrams/create-client.mermaid @@ -0,0 +1,14 @@ +sequenceDiagram + participant Alice + participant LibXMTP + participant Node + + Note over Alice,LibXMTP: These calls are coming from higher-level SDKs on behalf of users + Note over Alice,Node: Step 1 (Account Creation) & 2 (Initial Keying Material) of MLS group creation combined + Alice->>+LibXMTP: create_client(encryption_key, account_address) + LibXMTP-->>-Alice: client + Alice->>+LibXMTP: client.text_to_sign() + LibXMTP-->>-Alice: text to be signed for register_identity + Alice->>LibXMTP: client.register_identity(recoverable_wallet_signature) + LibXMTP->>+Node: register_installation(key_package:Alice) + Node-->>-LibXMTP: installation_key:Alice \ No newline at end of file diff --git a/diagrams/diagrams.md b/diagrams/diagrams.md index 150209072..ee658f2f9 100644 --- a/diagrams/diagrams.md +++ b/diagrams/diagrams.md @@ -4,6 +4,8 @@ The sequence diagrams stored here are for documenting LibXMTP's group chat imple The diagrams represent the creation of a group chat between Alice, Bob, and Charlie, our implmentation of [Figure 2](https://messaginglayersecurity.rocks/mls-architecture/draft-ietf-mls-architecture.html#fig-group-formation-example) from [The Messaging Layer Security (MLS) Architecture](https://messaginglayersecurity.rocks/mls-architecture/draft-ietf-mls-architecture.html) spec. +Note: calls into LibXMTP with the `conversations.` prefix use the [Conversations](https://github.com/xmtp/libxmtp/blob/204b35a337daf2a9f2ed0cb20199e254d0a7493a/bindings_ffi/src/mls.rs#L188) protocol, and calls with a `group.` prefix use the [Group](https://github.com/xmtp/libxmtp/blob/204b35a337daf2a9f2ed0cb20199e254d0a7493a/bindings_ffi/src/mls.rs#L315) protocol. + * *form-group.mermaid* - Covers Steps 1-4 of forming a group. In LibXMTP, steps 1 and 2 happen at the same time, and steps 3 and 4 can also be consolidated by calling `newGroup()` with multiple participants. * *send-recieve.mermaid* - Covers sending and receiving messages to the newly formed group. * *add-remove.mermaid* - Covers adding and removing group members. @@ -21,18 +23,30 @@ sequenceDiagram Note over Alice,Charlie: These calls are coming from higher-level
SDKs on behalf of users Note over Alice,Node: Step 1 (Account Creation) & 2 (Initial Keying Material) of MLS group creation combined - Alice->>LibXMTP: create_client(encryption_key, account_address) + Alice->>+LibXMTP: create_client(encryption_key, account_address) + LibXMTP-->>-Alice: client + Alice->>+LibXMTP: client.text_to_sign() + LibXMTP-->>-Alice: text to be signed for register_identity + Alice->>LibXMTP: client.register_identity(recoverable_wallet_signature) LibXMTP->>+Node: register_installation(key_package:Alice) Node-->>-LibXMTP: installation_key:Alice - Bob->>LibXMTP: create_client(encryption_key, account_address) + Bob->>+LibXMTP: create_client(encryption_key, account_address) + LibXMTP-->>-Bob: client + Bob->>+LibXMTP: client.text_to_sign() + LibXMTP-->>-Bob: text to be signed for register_identity + Bob->>LibXMTP: client.register_identity(recoverable_wallet_signature) LibXMTP->>+Node: register_installation(key_package:Bob) Node-->>-LibXMTP: installation_key:Bob - Charlie->>LibXMTP: create_client(encryption_key, account_address) + Charlie->>+LibXMTP: create_client(encryption_key, account_address) + LibXMTP-->>-Charlie: client + Charlie->>+LibXMTP: client.text_to_sign() + LibXMTP-->>-Charlie: text to be signed for register_identity + Charlie->>LibXMTP: client.register_identity(recoverable_wallet_signature) LibXMTP->>+Node: register_installation(key_package:Charlie) Node-->>-LibXMTP: installation_key:Charlie Note over Alice,Node: Step 3 (Adding Bob) & 4 (Adding Charlie) of MLS group creation - Alice->>LibXMTP: newGroup(Bob, Charlie) + Alice->>LibXMTP: conversations.create_group(Bob, Charlie) LibXMTP->>+Node: get-identity-updates(Bob) Node-->>-LibXMTP: installation_key:Bob + credential_identity:Bob LibXMTP->>+Node: get-identity-updates(Charlie) @@ -40,18 +54,16 @@ sequenceDiagram LibXMTP->>Node: fetch-key-packages(installation_keys: Bob + Charlie) Node-->>LibXMTP: KeyPackages(Bob+Charlie) LibXMTP->>Node: send-welcome-messages(KeyPackages:Bob + Charlie) - Bob->>+LibXMTP: syncGroups() + Bob->>+LibXMTP: conversations.sync() LibXMTP->>+Node: query-welcome-messages(installation_key:Bob) Node-->>-LibXMTP: WelcomeMessages() - LibXMTP-->>-Bob: "Alice has added you to a group" - Bob->>LibXMTP: rotate_key_packages() - LibXMTP->>Node: upload-key-package() - Charlie->>+LibXMTP: syncGroups() + Bob->>+LibXMTP: conversations.list() + LibXMTP-->>-Bob: List of groups including new group + Charlie->>+LibXMTP: conversations.sync() LibXMTP->>+Node: query-welcome-messages(installation_key:Charlie) Node-->>-LibXMTP: WelcomeMessages() - LibXMTP-->>-Charlie: "Alice has added you to a group" - Charlie->>LibXMTP: rotate_key_packages() - LibXMTP->>Node: upload-key-package() + Charlie->>+LibXMTP: conversations.list() + LibXMTP-->>-Charlie: List of groups including new group ``` ## Send and Receive Messages @@ -60,7 +72,6 @@ sequenceDiagram sequenceDiagram participant Alice participant Bob - participant Charlie participant LibXMTP participant Node @@ -69,10 +80,11 @@ sequenceDiagram LibXMTP->>Node: send-group-messages(SEND_MESSAGE:"Hello, group!") Note left of Alice: Receive Message - Bob->>+LibXMTP: group.messages() - LibXMTP->>+Node: query-group-messages(group_id) - Node-->>-LibXMTP: "Hello, group!" - LibXMTP->>-Bob: "Hello, group!" + Bob->>LibXMTP: group.sync() + LibXMTP->>Node: query-group-messages(group_id) + Node-->>LibXMTP: "Hello, group!" + Bob->>LibXMTP: group.find_messages() + LibXMTP->>Bob: "Hello, group!" ``` ## Add and Remove Group Members @@ -84,39 +96,37 @@ sequenceDiagram participant Charlie participant LibXMTP participant Node - + Note left of Alice: Remove Charlie - Alice->>LibXMTP: group.removeMembers(Charlie) + Alice->>LibXMTP: group.remove_members(Charlie) LibXMTP->>Node: send-group-message(REMOVE_MEMBER:installation_key:Charlie) - Alice->>+LibXMTP: group.messages() + Alice->>+LibXMTP: group.sync() LibXMTP->>+Node: query-group-messages(group_id) Node->>-LibXMTP: REMOVE_MEMBER:Charlie LibXMTP-->>-Alice: "Charlie has been removed from the group" - Bob->>+LibXMTP: group.messages() + Bob->>+LibXMTP: group.sync() LibXMTP->>+Node: query-group-messages(group_id) Node->>-LibXMTP: REMOVE_MEMBER:Charlie LibXMTP-->>-Bob: "Charlie has been removed from the group" Note left of Alice: Add Charlie - Bob->>LibXMTP: addMembers(Charlie) + Alice->>LibXMTP: add_members(Charlie) LibXMTP->>+Node: get-identity-updates(Charlie) Node-->>-LibXMTP: installation_key:Charlie + credential_identity:Charlie LibXMTP->>Node: send-group-message(ADD_MEMBER:installation_key:Charlie) - Bob->>+LibXMTP: group.messages() + Alice->>+LibXMTP: group.sync() LibXMTP->>+Node: query-group-messages(group_id) Node->>-LibXMTP: ADD_MEMBER:Charlie - LibXMTP-->>-Bob: "Charlie has been added to the group" - Alice->>+LibXMTP: group.messages() + LibXMTP-->>-Alice: "Charlie has been added to the group" + Bob->>+LibXMTP: group.sync() LibXMTP->>+Node: query-group-messages(group_id) Node->>-LibXMTP: ADD_MEMBER:Charlie - LibXMTP-->>-Alice: "Charlie has been added to the group" - Charlie->>+LibXMTP: syncGroups() + LibXMTP-->>-Bob: "Charlie has been added to the group" + Charlie->>+LibXMTP: conversations.sync() LibXMTP->>+Node: query-welcome-messages(installation_key:Charlie) Node-->>-LibXMTP: WelcomeMessages() LibXMTP-->>-Charlie: "Alice has added you to a group" - Charlie->>LibXMTP: rotate_key_packages() - LibXMTP->>Node: upload-key-package() ``` ## Sync Installations diff --git a/diagrams/form-group.mermaid b/diagrams/form-group.mermaid index d418deb43..025a3ca25 100644 --- a/diagrams/form-group.mermaid +++ b/diagrams/form-group.mermaid @@ -7,18 +7,30 @@ sequenceDiagram Note over Alice,Charlie: These calls are coming from higher-level
SDKs on behalf of users Note over Alice,Node: Step 1 (Account Creation) & 2 (Initial Keying Material) of MLS group creation combined - Alice->>LibXMTP: create_client(encryption_key, account_address) + Alice->>+LibXMTP: create_client(encryption_key, account_address) + LibXMTP-->>-Alice: client + Alice->>+LibXMTP: client.text_to_sign() + LibXMTP-->>-Alice: text to be signed for register_identity + Alice->>LibXMTP: client.register_identity(recoverable_wallet_signature) LibXMTP->>+Node: register_installation(key_package:Alice) Node-->>-LibXMTP: installation_key:Alice - Bob->>LibXMTP: create_client(encryption_key, account_address) + Bob->>+LibXMTP: create_client(encryption_key, account_address) + LibXMTP-->>-Bob: client + Bob->>+LibXMTP: client.text_to_sign() + LibXMTP-->>-Bob: text to be signed for register_identity + Bob->>LibXMTP: client.register_identity(recoverable_wallet_signature) LibXMTP->>+Node: register_installation(key_package:Bob) Node-->>-LibXMTP: installation_key:Bob - Charlie->>LibXMTP: create_client(encryption_key, account_address) + Charlie->>+LibXMTP: create_client(encryption_key, account_address) + LibXMTP-->>-Charlie: client + Charlie->>+LibXMTP: client.text_to_sign() + LibXMTP-->>-Charlie: text to be signed for register_identity + Charlie->>LibXMTP: client.register_identity(recoverable_wallet_signature) LibXMTP->>+Node: register_installation(key_package:Charlie) Node-->>-LibXMTP: installation_key:Charlie Note over Alice,Node: Step 3 (Adding Bob) & 4 (Adding Charlie) of MLS group creation - Alice->>LibXMTP: newGroup(Bob, Charlie) + Alice->>LibXMTP: conversations.create_group(Bob, Charlie) LibXMTP->>+Node: get-identity-updates(Bob) Node-->>-LibXMTP: installation_key:Bob + credential_identity:Bob LibXMTP->>+Node: get-identity-updates(Charlie) @@ -26,15 +38,13 @@ sequenceDiagram LibXMTP->>Node: fetch-key-packages(installation_keys: Bob + Charlie) Node-->>LibXMTP: KeyPackages(Bob+Charlie) LibXMTP->>Node: send-welcome-messages(KeyPackages:Bob + Charlie) - Bob->>+LibXMTP: syncGroups() + Bob->>+LibXMTP: conversations.sync() LibXMTP->>+Node: query-welcome-messages(installation_key:Bob) Node-->>-LibXMTP: WelcomeMessages() - LibXMTP-->>-Bob: "Alice has added you to a group" - Bob->>LibXMTP: rotate_key_packages() - LibXMTP->>Node: upload-key-package() - Charlie->>+LibXMTP: syncGroups() + Bob->>+LibXMTP: conversations.list() + LibXMTP-->>-Bob: List of groups including new group + Charlie->>+LibXMTP: conversations.sync() LibXMTP->>+Node: query-welcome-messages(installation_key:Charlie) Node-->>-LibXMTP: WelcomeMessages() - LibXMTP-->>-Charlie: "Alice has added you to a group" - Charlie->>LibXMTP: rotate_key_packages() - LibXMTP->>Node: upload-key-package() \ No newline at end of file + Charlie->>+LibXMTP: conversations.list() + LibXMTP-->>-Charlie: List of groups including new group diff --git a/diagrams/send-receive.mermaid b/diagrams/send-receive.mermaid index 08344b88c..93e92554f 100644 --- a/diagrams/send-receive.mermaid +++ b/diagrams/send-receive.mermaid @@ -1,7 +1,6 @@ sequenceDiagram participant Alice participant Bob - participant Charlie participant LibXMTP participant Node @@ -10,7 +9,8 @@ sequenceDiagram LibXMTP->>Node: send-group-messages(SEND_MESSAGE:"Hello, group!") Note left of Alice: Receive Message - Bob->>+LibXMTP: group.messages() - LibXMTP->>+Node: query-group-messages(group_id) - Node-->>-LibXMTP: "Hello, group!" - LibXMTP->>-Bob: "Hello, group!" \ No newline at end of file + Bob->>LibXMTP: group.sync() + LibXMTP->>Node: query-group-messages(group_id) + Node-->>LibXMTP: "Alice: Hello, group!" + Bob->>LibXMTP: group.find_messages() + LibXMTP-->>Bob: "Alice: Hello, group!" \ No newline at end of file diff --git a/xmtp_api_grpc/src/auth_token.rs b/xmtp_api_grpc/src/auth_token.rs index af82e143e..b2eb43f6b 100644 --- a/xmtp_api_grpc/src/auth_token.rs +++ b/xmtp_api_grpc/src/auth_token.rs @@ -55,8 +55,7 @@ impl Authenticator { let mut token_bytes = Vec::new(); let _ = token.encode(&mut token_bytes); - let token_base64 = base64::engine::general_purpose::STANDARD.encode(&token_bytes); - token_base64 + base64::engine::general_purpose::STANDARD.encode(&token_bytes) } fn sign(&self, bytes_to_sign: &[u8]) -> Signature { diff --git a/xmtp_cryptography/src/utils.rs b/xmtp_cryptography/src/utils.rs index 9b5b97bdd..efbc1c502 100644 --- a/xmtp_cryptography/src/utils.rs +++ b/xmtp_cryptography/src/utils.rs @@ -1,4 +1,4 @@ -use ethers::signers::LocalWallet; +pub use ethers::prelude::LocalWallet; use ethers_core::utils::keccak256; use k256::ecdsa::VerifyingKey; use rand::{CryptoRng, RngCore, SeedableRng}; diff --git a/xmtp_id/Cargo.toml b/xmtp_id/Cargo.toml index 360708dc8..1cdf4abc7 100644 --- a/xmtp_id/Cargo.toml +++ b/xmtp_id/Cargo.toml @@ -21,7 +21,18 @@ chrono.workspace = true serde.workspace = true async-trait.workspace = true futures.workspace = true +sha2 = "0.10.8" +rand.workspace = true +hex.workspace = true +ethers.workspace = true [dev-dependencies] -ethers.workspace = true -tokio.workspace = true +tracing-subscriber.workspace = true +serde_json.workspace = true +anyhow.workspace = true +tokio = { workspace = true, features = ["time"] } +jsonrpsee = { workspace = true, features = ["macros", "ws-client"] } +ethers = { workspace = true, features = ["ws"] } +tokio-test = "0.4" +ctor.workspace = true +regex = "1.10" diff --git a/xmtp_id/artifact/CoinbaseSmartWallet.json b/xmtp_id/artifact/CoinbaseSmartWallet.json new file mode 100644 index 000000000..8ab7f4d6c --- /dev/null +++ b/xmtp_id/artifact/CoinbaseSmartWallet.json @@ -0,0 +1,9281 @@ +{ + "abi": [ + { + "type": "constructor", + "inputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "fallback", + "stateMutability": "payable" + }, + { + "type": "receive", + "stateMutability": "payable" + }, + { + "type": "function", + "name": "REPLAYABLE_NONCE_KEY", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "addOwnerAddress", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "addOwnerPublicKey", + "inputs": [ + { + "name": "x", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "y", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "canSkipChainIdValidation", + "inputs": [ + { + "name": "functionSelector", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "domainSeparator", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "eip712Domain", + "inputs": [], + "outputs": [ + { + "name": "fields", + "type": "bytes1", + "internalType": "bytes1" + }, + { + "name": "name", + "type": "string", + "internalType": "string" + }, + { + "name": "version", + "type": "string", + "internalType": "string" + }, + { + "name": "chainId", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "verifyingContract", + "type": "address", + "internalType": "address" + }, + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "extensions", + "type": "uint256[]", + "internalType": "uint256[]" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "entryPoint", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "execute", + "inputs": [ + { + "name": "target", + "type": "address", + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "executeBatch", + "inputs": [ + { + "name": "calls", + "type": "tuple[]", + "internalType": "struct CoinbaseSmartWallet.Call[]", + "components": [ + { + "name": "target", + "type": "address", + "internalType": "address" + }, + { + "name": "value", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "executeWithoutChainIdValidation", + "inputs": [ + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "getUserOpHashWithoutChainId", + "inputs": [ + { + "name": "userOp", + "type": "tuple", + "internalType": "struct UserOperation", + "components": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "nonce", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "initCode", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "callData", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "callGasLimit", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "verificationGasLimit", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "preVerificationGas", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxFeePerGas", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxPriorityFeePerGas", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "paymasterAndData", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [ + { + "name": "userOpHash", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "implementation", + "inputs": [], + "outputs": [ + { + "name": "addr", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "owners", + "type": "bytes[]", + "internalType": "bytes[]" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "isOwnerAddress", + "inputs": [ + { + "name": "account", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isOwnerBytes", + "inputs": [ + { + "name": "account", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isOwnerPublicKey", + "inputs": [ + { + "name": "x", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "y", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "isValidSignature", + "inputs": [ + { + "name": "hash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "result", + "type": "bytes4", + "internalType": "bytes4" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "nextOwnerIndex", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "ownerAtIndex", + "inputs": [ + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes", + "internalType": "bytes" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "proxiableUUID", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "removeOwnerAtIndex", + "inputs": [ + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "replaySafeHash", + "inputs": [ + { + "name": "hash", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "upgradeToAndCall", + "inputs": [ + { + "name": "newImplementation", + "type": "address", + "internalType": "address" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "validateUserOp", + "inputs": [ + { + "name": "userOp", + "type": "tuple", + "internalType": "struct UserOperation", + "components": [ + { + "name": "sender", + "type": "address", + "internalType": "address" + }, + { + "name": "nonce", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "initCode", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "callData", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "callGasLimit", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "verificationGasLimit", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "preVerificationGas", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxFeePerGas", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxPriorityFeePerGas", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "paymasterAndData", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "name": "userOpHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "missingAccountFunds", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "validationData", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "payable" + }, + { + "type": "event", + "name": "AddOwner", + "inputs": [ + { + "name": "index", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "owner", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RemoveOwner", + "inputs": [ + { + "name": "index", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + }, + { + "name": "owner", + "type": "bytes", + "indexed": false, + "internalType": "bytes" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Upgraded", + "inputs": [ + { + "name": "implementation", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AlreadyOwner", + "inputs": [ + { + "name": "owner", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "type": "error", + "name": "Initialized", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidEthereumAddressOwner", + "inputs": [ + { + "name": "owner", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "type": "error", + "name": "InvalidNonceKey", + "inputs": [ + { + "name": "key", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "InvalidOwnerBytesLength", + "inputs": [ + { + "name": "owner", + "type": "bytes", + "internalType": "bytes" + } + ] + }, + { + "type": "error", + "name": "NoOwnerAtIndex", + "inputs": [ + { + "name": "index", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "SelectorNotAllowed", + "inputs": [ + { + "name": "selector", + "type": "bytes4", + "internalType": "bytes4" + } + ] + }, + { + "type": "error", + "name": "Unauthorized", + "inputs": [] + }, + { + "type": "error", + "name": "UnauthorizedCallContext", + "inputs": [] + }, + { + "type": "error", + "name": "UpgradeFailed", + "inputs": [] + } + ], + "bytecode": { + "object": "0x60a0604052306080523480156200001557600080fd5b50604080516001808252818301909252600091816020015b60608152602001906001900390816200002d57905050604080516000602082015291925001604051602081830303815290604052816000815181106200007757620000776200037a565b60209081029190910101526200008d8162000094565b50620005b0565b60005b81518110156200022657818181518110620000b657620000b66200037a565b602002602001015151602014158015620000ee5750818181518110620000e057620000e06200037a565b602002602001015151604014155b1562000136578181815181106200010957620001096200037a565b60200260200101516040516327755b9160e11b81526004016200012d9190620003b6565b60405180910390fd5b8181815181106200014b576200014b6200037a565b60200260200101515160201480156200019357506001600160a01b0380168282815181106200017e576200017e6200037a565b60200260200101516200019190620003eb565b115b15620001d257818181518110620001ae57620001ae6200037a565b602002602001015160405163bff1ac6560e01b81526004016200012d9190620003b6565b6200021d828281518110620001eb57620001eb6200037a565b6020026020010151620002036200022a60201b60201c565b8054906000620002138362000413565b909155506200023d565b60010162000097565b5050565b6000805160206200383783398151915290565b620002488262000326565b156200026b578160405163468b12ad60e11b81526004016200012d9190620003b6565b600160008051602062003837833981519152600201836040516200029091906200043b565b908152604051908190036020019020805491151560ff1990921691909117905581620002c86000805160206200383783398151915290565b60008381526001919091016020526040902090620002e79082620004e4565b50807f38109edc26e166b5579352ce56a50813177eb25208fd90d61f2f378386220220836040516200031a9190620003b6565b60405180910390a25050565b600060008051602062003837833981519152600201826040516200034b91906200043b565b9081526040519081900360200190205460ff1692915050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60005b83811015620003ad57818101518382015260200162000393565b50506000910152565b6020815260008251806020840152620003d781604085016020870162000390565b601f01601f19169190910160400192915050565b805160208083015191908110156200040d576000198160200360031b1b821691505b50919050565b6000600182016200043457634e487b7160e01b600052601160045260246000fd5b5060010190565b600082516200044f81846020870162000390565b9190910192915050565b600181811c908216806200046e57607f821691505b6020821081036200040d57634e487b7160e01b600052602260045260246000fd5b601f821115620004df576000816000526020600020601f850160051c81016020861015620004ba5750805b601f850160051c820191505b81811015620004db57828155600101620004c6565b5050505b505050565b81516001600160401b0381111562000500576200050062000364565b620005188162000511845462000459565b846200048f565b602080601f831160018114620005505760008415620005375750858301515b600019600386901b1c1916600185901b178555620004db565b600085815260208120601f198616915b82811015620005815788860151825594840194600190910190840162000560565b5085821015620005a05787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051613264620005d36000396000818161081e015261095501526132646000f3fe60806040526004361061014f5760003560e01c806372de3b5a116100b6578063b0d691fe1161006f578063b0d691fe146103f4578063b61d27f61461041b578063bf6ba1fc1461042e578063ce1506be14610441578063d948fd2e14610461578063f698da251461048357610156565b806372de3b5a1461032957806384b0196e1461034957806388ce4c7c146103715780638ea69029146103875780639f9bcb34146103b4578063a2e1a8d8146103d457610156565b80633a871cdd116101085780633a871cdd146102655780634f1ef286146102865780634f6e7f221461029957806352d1902d146102b95780635c60da1b146102ce5780636f2de70e1461031657610156565b8063066a1eb7146101845780630f0f3f24146101b95780631626ba7e146101d95780631ca5393f1461021257806329565e3b1461023257806334fcd5be1461025257610156565b3661015657005b60003560e01c63bc197c81811463f23a6e6182141763150b7a028214171561018257806020526020603cf35b005b34801561019057600080fd5b506101a461019f366004612769565b610498565b60405190151581526020015b60405180910390f35b3480156101c557600080fd5b506101826101d43660046127a7565b610507565b3480156101e557600080fd5b506101f96101f436600461280a565b61053f565b6040516001600160e01b031990911681526020016101b0565b34801561021e57600080fd5b506101a461022d366004612940565b610579565b34801561023e57600080fd5b5061018261024d366004612769565b6105b4565b6101826102603660046129b8565b6105dd565b610278610273366004612a12565b6106e1565b6040519081526020016101b0565b610182610294366004612a5f565b61081c565b3480156102a557600080fd5b506102786102b4366004612a98565b610900565b3480156102c557600080fd5b50610278610951565b3480156102da57600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545b6040516001600160a01b0390911681526020016101b0565b6101826103243660046129b8565b6109b1565b34801561033557600080fd5b50610182610344366004612acc565b6109f1565b34801561035557600080fd5b5061035e610ade565b6040516101b09796959493929190612b35565b34801561037d57600080fd5b5061027861210581565b34801561039357600080fd5b506103a76103a2366004612acc565b610b05565b6040516101b09190612bce565b3480156103c057600080fd5b506101a46103cf366004612be1565b610bc6565b3480156103e057600080fd5b506101a46103ef3660046127a7565b610c42565b34801561040057600080fd5b50735ff137d4b0fdcd49dca30c7cf57e578a026d27896102fe565b610182610429366004612c0b565b610c88565b61018261043c366004612c64565b610cec565b34801561044d57600080fd5b5061027861045c366004612acc565b610dad565b34801561046d57600080fd5b5060008051602061320f83398151915254610278565b34801561048f57600080fd5b50610278610db8565b60408051602081018490529081018290526000907f97e2c6aad4ce5d562ebfaa00db6b9e0fb66ea5d8162ed5b243f51a2e03086f029060600160408051601f19818403018152908290526104eb91612c99565b9081526040519081900360200190205460ff1690505b92915050565b61050f610e3e565b604080516001600160a01b038316602082015261053c91015b604051602081830303815290604052610e70565b50565b600061055461054d85610dad565b8484610e9b565b156105675750630b135d3f60e11b610572565b506001600160e01b03195b9392505050565b600060008051602061320f8339815191526002018260405161059b9190612c99565b9081526040519081900360200190205460ff1692915050565b6105bc610e3e565b60408051602081018490529081018290526105d990606001610528565b5050565b33735ff137d4b0fdcd49dca30c7cf57e578a026d27891461060057610600610e3e565b60005b818110156106dc576106d483838381811061062057610620612cb5565b90506020028101906106329190612ccb565b6106409060208101906127a7565b84848481811061065257610652612cb5565b90506020028101906106649190612ccb565b6020013585858581811061067a5761067a612cb5565b905060200281019061068c9190612ccb565b61069a906040810190612ce1565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610fb092505050565b600101610603565b505050565b600033735ff137d4b0fdcd49dca30c7cf57e578a026d278914610716576040516282b42960e81b815260040160405180910390fd5b81602085013560401c600461072e6060880188612ce1565b90501015801561077257506107466060870187612ce1565b61075591600491600091612d27565b61075e91612d51565b6001600160e01b03191663bf6ba1fc60e01b145b156107b15761078086610900565b945061210581146107ac57604051632ef3781360e01b8152600481018290526024015b60405180910390fd5b6107d6565b61210581036107d657604051632ef3781360e01b8152600481018290526024016107a3565b6107ed856107e8610140890189612ce1565b610e9b565b156107fc576000925050610802565b60019250505b80156108145760003860003884335af1505b509392505050565b7f000000000000000000000000000000000000000000000000000000000000000030810361085257639f03a0266000526004601cfd5b61085b84611020565b8360601b60601c93506352d1902d6001527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80602060016004601d895afa51146108ad576355299b496001526004601dfd5b847fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600038a284905581156108fa57604051828482376000388483885af46108f8573d6000823e3d81fd5b505b50505050565b600061090b82611028565b604080516020810192909252735ff137d4b0fdcd49dca30c7cf57e578a026d2789908201526060015b604051602081830303815290604052805190602001209050919050565b60007f000000000000000000000000000000000000000000000000000000000000000030811461098957639f03a0266000526004601cfd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91505b5090565b60008051602061320f83398151915254156109df576040516302ed543d60e51b815260040160405180910390fd5b6105d96109ec8284612d81565b611041565b6109f9610e3e565b6000610a0482610b05565b90508051600003610a2b5760405163340c473d60e11b8152600481018390526024016107a3565b6040517f97e2c6aad4ce5d562ebfaa00db6b9e0fb66ea5d8162ed5b243f51a2e03086f0290610a5b908390612c99565b908152604051908190036020019020805460ff19169055610a8760008051602061320f83398151915290565b600083815260019190910160205260408120610aa29161271f565b817fcf95bbfe6f870f8cc40482dc3dccdafd268f0e9ce0a4f24ea1bea9be64e505ff82604051610ad29190612bce565b60405180910390a25050565b600f60f81b6060806000808083610af3611193565b97989097965046955030945091925090565b60008181527f97e2c6aad4ce5d562ebfaa00db6b9e0fb66ea5d8162ed5b243f51a2e03086f0160205260409020805460609190610b4190612e06565b80601f0160208091040260200160405190810160405280929190818152602001828054610b6d90612e06565b8015610bba5780601f10610b8f57610100808354040283529160200191610bba565b820191906000526020600020905b815481529060010190602001808311610b9d57829003601f168201915b50505050509050919050565b60006001600160e01b031982166329565e3b60e01b1480610bf757506001600160e01b031982166303c3cfc960e21b145b80610c1257506001600160e01b0319821663396f1dad60e11b145b80610c2d57506001600160e01b0319821663278f794360e11b145b15610c3a57506001919050565b506000919050565b600060008051602061320f833981519152604080516001600160a01b0385166020820152600292909201910160408051601f198184030181529082905261059b91612c99565b33735ff137d4b0fdcd49dca30c7cf57e578a026d278914610cab57610cab610e3e565b6108fa848484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610fb092505050565b33735ff137d4b0fdcd49dca30c7cf57e578a026d278914610d1f576040516282b42960e81b815260040160405180910390fd5b6000610d2e6004828486612d27565b610d3791612d51565b9050610d4281610bc6565b610d6b57604051631d8370a360e11b81526001600160e01b0319821660048201526024016107a3565b6106dc30600085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610fb092505050565b6000610501826111da565b6000806000610dc5611193565b8151602080840191909120825182840120604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f9481019490945283019190915260608201524660808201523060a0820152919350915060c001604051602081830303815290604052805190602001209250505090565b610e4733610c42565b80610e5157503330145b15610e5857565b6040516282b42960e81b815260040160405180910390fd5b61053c8160008051602061320f8339815191525b8054906000610e9283612e50565b91905055611210565b600080610eaa83850185612e69565b90506000610ebb8260000151610b05565b90508051602003610f1a576001600160a01b03610ed782612ef5565b1115610ef8578060405163bff1ac6560e01b81526004016107a39190612bce565b600060208201519050610f10818885602001516112df565b9350505050610572565b8051604003610f955760008082806020019051810190610f3a9190612f19565b9150915060008460200151806020019051810190610f589190612f82565b9050610f8989604051602001610f7091815260200190565b60405160208183030381529060405260008386866113e4565b95505050505050610572565b806040516327755b9160e11b81526004016107a39190612bce565b600080846001600160a01b03168484604051610fcc9190612c99565b60006040518083038185875af1925050503d8060008114611009576040519150601f19603f3d011682016040523d82523d6000602084013e61100e565b606091505b5091509150816108f857805160208201fd5b61053c610e3e565b600061103382611754565b805190602001209050919050565b60005b81518110156105d95781818151811061105f5761105f612cb5565b602002602001015151602014158015611093575081818151811061108557611085612cb5565b602002602001015151604014155b156110cc578181815181106110aa576110aa612cb5565b60200260200101516040516327755b9160e11b81526004016107a39190612bce565b8181815181106110de576110de612cb5565b602002602001015151602014801561112057506001600160a01b03801682828151811061110d5761110d612cb5565b602002602001015161111e90612ef5565b115b156111595781818151811061113757611137612cb5565b602002602001015160405163bff1ac6560e01b81526004016107a39190612bce565b61118b82828151811061116e5761116e612cb5565b6020026020010151610e8460008051602061320f83398151915290565b600101611044565b604080518082018252601581527410dbda5b98985cd94814db585c9d0815d85b1b195d605a1b602080830191909152825180840190935260018352603160f81b9083015291565b60006111e4610db8565b6111ed83611827565b60405161190160f01b602082015260228101929092526042820152606201610934565b61121982610579565b15611239578160405163468b12ad60e11b81526004016107a39190612bce565b600160008051602061320f8339815191526002018360405161125b9190612c99565b908152604051908190036020019020805491151560ff199092169190911790558161129160008051602061320f83398151915290565b600083815260019190910160205260409020906112ae908261308d565b50807f38109edc26e166b5579352ce56a50813177eb25208fd90d61f2f37838622022083604051610ad29190612bce565b6001600160a01b03909216916000831561057257604051836000526020830151604052604083510361134f576040830151601b8160ff1c016020528060011b60011c60605250602060016080600060015afa805186183d151761134d57506000606052604052506001610572565b505b604183510361139557606083015160001a6020526040830151606052602060016080600060015afa805186183d151761139357506000606052604052506001610572565b505b600060605280604052631626ba7e60e01b808252846004830152602482016040815284516020018060448501828860045afa505060208160443d01858a5afa9051909114169150509392505050565b60007f7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a88460a00151111561141a5750600061174b565b606084015160009061143d9061143181601561314c565b60208801519190611862565b90507fff1a2a9176d650e4a99dedb58f1793003935130579fe17b5a3f698ac5b00e63481805190602001201461147757600091505061174b565b6000611485886001806118c8565b604051602001611495919061315f565b604051602081830303815290604052905060006114cd8760400151835189604001516114c1919061314c565b60208a01519190611862565b905081805190602001208180519060200120146114f0576000935050505061174b565b86518051600160f81b918291602090811061150d5761150d612cb5565b0160200151166001600160f81b0319161461152e576000935050505061174b565b878015611566575086518051600160fa1b918291602090811061155357611553612cb5565b0160200151166001600160f81b03191614155b15611577576000935050505061174b565b60006002886020015160405161158d9190612c99565b602060405180830381855afa1580156115aa573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906115cd91906131a0565b9050600060028960000151836040516020016115ea9291906131b9565b60408051601f198184030181529082905261160491612c99565b602060405180830381855afa158015611621573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061164491906131a0565b6080808b015160a0808d015160408051602081018790529081019390935260608301529181018b905290810189905290915060009060c00160405160208183030381529060405290506000806101006001600160a01b0316836040516116aa9190612c99565b600060405180830381855afa9150503d80600081146116e5576040519150601f19603f3d011682016040523d82523d6000602084013e6116ea565b606091505b508051919350915015158280156116fe5750805b1561172a578180602001905181019061171791906131a0565b600114995050505050505050505061174b565b61173f858e608001518f60a001518f8f6119bd565b99505050505050505050505b95945050505050565b606081356020830135600061177461176f6040870187612ce1565b611aa0565b9050600061178861176f6060880188612ce1565b9050608086013560a087013560c088013560e08901356101008a013560006117b761176f6101208e018e612ce1565b604080516001600160a01b039c909c1660208d01528b81019a909a5260608b019890985250608089019590955260a088019390935260c087019190915260e08601526101008501526101208401526101408084019190915281518084039091018152610160909201905292915050565b604080517f9b493d222105fee7df163ab5d57f0bf1ffd2da04dd5fafbe10b54c41c1adc6576020820152908101829052600090606001610934565b60608351828111611871578092505b83811161187c578093505b5081831015610572575060405182820380825293830193601f19601f820181165b868101518482015281018061189d5750600083830160200152603f9091011681016040529392505050565b606083518015610814576003600282010460021b60405192507f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526106708515027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f18603f52602083018181018388602001018051600082525b60038a0199508951603f8160121c1651600053603f81600c1c1651600153603f8160061c1651600253603f811651600353506000518452600484019350828410611944579052602001604052613d3d60f01b60038406600204808303919091526000861515909102918290035290038252509392505050565b60008415806119da57506000805160206131ef8339815191528510155b806119e3575083155b806119fc57506000805160206131ef8339815191528410155b15611a095750600061174b565b611a138383611ab3565b611a1f5750600061174b565b6000611a2a85611bad565b905060006000805160206131ef833981519152828909905060006000805160206131ef83398151915283890990506000611a6687878585611c1f565b90506000805160206131ef833981519152611a8f8a6000805160206131ef8339815191526131db565b8208159a9950505050505050505050565b6000604051828085833790209392505050565b600082158015611ac1575081155b80611ad95750600160601b63ffffffff60c01b031983145b80611af15750600160601b63ffffffff60c01b031982145b15611afe57506000610501565b6000600160601b63ffffffff60c01b031983840990506000600160601b63ffffffff60c01b0319807fffffffff00000001000000000000000000000000fffffffffffffffffffffffc8709600160601b63ffffffff60c01b031987600160601b63ffffffff60c01b0319898a0909089050600160601b63ffffffff60c01b03197f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b820891909114949350505050565b600060405160208152602080820152602060408201528260608201527fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f60808201526000805160206131ef83398151915260a082015260208160c0836005600019fa611c1857600080fd5b5192915050565b600080808060ff818088158015611c34575087155b15611c4857600096505050505050506122e1565b611c947f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2967f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f58d8d6122e9565b909250905081158015611ca5575080155b15611cd3576000805160206131ef833981519152886000805160206131ef833981519152038a089850600097505b600189841c16600189851c1660011b015b80611d065760018403935060018a851c1660018a861c1660011b019050611ce4565b50600189841c16600189851c1660011b01955060018603611d68577f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29696507f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f593505b60028603611d77578a96508993505b60038603611d86578196508093505b60018303925060019550600194505b82600019111561226a57600160601b63ffffffff60c01b031984600209600160601b63ffffffff60c01b0319818209600160601b63ffffffff60c01b0319818a09600160601b63ffffffff60c01b03198284099250600160601b63ffffffff60c01b031980600160601b63ffffffff60c01b03198b8d08600160601b63ffffffff60c01b03198c600160601b63ffffffff60c01b0319038e0809600309600160601b63ffffffff60c01b03198985099850600160601b63ffffffff60c01b03198a84099950600160601b63ffffffff60c01b031980836002600160601b0363ffffffff60c01b031909600160601b63ffffffff60c01b0319838409089a50600160601b63ffffffff60c01b03198083600160601b63ffffffff60c01b0319038d0882099250600160601b63ffffffff60c01b031983600160601b63ffffffff60c01b03198a870908975060018d881c1660018d891c1660011b01905080611f125787600160601b63ffffffff60c01b03190397505050505061225f565b60018103611f61577f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29693507f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f592505b60028103611f70578e93508d92505b60038103611f7f578593508492505b89611f98575091985060019750879650945061225f9050565b600160601b63ffffffff60c01b031988600160601b63ffffffff60c01b03198b860908600160601b63ffffffff60c01b03198c600160601b63ffffffff60c01b031903600160601b63ffffffff60c01b03198d880908935080612151578361215157600160601b63ffffffff60c01b0319896002600160601b0363ffffffff60c01b0319099450600160601b63ffffffff60c01b03198586099350600160601b63ffffffff60c01b0319848d099250600160601b63ffffffff60c01b03198486099450600160601b63ffffffff60c01b0319808c600160601b63ffffffff60c01b0319038e08600160601b63ffffffff60c01b03198d8f08099050600160601b63ffffffff60c01b0319816003099150600160601b63ffffffff60c01b03198a86099950600160601b63ffffffff60c01b03198b85099a50600160601b63ffffffff60c01b031980846002600160601b0363ffffffff60c01b031909600160601b63ffffffff60c01b0319848509089b50600160601b63ffffffff60c01b0319808d600160601b63ffffffff60c01b031903850883099350600160601b63ffffffff60c01b0319808a870985089850505050505061225f565b600160601b63ffffffff60c01b03198485099150600160601b63ffffffff60c01b0319848309600160601b63ffffffff60c01b0319838d099b50600160601b63ffffffff60c01b0319818c099a50600160601b63ffffffff60c01b0319838e09600160601b63ffffffff60c01b031980826002600160601b0363ffffffff60c01b031909600160601b63ffffffff60c01b031984600160601b63ffffffff60c01b031903600160601b63ffffffff60c01b031987880908089350600160601b63ffffffff60c01b031980838d09600160601b63ffffffff60c01b031985600160601b63ffffffff60c01b031988600160601b63ffffffff60c01b031903860809089a50505050809a50505050505b600183039250611d95565b60405186606082015260208152602080820152602060408201526002600160601b0363ffffffff60c01b03196080820152600160601b63ffffffff60c01b031960a082015260208160c0836005600019fa6122c457600080fd5b600160601b63ffffffff60c01b0319815189099750505050505050505b949350505050565b60008080808661230057858593509350505061236e565b8461231257878793509350505061236e565b858814801561232057508487145b15612341576123328888600180612377565b929a509098509250905061235b565b61235088886001808a8a6124d2565b929a50909850925090505b61236788888484612656565b9350935050505b94509492505050565b600080600080600160601b63ffffffff60c01b0319876002099350600160601b63ffffffff60c01b03198485099150600160601b63ffffffff60c01b03198289099050600160601b63ffffffff60c01b03198285099250600160601b63ffffffff60c01b03198683099150600160601b63ffffffff60c01b031980600160601b63ffffffff60c01b0319888b08600160601b63ffffffff60c01b031989600160601b63ffffffff60c01b0319038c08096003099550600160601b63ffffffff60c01b031980826002600160601b0363ffffffff60c01b031909600160601b63ffffffff60c01b0319888909089350600160601b63ffffffff60c01b03198085600160601b63ffffffff60c01b031903830887099750600160601b63ffffffff60c01b03198584099050600160601b63ffffffff60c01b031980888509600160601b63ffffffff60c01b03190389089250945094509450949050565b600080600080886000036124f157508492508391506001905080612649565b600160601b63ffffffff60c01b0319988903988981898809089450600160601b63ffffffff60c01b03198a600160601b63ffffffff60c01b031903600160601b63ffffffff60c01b03198a8909089550600160601b63ffffffff60c01b03198687099350600160601b63ffffffff60c01b03198685099250600160601b63ffffffff60c01b03198489099150600160601b63ffffffff60c01b03198388099050600160601b63ffffffff60c01b0319848b099750600160601b63ffffffff60c01b031980896002600160601b0363ffffffff60c01b031909600160601b63ffffffff60c01b031985600160601b63ffffffff60c01b031903600160601b63ffffffff60c01b0319898a0908089350600160601b63ffffffff60c01b031980848b09600160601b63ffffffff60c01b031987600160601b63ffffffff60c01b031988600160601b63ffffffff60c01b0319038d08090892505b9650965096509692505050565b6000806000612664846126c3565b9050600160601b63ffffffff60c01b031981870991506000600160601b63ffffffff60c01b03198287099050600160601b63ffffffff60c01b03198182099150600160601b63ffffffff60c01b03198289099350505094509492505050565b600060405160208152602080820152602060408201528260608201526002600160601b0363ffffffff60c01b03196080820152600160601b63ffffffff60c01b031960a082015260208160c0836005600019fa611c1857600080fd5b50805461272b90612e06565b6000825580601f1061273b575050565b601f01602090049060005260206000209081019061053c91905b808211156109ad5760008155600101612755565b6000806040838503121561277c57600080fd5b50508035926020909101359150565b80356001600160a01b03811681146127a257600080fd5b919050565b6000602082840312156127b957600080fd5b6105728261278b565b60008083601f8401126127d457600080fd5b5081356001600160401b038111156127eb57600080fd5b60208301915083602082850101111561280357600080fd5b9250929050565b60008060006040848603121561281f57600080fd5b8335925060208401356001600160401b0381111561283c57600080fd5b612848868287016127c2565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b038111828210171561288d5761288d612855565b60405290565b604051601f8201601f191681016001600160401b03811182821017156128bb576128bb612855565b604052919050565b60006001600160401b038211156128dc576128dc612855565b50601f01601f191660200190565b600082601f8301126128fb57600080fd5b813561290e612909826128c3565b612893565b81815284602083860101111561292357600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561295257600080fd5b81356001600160401b0381111561296857600080fd5b6122e1848285016128ea565b60008083601f84011261298657600080fd5b5081356001600160401b0381111561299d57600080fd5b6020830191508360208260051b850101111561280357600080fd5b600080602083850312156129cb57600080fd5b82356001600160401b038111156129e157600080fd5b6129ed85828601612974565b90969095509350505050565b60006101608284031215612a0c57600080fd5b50919050565b600080600060608486031215612a2757600080fd5b83356001600160401b03811115612a3d57600080fd5b612a49868287016129f9565b9660208601359650604090950135949350505050565b600080600060408486031215612a7457600080fd5b612a7d8461278b565b925060208401356001600160401b0381111561283c57600080fd5b600060208284031215612aaa57600080fd5b81356001600160401b03811115612ac057600080fd5b6122e1848285016129f9565b600060208284031215612ade57600080fd5b5035919050565b60005b83811015612b00578181015183820152602001612ae8565b50506000910152565b60008151808452612b21816020860160208601612ae5565b601f01601f19169290920160200192915050565b60ff60f81b881681526000602060e06020840152612b5660e084018a612b09565b8381036040850152612b68818a612b09565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b81811015612bbc57835183529284019291840191600101612ba0565b50909c9b505050505050505050505050565b6020815260006105726020830184612b09565b600060208284031215612bf357600080fd5b81356001600160e01b03198116811461057257600080fd5b60008060008060608587031215612c2157600080fd5b612c2a8561278b565b93506020850135925060408501356001600160401b03811115612c4c57600080fd5b612c58878288016127c2565b95989497509550505050565b60008060208385031215612c7757600080fd5b82356001600160401b03811115612c8d57600080fd5b6129ed858286016127c2565b60008251612cab818460208701612ae5565b9190910192915050565b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112612cab57600080fd5b6000808335601e19843603018112612cf857600080fd5b8301803591506001600160401b03821115612d1257600080fd5b60200191503681900382131561280357600080fd5b60008085851115612d3757600080fd5b83861115612d4457600080fd5b5050820193919092039150565b6001600160e01b03198135818116916004851015612d795780818660040360031b1b83161692505b505092915050565b60006001600160401b0380841115612d9b57612d9b612855565b8360051b6020612dad60208301612893565b86815291850191602081019036841115612dc657600080fd5b865b84811015612dfa57803586811115612de05760008081fd5b612dec36828b016128ea565b845250918301918301612dc8565b50979650505050505050565b600181811c90821680612e1a57607f821691505b602082108103612a0c57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201612e6257612e62612e3a565b5060010190565b600060208284031215612e7b57600080fd5b81356001600160401b0380821115612e9257600080fd5b9083019060408286031215612ea657600080fd5b604051604081018181108382111715612ec157612ec1612855565b60405282358152602083013582811115612eda57600080fd5b612ee6878286016128ea565b60208301525095945050505050565b80516020808301519190811015612a0c5760001960209190910360031b1b16919050565b60008060408385031215612f2c57600080fd5b505080516020909101519092909150565b600082601f830112612f4e57600080fd5b8151612f5c612909826128c3565b818152846020838601011115612f7157600080fd5b6122e1826020830160208701612ae5565b600060208284031215612f9457600080fd5b81516001600160401b0380821115612fab57600080fd5b9083019060c08286031215612fbf57600080fd5b612fc761286b565b825182811115612fd657600080fd5b612fe287828601612f3d565b825250602083015182811115612ff757600080fd5b61300387828601612f3d565b60208301525060408301516040820152606083015160608201526080830151608082015260a083015160a082015280935050505092915050565b601f8211156106dc576000816000526020600020601f850160051c810160208610156130665750805b601f850160051c820191505b8181101561308557828155600101613072565b505050505050565b81516001600160401b038111156130a6576130a6612855565b6130ba816130b48454612e06565b8461303d565b602080601f8311600181146130ef57600084156130d75750858301515b600019600386901b1c1916600185901b178555613085565b600085815260208120601f198616915b8281101561311e578886015182559484019460019091019084016130ff565b508582101561313c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b8082018082111561050157610501612e3a565b6c1131b430b63632b733b2911d1160991b8152815160009061318881600d850160208701612ae5565b601160f91b600d939091019283015250600e01919050565b6000602082840312156131b257600080fd5b5051919050565b600083516131cb818460208801612ae5565b9190910191825250602001919050565b8181038181111561050157610501612e3a56feffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255197e2c6aad4ce5d562ebfaa00db6b9e0fb66ea5d8162ed5b243f51a2e03086f00a26469706673582212206267bdd6ae13c948b83275fcdafdc1366dd287cbf41ef689e1d49904a10ea33e64736f6c6343000817003397e2c6aad4ce5d562ebfaa00db6b9e0fb66ea5d8162ed5b243f51a2e03086f00", + "sourceMap": "874:13344:40:-:0;;;1520:4:36;1461:66;;4176:257:40;;;;;;;;;-1:-1:-1;4333:14:40;;;4345:1;4333:14;;;;;;;;;4309:21;;4333:14;;;;;;;;;;;;;;;;;;;-1:-1:-1;4369:22:40;;;4388:1;4369:22;;;292:51:62;4309:38:40;;-1:-1:-1;265:18:62;4369:22:40;;;;;;;;;;;;4357:6;4364:1;4357:9;;;;;;;;:::i;:::-;;;;;;;;;;:34;4401:25;4419:6;4401:17;:25::i;:::-;4190:243;874:13344;;6627:532:43;6709:9;6704:449;6724:6;:13;6720:1;:17;6704:449;;;6762:6;6769:1;6762:9;;;;;;;;:::i;:::-;;;;;;;:16;6782:2;6762:22;;:48;;;;;6788:6;6795:1;6788:9;;;;;;;;:::i;:::-;;;;;;;:16;6808:2;6788:22;;6762:48;6758:128;;;6861:6;6868:1;6861:9;;;;;;;;:::i;:::-;;;;;;;6837:34;;-1:-1:-1;;;6837:34:43;;;;;;;;:::i;:::-;;;;;;;;6758:128;6904:6;6911:1;6904:9;;;;;;;;:::i;:::-;;;;;;;:16;6924:2;6904:22;:73;;;;;-1:-1:-1;;;;;6930:47:43;;6946:6;6953:1;6946:9;;;;;;;;:::i;:::-;;;;;;;6938:18;;;:::i;:::-;6930:47;6904:73;6900:157;;;7032:6;7039:1;7032:9;;;;;;;;:::i;:::-;;;;;;;7004:38;;-1:-1:-1;;;7004:38:43;;;;;;;;:::i;6900:157::-;7071:71;7088:6;7095:1;7088:9;;;;;;;;:::i;:::-;;;;;;;7099:25;:23;;;:25;;:::i;:::-;:42;;;:40;:42;;;:::i;:::-;;;;-1:-1:-1;7071:16:43;:71::i;:::-;6739:3;;6704:449;;;;6627:532;:::o;8529:194::-;-1:-1:-1;;;;;;;;;;;8677:30:43;8529:194::o;7672:305::-;7764:19;7777:5;7764:12;:19::i;:::-;7760:51;;;7805:5;7792:19;;-1:-1:-1;;;7792:19:43;;;;;;;;:::i;7760:51::-;7865:4;-1:-1:-1;;;;;;;;;;;7822:33:43;;7856:5;7822:40;;;;;;:::i;:::-;;;;;;;;;;;;;;:47;;;;;-1:-1:-1;;7822:47:43;;;;;;;;;7927:5;7879:25;-1:-1:-1;;;;;;;;;;;8677:30:43;8529:194;7879:25;:45;;;;:38;;;;;:45;;;;;;:53;;:45;:53;:::i;:::-;;7957:5;7948:22;7964:5;7948:22;;;;;;:::i;:::-;;;;;;;;7672:305;;:::o;5518:145::-;5591:4;-1:-1:-1;;;;;;;;;;;5614:33:43;;5648:7;5614:42;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;5518:145;-1:-1:-1;;5518:145:43:o;14:127:62:-;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;354:127;415:10;410:3;406:20;403:1;396:31;446:4;443:1;436:15;470:4;467:1;460:15;486:250;571:1;581:113;595:6;592:1;589:13;581:113;;;671:11;;;665:18;652:11;;;645:39;617:2;610:10;581:113;;;-1:-1:-1;;728:1:62;710:16;;703:27;486:250::o;741:394::-;888:2;877:9;870:21;851:4;920:6;914:13;963:6;958:2;947:9;943:18;936:34;979:79;1051:6;1046:2;1035:9;1031:18;1026:2;1018:6;1014:15;979:79;:::i;:::-;1119:2;1098:15;-1:-1:-1;;1094:29:62;1079:45;;;;1126:2;1075:54;;741:394;-1:-1:-1;;741:394:62:o;1140:297::-;1258:12;;1305:4;1294:16;;;1288:23;;1258:12;1323:16;;1320:111;;;1417:1;1413:6;1403;1397:4;1393:17;1390:1;1386:25;1382:38;1375:5;1371:50;1362:59;;1320:111;;1140:297;;;:::o;1442:232::-;1481:3;1502:17;;;1499:140;;1561:10;1556:3;1552:20;1549:1;1542:31;1596:4;1593:1;1586:15;1624:4;1621:1;1614:15;1499:140;-1:-1:-1;1666:1:62;1655:13;;1442:232::o;1679:287::-;1808:3;1846:6;1840:13;1862:66;1921:6;1916:3;1909:4;1901:6;1897:17;1862:66;:::i;:::-;1944:16;;;;;1679:287;-1:-1:-1;;1679:287:62:o;1971:380::-;2050:1;2046:12;;;;2093;;;2114:61;;2168:4;2160:6;2156:17;2146:27;;2114:61;2221:2;2213:6;2210:14;2190:18;2187:38;2184:161;;2267:10;2262:3;2258:20;2255:1;2248:31;2302:4;2299:1;2292:15;2330:4;2327:1;2320:15;2481:542;2582:2;2577:3;2574:11;2571:446;;;2618:1;2642:5;2639:1;2632:16;2686:4;2683:1;2673:18;2756:2;2744:10;2740:19;2737:1;2733:27;2727:4;2723:38;2792:4;2780:10;2777:20;2774:47;;;-1:-1:-1;2815:4:62;2774:47;2870:2;2865:3;2861:12;2858:1;2854:20;2848:4;2844:31;2834:41;;2925:82;2943:2;2936:5;2933:13;2925:82;;;2988:17;;;2969:1;2958:13;2925:82;;;2929:3;;;2571:446;2481:542;;;:::o;3199:1341::-;3317:10;;-1:-1:-1;;;;;3339:30:62;;3336:56;;;3372:18;;:::i;:::-;3401:96;3490:6;3450:38;3482:4;3476:11;3450:38;:::i;:::-;3444:4;3401:96;:::i;:::-;3552:4;;3609:2;3598:14;;3626:1;3621:662;;;;4327:1;4344:6;4341:89;;;-1:-1:-1;4396:19:62;;;4390:26;4341:89;-1:-1:-1;;3156:1:62;3152:11;;;3148:24;3144:29;3134:40;3180:1;3176:11;;;3131:57;4443:81;;3591:943;;3621:662;2428:1;2421:14;;;2465:4;2452:18;;-1:-1:-1;;3657:20:62;;;3774:236;3788:7;3785:1;3782:14;3774:236;;;3877:19;;;3871:26;3856:42;;3969:27;;;;3937:1;3925:14;;;;3804:19;;3774:236;;;3778:3;4038:6;4029:7;4026:19;4023:201;;;4099:19;;;4093:26;-1:-1:-1;;4182:1:62;4178:14;;;4194:3;4174:24;4170:37;4166:42;4151:58;4136:74;;4023:201;-1:-1:-1;;;;;4270:1:62;4254:14;;;4250:22;4237:36;;-1:-1:-1;3199:1341:62:o;:::-;874:13344:40;;;;;;;;;;;;;;;;;", + "linkReferences": {} + }, + "deployedBytecode": { + "object": "0x60806040526004361061014f5760003560e01c806372de3b5a116100b6578063b0d691fe1161006f578063b0d691fe146103f4578063b61d27f61461041b578063bf6ba1fc1461042e578063ce1506be14610441578063d948fd2e14610461578063f698da251461048357610156565b806372de3b5a1461032957806384b0196e1461034957806388ce4c7c146103715780638ea69029146103875780639f9bcb34146103b4578063a2e1a8d8146103d457610156565b80633a871cdd116101085780633a871cdd146102655780634f1ef286146102865780634f6e7f221461029957806352d1902d146102b95780635c60da1b146102ce5780636f2de70e1461031657610156565b8063066a1eb7146101845780630f0f3f24146101b95780631626ba7e146101d95780631ca5393f1461021257806329565e3b1461023257806334fcd5be1461025257610156565b3661015657005b60003560e01c63bc197c81811463f23a6e6182141763150b7a028214171561018257806020526020603cf35b005b34801561019057600080fd5b506101a461019f366004612769565b610498565b60405190151581526020015b60405180910390f35b3480156101c557600080fd5b506101826101d43660046127a7565b610507565b3480156101e557600080fd5b506101f96101f436600461280a565b61053f565b6040516001600160e01b031990911681526020016101b0565b34801561021e57600080fd5b506101a461022d366004612940565b610579565b34801561023e57600080fd5b5061018261024d366004612769565b6105b4565b6101826102603660046129b8565b6105dd565b610278610273366004612a12565b6106e1565b6040519081526020016101b0565b610182610294366004612a5f565b61081c565b3480156102a557600080fd5b506102786102b4366004612a98565b610900565b3480156102c557600080fd5b50610278610951565b3480156102da57600080fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545b6040516001600160a01b0390911681526020016101b0565b6101826103243660046129b8565b6109b1565b34801561033557600080fd5b50610182610344366004612acc565b6109f1565b34801561035557600080fd5b5061035e610ade565b6040516101b09796959493929190612b35565b34801561037d57600080fd5b5061027861210581565b34801561039357600080fd5b506103a76103a2366004612acc565b610b05565b6040516101b09190612bce565b3480156103c057600080fd5b506101a46103cf366004612be1565b610bc6565b3480156103e057600080fd5b506101a46103ef3660046127a7565b610c42565b34801561040057600080fd5b50735ff137d4b0fdcd49dca30c7cf57e578a026d27896102fe565b610182610429366004612c0b565b610c88565b61018261043c366004612c64565b610cec565b34801561044d57600080fd5b5061027861045c366004612acc565b610dad565b34801561046d57600080fd5b5060008051602061320f83398151915254610278565b34801561048f57600080fd5b50610278610db8565b60408051602081018490529081018290526000907f97e2c6aad4ce5d562ebfaa00db6b9e0fb66ea5d8162ed5b243f51a2e03086f029060600160408051601f19818403018152908290526104eb91612c99565b9081526040519081900360200190205460ff1690505b92915050565b61050f610e3e565b604080516001600160a01b038316602082015261053c91015b604051602081830303815290604052610e70565b50565b600061055461054d85610dad565b8484610e9b565b156105675750630b135d3f60e11b610572565b506001600160e01b03195b9392505050565b600060008051602061320f8339815191526002018260405161059b9190612c99565b9081526040519081900360200190205460ff1692915050565b6105bc610e3e565b60408051602081018490529081018290526105d990606001610528565b5050565b33735ff137d4b0fdcd49dca30c7cf57e578a026d27891461060057610600610e3e565b60005b818110156106dc576106d483838381811061062057610620612cb5565b90506020028101906106329190612ccb565b6106409060208101906127a7565b84848481811061065257610652612cb5565b90506020028101906106649190612ccb565b6020013585858581811061067a5761067a612cb5565b905060200281019061068c9190612ccb565b61069a906040810190612ce1565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610fb092505050565b600101610603565b505050565b600033735ff137d4b0fdcd49dca30c7cf57e578a026d278914610716576040516282b42960e81b815260040160405180910390fd5b81602085013560401c600461072e6060880188612ce1565b90501015801561077257506107466060870187612ce1565b61075591600491600091612d27565b61075e91612d51565b6001600160e01b03191663bf6ba1fc60e01b145b156107b15761078086610900565b945061210581146107ac57604051632ef3781360e01b8152600481018290526024015b60405180910390fd5b6107d6565b61210581036107d657604051632ef3781360e01b8152600481018290526024016107a3565b6107ed856107e8610140890189612ce1565b610e9b565b156107fc576000925050610802565b60019250505b80156108145760003860003884335af1505b509392505050565b7f000000000000000000000000000000000000000000000000000000000000000030810361085257639f03a0266000526004601cfd5b61085b84611020565b8360601b60601c93506352d1902d6001527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80602060016004601d895afa51146108ad576355299b496001526004601dfd5b847fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600038a284905581156108fa57604051828482376000388483885af46108f8573d6000823e3d81fd5b505b50505050565b600061090b82611028565b604080516020810192909252735ff137d4b0fdcd49dca30c7cf57e578a026d2789908201526060015b604051602081830303815290604052805190602001209050919050565b60007f000000000000000000000000000000000000000000000000000000000000000030811461098957639f03a0266000526004601cfd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91505b5090565b60008051602061320f83398151915254156109df576040516302ed543d60e51b815260040160405180910390fd5b6105d96109ec8284612d81565b611041565b6109f9610e3e565b6000610a0482610b05565b90508051600003610a2b5760405163340c473d60e11b8152600481018390526024016107a3565b6040517f97e2c6aad4ce5d562ebfaa00db6b9e0fb66ea5d8162ed5b243f51a2e03086f0290610a5b908390612c99565b908152604051908190036020019020805460ff19169055610a8760008051602061320f83398151915290565b600083815260019190910160205260408120610aa29161271f565b817fcf95bbfe6f870f8cc40482dc3dccdafd268f0e9ce0a4f24ea1bea9be64e505ff82604051610ad29190612bce565b60405180910390a25050565b600f60f81b6060806000808083610af3611193565b97989097965046955030945091925090565b60008181527f97e2c6aad4ce5d562ebfaa00db6b9e0fb66ea5d8162ed5b243f51a2e03086f0160205260409020805460609190610b4190612e06565b80601f0160208091040260200160405190810160405280929190818152602001828054610b6d90612e06565b8015610bba5780601f10610b8f57610100808354040283529160200191610bba565b820191906000526020600020905b815481529060010190602001808311610b9d57829003601f168201915b50505050509050919050565b60006001600160e01b031982166329565e3b60e01b1480610bf757506001600160e01b031982166303c3cfc960e21b145b80610c1257506001600160e01b0319821663396f1dad60e11b145b80610c2d57506001600160e01b0319821663278f794360e11b145b15610c3a57506001919050565b506000919050565b600060008051602061320f833981519152604080516001600160a01b0385166020820152600292909201910160408051601f198184030181529082905261059b91612c99565b33735ff137d4b0fdcd49dca30c7cf57e578a026d278914610cab57610cab610e3e565b6108fa848484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610fb092505050565b33735ff137d4b0fdcd49dca30c7cf57e578a026d278914610d1f576040516282b42960e81b815260040160405180910390fd5b6000610d2e6004828486612d27565b610d3791612d51565b9050610d4281610bc6565b610d6b57604051631d8370a360e11b81526001600160e01b0319821660048201526024016107a3565b6106dc30600085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610fb092505050565b6000610501826111da565b6000806000610dc5611193565b8151602080840191909120825182840120604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f9481019490945283019190915260608201524660808201523060a0820152919350915060c001604051602081830303815290604052805190602001209250505090565b610e4733610c42565b80610e5157503330145b15610e5857565b6040516282b42960e81b815260040160405180910390fd5b61053c8160008051602061320f8339815191525b8054906000610e9283612e50565b91905055611210565b600080610eaa83850185612e69565b90506000610ebb8260000151610b05565b90508051602003610f1a576001600160a01b03610ed782612ef5565b1115610ef8578060405163bff1ac6560e01b81526004016107a39190612bce565b600060208201519050610f10818885602001516112df565b9350505050610572565b8051604003610f955760008082806020019051810190610f3a9190612f19565b9150915060008460200151806020019051810190610f589190612f82565b9050610f8989604051602001610f7091815260200190565b60405160208183030381529060405260008386866113e4565b95505050505050610572565b806040516327755b9160e11b81526004016107a39190612bce565b600080846001600160a01b03168484604051610fcc9190612c99565b60006040518083038185875af1925050503d8060008114611009576040519150601f19603f3d011682016040523d82523d6000602084013e61100e565b606091505b5091509150816108f857805160208201fd5b61053c610e3e565b600061103382611754565b805190602001209050919050565b60005b81518110156105d95781818151811061105f5761105f612cb5565b602002602001015151602014158015611093575081818151811061108557611085612cb5565b602002602001015151604014155b156110cc578181815181106110aa576110aa612cb5565b60200260200101516040516327755b9160e11b81526004016107a39190612bce565b8181815181106110de576110de612cb5565b602002602001015151602014801561112057506001600160a01b03801682828151811061110d5761110d612cb5565b602002602001015161111e90612ef5565b115b156111595781818151811061113757611137612cb5565b602002602001015160405163bff1ac6560e01b81526004016107a39190612bce565b61118b82828151811061116e5761116e612cb5565b6020026020010151610e8460008051602061320f83398151915290565b600101611044565b604080518082018252601581527410dbda5b98985cd94814db585c9d0815d85b1b195d605a1b602080830191909152825180840190935260018352603160f81b9083015291565b60006111e4610db8565b6111ed83611827565b60405161190160f01b602082015260228101929092526042820152606201610934565b61121982610579565b15611239578160405163468b12ad60e11b81526004016107a39190612bce565b600160008051602061320f8339815191526002018360405161125b9190612c99565b908152604051908190036020019020805491151560ff199092169190911790558161129160008051602061320f83398151915290565b600083815260019190910160205260409020906112ae908261308d565b50807f38109edc26e166b5579352ce56a50813177eb25208fd90d61f2f37838622022083604051610ad29190612bce565b6001600160a01b03909216916000831561057257604051836000526020830151604052604083510361134f576040830151601b8160ff1c016020528060011b60011c60605250602060016080600060015afa805186183d151761134d57506000606052604052506001610572565b505b604183510361139557606083015160001a6020526040830151606052602060016080600060015afa805186183d151761139357506000606052604052506001610572565b505b600060605280604052631626ba7e60e01b808252846004830152602482016040815284516020018060448501828860045afa505060208160443d01858a5afa9051909114169150509392505050565b60007f7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a88460a00151111561141a5750600061174b565b606084015160009061143d9061143181601561314c565b60208801519190611862565b90507fff1a2a9176d650e4a99dedb58f1793003935130579fe17b5a3f698ac5b00e63481805190602001201461147757600091505061174b565b6000611485886001806118c8565b604051602001611495919061315f565b604051602081830303815290604052905060006114cd8760400151835189604001516114c1919061314c565b60208a01519190611862565b905081805190602001208180519060200120146114f0576000935050505061174b565b86518051600160f81b918291602090811061150d5761150d612cb5565b0160200151166001600160f81b0319161461152e576000935050505061174b565b878015611566575086518051600160fa1b918291602090811061155357611553612cb5565b0160200151166001600160f81b03191614155b15611577576000935050505061174b565b60006002886020015160405161158d9190612c99565b602060405180830381855afa1580156115aa573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906115cd91906131a0565b9050600060028960000151836040516020016115ea9291906131b9565b60408051601f198184030181529082905261160491612c99565b602060405180830381855afa158015611621573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061164491906131a0565b6080808b015160a0808d015160408051602081018790529081019390935260608301529181018b905290810189905290915060009060c00160405160208183030381529060405290506000806101006001600160a01b0316836040516116aa9190612c99565b600060405180830381855afa9150503d80600081146116e5576040519150601f19603f3d011682016040523d82523d6000602084013e6116ea565b606091505b508051919350915015158280156116fe5750805b1561172a578180602001905181019061171791906131a0565b600114995050505050505050505061174b565b61173f858e608001518f60a001518f8f6119bd565b99505050505050505050505b95945050505050565b606081356020830135600061177461176f6040870187612ce1565b611aa0565b9050600061178861176f6060880188612ce1565b9050608086013560a087013560c088013560e08901356101008a013560006117b761176f6101208e018e612ce1565b604080516001600160a01b039c909c1660208d01528b81019a909a5260608b019890985250608089019590955260a088019390935260c087019190915260e08601526101008501526101208401526101408084019190915281518084039091018152610160909201905292915050565b604080517f9b493d222105fee7df163ab5d57f0bf1ffd2da04dd5fafbe10b54c41c1adc6576020820152908101829052600090606001610934565b60608351828111611871578092505b83811161187c578093505b5081831015610572575060405182820380825293830193601f19601f820181165b868101518482015281018061189d5750600083830160200152603f9091011681016040529392505050565b606083518015610814576003600282010460021b60405192507f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f526106708515027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f18603f52602083018181018388602001018051600082525b60038a0199508951603f8160121c1651600053603f81600c1c1651600153603f8160061c1651600253603f811651600353506000518452600484019350828410611944579052602001604052613d3d60f01b60038406600204808303919091526000861515909102918290035290038252509392505050565b60008415806119da57506000805160206131ef8339815191528510155b806119e3575083155b806119fc57506000805160206131ef8339815191528410155b15611a095750600061174b565b611a138383611ab3565b611a1f5750600061174b565b6000611a2a85611bad565b905060006000805160206131ef833981519152828909905060006000805160206131ef83398151915283890990506000611a6687878585611c1f565b90506000805160206131ef833981519152611a8f8a6000805160206131ef8339815191526131db565b8208159a9950505050505050505050565b6000604051828085833790209392505050565b600082158015611ac1575081155b80611ad95750600160601b63ffffffff60c01b031983145b80611af15750600160601b63ffffffff60c01b031982145b15611afe57506000610501565b6000600160601b63ffffffff60c01b031983840990506000600160601b63ffffffff60c01b0319807fffffffff00000001000000000000000000000000fffffffffffffffffffffffc8709600160601b63ffffffff60c01b031987600160601b63ffffffff60c01b0319898a0909089050600160601b63ffffffff60c01b03197f5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b820891909114949350505050565b600060405160208152602080820152602060408201528260608201527fffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63254f60808201526000805160206131ef83398151915260a082015260208160c0836005600019fa611c1857600080fd5b5192915050565b600080808060ff818088158015611c34575087155b15611c4857600096505050505050506122e1565b611c947f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2967f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f58d8d6122e9565b909250905081158015611ca5575080155b15611cd3576000805160206131ef833981519152886000805160206131ef833981519152038a089850600097505b600189841c16600189851c1660011b015b80611d065760018403935060018a851c1660018a861c1660011b019050611ce4565b50600189841c16600189851c1660011b01955060018603611d68577f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29696507f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f593505b60028603611d77578a96508993505b60038603611d86578196508093505b60018303925060019550600194505b82600019111561226a57600160601b63ffffffff60c01b031984600209600160601b63ffffffff60c01b0319818209600160601b63ffffffff60c01b0319818a09600160601b63ffffffff60c01b03198284099250600160601b63ffffffff60c01b031980600160601b63ffffffff60c01b03198b8d08600160601b63ffffffff60c01b03198c600160601b63ffffffff60c01b0319038e0809600309600160601b63ffffffff60c01b03198985099850600160601b63ffffffff60c01b03198a84099950600160601b63ffffffff60c01b031980836002600160601b0363ffffffff60c01b031909600160601b63ffffffff60c01b0319838409089a50600160601b63ffffffff60c01b03198083600160601b63ffffffff60c01b0319038d0882099250600160601b63ffffffff60c01b031983600160601b63ffffffff60c01b03198a870908975060018d881c1660018d891c1660011b01905080611f125787600160601b63ffffffff60c01b03190397505050505061225f565b60018103611f61577f6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29693507f4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f592505b60028103611f70578e93508d92505b60038103611f7f578593508492505b89611f98575091985060019750879650945061225f9050565b600160601b63ffffffff60c01b031988600160601b63ffffffff60c01b03198b860908600160601b63ffffffff60c01b03198c600160601b63ffffffff60c01b031903600160601b63ffffffff60c01b03198d880908935080612151578361215157600160601b63ffffffff60c01b0319896002600160601b0363ffffffff60c01b0319099450600160601b63ffffffff60c01b03198586099350600160601b63ffffffff60c01b0319848d099250600160601b63ffffffff60c01b03198486099450600160601b63ffffffff60c01b0319808c600160601b63ffffffff60c01b0319038e08600160601b63ffffffff60c01b03198d8f08099050600160601b63ffffffff60c01b0319816003099150600160601b63ffffffff60c01b03198a86099950600160601b63ffffffff60c01b03198b85099a50600160601b63ffffffff60c01b031980846002600160601b0363ffffffff60c01b031909600160601b63ffffffff60c01b0319848509089b50600160601b63ffffffff60c01b0319808d600160601b63ffffffff60c01b031903850883099350600160601b63ffffffff60c01b0319808a870985089850505050505061225f565b600160601b63ffffffff60c01b03198485099150600160601b63ffffffff60c01b0319848309600160601b63ffffffff60c01b0319838d099b50600160601b63ffffffff60c01b0319818c099a50600160601b63ffffffff60c01b0319838e09600160601b63ffffffff60c01b031980826002600160601b0363ffffffff60c01b031909600160601b63ffffffff60c01b031984600160601b63ffffffff60c01b031903600160601b63ffffffff60c01b031987880908089350600160601b63ffffffff60c01b031980838d09600160601b63ffffffff60c01b031985600160601b63ffffffff60c01b031988600160601b63ffffffff60c01b031903860809089a50505050809a50505050505b600183039250611d95565b60405186606082015260208152602080820152602060408201526002600160601b0363ffffffff60c01b03196080820152600160601b63ffffffff60c01b031960a082015260208160c0836005600019fa6122c457600080fd5b600160601b63ffffffff60c01b0319815189099750505050505050505b949350505050565b60008080808661230057858593509350505061236e565b8461231257878793509350505061236e565b858814801561232057508487145b15612341576123328888600180612377565b929a509098509250905061235b565b61235088886001808a8a6124d2565b929a50909850925090505b61236788888484612656565b9350935050505b94509492505050565b600080600080600160601b63ffffffff60c01b0319876002099350600160601b63ffffffff60c01b03198485099150600160601b63ffffffff60c01b03198289099050600160601b63ffffffff60c01b03198285099250600160601b63ffffffff60c01b03198683099150600160601b63ffffffff60c01b031980600160601b63ffffffff60c01b0319888b08600160601b63ffffffff60c01b031989600160601b63ffffffff60c01b0319038c08096003099550600160601b63ffffffff60c01b031980826002600160601b0363ffffffff60c01b031909600160601b63ffffffff60c01b0319888909089350600160601b63ffffffff60c01b03198085600160601b63ffffffff60c01b031903830887099750600160601b63ffffffff60c01b03198584099050600160601b63ffffffff60c01b031980888509600160601b63ffffffff60c01b03190389089250945094509450949050565b600080600080886000036124f157508492508391506001905080612649565b600160601b63ffffffff60c01b0319988903988981898809089450600160601b63ffffffff60c01b03198a600160601b63ffffffff60c01b031903600160601b63ffffffff60c01b03198a8909089550600160601b63ffffffff60c01b03198687099350600160601b63ffffffff60c01b03198685099250600160601b63ffffffff60c01b03198489099150600160601b63ffffffff60c01b03198388099050600160601b63ffffffff60c01b0319848b099750600160601b63ffffffff60c01b031980896002600160601b0363ffffffff60c01b031909600160601b63ffffffff60c01b031985600160601b63ffffffff60c01b031903600160601b63ffffffff60c01b0319898a0908089350600160601b63ffffffff60c01b031980848b09600160601b63ffffffff60c01b031987600160601b63ffffffff60c01b031988600160601b63ffffffff60c01b0319038d08090892505b9650965096509692505050565b6000806000612664846126c3565b9050600160601b63ffffffff60c01b031981870991506000600160601b63ffffffff60c01b03198287099050600160601b63ffffffff60c01b03198182099150600160601b63ffffffff60c01b03198289099350505094509492505050565b600060405160208152602080820152602060408201528260608201526002600160601b0363ffffffff60c01b03196080820152600160601b63ffffffff60c01b031960a082015260208160c0836005600019fa611c1857600080fd5b50805461272b90612e06565b6000825580601f1061273b575050565b601f01602090049060005260206000209081019061053c91905b808211156109ad5760008155600101612755565b6000806040838503121561277c57600080fd5b50508035926020909101359150565b80356001600160a01b03811681146127a257600080fd5b919050565b6000602082840312156127b957600080fd5b6105728261278b565b60008083601f8401126127d457600080fd5b5081356001600160401b038111156127eb57600080fd5b60208301915083602082850101111561280357600080fd5b9250929050565b60008060006040848603121561281f57600080fd5b8335925060208401356001600160401b0381111561283c57600080fd5b612848868287016127c2565b9497909650939450505050565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b038111828210171561288d5761288d612855565b60405290565b604051601f8201601f191681016001600160401b03811182821017156128bb576128bb612855565b604052919050565b60006001600160401b038211156128dc576128dc612855565b50601f01601f191660200190565b600082601f8301126128fb57600080fd5b813561290e612909826128c3565b612893565b81815284602083860101111561292357600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561295257600080fd5b81356001600160401b0381111561296857600080fd5b6122e1848285016128ea565b60008083601f84011261298657600080fd5b5081356001600160401b0381111561299d57600080fd5b6020830191508360208260051b850101111561280357600080fd5b600080602083850312156129cb57600080fd5b82356001600160401b038111156129e157600080fd5b6129ed85828601612974565b90969095509350505050565b60006101608284031215612a0c57600080fd5b50919050565b600080600060608486031215612a2757600080fd5b83356001600160401b03811115612a3d57600080fd5b612a49868287016129f9565b9660208601359650604090950135949350505050565b600080600060408486031215612a7457600080fd5b612a7d8461278b565b925060208401356001600160401b0381111561283c57600080fd5b600060208284031215612aaa57600080fd5b81356001600160401b03811115612ac057600080fd5b6122e1848285016129f9565b600060208284031215612ade57600080fd5b5035919050565b60005b83811015612b00578181015183820152602001612ae8565b50506000910152565b60008151808452612b21816020860160208601612ae5565b601f01601f19169290920160200192915050565b60ff60f81b881681526000602060e06020840152612b5660e084018a612b09565b8381036040850152612b68818a612b09565b606085018990526001600160a01b038816608086015260a0850187905284810360c08601528551808252602080880193509091019060005b81811015612bbc57835183529284019291840191600101612ba0565b50909c9b505050505050505050505050565b6020815260006105726020830184612b09565b600060208284031215612bf357600080fd5b81356001600160e01b03198116811461057257600080fd5b60008060008060608587031215612c2157600080fd5b612c2a8561278b565b93506020850135925060408501356001600160401b03811115612c4c57600080fd5b612c58878288016127c2565b95989497509550505050565b60008060208385031215612c7757600080fd5b82356001600160401b03811115612c8d57600080fd5b6129ed858286016127c2565b60008251612cab818460208701612ae5565b9190910192915050565b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112612cab57600080fd5b6000808335601e19843603018112612cf857600080fd5b8301803591506001600160401b03821115612d1257600080fd5b60200191503681900382131561280357600080fd5b60008085851115612d3757600080fd5b83861115612d4457600080fd5b5050820193919092039150565b6001600160e01b03198135818116916004851015612d795780818660040360031b1b83161692505b505092915050565b60006001600160401b0380841115612d9b57612d9b612855565b8360051b6020612dad60208301612893565b86815291850191602081019036841115612dc657600080fd5b865b84811015612dfa57803586811115612de05760008081fd5b612dec36828b016128ea565b845250918301918301612dc8565b50979650505050505050565b600181811c90821680612e1a57607f821691505b602082108103612a0c57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201612e6257612e62612e3a565b5060010190565b600060208284031215612e7b57600080fd5b81356001600160401b0380821115612e9257600080fd5b9083019060408286031215612ea657600080fd5b604051604081018181108382111715612ec157612ec1612855565b60405282358152602083013582811115612eda57600080fd5b612ee6878286016128ea565b60208301525095945050505050565b80516020808301519190811015612a0c5760001960209190910360031b1b16919050565b60008060408385031215612f2c57600080fd5b505080516020909101519092909150565b600082601f830112612f4e57600080fd5b8151612f5c612909826128c3565b818152846020838601011115612f7157600080fd5b6122e1826020830160208701612ae5565b600060208284031215612f9457600080fd5b81516001600160401b0380821115612fab57600080fd5b9083019060c08286031215612fbf57600080fd5b612fc761286b565b825182811115612fd657600080fd5b612fe287828601612f3d565b825250602083015182811115612ff757600080fd5b61300387828601612f3d565b60208301525060408301516040820152606083015160608201526080830151608082015260a083015160a082015280935050505092915050565b601f8211156106dc576000816000526020600020601f850160051c810160208610156130665750805b601f850160051c820191505b8181101561308557828155600101613072565b505050505050565b81516001600160401b038111156130a6576130a6612855565b6130ba816130b48454612e06565b8461303d565b602080601f8311600181146130ef57600084156130d75750858301515b600019600386901b1c1916600185901b178555613085565b600085815260208120601f198616915b8281101561311e578886015182559484019460019091019084016130ff565b508582101561313c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b8082018082111561050157610501612e3a565b6c1131b430b63632b733b2911d1160991b8152815160009061318881600d850160208701612ae5565b601160f91b600d939091019283015250600e01919050565b6000602082840312156131b257600080fd5b5051919050565b600083516131cb818460208801612ae5565b9190910191825250602001919050565b8181038181111561050157610501612e3a56feffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc63255197e2c6aad4ce5d562ebfaa00db6b9e0fb66ea5d8162ed5b243f51a2e03086f00a26469706673582212206267bdd6ae13c948b83275fcdafdc1366dd287cbf41ef689e1d49904a10ea33e64736f6c63430008170033", + "sourceMap": "874:13344:40:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;887:1:31;874:15;869:3;865:25;1217:10;1214:1;1211:17;1198:10;1195:1;1192:17;1189:40;1176:10;1173:1;1170:17;1167:63;1164:190;;;1262:1;1256:4;1249:15;1256:4;1308;1301:18;1164:190;;5111:158:43;;;;;;;;;;-1:-1:-1;5111:158:43;;;;;:::i;:::-;;:::i;:::-;;;432:14:62;;425:22;407:41;;395:2;380:18;5111:158:43;;;;;;;;3531:110;;;;;;;;;;-1:-1:-1;3531:110:43;;;;;:::i;:::-;;:::i;3355:343:42:-;;;;;;;;;;-1:-1:-1;3355:343:42;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;1824:33:62;;;1806:52;;1794:2;1779:18;3355:343:42;1662:202:62;5518:145:43;;;;;;;;;;-1:-1:-1;5518:145:43;;;;;:::i;:::-;;:::i;3824:118::-;;;;;;;;;;-1:-1:-1;3824:118:43;;;;;:::i;:::-;;:::i;8796:278:40:-;;;;;;:::i;:::-;;:::i;5921:1184::-;;;;;;:::i;:::-;;:::i;:::-;;;5209:25:62;;;5197:2;5182:18;5921:1184:40;5063:177:62;4012:1575:36;;;;;;:::i;:::-;;:::i;9723:243:40:-;;;;;;;;;;-1:-1:-1;9723:243:40;;;;;:::i;:::-;;:::i;3579:227:36:-;;;;;;;;;;;;;:::i;10106:153:40:-;;;;;;;;;;-1:-1:-1;10214:28:40;10208:35;10106:153;;;-1:-1:-1;;;;;6452:32:62;;;6434:51;;6422:2;6407:18;10106:153:40;6288:203:62;4671:192:40;;;;;;:::i;:::-;;:::i;4132:347:43:-;;;;;;;;;;-1:-1:-1;4132:347:43;;;;;:::i;:::-;;:::i;2125:597:42:-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;1850:51:40:-;;;;;;;;;;;;1897:4;1850:51;;5872:149:43;;;;;;;;;;-1:-1:-1;5872:149:43;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;10557:485:40:-;;;;;;;;;;-1:-1:-1;10557:485:40;;;;;:::i;:::-;;:::i;4697:154:43:-;;;;;;;;;;-1:-1:-1;4697:154:43;;;;;:::i;:::-;;:::i;9199:126:40:-;;;;;;;;;;-1:-1:-1;9276:42:40;9199:126;;8399:157;;;;;;:::i;:::-;;:::i;7785:302::-;;;;;;:::i;:::-;;:::i;4177:117:42:-;;;;;;;;;;-1:-1:-1;4177:117:42;;;;;:::i;:::-;;:::i;6181:128:43:-;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;6262:40:43;6181:128;;4612:475:42;;;;;;;;;;;;;:::i;5111:158:43:-;5245:16;;;;;;10785:25:62;;;10826:18;;;10819:34;;;5188:4:43;;5211:33;;10758:18:62;;5245:16:43;;;-1:-1:-1;;5245:16:43;;;;;;;;;;5211:51;;;:::i;:::-;;;;;;;;;;;;;;;;;;-1:-1:-1;5111:158:43;;;;;:::o;3531:110::-;3381:13;:11;:13::i;:::-;3616:17:::1;::::0;;-1:-1:-1;;;;;6452:32:62;;3616:17:43::1;::::0;::::1;6434:51:62::0;3606:28:43::1;::::0;6407:18:62;3616:17:43::1;;;;;;;;;;;;;3606:9;:28::i;:::-;3531:110:::0;:::o;3355:343:42:-;3450:13;3479:73;3508:20;3523:4;3508:14;:20::i;:::-;3541:9;;3479:18;:73::i;:::-;3475:189;;;-1:-1:-1;;;;3636:17:42;;3475:189;-1:-1:-1;;;;;;;3355:343:42;;;;;;:::o;5518:145:43:-;5591:4;-1:-1:-1;;;;;;;;;;;5614:33:43;;5648:7;5614:42;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;5518:145;-1:-1:-1;;5518:145:43:o;3824:118::-;3381:13;:11;:13::i;:::-;3918:16:::1;::::0;;::::1;::::0;::::1;10785:25:62::0;;;10826:18;;;10819:34;;;3908:27:43::1;::::0;10758:18:62;;3918:16:43::1;10611:248:62::0;3908:27:43::1;3824:118:::0;;:::o;8796:278:40:-;3122:10;9276:42;3122:26;3118:70;;3164:13;:11;:13::i;:::-;8901:9:::1;8896:172;8912:16:::0;;::::1;8896:172;;;8945:53;8951:5;;8957:1;8951:8;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:15;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;8968:5;;8974:1;8968:8;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:14;;;8984:5;;8990:1;8984:8;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:13;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;8945:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;8945:5:40::1;::::0;-1:-1:-1;;;8945:53:40:i:1;:::-;9040:3;;8896:172;;;;8796:278:::0;;:::o;5921:1184::-;6152:22;2869:10;9276:42;2869:26;2865:78;;2918:14;;-1:-1:-1;;;2918:14:40;;;;;;;;;;;2865:78;6114:19;6204:12:::2;::::0;::::2;;6220:2;6204:18;6347:1;6321:15;;::::0;::::2;6204:6:::0;6321:15:::2;:::i;:::-;:22;;:27;;:73;;;;-1:-1:-1::0;6359:15:40::2;;::::0;::::2;:6:::0;:15:::2;:::i;:::-;:20;::::0;6377:1:::2;::::0;6375::::2;::::0;6359:20:::2;:::i;:::-;6352:28;::::0;::::2;:::i;:::-;-1:-1:-1::0;;;;;6352:42:40::2;;6384:10;6352:42;;;6321:73;6317:381;;;6423:35;6451:6;6423:27;:35::i;:::-;6410:48;;1897:4;6476:3;:27;6472:93;;6530:20;::::0;-1:-1:-1;;;6530:20:40;;::::2;::::0;::::2;5209:25:62::0;;;5182:18;;6530:20:40::2;;;;;;;;6472:93;6317:381;;;1897:4;6599:3;:27:::0;6595:93:::2;;6653:20;::::0;-1:-1:-1;;;6653:20:40;;::::2;::::0;::::2;5209:25:62::0;;;5182:18;;6653:20:40::2;5063:177:62::0;6595:93:40::2;6776:48;6795:10:::0;6807:16:::2;;::::0;::::2;:6:::0;:16:::2;:::i;:::-;6776:18;:48::i;:::-;6772:87;;;6847:1;6840:8;;;;;6772:87;7097:1;7090:8;;;3877:1;3931:19:::1;3928:226;;;4134:4;4122:10;4116:4;4104:10;4083:19;4073:8;4066:5;4061:78;4057:83;3928:226;2953:1;5921:1184:::0;;;;;:::o;4012:1575:36:-;5707:6;6068:9;6062:16;;6059:143;;6110:10;6104:4;6097:24;6183:4;6177;6170:18;6059:143;4165:36:::1;4183:17;4165;:36::i;:::-;4314:17;4310:2;4306:26;4302:2;4298:35;4277:56;;4384:10;4378:4;4371:24;4439:28;4644:1;4636:4;4630;4624;4618;4599:17;4592:5;4581:60;4575:67;4572:74;4562:199;;4679:10;4673:4;4666:24;4742:4;4736;4729:18;4562:199;4866:17;4839:25;4833:4;4821:10;4816:68;4897:28:::0;;;5055:516;::::1;;;5183:4;5177:11;5234;5221;5218:1;5205:41;5340:4;5328:10;5315:11;5312:1;5293:17;5286:5;5273:72;5263:294;;5474:16;5468:4;5465:1;5450:41;5522:16;5519:1;5512:27;5263:294;;5055:516;5685:544:::0;4012:1575;;;:::o;9723:243:40:-;9852:18;9914:29;9936:6;9914:21;:29::i;:::-;9903:55;;;;;;12979:25:62;;;;9276:42:40;13020:18:62;;;13013:60;12952:18;;9903:55:40;;;;;;;;;;;;;9893:66;;;;;;9886:73;;9723:243;;;:::o;3579:227:36:-;3646:7;6402:6;6500:9;6494:16;;6484:151;;6543:10;6537:4;6530:24;6616:4;6610;6603:18;6484:151;2614:66:::1;::::0;-1:-1:-1;6654:1:36::1;6380:282:::0;3579:227;:::o;4671:192:40:-;-1:-1:-1;;;;;;;;;;;6262:40:43;4753:21:40;4749:72;;4797:13;;-1:-1:-1;;;4797:13:40;;;;;;;;;;;4749:72;4831:25;;4849:6;;4831:25;:::i;:::-;:17;:25::i;4132:347:43:-;3381:13;:11;:13::i;:::-;4210:18:::1;4231:19;4244:5;4231:12;:19::i;:::-;4210:40;;4264:5;:12;4280:1;4264:17:::0;4260:51:::1;;4290:21;::::0;-1:-1:-1;;;4290:21:43;;::::1;::::0;::::1;5209:25:62::0;;;5182:18;;4290:21:43::1;5063:177:62::0;4260:51:43::1;4329:40;::::0;:33;;:40:::1;::::0;4363:5;;4329:40:::1;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;4322:47;;-1:-1:-1;;4322:47:43::1;::::0;;4386:25:::1;-1:-1:-1::0;;;;;;;;;;;8677:30:43;8529:194;4386:25:::1;:45;::::0;;;:38:::1;::::0;;;::::1;:45;::::0;;;;4379:52:::1;::::0;::::1;:::i;:::-;4459:5;4447:25;4466:5;4447:25;;;;;;:::i;:::-;;;;;;;;4200:279;4132:347:::0;:::o;2125:597:42:-;-1:-1:-1;;;2252:18:42;;2225:13;;;2252:18;2522:23;:21;:23::i;:::-;2125:597;;2504:41;;;-1:-1:-1;2565:13:42;;-1:-1:-1;2616:4:42;;-1:-1:-1;2125:597:42;;-1:-1:-1;2125:597:42;:::o;5872:149:43:-;5969:45;;;;:38;:45;;;;;5962:52;;5938:12;;5969:45;5962:52;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5872:149;;;:::o;10557:485:40:-;10637:4;-1:-1:-1;;;;;;10670:59:40;;-1:-1:-1;;;10670:59:40;;:136;;-1:-1:-1;;;;;;;10749:57:40;;-1:-1:-1;;;10749:57:40;10670:136;:216;;;-1:-1:-1;;;;;;;10826:60:40;;-1:-1:-1;;;10826:60:40;10670:216;:297;;;-1:-1:-1;;;;;;;10906:61:40;;-1:-1:-1;;;10906:61:40;10670:297;10653:361;;;-1:-1:-1;10999:4:40;;10557:485;-1:-1:-1;10557:485:40:o;10653:361::-;-1:-1:-1;11030:5:40;;10557:485;-1:-1:-1;10557:485:40:o;4697:154:43:-;4767:4;-1:-1:-1;;;;;;;;;;;4824:19:43;;;-1:-1:-1;;;;;6452:32:62;;4824:19:43;;;6434:51:62;4790:33:43;;;;;;6407:18:62;4824:19:43;;;-1:-1:-1;;4824:19:43;;;;;;;;;;4790:54;;;:::i;8399:157:40:-;3122:10;9276:42;3122:26;3118:70;;3164:13;:11;:13::i;:::-;8523:26:::1;8529:6;8537:5;8544:4;;8523:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;8523:5:40::1;::::0;-1:-1:-1;;;8523:26:40:i:1;7785:302::-:0;2869:10;9276:42;2869:26;2865:78;;2918:14;;-1:-1:-1;;;2918:14:40;;;;;;;;;;;2865:78;7895:15:::1;7920:9;7927:1;7895:15:::0;7920:4;;:9:::1;:::i;:::-;7913:17;::::0;::::1;:::i;:::-;7895:35;;7945:34;7970:8;7945:24;:34::i;:::-;7940:101;;8002:28;::::0;-1:-1:-1;;;8002:28:40;;-1:-1:-1;;;;;;1824:33:62;;8002:28:40::1;::::0;::::1;1806:52:62::0;1779:18;;8002:28:40::1;1662:202:62::0;7940:101:40::1;8051:29;8065:4;8072:1;8075:4;;8051:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;8051:5:40::1;::::0;-1:-1:-1;;;8051:29:40:i:1;4177:117:42:-:0;4244:7;4270:17;4282:4;4270:11;:17::i;4612:475::-;4660:7;4680:18;4700:21;4725:23;:21;:23::i;:::-;4929:22;;;;;;;;;;4969:25;;;;;;4788:282;;;4816:95;4788:282;;;14671:25:62;;;;14712:18;;14705:34;;;;14755:18;;;14748:34;5012:13:42;14798:18:62;;;14791:34;5051:4:42;14841:19:62;;;14834:61;4679:69:42;;-1:-1:-1;4679:69:42;-1:-1:-1;14643:19:62;;4788:282:42;;;;;;;;;;;;4765:315;;;;;;4758:322;;;;4612:475;:::o;8155:189:43:-;8214:26;8229:10;8214:14;:26::i;:::-;:59;;;-1:-1:-1;8245:10:43;8267:4;8245:27;8214:59;8210:96;;;8155:189::o;8210:96::-;8323:14;;-1:-1:-1;;;8323:14:43;;;;;;;;;;;7293:140;7359:67;7376:5;-1:-1:-1;;;;;;;;;;;7383:25:43;:42;;;:40;:42;;;:::i;:::-;;;;;7359:16;:67::i;12316:1469:40:-;12467:4;;12524:41;;;;12535:9;12524:41;:::i;:::-;12487:78;;12575:23;12601:35;12614:10;:21;;;12601:12;:35::i;:::-;12575:61;;12651:10;:17;12672:2;12651:23;12647:607;;-1:-1:-1;;;;;12702:19:40;12710:10;12702:19;:::i;:::-;12694:48;12690:318;;;12982:10;12954:39;;-1:-1:-1;;;12954:39:40;;;;;;;;:::i;12690:318::-;13022:13;13123:2;13111:10;13107:19;13101:26;13092:35;;13162:81;13202:5;13209:7;13218:10;:24;;;13162:39;:81::i;:::-;13155:88;;;;;;;12647:607;13268:10;:17;13289:2;13268:23;13264:462;;13308:9;13319;13343:10;13332:42;;;;;;;;;;;;:::i;:::-;13307:67;;;;13389:33;13436:10;:24;;;13425:61;;;;;;;;;;;;:::i;:::-;13389:97;;13508:207;13564:7;13553:19;;;;;;5209:25:62;;5197:2;5182:18;;5063:177;13553:19:40;;;;;;;;;;;;;13615:5;13652:4;13677:1;13699;13508:15;:207::i;:::-;13501:214;;;;;;;;;13264:462;13767:10;13743:35;;-1:-1:-1;;;13743:35:40;;;;;;;;:::i;11413:302::-;11498:12;11512:19;11535:6;-1:-1:-1;;;;;11535:11:40;11554:5;11561:4;11535:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11497:69;;;;11581:7;11576:133;;11677:6;11671:13;11666:2;11658:6;11654:15;11647:38;13928:96;3381:13:43;:11;:13::i;3509:124:8:-;3577:7;3613:12;3618:6;3613:4;:12::i;:::-;3603:23;;;;;;3596:30;;3509:124;;;:::o;6627:532:43:-;6709:9;6704:449;6724:6;:13;6720:1;:17;6704:449;;;6762:6;6769:1;6762:9;;;;;;;;:::i;:::-;;;;;;;:16;6782:2;6762:22;;:48;;;;;6788:6;6795:1;6788:9;;;;;;;;:::i;:::-;;;;;;;:16;6808:2;6788:22;;6762:48;6758:128;;;6861:6;6868:1;6861:9;;;;;;;;:::i;:::-;;;;;;;6837:34;;-1:-1:-1;;;6837:34:43;;;;;;;;:::i;6758:128::-;6904:6;6911:1;6904:9;;;;;;;;:::i;:::-;;;;;;;:16;6924:2;6904:22;:73;;;;;-1:-1:-1;;;;;6930:47:43;;6946:6;6953:1;6946:9;;;;;;;;:::i;:::-;;;;;;;6938:18;;;:::i;:::-;6930:47;6904:73;6900:157;;;7032:6;7039:1;7032:9;;;;;;;;:::i;:::-;;;;;;;7004:38;;-1:-1:-1;;;7004:38:43;;;;;;;;:::i;6900:157::-;7071:71;7088:6;7095:1;7088:9;;;;;;;;:::i;:::-;;;;;;;7099:25;-1:-1:-1;;;;;;;;;;;8677:30:43;8529:194;7071:71;6739:3;;6704:449;;14058:158:40;14172:37;;;;;;;;;;;-1:-1:-1;;;14172:37:40;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;14172:37:40;;;;;14058:158::o;5554:176:42:-;5620:7;5685:17;:15;:17::i;:::-;5704;5716:4;5704:11;:17::i;:::-;5656:66;;-1:-1:-1;;;5656:66:42;;;18277:27:62;18320:11;;;18313:27;;;;18356:12;;;18349:28;18393:12;;5656:66:42;18019:392:62;7672:305:43;7764:19;7777:5;7764:12;:19::i;:::-;7760:51;;;7805:5;7792:19;;-1:-1:-1;;;7792:19:43;;;;;;;;:::i;7760:51::-;7865:4;-1:-1:-1;;;;;;;;;;;7822:33:43;;7856:5;7822:40;;;;;;:::i;:::-;;;;;;;;;;;;;;:47;;;;;-1:-1:-1;;7822:47:43;;;;;;;;;7927:5;7879:25;-1:-1:-1;;;;;;;;;;;8677:30:43;8529:194;7879:25;:45;;;;:38;;;;;:45;;;;;;:53;;:45;:53;:::i;:::-;;7957:5;7948:22;7964:5;7948:22;;;;;;:::i;1980:4154:35:-;-1:-1:-1;;;;;2295:24:35;;;;2110:12;2322:6;2279:3839;;;2365:4;2359:11;2400:4;2394;2387:18;2456:4;2445:9;2441:20;2435:27;2429:4;2422:41;2512:2;2500:9;2494:16;2491:24;2488:1077;;2569:4;2558:9;2554:20;2548:27;2627:2;2622;2617:3;2613:12;2609:21;2603:4;2596:35;2687:2;2684:1;2680:10;2677:1;2673:18;2667:4;2660:32;;3089:4;3035;2983;2930;2872:1;2794:5;2754:384;3309:1;3303:8;3295:6;3291:21;3272:16;3265:24;3262:51;3252:295;;-1:-1:-1;3391:1:35;3385:4;3378:15;3451:4;3444:15;-1:-1:-1;3352:1:35;3520:5;;3252:295;;2488:1077;3606:2;3594:9;3588:16;3585:24;3582:1043;;3674:4;3663:9;3659:20;3653:27;3650:1;3645:36;3639:4;3632:50;3745:4;3734:9;3730:20;3724:27;3718:4;3711:41;4149:4;4095;4043;3990;3932:1;3854:5;3814:384;4369:1;4363:8;4355:6;4351:21;4332:16;4325:24;4322:51;4312:295;;-1:-1:-1;4451:1:35;4445:4;4438:15;4511:4;4504:15;-1:-1:-1;4412:1:35;4580:5;;4312:295;;3582:1043;4655:1;4649:4;4642:15;4713:1;4707:4;4700:15;4787:10;4782:3;4778:20;4825:1;4822;4815:12;4924:4;4917;4914:1;4910:12;4903:26;4962:4;4959:1;4955:12;4994:4;4991:1;4984:15;5137:9;5131:16;5125:4;5121:27;5218:1;5211:4;5208:1;5204:12;5201:1;5190:9;5187:1;5180:5;5169:51;5165:56;;6004:4;5952:1;5888:4;5870:16;5866:27;5806:1;5749:6;5700:5;5664:400;5418:8;;5415:15;;;5296:786;;-1:-1:-1;;1980:4154:35;;;;;:::o;5726:2978:38:-;5921:4;1643:77;5941:12;:14;;;:29;5937:124;;;-1:-1:-1;6045:5:38;6038:12;;5937:124;6254:22;;;;6198:19;;6220:86;;6278:27;6254:22;6303:2;6278:27;:::i;:::-;6220;;;;;:86;:33;:86::i;:::-;6198:108;;1812:34;6336:5;6320:23;;;;;;:45;6316:88;;6388:5;6381:12;;;;;6316:88;6518:30;6600:36;6614:9;6625:4;6631;6600:13;:36::i;:::-;6569:73;;;;;;;;:::i;:::-;;;;;;;;;;;;;6518:125;;6653:29;6685:140;6732:12;:27;;;6791:17;:24;6761:12;:27;;;:54;;;;:::i;:::-;6685:27;;;;;:140;:33;:140::i;:::-;6653:172;;6886:17;6876:28;;;;;;6855:15;6839:33;;;;;;:65;6835:108;;6927:5;6920:12;;;;;;;6835:108;7059:30;;:34;;-1:-1:-1;;;7118:18:38;;;7090:2;;7059:34;;;;;;:::i;:::-;;;;;:55;-1:-1:-1;;;;;;7059:55:38;:77;7055:120;;7159:5;7152:12;;;;;;;7055:120;7324:23;:106;;;;-1:-1:-1;7352:30:38;;:34;;-1:-1:-1;;;7412:18:38;;;7383:2;;7352:34;;;;;;:::i;:::-;;;;;:55;-1:-1:-1;;;;;;7352:55:38;7351:79;;7324:106;7320:157;;;7461:5;7454:12;;;;;;;7320:157;7596:26;7625:42;7638:12;:27;;;7625:42;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7596:71;;7809:19;7831:76;7855:12;:30;;;7887:18;7838:68;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;7838:68:38;;;;;;;;;;7831:76;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7961:14;;;;;7977;;;;;7937:61;;;;;;22187:25:62;;;22228:18;;;22221:34;;;;-1:-1:-1;22271:18:62;;22264:34;22314:18;;;22307:34;;;22357:19;;;22350:35;;;7809:98:38;;-1:-1:-1;7917:17:38;;22159:19:62;;7937:61:38;;;;;;;;;;;;7917:81;;8056:12;8070:16;1762:5;-1:-1:-1;;;;;8090:19:38;8110:4;8090:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8522:10:38;;8055:60;;-1:-1:-1;8055:60:38;-1:-1:-1;8522:14:38;;8055:60;8550:16;;;;;8561:5;8550:16;8546:60;;;8586:3;8575:26;;;;;;;;;;;;:::i;:::-;8605:1;8575:31;8568:38;;;;;;;;;;;;;8546:60;8624:73;8647:11;8660:12;:14;;;8676:12;:14;;;8692:1;8695;8624:22;:73::i;:::-;8617:80;;;;;;;;;;;5726:2978;;;;;;;;:::o;2561:942:8:-;2629:16;1877:20;;2717:12;;;;2657:14;2762:31;2777:15;;;;1877:20;2777:15;:::i;:::-;2762:14;:31::i;:::-;2739:54;-1:-1:-1;2803:20:8;2826:31;2841:15;;;;:6;:15;:::i;2826:31::-;2803:54;-1:-1:-1;2890:19:8;;;;2950:27;;;;3016:25;;;;3074:19;;;;3134:27;;;;2867:20;3202:39;3217:23;;;;2890:6;3217:23;:::i;3202:39::-;3259:237;;;-1:-1:-1;;;;;23002:32:62;;;;3259:237:8;;;22984:51:62;23051:18;;;23044:34;;;;23094:18;;;23087:34;;;;-1:-1:-1;23137:18:62;;;23130:34;;;;23180:19;;;23173:35;;;;23224:19;;;23217:35;;;;23268:19;;;23261:35;23312:19;;;23305:35;23356:19;;;23349:35;23400:19;;;;23393:35;;;;3259:237:8;;;;;;;;;;22956:19:62;;;;3259:237:8;;;2561:942;-1:-1:-1;;2561:942:8:o;6163:145:42:-;6265:35;;;1360:53;6265:35;;;10785:25:62;10826:18;;;10819:34;;;6229:7:42;;10758:18:62;;6265:35:42;10611:248:62;30663:1307:34;30776:20;30905:7;30899:14;30954:3;30939:13;30936:22;30926:58;;30969:13;30962:20;;30926:58;31025:5;31010:13;31007:24;30997:62;;31044:13;31035:22;;30997:62;;31085:3;31078:5;31075:14;31072:882;;;-1:-1:-1;31124:4:34;31118:11;31166:15;;;31198:28;;;31254:19;;;;-1:-1:-1;;31303:4:34;31413:23;;31409:31;;31394:237;31499:15;;;31493:22;31477:14;;;31470:46;31542:9;;31591:22;31394:237;31591:22;-1:-1:-1;31747:1:34;31709:36;;;31725:4;31709:36;31702:47;31929:4;31911:23;;;31907:31;31895:44;;31889:4;31882:58;30663:1307;;;;;:::o;722:2892:32:-;835:20;961:4;955:11;983:10;980:2618;;;1183:1;1179;1167:10;1163:18;1159:26;1156:1;1152:34;1294:4;1288:11;1278:21;;1664:34;1658:4;1651:48;1791:6;1780:8;1773:16;1769:29;1733:34;1729:70;1723:4;1716:84;1906:4;1898:6;1894:17;1948:13;1943:3;1939:23;2016:10;2009:4;2003;1999:15;1995:32;2070:7;2064:14;2153:4;2144:7;2137:21;2285:623;2337:1;2331:4;2327:12;2319:20;;2399:4;2393:11;2539:4;2531:5;2527:2;2523:14;2519:25;2513:32;2510:1;2502:44;2604:4;2596:5;2592:2;2588:14;2584:25;2578:32;2575:1;2567:44;2668:4;2660:5;2657:1;2653:13;2649:24;2643:31;2640:1;2632:43;2724:4;2717:5;2713:16;2707:23;2704:1;2696:35;;2770:4;2764:11;2759:3;2752:24;2814:1;2809:3;2805:11;2798:18;;2875:3;2870;2867:12;2285:623;2857:33;2925:29;;3035:4;3026:14;3020:4;3013:28;-1:-1:-1;;;3180:1:32;3164:18;;3161:1;3157:26;3291:11;;;3284:37;;;;3469:1;3410:17;;3403:25;3399:33;;;3456:11;;;;3449:22;3541:21;;3526:37;;980:2618;722:2892;;;;;:::o;1562:703:0:-;1671:4;1691:6;;;:32;;;-1:-1:-1;;;;;;;;;;;1701:1:0;:22;;1691:32;:42;;;-1:-1:-1;1727:6:0;;1691:42;:68;;;;-1:-1:-1;;;;;;;;;;;1737:1:0;:22;;1691:68;1687:111;;;-1:-1:-1;1782:5:0;1775:12;;1687:111;1821:39;1853:2;1857;1821:31;:39::i;:::-;1816:83;;-1:-1:-1;1883:5:0;1876:12;;1816:83;1909:12;1924:30;1952:1;1924:27;:30::i;:::-;1909:45;-1:-1:-1;1965:16:0;-1:-1:-1;;;;;;;;;;;2009:4:0;1999:7;1984:49;1965:68;-1:-1:-1;2043:16:0;-1:-1:-1;;;;;;;;;;;2072:4:0;2069:1;2062:34;2043:53;;2106:10;2132:64;2169:2;2173;2177:8;2187;2132:36;:64::i;:::-;2127:69;-1:-1:-1;;;;;;;;;;;;2222:3:0;2224:1;-1:-1:-1;;;;;;;;;;;2222:3:0;:::i;:::-;2218:2;2211:18;2251:7;;1562:703;-1:-1:-1;;;;;;;;;;1562:703:0:o;3357:265:3:-;3416:11;3479:4;3473:11;3508;3563:3;3550:11;3545:3;3532:35;3587:19;;;3357:265;-1:-1:-1;;;3357:265:3:o;12684:440:1:-;12754:4;12777:6;;12776:19;;;;-1:-1:-1;12788:6:1;;12776:19;12775:31;;;;-1:-1:-1;;;;;;;;12800:1:1;:6;12775:31;:43;;;;-1:-1:-1;;;;;;;;12812:1:1;:6;12775:43;12770:87;;;-1:-1:-1;12841:5:1;12834:12;;12770:87;12890:11;-1:-1:-1;;;;;;;;12914:1:1;12911;12904:15;12890:29;-1:-1:-1;12940:11:1;-1:-1:-1;;;;;;;;1531:66:1;1666;12999:1;12992:15;-1:-1:-1;;;;;;;;12985:1:1;-1:-1:-1;;;;;;;;12978:1:1;12975;12968:15;12961:29;12954:57;12940:71;-1:-1:-1;;;;;;;;;1802:66:1;13048:3;13041:17;13097:10;;;;;12684:440;-1:-1:-1;;;;12684:440:1:o;3154:734::-;3209:14;3279:4;3273:11;3390:4;3381:7;3374:21;3435:4;3428;3419:7;3415:18;3408:32;3480:4;3473;3464:7;3460:18;3453:32;3584:1;3577:4;3568:7;3564:18;3557:29;3626:11;3619:4;3610:7;3606:18;3599:39;-1:-1:-1;;;;;;;;;;;3671:4:1;3662:7;3658:18;3651:29;3812:4;3803:7;3797:4;3788:7;3782:4;3778:1;3774:6;3763:54;3753:82;;3831:1;3828;3821:12;3753:82;3858:14;;3154:734;-1:-1:-1;;3154:734:1:o;13897:6526::-;14079:9;;;;14176:3;14079:9;;14258:13;;:30;;;;-1:-1:-1;14275:13:1;;14258:30;14254:44;;;14297:1;14290:8;;;;;;;;;;14254:44;14324:25;1938:66;2032;14342:2;14346;14324:9;:25::i;:::-;14313:36;;-1:-1:-1;14313:36:1;-1:-1:-1;14368:5:1;;14367:16;;;;-1:-1:-1;14377:5:1;;14367:16;14364:150;;;-1:-1:-1;;;;;;;;;;;14458:8:1;-1:-1:-1;;;;;;;;;;;14456:10:1;14446:8;14439:31;14430:40;;14497:1;14488:10;;14364:150;14638:1;14627:8;14620:5;14616:20;14612:28;14607:1;14596:8;14589:5;14585:20;14581:28;14578:1;14574:36;14570:71;14554:263;14647:2;14554:263;;14696:1;14689:5;14685:13;14676:22;;14793:1;14782:8;14775:5;14771:20;14767:28;14762:1;14751:8;14744:5;14740:20;14736:28;14733:1;14729:36;14725:71;14719:77;;14554:263;;;14558:85;14908:1;14897:8;14890:5;14886:20;14882:28;14877:1;14866:8;14859:5;14855:20;14851:28;14848:1;14844:36;14840:71;14834:77;;14939:1;14935:2;14932:9;14929:88;;14969:2;14964:7;;14997:2;14992:7;;14929:88;15044:1;15040:2;15037:9;15034:88;;15074:2;15069:7;;15102:2;15097:7;;15034:88;15149:1;15145:2;15142:9;15139:88;;15179:2;15174:7;;15207:2;15202:7;;15139:88;15265:1;15258:5;15254:13;15245:22;;15290:1;15284:7;;15315:1;15308:8;;15334:4025;15353:5;-1:-1:-1;;15341:18:1;15334:4025;;;-1:-1:-1;;;;;;;;15469:1:1;15466;15459:15;-1:-1:-1;;;;;;;;15535:2:1;15531;15524:17;-1:-1:-1;;;;;;;;15591:2:1;15588:1;15581:16;-1:-1:-1;;;;;;;;15647:2:1;15643;15636:17;15630:23;;-1:-1:-1;;;;;;;;15753:1:1;-1:-1:-1;;;;;;;;15745:2:1;15742:1;15735:16;-1:-1:-1;;;;;;;;15726:2:1;-1:-1:-1;;;;;;;;15719:10:1;15716:1;15709:24;15702:53;15699:1;15692:67;-1:-1:-1;;;;;;;;15822:3:1;15818:2;15811:18;15804:25;;-1:-1:-1;;;;;;;;15881:2:1;15877;15870:17;15864:23;;-1:-1:-1;;;;;;;;15980:1:1;15976:2;-1:-1:-1;;;;;;;;;;15960:22:1;-1:-1:-1;;;;;;;;15952:2:1;15948;15941:17;15934:52;15929:57;;-1:-1:-1;;;;;;;;16058:1:1;16053:2;-1:-1:-1;;;;;;;;16046:10:1;16043:1;16036:24;16032:2;16025:39;16019:45;;-1:-1:-1;;;;;;;;16134:2:1;-1:-1:-1;;;;;;;;16127:1:1;16123:2;16116:16;16109:31;16104:36;;16367:1;16356:8;16349:5;16345:20;16341:28;16336:1;16325:8;16318:5;16314:20;16310:28;16307:1;16303:36;16299:71;16293:77;;16406:2;16396:148;;16452:1;-1:-1:-1;;;;;;;;16445:9:1;16440:14;;16510:8;;;;;;16396:148;16592:1;16588:2;16585:9;16582:114;;16631:2;16625:8;;16668:2;16662:8;;16582:114;16731:1;16727:2;16724:9;16721:114;;16770:2;16764:8;;16807:2;16801:8;;16721:114;16870:1;16866:2;16863:9;16860:114;;16909:2;16903:8;;16946:2;16940:8;;16860:114;17009:2;16999:223;;-1:-1:-1;17048:2:1;;-1:-1:-1;17121:1:1;;-1:-1:-1;17121:1:1;;-1:-1:-1;17084:2:1;-1:-1:-1;17188:8:1;;-1:-1:-1;17188:8:1;16999:223;-1:-1:-1;;;;;;;;17402:1:1;-1:-1:-1;;;;;;;;17393:3:1;17389:2;17382:18;17375:32;-1:-1:-1;;;;;;;;17475:1:1;-1:-1:-1;;;;;;;;17468:9:1;-1:-1:-1;;;;;;;;17460:2:1;17456;17449:17;17442:39;17436:45;;17706:2;17696:1043;;17750:2;17740:973;;-1:-1:-1;;;;;;;;17810:1:1;-1:-1:-1;;;;;;;;;;17794:21:1;17788:27;;-1:-1:-1;;;;;;;;17884:2:1;17880;17873:17;17867:23;;-1:-1:-1;;;;;;;;17948:2:1;17945:1;17938:16;17932:22;;-1:-1:-1;;;;;;;;18017:2:1;18013;18006:17;18000:23;;-1:-1:-1;;;;;;;;18117:1:1;18112:2;-1:-1:-1;;;;;;;;18105:10:1;18102:1;18095:24;-1:-1:-1;;;;;;;;18087:2:1;18084:1;18077:16;18070:53;18064:59;;-1:-1:-1;;;;;;;;18187:2:1;18184:1;18177:16;18171:22;;-1:-1:-1;;;;;;;;18264:3:1;18260:2;18253:18;18246:25;;-1:-1:-1;;;;;;;;18335:2:1;18331;18324:17;18318:23;;-1:-1:-1;;;;;;;;18446:1:1;18442:2;-1:-1:-1;;;;;;;;;;18426:22:1;-1:-1:-1;;;;;;;;18418:2:1;18414;18407:17;18400:52;18395:57;;-1:-1:-1;;;;;;;;18536:1:1;18532;-1:-1:-1;;;;;;;;18525:9:1;18521:2;18514:24;18510:2;18503:39;18497:45;;-1:-1:-1;;;;;;;;18616:1:1;18613;18609:2;18602:16;18598:2;18591:31;18586:36;;18675:8;;;;;;;17740:973;-1:-1:-1;;;;;;;;18782:2:1;18778;18771:17;18765:23;;-1:-1:-1;;;;;;;;18840:2:1;18836;18829:17;-1:-1:-1;;;;;;;;18956:2:1;18952;18945:17;18939:23;;-1:-1:-1;;;;;;;;19006:3:1;19001;18994:19;18987:26;;-1:-1:-1;;;;;;;;19071:2:1;19068:1;19061:16;-1:-1:-1;;;;;;;;19179:1:1;19174:3;-1:-1:-1;;;;;;;;;;19158:23:1;-1:-1:-1;;;;;;;;19148:3:1;-1:-1:-1;;;;;;;;19141:11:1;-1:-1:-1;;;;;;;;19133:2:1;19129;19122:17;19115:41;19108:77;19102:83;;-1:-1:-1;;;;;;;;19280:1:1;19275:3;19272:1;19265:17;-1:-1:-1;;;;;;;;19257:2:1;-1:-1:-1;;;;;;;;19248:2:1;-1:-1:-1;;;;;;;;19241:10:1;19236:3;19229:26;19222:41;19215:71;19210:76;;;;;19317:2;19312:7;;16226:3115;;;;15334:4025;15382:1;15375:5;15371:13;15362:22;;15334:4025;;;19402:4;19396:11;19445:2;19438:4;19435:1;19431:12;19424:24;19710:4;19707:1;19700:15;19753:4;19746;19743:1;19739:12;19732:26;19796:4;19789;19786:1;19782:12;19775:26;-1:-1:-1;;;;;;;;;;19943:4:1;19940:1;19936:12;19929:29;-1:-1:-1;;;;;;;;19989:4:1;19986:1;19982:12;19975:23;20126:4;20123:1;20117:4;20114:1;20108:4;20104:1;20100:6;20089:42;20079:70;;20145:1;20142;20135:12;20079:70;-1:-1:-1;;;;;;;;20330:1:1;20324:8;20321:1;20314:22;20309:27;;;20408:8;;;;;;13897:6526;;;;;;;:::o;13226:499::-;13316:7;;;;12535:6;13388:41;;13422:2;13426;13414:15;;;;;;;;13388:41;12535:6;13439:41;;13473:2;13477;13465:15;;;;;;;;13439:41;13498:2;13494;:6;13493:18;;;;;13508:2;13504;:6;13493:18;13490:181;;;13549:20;13558:2;13562;13565:1;13567;13549:8;:20::i;:::-;13527:42;;-1:-1:-1;13527:42:1;;-1:-1:-1;13527:42:1;-1:-1:-1;13527:42:1;-1:-1:-1;13490:181:1;;;13629:31;13639:2;13643;13647:1;13650;13653:2;13657;13629:9;:31::i;:::-;13607:53;;-1:-1:-1;13607:53:1;;-1:-1:-1;13607:53:1;-1:-1:-1;13607:53:1;-1:-1:-1;13490:181:1;13688:30;13700:2;13704;13708:3;13713:4;13688:11;:30::i;:::-;13681:37;;;;;;13226:499;;;;;;;;:::o;9414:928::-;9526:10;9538;9550;9562;-1:-1:-1;;;;;;;;9655:1:1;9652;9645:15;9639:21;;-1:-1:-1;;;;;;;;9705:2:1;9701;9694:17;9688:23;;-1:-1:-1;;;;;;;;9753:2:1;9750:1;9743:16;9737:22;;-1:-1:-1;;;;;;;;9805:2:1;9801;9794:17;9788:23;;-1:-1:-1;;;;;;;;9853:2:1;9849;9842:17;9836:23;;-1:-1:-1;;;;;;;;9955:1:1;-1:-1:-1;;;;;;;;9947:2:1;9944:1;9937:16;-1:-1:-1;;;;;;;;9928:2:1;-1:-1:-1;;;;;;;;9921:10:1;9918:1;9911:24;9904:53;9901:1;9894:67;9888:73;;-1:-1:-1;;;;;;;;10054:1:1;10050:2;-1:-1:-1;;;;;;;;;;10034:22:1;-1:-1:-1;;;;;;;;10026:2:1;10022;10015:17;10008:52;10002:58;;-1:-1:-1;;;;;;;;10128:1:1;10123:2;-1:-1:-1;;;;;;;;10116:10:1;10112:2;10105:25;10101:2;10094:40;10089:45;;-1:-1:-1;;;;;;;;10178:3:1;10174:2;10167:18;10161:24;;-1:-1:-1;;;;;;;;10253:1:1;10250;10246:2;10239:16;-1:-1:-1;;;;;;;;10232:24:1;10229:1;10222:38;10216:44;;9414:928;;;;;;;;;:::o;10559:1073::-;10700:10;10712;10724;10736;10790:2;10796:1;10790:7;10786:67;;-1:-1:-1;10825:2:1;;-1:-1:-1;10829:2:1;;-1:-1:-1;10833:1:1;;-1:-1:-1;10833:1:1;10817:21;;10786:67;-1:-1:-1;;;;;;;;10900:10:1;;;;;10904:1;10951:4;10947:2;10940:19;10933:34;10927:40;;-1:-1:-1;;;;;;;;11024:2:1;-1:-1:-1;;;;;;;;11017:10:1;-1:-1:-1;;;;;;;;11008:3:1;11004:2;10997:18;10990:41;10984:47;;-1:-1:-1;;;;;;;;11065:2:1;11061;11054:17;11048:23;;-1:-1:-1;;;;;;;;11116:2:1;11112;11105:17;11099:23;;-1:-1:-1;;;;;;;;11170:2:1;11165:3;11158:18;11152:24;;-1:-1:-1;;;;;;;;11229:2:1;11223:4;11216:19;11210:25;;-1:-1:-1;;;;;;;;11290:2:1;11286;11279:17;11272:24;;-1:-1:-1;;;;;;;;11401:1:1;11396:3;-1:-1:-1;;;;;;;;;;11380:23:1;-1:-1:-1;;;;;;;;11371:2:1;-1:-1:-1;;;;;;;;11364:10:1;-1:-1:-1;;;;;;;;11356:2:1;11352;11345:17;11338:40;11331:76;11325:82;;-1:-1:-1;;;;;;;;11509:1:1;11505:2;11501;11494:17;-1:-1:-1;;;;;;;;11486:2:1;-1:-1:-1;;;;;;;;11477:2:1;-1:-1:-1;;;;;;;;11470:10:1;11465:3;11458:26;11451:41;11444:71;11438:77;;10559:1073;;;;;;;;;;;;:::o;8954:351::-;9045:10;9057;9079:14;9096:16;9108:3;9096:11;:16::i;:::-;9079:33;-1:-1:-1;;;;;;;;;9145:6:1;9142:1;9135:20;9130:25;-1:-1:-1;9173:10:1;-1:-1:-1;;;;;;;;9197:6:1;9193:2;9186:21;9173:34;-1:-1:-1;;;;;;;;;9243:2:1;9239;9232:17;9223:26;-1:-1:-1;;;;;;;;;9281:6:1;9278:1;9271:20;9266:25;;9069:236;;8954:351;;;;;;;:::o;4000:730::-;4055:14;4125:4;4119:11;4236:4;4227:7;4220:21;4281:4;4274;4265:7;4261:18;4254:32;4326:4;4319;4310:7;4306:18;4299:32;4430:1;4423:4;4414:7;4410:18;4403:29;-1:-1:-1;;;;;;;;;;4465:4:1;4456:7;4452:18;4445:35;-1:-1:-1;;;;;;;;4513:4:1;4504:7;4500:18;4493:29;4654:4;4645:7;4639:4;4630:7;4624:4;4620:1;4616:6;4605:54;4595:82;;4673:1;4670;4663:12;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:248:62;82:6;90;143:2;131:9;122:7;118:23;114:32;111:52;;;159:1;156;149:12;111:52;-1:-1:-1;;182:23:62;;;252:2;237:18;;;224:32;;-1:-1:-1;14:248:62:o;459:173::-;527:20;;-1:-1:-1;;;;;576:31:62;;566:42;;556:70;;622:1;619;612:12;556:70;459:173;;;:::o;637:186::-;696:6;749:2;737:9;728:7;724:23;720:32;717:52;;;765:1;762;755:12;717:52;788:29;807:9;788:29;:::i;828:347::-;879:8;889:6;943:3;936:4;928:6;924:17;920:27;910:55;;961:1;958;951:12;910:55;-1:-1:-1;984:20:62;;-1:-1:-1;;;;;1016:30:62;;1013:50;;;1059:1;1056;1049:12;1013:50;1096:4;1088:6;1084:17;1072:29;;1148:3;1141:4;1132:6;1124;1120:19;1116:30;1113:39;1110:59;;;1165:1;1162;1155:12;1110:59;828:347;;;;;:::o;1180:477::-;1259:6;1267;1275;1328:2;1316:9;1307:7;1303:23;1299:32;1296:52;;;1344:1;1341;1334:12;1296:52;1380:9;1367:23;1357:33;;1441:2;1430:9;1426:18;1413:32;-1:-1:-1;;;;;1460:6:62;1457:30;1454:50;;;1500:1;1497;1490:12;1454:50;1539:58;1589:7;1580:6;1569:9;1565:22;1539:58;:::i;:::-;1180:477;;1616:8;;-1:-1:-1;1513:84:62;;-1:-1:-1;;;;1180:477:62:o;1869:127::-;1930:10;1925:3;1921:20;1918:1;1911:31;1961:4;1958:1;1951:15;1985:4;1982:1;1975:15;2001:253;2073:2;2067:9;2115:4;2103:17;;-1:-1:-1;;;;;2135:34:62;;2171:22;;;2132:62;2129:88;;;2197:18;;:::i;:::-;2233:2;2226:22;2001:253;:::o;2259:275::-;2330:2;2324:9;2395:2;2376:13;;-1:-1:-1;;2372:27:62;2360:40;;-1:-1:-1;;;;;2415:34:62;;2451:22;;;2412:62;2409:88;;;2477:18;;:::i;:::-;2513:2;2506:22;2259:275;;-1:-1:-1;2259:275:62:o;2539:186::-;2587:4;-1:-1:-1;;;;;2612:6:62;2609:30;2606:56;;;2642:18;;:::i;:::-;-1:-1:-1;2708:2:62;2687:15;-1:-1:-1;;2683:29:62;2714:4;2679:40;;2539:186::o;2730:462::-;2772:5;2825:3;2818:4;2810:6;2806:17;2802:27;2792:55;;2843:1;2840;2833:12;2792:55;2879:6;2866:20;2910:48;2926:31;2954:2;2926:31;:::i;:::-;2910:48;:::i;:::-;2983:2;2974:7;2967:19;3029:3;3022:4;3017:2;3009:6;3005:15;3001:26;2998:35;2995:55;;;3046:1;3043;3036:12;2995:55;3111:2;3104:4;3096:6;3092:17;3085:4;3076:7;3072:18;3059:55;3159:1;3134:16;;;3152:4;3130:27;3123:38;;;;3138:7;2730:462;-1:-1:-1;;;2730:462:62:o;3197:320::-;3265:6;3318:2;3306:9;3297:7;3293:23;3289:32;3286:52;;;3334:1;3331;3324:12;3286:52;3374:9;3361:23;-1:-1:-1;;;;;3399:6:62;3396:30;3393:50;;;3439:1;3436;3429:12;3393:50;3462:49;3503:7;3494:6;3483:9;3479:22;3462:49;:::i;3522:380::-;3598:8;3608:6;3662:3;3655:4;3647:6;3643:17;3639:27;3629:55;;3680:1;3677;3670:12;3629:55;-1:-1:-1;3703:20:62;;-1:-1:-1;;;;;3735:30:62;;3732:50;;;3778:1;3775;3768:12;3732:50;3815:4;3807:6;3803:17;3791:29;;3875:3;3868:4;3858:6;3855:1;3851:14;3843:6;3839:27;3835:38;3832:47;3829:67;;;3892:1;3889;3882:12;3907:475;4018:6;4026;4079:2;4067:9;4058:7;4054:23;4050:32;4047:52;;;4095:1;4092;4085:12;4047:52;4135:9;4122:23;-1:-1:-1;;;;;4160:6:62;4157:30;4154:50;;;4200:1;4197;4190:12;4154:50;4239:83;4314:7;4305:6;4294:9;4290:22;4239:83;:::i;:::-;4341:8;;4213:109;;-1:-1:-1;3907:475:62;-1:-1:-1;;;;3907:475:62:o;4387:162::-;4453:5;4498:3;4489:6;4484:3;4480:16;4476:26;4473:46;;;4515:1;4512;4505:12;4473:46;-1:-1:-1;4537:6:62;4387:162;-1:-1:-1;4387:162:62:o;4554:504::-;4664:6;4672;4680;4733:2;4721:9;4712:7;4708:23;4704:32;4701:52;;;4749:1;4746;4739:12;4701:52;4789:9;4776:23;-1:-1:-1;;;;;4814:6:62;4811:30;4808:50;;;4854:1;4851;4844:12;4808:50;4877:73;4942:7;4933:6;4922:9;4918:22;4877:73;:::i;:::-;4867:83;4997:2;4982:18;;4969:32;;-1:-1:-1;5048:2:62;5033:18;;;5020:32;;4554:504;-1:-1:-1;;;;4554:504:62:o;5245:483::-;5324:6;5332;5340;5393:2;5381:9;5372:7;5368:23;5364:32;5361:52;;;5409:1;5406;5399:12;5361:52;5432:29;5451:9;5432:29;:::i;:::-;5422:39;;5512:2;5501:9;5497:18;5484:32;-1:-1:-1;;;;;5531:6:62;5528:30;5525:50;;;5571:1;5568;5561:12;5733:368;5825:6;5878:2;5866:9;5857:7;5853:23;5849:32;5846:52;;;5894:1;5891;5884:12;5846:52;5934:9;5921:23;-1:-1:-1;;;;;5959:6:62;5956:30;5953:50;;;5999:1;5996;5989:12;5953:50;6022:73;6087:7;6078:6;6067:9;6063:22;6022:73;:::i;6962:180::-;7021:6;7074:2;7062:9;7053:7;7049:23;7045:32;7042:52;;;7090:1;7087;7080:12;7042:52;-1:-1:-1;7113:23:62;;6962:180;-1:-1:-1;6962:180:62:o;7147:250::-;7232:1;7242:113;7256:6;7253:1;7250:13;7242:113;;;7332:11;;;7326:18;7313:11;;;7306:39;7278:2;7271:10;7242:113;;;-1:-1:-1;;7389:1:62;7371:16;;7364:27;7147:250::o;7402:271::-;7444:3;7482:5;7476:12;7509:6;7504:3;7497:19;7525:76;7594:6;7587:4;7582:3;7578:14;7571:4;7564:5;7560:16;7525:76;:::i;:::-;7655:2;7634:15;-1:-1:-1;;7630:29:62;7621:39;;;;7662:4;7617:50;;7402:271;-1:-1:-1;;7402:271:62:o;7678:1259::-;8084:3;8079;8075:13;8067:6;8063:26;8052:9;8045:45;8026:4;8109:2;8147:3;8142:2;8131:9;8127:18;8120:31;8174:46;8215:3;8204:9;8200:19;8192:6;8174:46;:::i;:::-;8268:9;8260:6;8256:22;8251:2;8240:9;8236:18;8229:50;8302:33;8328:6;8320;8302:33;:::i;:::-;8366:2;8351:18;;8344:34;;;-1:-1:-1;;;;;8415:32:62;;8409:3;8394:19;;8387:61;8435:3;8464:19;;8457:35;;;8529:22;;;8523:3;8508:19;;8501:51;8601:13;;8623:22;;;8673:2;8699:15;;;;-1:-1:-1;8661:15:62;;;;-1:-1:-1;8742:169:62;8756:6;8753:1;8750:13;8742:169;;;8817:13;;8805:26;;8886:15;;;;8851:12;;;;8778:1;8771:9;8742:169;;;-1:-1:-1;8928:3:62;;7678:1259;-1:-1:-1;;;;;;;;;;;;7678:1259:62:o;8942:218::-;9089:2;9078:9;9071:21;9052:4;9109:45;9150:2;9139:9;9135:18;9127:6;9109:45;:::i;9165:286::-;9223:6;9276:2;9264:9;9255:7;9251:23;9247:32;9244:52;;;9292:1;9289;9282:12;9244:52;9318:23;;-1:-1:-1;;;;;;9370:32:62;;9360:43;;9350:71;;9417:1;9414;9407:12;9456:551;9544:6;9552;9560;9568;9621:2;9609:9;9600:7;9596:23;9592:32;9589:52;;;9637:1;9634;9627:12;9589:52;9660:29;9679:9;9660:29;:::i;:::-;9650:39;;9736:2;9725:9;9721:18;9708:32;9698:42;;9791:2;9780:9;9776:18;9763:32;-1:-1:-1;;;;;9810:6:62;9807:30;9804:50;;;9850:1;9847;9840:12;9804:50;9889:58;9939:7;9930:6;9919:9;9915:22;9889:58;:::i;:::-;9456:551;;;;-1:-1:-1;9966:8:62;-1:-1:-1;;;;9456:551:62:o;10012:409::-;10082:6;10090;10143:2;10131:9;10122:7;10118:23;10114:32;10111:52;;;10159:1;10156;10149:12;10111:52;10199:9;10186:23;-1:-1:-1;;;;;10224:6:62;10221:30;10218:50;;;10264:1;10261;10254:12;10218:50;10303:58;10353:7;10344:6;10333:9;10329:22;10303:58;:::i;10864:287::-;10993:3;11031:6;11025:13;11047:66;11106:6;11101:3;11094:4;11086:6;11082:17;11047:66;:::i;:::-;11129:16;;;;;10864:287;-1:-1:-1;;10864:287:62:o;11156:127::-;11217:10;11212:3;11208:20;11205:1;11198:31;11248:4;11245:1;11238:15;11272:4;11269:1;11262:15;11288:322;11379:4;11437:11;11424:25;11531:2;11527:7;11516:8;11500:14;11496:29;11492:43;11472:18;11468:68;11458:96;;11550:1;11547;11540:12;11615:521;11692:4;11698:6;11758:11;11745:25;11852:2;11848:7;11837:8;11821:14;11817:29;11813:43;11793:18;11789:68;11779:96;;11871:1;11868;11861:12;11779:96;11898:33;;11950:20;;;-1:-1:-1;;;;;;11982:30:62;;11979:50;;;12025:1;12022;12015:12;11979:50;12058:4;12046:17;;-1:-1:-1;12089:14:62;12085:27;;;12075:38;;12072:58;;;12126:1;12123;12116:12;12141:331;12246:9;12257;12299:8;12287:10;12284:24;12281:44;;;12321:1;12318;12311:12;12281:44;12350:6;12340:8;12337:20;12334:40;;;12370:1;12367;12360:12;12334:40;-1:-1:-1;;12396:23:62;;;12441:25;;;;;-1:-1:-1;12141:331:62:o;12477:323::-;-1:-1:-1;;;;;;12597:19:62;;12673:11;;;;12704:1;12696:10;;12693:101;;;12781:2;12775;12768:3;12765:1;12761:11;12758:1;12754:19;12750:28;12746:2;12742:37;12738:46;12729:55;;12693:101;;;12477:323;;;;:::o;13084:938::-;13220:9;-1:-1:-1;;;;;13295:2:62;13287:6;13284:14;13281:40;;;13301:18;;:::i;:::-;13347:6;13344:1;13340:14;13373:4;13397:30;13421:4;13417:2;13413:13;13397:30;:::i;:::-;13461:19;;;13533:14;;;;13505:4;13496:14;;;13570;13559:26;;13556:46;;;13598:1;13595;13588:12;13556:46;13622:5;13636:353;13652:6;13647:3;13644:15;13636:353;;;13738:3;13725:17;13774:2;13761:11;13758:19;13755:109;;;13818:1;13847:2;13843;13836:14;13755:109;13889:57;13931:14;13917:11;13910:5;13906:23;13889:57;:::i;:::-;13877:70;;-1:-1:-1;13967:12:62;;;;13669;;13636:353;;;-1:-1:-1;14011:5:62;13084:938;-1:-1:-1;;;;;;;13084:938:62:o;14027:380::-;14106:1;14102:12;;;;14149;;;14170:61;;14224:4;14216:6;14212:17;14202:27;;14170:61;14277:2;14269:6;14266:14;14246:18;14243:38;14240:161;;14323:10;14318:3;14314:20;14311:1;14304:31;14358:4;14355:1;14348:15;14386:4;14383:1;14376:15;14906:127;14967:10;14962:3;14958:20;14955:1;14948:31;14998:4;14995:1;14988:15;15022:4;15019:1;15012:15;15038:135;15077:3;15098:17;;;15095:43;;15118:18;;:::i;:::-;-1:-1:-1;15165:1:62;15154:13;;15038:135::o;15178:827::-;15272:6;15325:2;15313:9;15304:7;15300:23;15296:32;15293:52;;;15341:1;15338;15331:12;15293:52;15381:9;15368:23;-1:-1:-1;;;;;15451:2:62;15443:6;15440:14;15437:34;;;15467:1;15464;15457:12;15437:34;15490:22;;;;15546:4;15528:16;;;15524:27;15521:47;;;15564:1;15561;15554:12;15521:47;15597:4;15591:11;15641:4;15633:6;15629:17;15696:6;15684:10;15681:22;15676:2;15664:10;15661:18;15658:46;15655:72;;;15707:18;;:::i;:::-;15743:4;15736:24;15784:16;;15769:32;;15847:2;15839:11;;15826:25;15863:16;;;15860:36;;;15892:1;15889;15882:12;15860:36;15929:44;15965:7;15954:8;15950:2;15946:17;15929:44;:::i;:::-;15924:2;15912:15;;15905:69;-1:-1:-1;15916:6:62;15178:827;-1:-1:-1;;;;;15178:827:62:o;16010:297::-;16128:12;;16175:4;16164:16;;;16158:23;;16128:12;16193:16;;16190:111;;;-1:-1:-1;;16267:4:62;16263:17;;;;16260:1;16256:25;16252:38;16241:50;;16010:297;-1:-1:-1;16010:297:62:o;16312:245::-;16391:6;16399;16452:2;16440:9;16431:7;16427:23;16423:32;16420:52;;;16468:1;16465;16458:12;16420:52;-1:-1:-1;;16491:16:62;;16547:2;16532:18;;;16526:25;16491:16;;16526:25;;-1:-1:-1;16312:245:62:o;16562:441::-;16615:5;16668:3;16661:4;16653:6;16649:17;16645:27;16635:55;;16686:1;16683;16676:12;16635:55;16715:6;16709:13;16746:48;16762:31;16790:2;16762:31;:::i;16746:48::-;16819:2;16810:7;16803:19;16865:3;16858:4;16853:2;16845:6;16841:15;16837:26;16834:35;16831:55;;;16882:1;16879;16872:12;16831:55;16895:77;16969:2;16962:4;16953:7;16949:18;16942:4;16934:6;16930:17;16895:77;:::i;17008:1006::-;17109:6;17162:2;17150:9;17141:7;17137:23;17133:32;17130:52;;;17178:1;17175;17168:12;17130:52;17211:9;17205:16;-1:-1:-1;;;;;17281:2:62;17273:6;17270:14;17267:34;;;17297:1;17294;17287:12;17267:34;17320:22;;;;17376:4;17358:16;;;17354:27;17351:47;;;17394:1;17391;17384:12;17351:47;17420:22;;:::i;:::-;17473:2;17467:9;17501:2;17491:8;17488:16;17485:36;;;17517:1;17514;17507:12;17485:36;17544:55;17591:7;17580:8;17576:2;17572:17;17544:55;:::i;:::-;17537:5;17530:70;;17639:2;17635;17631:11;17625:18;17668:2;17658:8;17655:16;17652:36;;;17684:1;17681;17674:12;17652:36;17720:55;17767:7;17756:8;17752:2;17748:17;17720:55;:::i;:::-;17715:2;17708:5;17704:14;17697:79;;17822:2;17818;17814:11;17808:18;17803:2;17796:5;17792:14;17785:42;17873:2;17869;17865:11;17859:18;17854:2;17847:5;17843:14;17836:42;17925:3;17921:2;17917:12;17911:19;17905:3;17898:5;17894:15;17887:44;17978:3;17974:2;17970:12;17964:19;17958:3;17951:5;17947:15;17940:44;18003:5;17993:15;;;;;17008:1006;;;;:::o;18541:542::-;18642:2;18637:3;18634:11;18631:446;;;18678:1;18702:5;18699:1;18692:16;18746:4;18743:1;18733:18;18816:2;18804:10;18800:19;18797:1;18793:27;18787:4;18783:38;18852:4;18840:10;18837:20;18834:47;;;-1:-1:-1;18875:4:62;18834:47;18930:2;18925:3;18921:12;18918:1;18914:20;18908:4;18904:31;18894:41;;18985:82;19003:2;18996:5;18993:13;18985:82;;;19048:17;;;19029:1;19018:13;18985:82;;;18989:3;;;18541:542;;;:::o;19259:1341::-;19383:3;19377:10;-1:-1:-1;;;;;19402:6:62;19399:30;19396:56;;;19432:18;;:::i;:::-;19461:96;19550:6;19510:38;19542:4;19536:11;19510:38;:::i;:::-;19504:4;19461:96;:::i;:::-;19612:4;;19669:2;19658:14;;19686:1;19681:662;;;;20387:1;20404:6;20401:89;;;-1:-1:-1;20456:19:62;;;20450:26;20401:89;-1:-1:-1;;19216:1:62;19212:11;;;19208:24;19204:29;19194:40;19240:1;19236:11;;;19191:57;20503:81;;19651:943;;19681:662;18488:1;18481:14;;;18525:4;18512:18;;-1:-1:-1;;19717:20:62;;;19834:236;19848:7;19845:1;19842:14;19834:236;;;19937:19;;;19931:26;19916:42;;20029:27;;;;19997:1;19985:14;;;;19864:19;;19834:236;;;19838:3;20098:6;20089:7;20086:19;20083:201;;;20159:19;;;20153:26;-1:-1:-1;;20242:1:62;20238:14;;;20254:3;20234:24;20230:37;20226:42;20211:58;20196:74;;20083:201;-1:-1:-1;;;;;20330:1:62;20314:14;;;20310:22;20297:36;;-1:-1:-1;19259:1341:62:o;20605:125::-;20670:9;;;20691:10;;;20688:36;;;20704:18;;:::i;20735:611::-;-1:-1:-1;;;21065:51:62;;21139:13;;21047:3;;21161:75;21139:13;21224:2;21215:12;;21208:4;21196:17;;21161:75;:::i;:::-;-1:-1:-1;;;21295:2:62;21255:16;;;;21287:11;;;21280:33;-1:-1:-1;21337:2:62;21329:11;;20735:611;-1:-1:-1;20735:611:62:o;21351:184::-;21421:6;21474:2;21462:9;21453:7;21449:23;21445:32;21442:52;;;21490:1;21487;21480:12;21442:52;-1:-1:-1;21513:16:62;;21351:184;-1:-1:-1;21351:184:62:o;21540:383::-;21697:3;21735:6;21729:13;21751:66;21810:6;21805:3;21798:4;21790:6;21786:17;21751:66;:::i;:::-;21839:16;;;;21864:21;;;-1:-1:-1;21912:4:62;21901:16;;21540:383;-1:-1:-1;21540:383:62:o;23571:128::-;23638:9;;;23659:11;;;23656:37;;;23673:18;;:::i", + "linkReferences": {}, + "immutableReferences": { + "49415": [ + { + "start": 2078, + "length": 32 + }, + { + "start": 2389, + "length": 32 + } + ] + } + }, + "methodIdentifiers": { + "REPLAYABLE_NONCE_KEY()": "88ce4c7c", + "addOwnerAddress(address)": "0f0f3f24", + "addOwnerPublicKey(bytes32,bytes32)": "29565e3b", + "canSkipChainIdValidation(bytes4)": "9f9bcb34", + "domainSeparator()": "f698da25", + "eip712Domain()": "84b0196e", + "entryPoint()": "b0d691fe", + "execute(address,uint256,bytes)": "b61d27f6", + "executeBatch((address,uint256,bytes)[])": "34fcd5be", + "executeWithoutChainIdValidation(bytes)": "bf6ba1fc", + "getUserOpHashWithoutChainId((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))": "4f6e7f22", + "implementation()": "5c60da1b", + "initialize(bytes[])": "6f2de70e", + "isOwnerAddress(address)": "a2e1a8d8", + "isOwnerBytes(bytes)": "1ca5393f", + "isOwnerPublicKey(bytes32,bytes32)": "066a1eb7", + "isValidSignature(bytes32,bytes)": "1626ba7e", + "nextOwnerIndex()": "d948fd2e", + "ownerAtIndex(uint256)": "8ea69029", + "proxiableUUID()": "52d1902d", + "removeOwnerAtIndex(uint256)": "72de3b5a", + "replaySafeHash(bytes32)": "ce1506be", + "upgradeToAndCall(address,bytes)": "4f1ef286", + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": "3a871cdd" + }, + "rawMetadata": "{\"compiler\":{\"version\":\"0.8.23+commit.f704f362\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"owner\",\"type\":\"bytes\"}],\"name\":\"AlreadyOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Initialized\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"owner\",\"type\":\"bytes\"}],\"name\":\"InvalidEthereumAddressOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"key\",\"type\":\"uint256\"}],\"name\":\"InvalidNonceKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"owner\",\"type\":\"bytes\"}],\"name\":\"InvalidOwnerBytesLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"NoOwnerAtIndex\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"selector\",\"type\":\"bytes4\"}],\"name\":\"SelectorNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedCallContext\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UpgradeFailed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"owner\",\"type\":\"bytes\"}],\"name\":\"AddOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"owner\",\"type\":\"bytes\"}],\"name\":\"RemoveOwner\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"REPLAYABLE_NONCE_KEY\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"addOwnerAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"x\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"addOwnerPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"functionSelector\",\"type\":\"bytes4\"}],\"name\":\"canSkipChainIdValidation\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eip712Domain\",\"outputs\":[{\"internalType\":\"bytes1\",\"name\":\"fields\",\"type\":\"bytes1\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"verifyingContract\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[]\",\"name\":\"extensions\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct CoinbaseSmartWallet.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"executeBatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"executeWithoutChainIdValidation\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"getUserOpHashWithoutChainId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"owners\",\"type\":\"bytes[]\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"isOwnerAddress\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"account\",\"type\":\"bytes\"}],\"name\":\"isOwnerBytes\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"x\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"y\",\"type\":\"bytes32\"}],\"name\":\"isOwnerPublicKey\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"result\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextOwnerIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"ownerAtIndex\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proxiableUUID\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"removeOwnerAtIndex\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"hash\",\"type\":\"bytes32\"}],\"name\":\"replaySafeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"missingAccountFunds\",\"type\":\"uint256\"}],\"name\":\"validateUserOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"validationData\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"author\":\"Coinbase (https://github.com/coinbase/smart-wallet)Solady (https://github.com/vectorized/solady/blob/main/src/accounts/ERC4337.sol)\",\"errors\":{\"AlreadyOwner(bytes)\":[{\"params\":{\"owner\":\"The raw abi encoded owner bytes.\"}}],\"InvalidEthereumAddressOwner(bytes)\":[{\"params\":{\"owner\":\"The invalid raw abi encoded owner bytes.\"}}],\"InvalidNonceKey(uint256)\":[{\"details\":\"The `UserOperation` key validation is based on the `UserOperation` call selector.\",\"params\":{\"key\":\"The invalid `UserOperation` key.\"}}],\"InvalidOwnerBytesLength(bytes)\":[{\"params\":{\"owner\":\"The invalid raw abi encoded owner bytes.\"}}],\"NoOwnerAtIndex(uint256)\":[{\"params\":{\"index\":\"The targeted index for removal.\"}}],\"SelectorNotAllowed(bytes4)\":[{\"details\":\"Whitelisting of `UserOperation`s that are allowed to skip the chain ID validation is based on their call selectors (see `canSkipChainIdValidation()`).\",\"params\":{\"selector\":\"The user operation call selector that raised the error.\"}}],\"UnauthorizedCallContext()\":[{\"details\":\"The call is from an unauthorized call context.\"}],\"UpgradeFailed()\":[{\"details\":\"The upgrade failed.\"}]},\"events\":{\"AddOwner(uint256,bytes)\":{\"params\":{\"index\":\"The owner index.\",\"owner\":\"The raw abi encoded owner bytes.\"}},\"RemoveOwner(uint256,bytes)\":{\"params\":{\"index\":\"The owner index.\",\"owner\":\"The raw abi encoded owner bytes.\"}},\"Upgraded(address)\":{\"details\":\"Emitted when the proxy's implementation is upgraded.\"}},\"kind\":\"dev\",\"methods\":{\"addOwnerAddress(address)\":{\"params\":{\"owner\":\"The owner address.\"}},\"addOwnerPublicKey(bytes32,bytes32)\":{\"params\":{\"x\":\"The owner public key x coordinate.\",\"y\":\"The owner public key y coordinate.\"}},\"canSkipChainIdValidation(bytes4)\":{\"returns\":{\"_0\":\"`true` is the function selector is whitelisted to skip the chain ID validation, else `false`.\"}},\"domainSeparator()\":{\"details\":\"Implements domainSeparator = hashStruct(eip712Domain). See https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator.\",\"returns\":{\"_0\":\"The 32 bytes domain separator result.\"}},\"eip712Domain()\":{\"details\":\"Follows ERC-5267 (see https://eips.ethereum.org/EIPS/eip-5267).\",\"returns\":{\"chainId\":\"The value of the `EIP712Domain.chainId` field.\",\"extensions\":\"The list of EIP numbers, that extends EIP-712 with new domain fields.\",\"fields\":\"The bitmap of used fields.\",\"name\":\"The value of the `EIP712Domain.name` field.\",\"salt\":\"The value of the `EIP712Domain.salt` field.\",\"verifyingContract\":\"The value of the `EIP712Domain.verifyingContract` field.\",\"version\":\"The value of the `EIP712Domain.version` field.\"}},\"entryPoint()\":{\"returns\":{\"_0\":\"The address of the EntryPoint v0.6\"}},\"execute(address,uint256,bytes)\":{\"details\":\"Can only be called by the Entrypoint or an owner of this account (including itself).\",\"params\":{\"data\":\"The raw call data.\",\"target\":\"The target call address.\",\"value\":\"The call value to user.\"}},\"executeBatch((address,uint256,bytes)[])\":{\"details\":\"Can only be called by the Entrypoint or an owner of this account (including itself).\",\"params\":{\"calls\":\"The list of `Call`s to execute.\"}},\"executeWithoutChainIdValidation(bytes)\":{\"details\":\"Can only be called by the Entrypoint.Reverts if the given call is not authorized to skip the chain ID validtion.`validateUserOp()` will recompute the `userOpHash` without the chain ID before validating it if the `UserOperation` aims at executing this function. This allows certain operations to be replayed for all accounts sharing the same address across chains. E.g. This may be useful for syncing owner changes.\",\"params\":{\"data\":\"The `UserOperation` raw call data of the execute.\"}},\"getUserOpHashWithoutChainId((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"details\":\"This allows accounts to sign a hash that can be used on many chains.\",\"params\":{\"userOp\":\"The `UserOperation` to compute the hash for.\"},\"returns\":{\"userOpHash\":\"The `UserOperation` hash, not including the chain ID.\"}},\"implementation()\":{\"returns\":{\"addr\":\"The address of implementation contract.\"}},\"initialize(bytes[])\":{\"details\":\"Reverts if the account has already been initialized.\",\"params\":{\"owners\":\"The initial array of owners to initialize this account with.\"}},\"isOwnerAddress(address)\":{\"params\":{\"account\":\"The account address to check.\"},\"returns\":{\"_0\":\"`true` if the account is an owner, else `false`.\"}},\"isOwnerBytes(bytes)\":{\"params\":{\"account\":\"The account to check identified by its address or passkey.\"},\"returns\":{\"_0\":\"`true` if the account is an owner, else `false`.\"}},\"isOwnerPublicKey(bytes32,bytes32)\":{\"params\":{\"x\":\"The public key x coordinate.\",\"y\":\"The public key y coordinate.\"},\"returns\":{\"_0\":\"`true` if the account is an owner, else `false`.\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"This implementation follows ERC-1271. See https://eips.ethereum.org/EIPS/eip-1271.IMPORTANT: Signature verification is performed on the hash produced AFTER applying the anti cross-account-replay layer on the given `hash` (i.e., verification is run on the replay-safe hash version).\",\"params\":{\"hash\":\"The original hash.\",\"signature\":\"The signature of the replay-safe hash to validate.\"},\"returns\":{\"result\":\"`0x1626ba7e` if validation succeeded, else `0xffffffff`.\"}},\"nextOwnerIndex()\":{\"returns\":{\"_0\":\"The next index that will be used to add a new owner.\"}},\"ownerAtIndex(uint256)\":{\"params\":{\"index\":\"The index to lookup.\"},\"returns\":{\"_0\":\"The owner bytes (empty if no owner is registered at this `index`).\"}},\"proxiableUUID()\":{\"details\":\"Returns the storage slot used by the implementation, as specified in [ERC1822](https://eips.ethereum.org/EIPS/eip-1822). Note: The `notDelegated` modifier prevents accidental upgrades to an implementation that is a proxy contract.\"},\"removeOwnerAtIndex(uint256)\":{\"details\":\"Reverts if the owner is not registered at `index`.\",\"params\":{\"index\":\"The index to remove from.\"}},\"replaySafeHash(bytes32)\":{\"details\":\"The returned EIP-712 compliant replay-safe hash is the result of: keccak256( \\\\x19\\\\x01 || this.domainSeparator || hashStruct(CoinbaseSmartWalletMessage({ hash: `hash`})) )\",\"params\":{\"hash\":\"The original hash.\"},\"returns\":{\"_0\":\"The corresponding replay-safe hash.\"}},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrades the proxy's implementation to `newImplementation`. Emits a {Upgraded} event. Note: Passing in empty `data` skips the delegatecall to `newImplementation`.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"details\":\"Signature failure should be reported by returning 1 (see: `_validateSignature()`). This allows making a \\\"simulation call\\\" without a valid signature. Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.Reverts if the `UserOperation` key is invalid.Reverts if the signature verification fails (except for the case mentionned earlier).\",\"params\":{\"missingAccountFunds\":\"The missing account funds that must be deposited on the Entrypoint.\",\"userOp\":\"The `UserOperation` to validate.\",\"userOpHash\":\"The `UserOperation` hash (including the chain ID).\"},\"returns\":{\"validationData\":\"The encoded `ValidationData` structure.\"}}},\"stateVariables\":{\"REPLAYABLE_NONCE_KEY\":{\"details\":\"Helps enforce sequential sequencing of replayable transactions.\"}},\"title\":\"Coinbase Smart Wallet\",\"version\":1},\"userdoc\":{\"errors\":{\"AlreadyOwner(bytes)\":[{\"notice\":\"Thrown when trying to add an already registered owner.\"}],\"Initialized()\":[{\"notice\":\"Thrown when trying to re-initialize an account.\"}],\"InvalidEthereumAddressOwner(bytes)\":[{\"notice\":\"Thrown when trying to intialize the contracts owners if a provided owner is 32 bytes long but does not fit in an `address` type (`uint160`).\"}],\"InvalidNonceKey(uint256)\":[{\"notice\":\"Thrown during a `UserOperation` validation when its key is invalid.\"}],\"InvalidOwnerBytesLength(bytes)\":[{\"notice\":\"Thrown when trying to intialize the contracts owners if a provided owner is neither 64 bytes long (for passkey) nor a valid address.\"}],\"NoOwnerAtIndex(uint256)\":[{\"notice\":\"Thrown when trying to remove an owner from an index that is empty.\"}],\"SelectorNotAllowed(bytes4)\":[{\"notice\":\"Thrown when executing a `UserOperation` that requires the chain ID to be validated but this validation has been omitted.\"}],\"Unauthorized()\":[{\"notice\":\"Thrown when the sender is not an owner and is trying to call a privileged function.\"}]},\"events\":{\"AddOwner(uint256,bytes)\":{\"notice\":\"Emitted when a new owner is registered.\"},\"RemoveOwner(uint256,bytes)\":{\"notice\":\"Emitted when an owner is removed.\"}},\"kind\":\"user\",\"methods\":{\"REPLAYABLE_NONCE_KEY()\":{\"notice\":\"Reserved nonce key (upper 192 bits of `UserOperation.nonce`) for cross-chain replayable transactions.\"},\"addOwnerAddress(address)\":{\"notice\":\"Convenience function to add a new owner address.\"},\"addOwnerPublicKey(bytes32,bytes32)\":{\"notice\":\"Convenience function to add a new owner passkey.\"},\"domainSeparator()\":{\"notice\":\"Returns the `domainSeparator` used to create EIP-712 compliant hashes.\"},\"eip712Domain()\":{\"notice\":\"Returns information about the `EIP712Domain` used to create EIP-712 compliant hashes.\"},\"entryPoint()\":{\"notice\":\"Returns the address of the EntryPoint v0.6.\"},\"execute(address,uint256,bytes)\":{\"notice\":\"Execute the given call from this account.\"},\"executeBatch((address,uint256,bytes)[])\":{\"notice\":\"Execute the given list of calls from this account.\"},\"executeWithoutChainIdValidation(bytes)\":{\"notice\":\"Execute the given call from this account to this account (i.e., self call).\"},\"getUserOpHashWithoutChainId((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"Computes the hash of the `UserOperation` in the same way as EntryPoint v0.6, but leaves out the chain ID.\"},\"implementation()\":{\"notice\":\"Returns the implementation of the ERC1967 proxy.\"},\"initialize(bytes[])\":{\"notice\":\"Initializes the account with the the given owners.\"},\"isOwnerAddress(address)\":{\"notice\":\"Checks if the given `account` address is registered as owner.\"},\"isOwnerBytes(bytes)\":{\"notice\":\"Checks if the given `account` raw bytes is registered as owner.\"},\"isOwnerPublicKey(bytes32,bytes32)\":{\"notice\":\"Checks if the given `account` public key is registered as owner.\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Validates the `signature` against the given `hash`.\"},\"nextOwnerIndex()\":{\"notice\":\"Returns the next index that will be used to add a new owner.\"},\"ownerAtIndex(uint256)\":{\"notice\":\"Returns the owner bytes at the given `index`.\"},\"removeOwnerAtIndex(uint256)\":{\"notice\":\"Removes an owner from the given `index`.\"},\"replaySafeHash(bytes32)\":{\"notice\":\"Wrapper around `_eip712Hash()` to produce a replay-safe hash fron the given `hash`.\"},\"validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)\":{\"notice\":\"Custom implemenentation of the ERC-4337 `validateUserOp` method. The EntryPoint will make the call to the recipient only if this validation call returns successfully. See `IAccount.validateUserOp()`.\"}},\"notice\":\"ERC4337-compatible smart contract wallet, based on Solady ERC4337 account implementation with inspiration from Alchemy's LightAccount and Daimo's DaimoAccount.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/CoinbaseSmartWallet.sol\":\"CoinbaseSmartWallet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@openzeppelin/contracts/=lib/p256-verifier/lib/openzeppelin-contracts/contracts/\",\":FreshCryptoLib/=lib/FreshCryptoLib/solidity/src/\",\":account-abstraction/=lib/account-abstraction/contracts/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/p256-verifier/lib/openzeppelin-contracts/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts/=lib/p256-verifier/lib/openzeppelin-contracts/\",\":p256-verifier/=lib/p256-verifier/\",\":solady/=lib/solady/src/\",\":webauthn-sol/=lib/webauthn-sol/src/\"]},\"sources\":{\"lib/FreshCryptoLib/solidity/src/FCL_ecdsa.sol\":{\"keccak256\":\"0x679d2e9a655cd7e156a0cfc24de0aca88d4e0b34a8e0dfe6a599f23af092f5a2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://db31eb84c6f854f076d2501e3d8b5a606fb4924168bdfc6fc3de84e67ed8a80d\",\"dweb:/ipfs/QmWGAmc7B4aT6Ki52uF9QmPQKWipaptit7r3JknBHjUGfe\"]},\"lib/FreshCryptoLib/solidity/src/FCL_elliptic.sol\":{\"keccak256\":\"0x097f137d52dc9bd97d6fee7426b2d6d809ad3684767df288d58ffd76f7924e5b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://30ffae5b57f2e0fcabcc1642eb7c60e1b4369151d58a78034bb372187fdffa8e\",\"dweb:/ipfs/Qma8RXPxaV52ZMuR5HaoFWqMGSAo7g2u3qG6poguDbFsL4\"]},\"lib/account-abstraction/contracts/core/Helpers.sol\":{\"keccak256\":\"0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://69643e83f68e6a13d5075c7565bfce326673b0bd98c432033c4603ea84835746\",\"dweb:/ipfs/QmSwSzjYyV7qudi5vvsmzHMG2Z4YJZxX51RRXXVCLaNcEU\"]},\"lib/account-abstraction/contracts/interfaces/UserOperation.sol\":{\"keccak256\":\"0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://6ff83c59432e733bf6304dda27cd4b0f34401917dd535e2669cc842d2d26568c\",\"dweb:/ipfs/QmPJbHU5TAjHqUTZzAcicEeG2nknmwCN43L4EW9LHbknTN\"]},\"lib/solady/src/accounts/Receiver.sol\":{\"keccak256\":\"0x9bf48dca73f428c20a0878a5a97d2d66626f835b077c012fd5b1ba6389feb2d0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://15cb4c81e6c5b2f609e5c6ba13d3241b5c017f9997cab5cebc0572c2dd7f34da\",\"dweb:/ipfs/QmQr7sWaqW27XhyCVGx4wED1rMmFKGhSHPjSGVLz45dbeD\"]},\"lib/solady/src/utils/Base64.sol\":{\"keccak256\":\"0x07dcf983a86bc961e4cc0b57a2cfc3e46b20a50fed9b2092c7497e5fe3715a93\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://65c6c0a8a29cfc5b757abe84635c83e62a177a48c2ad0be24de6b0fba1a60ea2\",\"dweb:/ipfs/QmYuYwxHiBoUt6vaLTLbs2bZamRzqrTfA4BsNZ1TApTfrm\"]},\"lib/solady/src/utils/LibString.sol\":{\"keccak256\":\"0x4fc555fe1ceb29162b143ce1564ac936099071c853065efc289f6c30c712f125\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8f9d3fdb7c03ed63323ae27e0176e080f27ca453f91bacb73f8d59b09da94cf7\",\"dweb:/ipfs/Qmcix9BzxupvYYLX3t8wf4Wsf1yp1b2q65CJb5agaFPtQ9\"]},\"lib/solady/src/utils/SignatureCheckerLib.sol\":{\"keccak256\":\"0x7a7acc59723ed291f24d9a2ed019109c8be69f32701f35f8a61dc7fff6652379\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7bab15a03dfca0567d7472933ee4e776fc21f9dfb6c4dbc06934fa75eceeff5e\",\"dweb:/ipfs/QmPUuKsRwpZXz15DpsoJMMPN9DtZiRvMfwjqJScxkppNsP\"]},\"lib/solady/src/utils/UUPSUpgradeable.sol\":{\"keccak256\":\"0x0f4da34fe99caf063e6d3a09d0a4ce783fdcd955b475d46ba00be48f7fda348f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5f8e8e92e7b781a8b0d3fdb720915964f46354395a806e87aa7d0a355a024a83\",\"dweb:/ipfs/QmdDmVgUstEYpVQn97jDdaACoqoqiEvcXjxtEhC8b6vmFC\"]},\"lib/webauthn-sol/src/WebAuthn.sol\":{\"keccak256\":\"0x2441d1c9cd3ed38f53ad8920db4ccf1dfc4e081f91138432fd1a91f9a94d46c7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f6613c0ab26c03824b4db51d5d00a7fd665599ec1c4a20cc559c8fa19e885294\",\"dweb:/ipfs/QmaWPGM1ogH4nrxFYReaBoB7kA7AWy176kmLXFAZVEDTQp\"]},\"src/CoinbaseSmartWallet.sol\":{\"keccak256\":\"0xf19cd33c8dca8017513a391d007e9a16d3218b1e456c8aad5f8ca6417d1e53eb\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c09de4c78680e6f8818e6dba4eb8cc6cbfcb5893dfeb2a2f3c76b31bd07c382a\",\"dweb:/ipfs/QmWNGeNEpgSnfJLp9ZXYETctQzAHiSa2iX9pEpUdPNXTND\"]},\"src/ERC1271.sol\":{\"keccak256\":\"0x670872019ca67ef9156017aaf0ec80c6be75258f3bcd6a21df270c45f8af3871\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fad973b58b631f72cf53f54caf736f8100942d51c632f1c5c486d5b7228d4593\",\"dweb:/ipfs/QmaxTVxCvEwe1cBoxw3TNtssBaFejnjcACdymZrYhgEeSj\"]},\"src/MultiOwnable.sol\":{\"keccak256\":\"0x9c0a57f9fd802e3ff10383257b10bea2637a01bda9986fc18a06246155fdbe6e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0efe6691756a2bb0357caa1bdbd0dcc08407cd30ded5efee3fdffa4f99885c8a\",\"dweb:/ipfs/QmVz9YQaUsH4NLv47JDcVQCmUWstrgzwTTEGv7cNQTjXyg\"]}},\"version\":1}", + "metadata": { + "compiler": { + "version": "0.8.23+commit.f704f362" + }, + "language": "Solidity", + "output": { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "owner", + "type": "bytes" + } + ], + "type": "error", + "name": "AlreadyOwner" + }, + { + "inputs": [], + "type": "error", + "name": "Initialized" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "owner", + "type": "bytes" + } + ], + "type": "error", + "name": "InvalidEthereumAddressOwner" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "key", + "type": "uint256" + } + ], + "type": "error", + "name": "InvalidNonceKey" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "owner", + "type": "bytes" + } + ], + "type": "error", + "name": "InvalidOwnerBytesLength" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "type": "error", + "name": "NoOwnerAtIndex" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "selector", + "type": "bytes4" + } + ], + "type": "error", + "name": "SelectorNotAllowed" + }, + { + "inputs": [], + "type": "error", + "name": "Unauthorized" + }, + { + "inputs": [], + "type": "error", + "name": "UnauthorizedCallContext" + }, + { + "inputs": [], + "type": "error", + "name": "UpgradeFailed" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256", + "indexed": true + }, + { + "internalType": "bytes", + "name": "owner", + "type": "bytes", + "indexed": false + } + ], + "type": "event", + "name": "AddOwner", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256", + "indexed": true + }, + { + "internalType": "bytes", + "name": "owner", + "type": "bytes", + "indexed": false + } + ], + "type": "event", + "name": "RemoveOwner", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address", + "indexed": true + } + ], + "type": "event", + "name": "Upgraded", + "anonymous": false + }, + { + "inputs": [], + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "REPLAYABLE_NONCE_KEY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "addOwnerAddress" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "x", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "y", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "addOwnerPublicKey" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "functionSelector", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function", + "name": "canSkipChainIdValidation", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "domainSeparator", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "eip712Domain", + "outputs": [ + { + "internalType": "bytes1", + "name": "fields", + "type": "bytes1" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "version", + "type": "string" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "entryPoint", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function", + "name": "execute" + }, + { + "inputs": [ + { + "internalType": "struct CoinbaseSmartWallet.Call[]", + "name": "calls", + "type": "tuple[]", + "components": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ] + } + ], + "stateMutability": "payable", + "type": "function", + "name": "executeBatch" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function", + "name": "executeWithoutChainIdValidation" + }, + { + "inputs": [ + { + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple", + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ] + } + ], + "stateMutability": "view", + "type": "function", + "name": "getUserOpHashWithoutChainId", + "outputs": [ + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "owners", + "type": "bytes[]" + } + ], + "stateMutability": "payable", + "type": "function", + "name": "initialize" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function", + "name": "isOwnerAddress", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ] + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "account", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function", + "name": "isOwnerBytes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ] + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "x", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "y", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function", + "name": "isOwnerPublicKey", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ] + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function", + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "result", + "type": "bytes4" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "nextOwnerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ] + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "name": "ownerAtIndex", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ] + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "removeOwnerAtIndex" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function", + "name": "replaySafeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ] + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "function", + "name": "upgradeToAndCall" + }, + { + "inputs": [ + { + "internalType": "struct UserOperation", + "name": "userOp", + "type": "tuple", + "components": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "initCode", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "callGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "verificationGasLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "preVerificationGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxFeePerGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxPriorityFeePerGas", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "paymasterAndData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ] + }, + { + "internalType": "bytes32", + "name": "userOpHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "missingAccountFunds", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function", + "name": "validateUserOp", + "outputs": [ + { + "internalType": "uint256", + "name": "validationData", + "type": "uint256" + } + ] + }, + { + "inputs": [], + "stateMutability": "payable", + "type": "receive" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "addOwnerAddress(address)": { + "params": { + "owner": "The owner address." + } + }, + "addOwnerPublicKey(bytes32,bytes32)": { + "params": { + "x": "The owner public key x coordinate.", + "y": "The owner public key y coordinate." + } + }, + "canSkipChainIdValidation(bytes4)": { + "returns": { + "_0": "`true` is the function selector is whitelisted to skip the chain ID validation, else `false`." + } + }, + "domainSeparator()": { + "details": "Implements domainSeparator = hashStruct(eip712Domain). See https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator.", + "returns": { + "_0": "The 32 bytes domain separator result." + } + }, + "eip712Domain()": { + "details": "Follows ERC-5267 (see https://eips.ethereum.org/EIPS/eip-5267).", + "returns": { + "chainId": "The value of the `EIP712Domain.chainId` field.", + "extensions": "The list of EIP numbers, that extends EIP-712 with new domain fields.", + "fields": "The bitmap of used fields.", + "name": "The value of the `EIP712Domain.name` field.", + "salt": "The value of the `EIP712Domain.salt` field.", + "verifyingContract": "The value of the `EIP712Domain.verifyingContract` field.", + "version": "The value of the `EIP712Domain.version` field." + } + }, + "entryPoint()": { + "returns": { + "_0": "The address of the EntryPoint v0.6" + } + }, + "execute(address,uint256,bytes)": { + "details": "Can only be called by the Entrypoint or an owner of this account (including itself).", + "params": { + "data": "The raw call data.", + "target": "The target call address.", + "value": "The call value to user." + } + }, + "executeBatch((address,uint256,bytes)[])": { + "details": "Can only be called by the Entrypoint or an owner of this account (including itself).", + "params": { + "calls": "The list of `Call`s to execute." + } + }, + "executeWithoutChainIdValidation(bytes)": { + "details": "Can only be called by the Entrypoint.Reverts if the given call is not authorized to skip the chain ID validtion.`validateUserOp()` will recompute the `userOpHash` without the chain ID before validating it if the `UserOperation` aims at executing this function. This allows certain operations to be replayed for all accounts sharing the same address across chains. E.g. This may be useful for syncing owner changes.", + "params": { + "data": "The `UserOperation` raw call data of the execute." + } + }, + "getUserOpHashWithoutChainId((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))": { + "details": "This allows accounts to sign a hash that can be used on many chains.", + "params": { + "userOp": "The `UserOperation` to compute the hash for." + }, + "returns": { + "userOpHash": "The `UserOperation` hash, not including the chain ID." + } + }, + "implementation()": { + "returns": { + "addr": "The address of implementation contract." + } + }, + "initialize(bytes[])": { + "details": "Reverts if the account has already been initialized.", + "params": { + "owners": "The initial array of owners to initialize this account with." + } + }, + "isOwnerAddress(address)": { + "params": { + "account": "The account address to check." + }, + "returns": { + "_0": "`true` if the account is an owner, else `false`." + } + }, + "isOwnerBytes(bytes)": { + "params": { + "account": "The account to check identified by its address or passkey." + }, + "returns": { + "_0": "`true` if the account is an owner, else `false`." + } + }, + "isOwnerPublicKey(bytes32,bytes32)": { + "params": { + "x": "The public key x coordinate.", + "y": "The public key y coordinate." + }, + "returns": { + "_0": "`true` if the account is an owner, else `false`." + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "This implementation follows ERC-1271. See https://eips.ethereum.org/EIPS/eip-1271.IMPORTANT: Signature verification is performed on the hash produced AFTER applying the anti cross-account-replay layer on the given `hash` (i.e., verification is run on the replay-safe hash version).", + "params": { + "hash": "The original hash.", + "signature": "The signature of the replay-safe hash to validate." + }, + "returns": { + "result": "`0x1626ba7e` if validation succeeded, else `0xffffffff`." + } + }, + "nextOwnerIndex()": { + "returns": { + "_0": "The next index that will be used to add a new owner." + } + }, + "ownerAtIndex(uint256)": { + "params": { + "index": "The index to lookup." + }, + "returns": { + "_0": "The owner bytes (empty if no owner is registered at this `index`)." + } + }, + "proxiableUUID()": { + "details": "Returns the storage slot used by the implementation, as specified in [ERC1822](https://eips.ethereum.org/EIPS/eip-1822). Note: The `notDelegated` modifier prevents accidental upgrades to an implementation that is a proxy contract." + }, + "removeOwnerAtIndex(uint256)": { + "details": "Reverts if the owner is not registered at `index`.", + "params": { + "index": "The index to remove from." + } + }, + "replaySafeHash(bytes32)": { + "details": "The returned EIP-712 compliant replay-safe hash is the result of: keccak256( \\x19\\x01 || this.domainSeparator || hashStruct(CoinbaseSmartWalletMessage({ hash: `hash`})) )", + "params": { + "hash": "The original hash." + }, + "returns": { + "_0": "The corresponding replay-safe hash." + } + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrades the proxy's implementation to `newImplementation`. Emits a {Upgraded} event. Note: Passing in empty `data` skips the delegatecall to `newImplementation`." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "details": "Signature failure should be reported by returning 1 (see: `_validateSignature()`). This allows making a \"simulation call\" without a valid signature. Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.Reverts if the `UserOperation` key is invalid.Reverts if the signature verification fails (except for the case mentionned earlier).", + "params": { + "missingAccountFunds": "The missing account funds that must be deposited on the Entrypoint.", + "userOp": "The `UserOperation` to validate.", + "userOpHash": "The `UserOperation` hash (including the chain ID)." + }, + "returns": { + "validationData": "The encoded `ValidationData` structure." + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "REPLAYABLE_NONCE_KEY()": { + "notice": "Reserved nonce key (upper 192 bits of `UserOperation.nonce`) for cross-chain replayable transactions." + }, + "addOwnerAddress(address)": { + "notice": "Convenience function to add a new owner address." + }, + "addOwnerPublicKey(bytes32,bytes32)": { + "notice": "Convenience function to add a new owner passkey." + }, + "domainSeparator()": { + "notice": "Returns the `domainSeparator` used to create EIP-712 compliant hashes." + }, + "eip712Domain()": { + "notice": "Returns information about the `EIP712Domain` used to create EIP-712 compliant hashes." + }, + "entryPoint()": { + "notice": "Returns the address of the EntryPoint v0.6." + }, + "execute(address,uint256,bytes)": { + "notice": "Execute the given call from this account." + }, + "executeBatch((address,uint256,bytes)[])": { + "notice": "Execute the given list of calls from this account." + }, + "executeWithoutChainIdValidation(bytes)": { + "notice": "Execute the given call from this account to this account (i.e., self call)." + }, + "getUserOpHashWithoutChainId((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))": { + "notice": "Computes the hash of the `UserOperation` in the same way as EntryPoint v0.6, but leaves out the chain ID." + }, + "implementation()": { + "notice": "Returns the implementation of the ERC1967 proxy." + }, + "initialize(bytes[])": { + "notice": "Initializes the account with the the given owners." + }, + "isOwnerAddress(address)": { + "notice": "Checks if the given `account` address is registered as owner." + }, + "isOwnerBytes(bytes)": { + "notice": "Checks if the given `account` raw bytes is registered as owner." + }, + "isOwnerPublicKey(bytes32,bytes32)": { + "notice": "Checks if the given `account` public key is registered as owner." + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Validates the `signature` against the given `hash`." + }, + "nextOwnerIndex()": { + "notice": "Returns the next index that will be used to add a new owner." + }, + "ownerAtIndex(uint256)": { + "notice": "Returns the owner bytes at the given `index`." + }, + "removeOwnerAtIndex(uint256)": { + "notice": "Removes an owner from the given `index`." + }, + "replaySafeHash(bytes32)": { + "notice": "Wrapper around `_eip712Hash()` to produce a replay-safe hash fron the given `hash`." + }, + "validateUserOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes32,uint256)": { + "notice": "Custom implemenentation of the ERC-4337 `validateUserOp` method. The EntryPoint will make the call to the recipient only if this validation call returns successfully. See `IAccount.validateUserOp()`." + } + }, + "version": 1 + } + }, + "settings": { + "remappings": [ + "@openzeppelin/contracts/=lib/p256-verifier/lib/openzeppelin-contracts/contracts/", + "FreshCryptoLib/=lib/FreshCryptoLib/solidity/src/", + "account-abstraction/=lib/account-abstraction/contracts/", + "ds-test/=lib/forge-std/lib/ds-test/src/", + "erc4626-tests/=lib/p256-verifier/lib/openzeppelin-contracts/lib/erc4626-tests/", + "forge-std/=lib/forge-std/src/", + "openzeppelin-contracts/=lib/p256-verifier/lib/openzeppelin-contracts/", + "p256-verifier/=lib/p256-verifier/", + "solady/=lib/solady/src/", + "webauthn-sol/=lib/webauthn-sol/src/" + ], + "optimizer": { + "enabled": true, + "runs": 200 + }, + "metadata": { + "bytecodeHash": "ipfs" + }, + "compilationTarget": { + "src/CoinbaseSmartWallet.sol": "CoinbaseSmartWallet" + }, + "evmVersion": "paris", + "libraries": {} + }, + "sources": { + "lib/FreshCryptoLib/solidity/src/FCL_ecdsa.sol": { + "keccak256": "0x679d2e9a655cd7e156a0cfc24de0aca88d4e0b34a8e0dfe6a599f23af092f5a2", + "urls": [ + "bzz-raw://db31eb84c6f854f076d2501e3d8b5a606fb4924168bdfc6fc3de84e67ed8a80d", + "dweb:/ipfs/QmWGAmc7B4aT6Ki52uF9QmPQKWipaptit7r3JknBHjUGfe" + ], + "license": "MIT" + }, + "lib/FreshCryptoLib/solidity/src/FCL_elliptic.sol": { + "keccak256": "0x097f137d52dc9bd97d6fee7426b2d6d809ad3684767df288d58ffd76f7924e5b", + "urls": [ + "bzz-raw://30ffae5b57f2e0fcabcc1642eb7c60e1b4369151d58a78034bb372187fdffa8e", + "dweb:/ipfs/Qma8RXPxaV52ZMuR5HaoFWqMGSAo7g2u3qG6poguDbFsL4" + ], + "license": "MIT" + }, + "lib/account-abstraction/contracts/core/Helpers.sol": { + "keccak256": "0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a", + "urls": [ + "bzz-raw://69643e83f68e6a13d5075c7565bfce326673b0bd98c432033c4603ea84835746", + "dweb:/ipfs/QmSwSzjYyV7qudi5vvsmzHMG2Z4YJZxX51RRXXVCLaNcEU" + ], + "license": "GPL-3.0" + }, + "lib/account-abstraction/contracts/interfaces/UserOperation.sol": { + "keccak256": "0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c", + "urls": [ + "bzz-raw://6ff83c59432e733bf6304dda27cd4b0f34401917dd535e2669cc842d2d26568c", + "dweb:/ipfs/QmPJbHU5TAjHqUTZzAcicEeG2nknmwCN43L4EW9LHbknTN" + ], + "license": "GPL-3.0" + }, + "lib/solady/src/accounts/Receiver.sol": { + "keccak256": "0x9bf48dca73f428c20a0878a5a97d2d66626f835b077c012fd5b1ba6389feb2d0", + "urls": [ + "bzz-raw://15cb4c81e6c5b2f609e5c6ba13d3241b5c017f9997cab5cebc0572c2dd7f34da", + "dweb:/ipfs/QmQr7sWaqW27XhyCVGx4wED1rMmFKGhSHPjSGVLz45dbeD" + ], + "license": "MIT" + }, + "lib/solady/src/utils/Base64.sol": { + "keccak256": "0x07dcf983a86bc961e4cc0b57a2cfc3e46b20a50fed9b2092c7497e5fe3715a93", + "urls": [ + "bzz-raw://65c6c0a8a29cfc5b757abe84635c83e62a177a48c2ad0be24de6b0fba1a60ea2", + "dweb:/ipfs/QmYuYwxHiBoUt6vaLTLbs2bZamRzqrTfA4BsNZ1TApTfrm" + ], + "license": "MIT" + }, + "lib/solady/src/utils/LibString.sol": { + "keccak256": "0x4fc555fe1ceb29162b143ce1564ac936099071c853065efc289f6c30c712f125", + "urls": [ + "bzz-raw://8f9d3fdb7c03ed63323ae27e0176e080f27ca453f91bacb73f8d59b09da94cf7", + "dweb:/ipfs/Qmcix9BzxupvYYLX3t8wf4Wsf1yp1b2q65CJb5agaFPtQ9" + ], + "license": "MIT" + }, + "lib/solady/src/utils/SignatureCheckerLib.sol": { + "keccak256": "0x7a7acc59723ed291f24d9a2ed019109c8be69f32701f35f8a61dc7fff6652379", + "urls": [ + "bzz-raw://7bab15a03dfca0567d7472933ee4e776fc21f9dfb6c4dbc06934fa75eceeff5e", + "dweb:/ipfs/QmPUuKsRwpZXz15DpsoJMMPN9DtZiRvMfwjqJScxkppNsP" + ], + "license": "MIT" + }, + "lib/solady/src/utils/UUPSUpgradeable.sol": { + "keccak256": "0x0f4da34fe99caf063e6d3a09d0a4ce783fdcd955b475d46ba00be48f7fda348f", + "urls": [ + "bzz-raw://5f8e8e92e7b781a8b0d3fdb720915964f46354395a806e87aa7d0a355a024a83", + "dweb:/ipfs/QmdDmVgUstEYpVQn97jDdaACoqoqiEvcXjxtEhC8b6vmFC" + ], + "license": "MIT" + }, + "lib/webauthn-sol/src/WebAuthn.sol": { + "keccak256": "0x2441d1c9cd3ed38f53ad8920db4ccf1dfc4e081f91138432fd1a91f9a94d46c7", + "urls": [ + "bzz-raw://f6613c0ab26c03824b4db51d5d00a7fd665599ec1c4a20cc559c8fa19e885294", + "dweb:/ipfs/QmaWPGM1ogH4nrxFYReaBoB7kA7AWy176kmLXFAZVEDTQp" + ], + "license": "MIT" + }, + "src/CoinbaseSmartWallet.sol": { + "keccak256": "0xf19cd33c8dca8017513a391d007e9a16d3218b1e456c8aad5f8ca6417d1e53eb", + "urls": [ + "bzz-raw://c09de4c78680e6f8818e6dba4eb8cc6cbfcb5893dfeb2a2f3c76b31bd07c382a", + "dweb:/ipfs/QmWNGeNEpgSnfJLp9ZXYETctQzAHiSa2iX9pEpUdPNXTND" + ], + "license": "MIT" + }, + "src/ERC1271.sol": { + "keccak256": "0x670872019ca67ef9156017aaf0ec80c6be75258f3bcd6a21df270c45f8af3871", + "urls": [ + "bzz-raw://fad973b58b631f72cf53f54caf736f8100942d51c632f1c5c486d5b7228d4593", + "dweb:/ipfs/QmaxTVxCvEwe1cBoxw3TNtssBaFejnjcACdymZrYhgEeSj" + ], + "license": "MIT" + }, + "src/MultiOwnable.sol": { + "keccak256": "0x9c0a57f9fd802e3ff10383257b10bea2637a01bda9986fc18a06246155fdbe6e", + "urls": [ + "bzz-raw://0efe6691756a2bb0357caa1bdbd0dcc08407cd30ded5efee3fdffa4f99885c8a", + "dweb:/ipfs/QmVz9YQaUsH4NLv47JDcVQCmUWstrgzwTTEGv7cNQTjXyg" + ], + "license": "MIT" + } + }, + "version": 1 + }, + "ast": { + "absolutePath": "src/CoinbaseSmartWallet.sol", + "id": 50483, + "exportedSymbols": { + "CoinbaseSmartWallet": [ + 50482 + ], + "ERC1271": [ + 50822 + ], + "MultiOwnable": [ + 51215 + ], + "Receiver": [ + 47844 + ], + "SignatureCheckerLib": [ + 49393 + ], + "UUPSUpgradeable": [ + 49482 + ], + "UserOperation": [ + 2402 + ], + "UserOperationLib": [ + 2572 + ], + "WebAuthn": [ + 49808 + ] + }, + "nodeType": "SourceUnit", + "src": "32:14187:40", + "nodes": [ + { + "id": 49909, + "nodeType": "PragmaDirective", + "src": "32:23:40", + "nodes": [], + "literals": [ + "solidity", + "0.8", + ".23" + ] + }, + { + "id": 49911, + "nodeType": "ImportDirective", + "src": "57:54:40", + "nodes": [], + "absolutePath": "lib/solady/src/accounts/Receiver.sol", + "file": "solady/accounts/Receiver.sol", + "nameLocation": "-1:-1:-1", + "scope": 50483, + "sourceUnit": 47845, + "symbolAliases": [ + { + "foreign": { + "id": 49910, + "name": "Receiver", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 47844, + "src": "65:8:40", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 49913, + "nodeType": "ImportDirective", + "src": "112:65:40", + "nodes": [], + "absolutePath": "lib/solady/src/utils/UUPSUpgradeable.sol", + "file": "solady/utils/UUPSUpgradeable.sol", + "nameLocation": "-1:-1:-1", + "scope": 50483, + "sourceUnit": 49483, + "symbolAliases": [ + { + "foreign": { + "id": 49912, + "name": "UUPSUpgradeable", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49482, + "src": "120:15:40", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 49915, + "nodeType": "ImportDirective", + "src": "178:73:40", + "nodes": [], + "absolutePath": "lib/solady/src/utils/SignatureCheckerLib.sol", + "file": "solady/utils/SignatureCheckerLib.sol", + "nameLocation": "-1:-1:-1", + "scope": 50483, + "sourceUnit": 49394, + "symbolAliases": [ + { + "foreign": { + "id": 49914, + "name": "SignatureCheckerLib", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49393, + "src": "186:19:40", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 49918, + "nodeType": "ImportDirective", + "src": "252:97:40", + "nodes": [], + "absolutePath": "lib/account-abstraction/contracts/interfaces/UserOperation.sol", + "file": "account-abstraction/interfaces/UserOperation.sol", + "nameLocation": "-1:-1:-1", + "scope": 50483, + "sourceUnit": 2573, + "symbolAliases": [ + { + "foreign": { + "id": 49916, + "name": "UserOperation", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2402, + "src": "260:13:40", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + }, + { + "foreign": { + "id": 49917, + "name": "UserOperationLib", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2572, + "src": "275:16:40", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 49920, + "nodeType": "ImportDirective", + "src": "350:51:40", + "nodes": [], + "absolutePath": "lib/webauthn-sol/src/WebAuthn.sol", + "file": "webauthn-sol/WebAuthn.sol", + "nameLocation": "-1:-1:-1", + "scope": 50483, + "sourceUnit": 49809, + "symbolAliases": [ + { + "foreign": { + "id": 49919, + "name": "WebAuthn", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49808, + "src": "358:8:40", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 49922, + "nodeType": "ImportDirective", + "src": "403:38:40", + "nodes": [], + "absolutePath": "src/ERC1271.sol", + "file": "./ERC1271.sol", + "nameLocation": "-1:-1:-1", + "scope": 50483, + "sourceUnit": 50823, + "symbolAliases": [ + { + "foreign": { + "id": 49921, + "name": "ERC1271", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50822, + "src": "411:7:40", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 49924, + "nodeType": "ImportDirective", + "src": "442:48:40", + "nodes": [], + "absolutePath": "src/MultiOwnable.sol", + "file": "./MultiOwnable.sol", + "nameLocation": "-1:-1:-1", + "scope": 50483, + "sourceUnit": 51216, + "symbolAliases": [ + { + "foreign": { + "id": 49923, + "name": "MultiOwnable", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 51215, + "src": "450:12:40", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 50482, + "nodeType": "ContractDefinition", + "src": "874:13344:40", + "nodes": [ + { + "id": 49941, + "nodeType": "StructDefinition", + "src": "1060:247:40", + "nodes": [], + "canonicalName": "CoinbaseSmartWallet.SignatureWrapper", + "documentation": { + "id": 49934, + "nodeType": "StructuredDocumentation", + "src": "961:94:40", + "text": "@notice Wrapper struct, used during signature validation, tie a signature with its signer." + }, + "members": [ + { + "constant": false, + "id": 49937, + "mutability": "mutable", + "name": "ownerIndex", + "nameLocation": "1179:10:40", + "nodeType": "VariableDeclaration", + "scope": 49941, + "src": "1171:18:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 49936, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1171:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 49940, + "mutability": "mutable", + "name": "signatureData", + "nameLocation": "1287:13:40", + "nodeType": "VariableDeclaration", + "scope": 49941, + "src": "1281:19:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 49939, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1281:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "name": "SignatureWrapper", + "nameLocation": "1067:16:40", + "scope": 50482, + "visibility": "public" + }, + { + "id": 49952, + "nodeType": "StructDefinition", + "src": "1403:222:40", + "nodes": [], + "canonicalName": "CoinbaseSmartWallet.Call", + "documentation": { + "id": 49942, + "nodeType": "StructuredDocumentation", + "src": "1313:85:40", + "text": "@notice Wrapper struct, used in `executeBatch`, describing a raw call to execute." + }, + "members": [ + { + "constant": false, + "id": 49945, + "mutability": "mutable", + "name": "target", + "nameLocation": "1478:6:40", + "nodeType": "VariableDeclaration", + "scope": 49952, + "src": "1470:14:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 49944, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1470:7:40", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 49948, + "mutability": "mutable", + "name": "value", + "nameLocation": "1557:5:40", + "nodeType": "VariableDeclaration", + "scope": 49952, + "src": "1549:13:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 49947, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1549:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 49951, + "mutability": "mutable", + "name": "data", + "nameLocation": "1614:4:40", + "nodeType": "VariableDeclaration", + "scope": 49952, + "src": "1608:10:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 49950, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1608:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "name": "Call", + "nameLocation": "1410:4:40", + "scope": 50482, + "visibility": "public" + }, + { + "id": 49956, + "nodeType": "VariableDeclaration", + "src": "1850:51:40", + "nodes": [], + "constant": true, + "documentation": { + "id": 49953, + "nodeType": "StructuredDocumentation", + "src": "1631:214:40", + "text": "@notice Reserved nonce key (upper 192 bits of `UserOperation.nonce`) for cross-chain replayable\n transactions.\n @dev Helps enforce sequential sequencing of replayable transactions." + }, + "functionSelector": "88ce4c7c", + "mutability": "constant", + "name": "REPLAYABLE_NONCE_KEY", + "nameLocation": "1874:20:40", + "scope": 50482, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 49954, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1850:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "38343533", + "id": 49955, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1897:4:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_8453_by_1", + "typeString": "int_const 8453" + }, + "value": "8453" + }, + "visibility": "public" + }, + { + "id": 49959, + "nodeType": "ErrorDefinition", + "src": "1972:20:40", + "nodes": [], + "documentation": { + "id": 49957, + "nodeType": "StructuredDocumentation", + "src": "1908:59:40", + "text": "@notice Thrown when trying to re-initialize an account." + }, + "errorSelector": "5daa87a0", + "name": "Initialized", + "nameLocation": "1978:11:40", + "parameters": { + "id": 49958, + "nodeType": "ParameterList", + "parameters": [], + "src": "1989:2:40" + } + }, + { + "id": 49964, + "nodeType": "ErrorDefinition", + "src": "2424:42:40", + "nodes": [], + "documentation": { + "id": 49960, + "nodeType": "StructuredDocumentation", + "src": "1998:421:40", + "text": "@notice Thrown when executing a `UserOperation` that requires the chain ID to be validated\n but this validation has been omitted.\n @dev Whitelisting of `UserOperation`s that are allowed to skip the chain ID validation is\n based on their call selectors (see `canSkipChainIdValidation()`).\n @param selector The user operation call selector that raised the error." + }, + "errorSelector": "3b06e146", + "name": "SelectorNotAllowed", + "nameLocation": "2430:18:40", + "parameters": { + "id": 49963, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 49962, + "mutability": "mutable", + "name": "selector", + "nameLocation": "2456:8:40", + "nodeType": "VariableDeclaration", + "scope": 49964, + "src": "2449:15:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 49961, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "2449:6:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "visibility": "internal" + } + ], + "src": "2448:17:40" + } + }, + { + "id": 49969, + "nodeType": "ErrorDefinition", + "src": "2719:35:40", + "nodes": [], + "documentation": { + "id": 49965, + "nodeType": "StructuredDocumentation", + "src": "2472:242:40", + "text": "@notice Thrown during a `UserOperation` validation when its key is invalid.\n @dev The `UserOperation` key validation is based on the `UserOperation` call selector.\n @param key The invalid `UserOperation` key." + }, + "errorSelector": "2ef37813", + "name": "InvalidNonceKey", + "nameLocation": "2725:15:40", + "parameters": { + "id": 49968, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 49967, + "mutability": "mutable", + "name": "key", + "nameLocation": "2749:3:40", + "nodeType": "VariableDeclaration", + "scope": 49969, + "src": "2741:11:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 49966, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2741:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2740:13:40" + } + }, + { + "id": 49984, + "nodeType": "ModifierDefinition", + "src": "2821:140:40", + "nodes": [], + "body": { + "id": 49983, + "nodeType": "Block", + "src": "2855:106:40", + "nodes": [], + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 49976, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 49972, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "2869:3:40", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 49973, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2873:6:40", + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "2869:10:40", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 49974, + "name": "entryPoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50244, + "src": "2883:10:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_address_$", + "typeString": "function () view returns (address)" + } + }, + "id": 49975, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2883:12:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "2869:26:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 49981, + "nodeType": "IfStatement", + "src": "2865:78:40", + "trueBody": { + "id": 49980, + "nodeType": "Block", + "src": "2897:46:40", + "statements": [ + { + "errorCall": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 49977, + "name": "Unauthorized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50847, + "src": "2918:12:40", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 49978, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2918:14:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 49979, + "nodeType": "RevertStatement", + "src": "2911:21:40" + } + ] + } + }, + { + "id": 49982, + "nodeType": "PlaceholderStatement", + "src": "2953:1:40" + } + ] + }, + "documentation": { + "id": 49970, + "nodeType": "StructuredDocumentation", + "src": "2760:56:40", + "text": "@notice Reverts if the caller is not the EntryPoint." + }, + "name": "onlyEntryPoint", + "nameLocation": "2830:14:40", + "parameters": { + "id": 49971, + "nodeType": "ParameterList", + "parameters": [], + "src": "2844:2:40" + }, + "virtual": true, + "visibility": "internal" + }, + { + "id": 49999, + "nodeType": "ModifierDefinition", + "src": "3067:139:40", + "nodes": [], + "body": { + "id": 49998, + "nodeType": "Block", + "src": "3108:98:40", + "nodes": [], + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 49991, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 49987, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "3122:3:40", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 49988, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3126:6:40", + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "3122:10:40", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 49989, + "name": "entryPoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50244, + "src": "3136:10:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_address_$", + "typeString": "function () view returns (address)" + } + }, + "id": 49990, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3136:12:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "3122:26:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 49996, + "nodeType": "IfStatement", + "src": "3118:70:40", + "trueBody": { + "id": 49995, + "nodeType": "Block", + "src": "3150:38:40", + "statements": [ + { + "expression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 49992, + "name": "_checkOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 51205, + "src": "3164:11:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$__$", + "typeString": "function () view" + } + }, + "id": 49993, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3164:13:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 49994, + "nodeType": "ExpressionStatement", + "src": "3164:13:40" + } + ] + } + }, + { + "id": 49997, + "nodeType": "PlaceholderStatement", + "src": "3198:1:40" + } + ] + }, + "documentation": { + "id": 49985, + "nodeType": "StructuredDocumentation", + "src": "2967:95:40", + "text": "@notice Reverts if the caller is neither the EntryPoint, the owner, nor the account itself." + }, + "name": "onlyEntryPointOrOwner", + "nameLocation": "3076:21:40", + "parameters": { + "id": 49986, + "nodeType": "ParameterList", + "parameters": [], + "src": "3097:2:40" + }, + "virtual": true, + "visibility": "internal" + }, + { + "id": 50007, + "nodeType": "ModifierDefinition", + "src": "3810:360:40", + "nodes": [], + "body": { + "id": 50006, + "nodeType": "Block", + "src": "3867:303:40", + "nodes": [], + "statements": [ + { + "id": 50004, + "nodeType": "PlaceholderStatement", + "src": "3877:1:40" + }, + { + "AST": { + "nativeSrc": "3914:250:40", + "nodeType": "YulBlock", + "src": "3914:250:40", + "statements": [ + { + "body": { + "nativeSrc": "3951:203:40", + "nodeType": "YulBlock", + "src": "3951:203:40", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "gas", + "nativeSrc": "4066:3:40", + "nodeType": "YulIdentifier", + "src": "4066:3:40" + }, + "nativeSrc": "4066:5:40", + "nodeType": "YulFunctionCall", + "src": "4066:5:40" + }, + { + "arguments": [], + "functionName": { + "name": "caller", + "nativeSrc": "4073:6:40", + "nodeType": "YulIdentifier", + "src": "4073:6:40" + }, + "nativeSrc": "4073:8:40", + "nodeType": "YulFunctionCall", + "src": "4073:8:40" + }, + { + "name": "missingAccountFunds", + "nativeSrc": "4083:19:40", + "nodeType": "YulIdentifier", + "src": "4083:19:40" + }, + { + "arguments": [], + "functionName": { + "name": "codesize", + "nativeSrc": "4104:8:40", + "nodeType": "YulIdentifier", + "src": "4104:8:40" + }, + "nativeSrc": "4104:10:40", + "nodeType": "YulFunctionCall", + "src": "4104:10:40" + }, + { + "kind": "number", + "nativeSrc": "4116:4:40", + "nodeType": "YulLiteral", + "src": "4116:4:40", + "type": "", + "value": "0x00" + }, + { + "arguments": [], + "functionName": { + "name": "codesize", + "nativeSrc": "4122:8:40", + "nodeType": "YulIdentifier", + "src": "4122:8:40" + }, + "nativeSrc": "4122:10:40", + "nodeType": "YulFunctionCall", + "src": "4122:10:40" + }, + { + "kind": "number", + "nativeSrc": "4134:4:40", + "nodeType": "YulLiteral", + "src": "4134:4:40", + "type": "", + "value": "0x00" + } + ], + "functionName": { + "name": "call", + "nativeSrc": "4061:4:40", + "nodeType": "YulIdentifier", + "src": "4061:4:40" + }, + "nativeSrc": "4061:78:40", + "nodeType": "YulFunctionCall", + "src": "4061:78:40" + } + ], + "functionName": { + "name": "pop", + "nativeSrc": "4057:3:40", + "nodeType": "YulIdentifier", + "src": "4057:3:40" + }, + "nativeSrc": "4057:83:40", + "nodeType": "YulFunctionCall", + "src": "4057:83:40" + }, + "nativeSrc": "4057:83:40", + "nodeType": "YulExpressionStatement", + "src": "4057:83:40" + } + ] + }, + "condition": { + "name": "missingAccountFunds", + "nativeSrc": "3931:19:40", + "nodeType": "YulIdentifier", + "src": "3931:19:40" + }, + "nativeSrc": "3928:226:40", + "nodeType": "YulIf", + "src": "3928:226:40" + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 50002, + "isOffset": false, + "isSlot": false, + "src": "3931:19:40", + "valueSize": 1 + }, + { + "declaration": 50002, + "isOffset": false, + "isSlot": false, + "src": "4083:19:40", + "valueSize": 1 + } + ], + "flags": [ + "memory-safe" + ], + "id": 50005, + "nodeType": "InlineAssembly", + "src": "3889:275:40" + } + ] + }, + "documentation": { + "id": 50000, + "nodeType": "StructuredDocumentation", + "src": "3212:593:40", + "text": "@notice Sends to the EntryPoint (i.e. `msg.sender`) the missing funds for this transaction.\n @dev Subclass MAY override this modifier for better funds management (e.g. send to the\n EntryPoint more than the minimum required, so that in future transactions it will not\n be required to send again).\n @param missingAccountFunds The minimum value this modifier should send the EntryPoint which\n MAY be zero, in case there is enough deposit, or the userOp has a\n paymaster." + }, + "name": "payPrefund", + "nameLocation": "3819:10:40", + "parameters": { + "id": 50003, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50002, + "mutability": "mutable", + "name": "missingAccountFunds", + "nameLocation": "3838:19:40", + "nodeType": "VariableDeclaration", + "scope": 50007, + "src": "3830:27:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 50001, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3830:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3829:29:40" + }, + "virtual": true, + "visibility": "internal" + }, + { + "id": 50038, + "nodeType": "FunctionDefinition", + "src": "4176:257:40", + "nodes": [], + "body": { + "id": 50037, + "nodeType": "Block", + "src": "4190:243:40", + "nodes": [], + "statements": [ + { + "assignments": [ + 50014 + ], + "declarations": [ + { + "constant": false, + "id": 50014, + "mutability": "mutable", + "name": "owners", + "nameLocation": "4324:6:40", + "nodeType": "VariableDeclaration", + "scope": 50037, + "src": "4309:21:40", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_memory_ptr_$dyn_memory_ptr", + "typeString": "bytes[]" + }, + "typeName": { + "baseType": { + "id": 50012, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4309:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "id": 50013, + "nodeType": "ArrayTypeName", + "src": "4309:7:40", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_storage_$dyn_storage_ptr", + "typeString": "bytes[]" + } + }, + "visibility": "internal" + } + ], + "id": 50020, + "initialValue": { + "arguments": [ + { + "hexValue": "31", + "id": 50018, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4345:1:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + } + ], + "id": 50017, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "NewExpression", + "src": "4333:11:40", + "typeDescriptions": { + "typeIdentifier": "t_function_objectcreation_pure$_t_uint256_$returns$_t_array$_t_bytes_memory_ptr_$dyn_memory_ptr_$", + "typeString": "function (uint256) pure returns (bytes memory[] memory)" + }, + "typeName": { + "baseType": { + "id": 50015, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4337:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "id": 50016, + "nodeType": "ArrayTypeName", + "src": "4337:7:40", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_storage_$dyn_storage_ptr", + "typeString": "bytes[]" + } + } + }, + "id": 50019, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4333:14:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_memory_ptr_$dyn_memory_ptr", + "typeString": "bytes memory[] memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4309:38:40" + }, + { + "expression": { + "id": 50031, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "baseExpression": { + "id": 50021, + "name": "owners", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50014, + "src": "4357:6:40", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_memory_ptr_$dyn_memory_ptr", + "typeString": "bytes memory[] memory" + } + }, + "id": 50023, + "indexExpression": { + "hexValue": "30", + "id": 50022, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4364:1:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "4357:9:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "arguments": [ + { + "hexValue": "30", + "id": 50028, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4388:1:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 50027, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4380:7:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 50026, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4380:7:40", + "typeDescriptions": {} + } + }, + "id": 50029, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4380:10:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "id": 50024, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "4369:3:40", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 50025, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "4373:6:40", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "4369:10:40", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 50030, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4369:22:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "src": "4357:34:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 50032, + "nodeType": "ExpressionStatement", + "src": "4357:34:40" + }, + { + "expression": { + "arguments": [ + { + "id": 50034, + "name": "owners", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50014, + "src": "4419:6:40", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_memory_ptr_$dyn_memory_ptr", + "typeString": "bytes memory[] memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_bytes_memory_ptr_$dyn_memory_ptr", + "typeString": "bytes memory[] memory" + } + ], + "id": 50033, + "name": "_initializeOwners", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 51128, + "src": "4401:17:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_array$_t_bytes_memory_ptr_$dyn_memory_ptr_$returns$__$", + "typeString": "function (bytes memory[] memory)" + } + }, + "id": 50035, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4401:25:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50036, + "nodeType": "ExpressionStatement", + "src": "4401:25:40" + } + ] + }, + "implemented": true, + "kind": "constructor", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "parameters": { + "id": 50008, + "nodeType": "ParameterList", + "parameters": [], + "src": "4187:2:40" + }, + "returnParameters": { + "id": 50009, + "nodeType": "ParameterList", + "parameters": [], + "src": "4190:0:40" + }, + "scope": 50482, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "id": 50059, + "nodeType": "FunctionDefinition", + "src": "4671:192:40", + "nodes": [], + "body": { + "id": 50058, + "nodeType": "Block", + "src": "4739:124:40", + "nodes": [], + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 50048, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 50045, + "name": "nextOwnerIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 51047, + "src": "4753:14:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 50046, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4753:16:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "hexValue": "30", + "id": 50047, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4773:1:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4753:21:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50053, + "nodeType": "IfStatement", + "src": "4749:72:40", + "trueBody": { + "id": 50052, + "nodeType": "Block", + "src": "4776:45:40", + "statements": [ + { + "errorCall": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 50049, + "name": "Initialized", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49959, + "src": "4797:11:40", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 50050, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4797:13:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50051, + "nodeType": "RevertStatement", + "src": "4790:20:40" + } + ] + } + }, + { + "expression": { + "arguments": [ + { + "id": 50055, + "name": "owners", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50042, + "src": "4849:6:40", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + } + ], + "id": 50054, + "name": "_initializeOwners", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 51128, + "src": "4831:17:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_array$_t_bytes_memory_ptr_$dyn_memory_ptr_$returns$__$", + "typeString": "function (bytes memory[] memory)" + } + }, + "id": 50056, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4831:25:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50057, + "nodeType": "ExpressionStatement", + "src": "4831:25:40" + } + ] + }, + "documentation": { + "id": 50039, + "nodeType": "StructuredDocumentation", + "src": "4439:227:40", + "text": "@notice Initializes the account with the the given owners.\n @dev Reverts if the account has already been initialized.\n @param owners The initial array of owners to initialize this account with." + }, + "functionSelector": "6f2de70e", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "initialize", + "nameLocation": "4680:10:40", + "parameters": { + "id": 50043, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50042, + "mutability": "mutable", + "name": "owners", + "nameLocation": "4708:6:40", + "nodeType": "VariableDeclaration", + "scope": 50059, + "src": "4691:23:40", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes[]" + }, + "typeName": { + "baseType": { + "id": 50040, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4691:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "id": 50041, + "nodeType": "ArrayTypeName", + "src": "4691:7:40", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_storage_$dyn_storage_ptr", + "typeString": "bytes[]" + } + }, + "visibility": "internal" + } + ], + "src": "4690:25:40" + }, + "returnParameters": { + "id": 50044, + "nodeType": "ParameterList", + "parameters": [], + "src": "4739:0:40" + }, + "scope": 50482, + "stateMutability": "payable", + "virtual": true, + "visibility": "public" + }, + { + "id": 50139, + "nodeType": "FunctionDefinition", + "src": "5921:1184:40", + "nodes": [], + "body": { + "id": 50138, + "nodeType": "Block", + "src": "6180:925:40", + "nodes": [], + "statements": [ + { + "assignments": [ + 50078 + ], + "declarations": [ + { + "constant": false, + "id": 50078, + "mutability": "mutable", + "name": "key", + "nameLocation": "6198:3:40", + "nodeType": "VariableDeclaration", + "scope": 50138, + "src": "6190:11:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 50077, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6190:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 50083, + "initialValue": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 50082, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 50079, + "name": "userOp", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50063, + "src": "6204:6:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_UserOperation_$2402_calldata_ptr", + "typeString": "struct UserOperation calldata" + } + }, + "id": 50080, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6211:5:40", + "memberName": "nonce", + "nodeType": "MemberAccess", + "referencedDeclaration": 2383, + "src": "6204:12:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": { + "hexValue": "3634", + "id": 50081, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6220:2:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_64_by_1", + "typeString": "int_const 64" + }, + "value": "64" + }, + "src": "6204:18:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "6190:32:40" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 50099, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 50088, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "expression": { + "id": 50084, + "name": "userOp", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50063, + "src": "6321:6:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_UserOperation_$2402_calldata_ptr", + "typeString": "struct UserOperation calldata" + } + }, + "id": 50085, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6328:8:40", + "memberName": "callData", + "nodeType": "MemberAccess", + "referencedDeclaration": 2387, + "src": "6321:15:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 50086, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6337:6:40", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "6321:22:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "hexValue": "34", + "id": 50087, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6347:1:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "src": "6321:27:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "commonType": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "id": 50098, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "arguments": [ + { + "baseExpression": { + "expression": { + "id": 50091, + "name": "userOp", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50063, + "src": "6359:6:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_UserOperation_$2402_calldata_ptr", + "typeString": "struct UserOperation calldata" + } + }, + "id": 50092, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6366:8:40", + "memberName": "callData", + "nodeType": "MemberAccess", + "referencedDeclaration": 2387, + "src": "6359:15:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "endExpression": { + "hexValue": "34", + "id": 50094, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6377:1:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "id": 50095, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "6359:20:40", + "startExpression": { + "hexValue": "30", + "id": 50093, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6375:1:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + ], + "id": 50090, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "6352:6:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": { + "id": 50089, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "6352:6:40", + "typeDescriptions": {} + } + }, + "id": 50096, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6352:28:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "30786266366261316663", + "id": 50097, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6384:10:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_3211502076_by_1", + "typeString": "int_const 3211502076" + }, + "value": "0xbf6ba1fc" + }, + "src": "6352:42:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "6321:73:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 50125, + "nodeType": "Block", + "src": "6581:117:40", + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 50118, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 50116, + "name": "key", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50078, + "src": "6599:3:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 50117, + "name": "REPLAYABLE_NONCE_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49956, + "src": "6606:20:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "6599:27:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50124, + "nodeType": "IfStatement", + "src": "6595:93:40", + "trueBody": { + "id": 50123, + "nodeType": "Block", + "src": "6628:60:40", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "id": 50120, + "name": "key", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50078, + "src": "6669:3:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 50119, + "name": "InvalidNonceKey", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49969, + "src": "6653:15:40", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_uint256_$returns$__$", + "typeString": "function (uint256) pure" + } + }, + "id": 50121, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6653:20:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50122, + "nodeType": "RevertStatement", + "src": "6646:27:40" + } + ] + } + } + ] + }, + "id": 50126, + "nodeType": "IfStatement", + "src": "6317:381:40", + "trueBody": { + "id": 50115, + "nodeType": "Block", + "src": "6396:179:40", + "statements": [ + { + "expression": { + "id": 50104, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 50100, + "name": "userOpHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50065, + "src": "6410:10:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 50102, + "name": "userOp", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50063, + "src": "6451:6:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_UserOperation_$2402_calldata_ptr", + "typeString": "struct UserOperation calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_UserOperation_$2402_calldata_ptr", + "typeString": "struct UserOperation calldata" + } + ], + "id": 50101, + "name": "getUserOpHashWithoutChainId", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50266, + "src": "6423:27:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_struct$_UserOperation_$2402_calldata_ptr_$returns$_t_bytes32_$", + "typeString": "function (struct UserOperation calldata) view returns (bytes32)" + } + }, + "id": 50103, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6423:35:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "6410:48:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 50105, + "nodeType": "ExpressionStatement", + "src": "6410:48:40" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 50108, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 50106, + "name": "key", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50078, + "src": "6476:3:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "id": 50107, + "name": "REPLAYABLE_NONCE_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49956, + "src": "6483:20:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "6476:27:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50114, + "nodeType": "IfStatement", + "src": "6472:93:40", + "trueBody": { + "id": 50113, + "nodeType": "Block", + "src": "6505:60:40", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "id": 50110, + "name": "key", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50078, + "src": "6546:3:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 50109, + "name": "InvalidNonceKey", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49969, + "src": "6530:15:40", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_uint256_$returns$__$", + "typeString": "function (uint256) pure" + } + }, + "id": 50111, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6530:20:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50112, + "nodeType": "RevertStatement", + "src": "6523:27:40" + } + ] + } + } + ] + } + }, + { + "condition": { + "arguments": [ + { + "id": 50128, + "name": "userOpHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50065, + "src": "6795:10:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": { + "id": 50129, + "name": "userOp", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50063, + "src": "6807:6:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_UserOperation_$2402_calldata_ptr", + "typeString": "struct UserOperation calldata" + } + }, + "id": 50130, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6814:9:40", + "memberName": "signature", + "nodeType": "MemberAccess", + "referencedDeclaration": 2401, + "src": "6807:16:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 50127, + "name": "_validateSignature", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 50455 + ], + "referencedDeclaration": 50455, + "src": "6776:18:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_bool_$", + "typeString": "function (bytes32,bytes calldata) view returns (bool)" + } + }, + "id": 50131, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6776:48:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50135, + "nodeType": "IfStatement", + "src": "6772:87:40", + "trueBody": { + "id": 50134, + "nodeType": "Block", + "src": "6826:33:40", + "statements": [ + { + "expression": { + "hexValue": "30", + "id": 50132, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6847:1:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "functionReturnParameters": 50076, + "id": 50133, + "nodeType": "Return", + "src": "6840:8:40" + } + ] + } + }, + { + "expression": { + "hexValue": "31", + "id": 50136, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7097:1:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "functionReturnParameters": 50076, + "id": 50137, + "nodeType": "Return", + "src": "7090:8:40" + } + ] + }, + "documentation": { + "id": 50060, + "nodeType": "StructuredDocumentation", + "src": "4869:1047:40", + "text": "@notice Custom implemenentation of the ERC-4337 `validateUserOp` method. The EntryPoint will\n make the call to the recipient only if this validation call returns successfully.\n See `IAccount.validateUserOp()`.\n @dev Signature failure should be reported by returning 1 (see: `_validateSignature()`). This\n allows making a \"simulation call\" without a valid signature. Other failures (e.g. nonce\n mismatch, or invalid signature format) should still revert to signal failure.\n @dev Reverts if the `UserOperation` key is invalid.\n @dev Reverts if the signature verification fails (except for the case mentionned earlier).\n @param userOp The `UserOperation` to validate.\n @param userOpHash The `UserOperation` hash (including the chain ID).\n @param missingAccountFunds The missing account funds that must be deposited on the Entrypoint.\n @return validationData The encoded `ValidationData` structure." + }, + "functionSelector": "3a871cdd", + "implemented": true, + "kind": "function", + "modifiers": [ + { + "id": 50070, + "kind": "modifierInvocation", + "modifierName": { + "id": 50069, + "name": "onlyEntryPoint", + "nameLocations": [ + "6080:14:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 49984, + "src": "6080:14:40" + }, + "nodeType": "ModifierInvocation", + "src": "6080:14:40" + }, + { + "arguments": [ + { + "id": 50072, + "name": "missingAccountFunds", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50067, + "src": "6114:19:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 50073, + "kind": "modifierInvocation", + "modifierName": { + "id": 50071, + "name": "payPrefund", + "nameLocations": [ + "6103:10:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 50007, + "src": "6103:10:40" + }, + "nodeType": "ModifierInvocation", + "src": "6103:31:40" + } + ], + "name": "validateUserOp", + "nameLocation": "5930:14:40", + "parameters": { + "id": 50068, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50063, + "mutability": "mutable", + "name": "userOp", + "nameLocation": "5968:6:40", + "nodeType": "VariableDeclaration", + "scope": 50139, + "src": "5945:29:40", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_struct$_UserOperation_$2402_calldata_ptr", + "typeString": "struct UserOperation" + }, + "typeName": { + "id": 50062, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 50061, + "name": "UserOperation", + "nameLocations": [ + "5945:13:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2402, + "src": "5945:13:40" + }, + "referencedDeclaration": 2402, + "src": "5945:13:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_UserOperation_$2402_storage_ptr", + "typeString": "struct UserOperation" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50065, + "mutability": "mutable", + "name": "userOpHash", + "nameLocation": "5984:10:40", + "nodeType": "VariableDeclaration", + "scope": 50139, + "src": "5976:18:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 50064, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5976:7:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50067, + "mutability": "mutable", + "name": "missingAccountFunds", + "nameLocation": "6004:19:40", + "nodeType": "VariableDeclaration", + "scope": 50139, + "src": "5996:27:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 50066, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5996:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "5944:80:40" + }, + "returnParameters": { + "id": 50076, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50075, + "mutability": "mutable", + "name": "validationData", + "nameLocation": "6160:14:40", + "nodeType": "VariableDeclaration", + "scope": 50139, + "src": "6152:22:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 50074, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6152:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "6151:24:40" + }, + "scope": 50482, + "stateMutability": "payable", + "virtual": true, + "visibility": "public" + }, + { + "id": 50177, + "nodeType": "FunctionDefinition", + "src": "7785:302:40", + "nodes": [], + "body": { + "id": 50176, + "nodeType": "Block", + "src": "7885:202:40", + "nodes": [], + "statements": [ + { + "assignments": [ + 50148 + ], + "declarations": [ + { + "constant": false, + "id": 50148, + "mutability": "mutable", + "name": "selector", + "nameLocation": "7902:8:40", + "nodeType": "VariableDeclaration", + "scope": 50176, + "src": "7895:15:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 50147, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "7895:6:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "visibility": "internal" + } + ], + "id": 50156, + "initialValue": { + "arguments": [ + { + "baseExpression": { + "id": 50151, + "name": "data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50142, + "src": "7920:4:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "endExpression": { + "hexValue": "34", + "id": 50153, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7927:1:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "id": 50154, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "7920:9:40", + "startExpression": { + "hexValue": "30", + "id": 50152, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7925:1:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + ], + "id": 50150, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "7913:6:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": { + "id": 50149, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "7913:6:40", + "typeDescriptions": {} + } + }, + "id": 50155, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7913:17:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "7895:35:40" + }, + { + "condition": { + "id": 50160, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "7944:35:40", + "subExpression": { + "arguments": [ + { + "id": 50158, + "name": "selector", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50148, + "src": "7970:8:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + ], + "id": 50157, + "name": "canSkipChainIdValidation", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50312, + "src": "7945:24:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes4_$returns$_t_bool_$", + "typeString": "function (bytes4) pure returns (bool)" + } + }, + "id": 50159, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7945:34:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50166, + "nodeType": "IfStatement", + "src": "7940:101:40", + "trueBody": { + "id": 50165, + "nodeType": "Block", + "src": "7981:60:40", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "id": 50162, + "name": "selector", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50148, + "src": "8021:8:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + ], + "id": 50161, + "name": "SelectorNotAllowed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49964, + "src": "8002:18:40", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes4_$returns$__$", + "typeString": "function (bytes4) pure" + } + }, + "id": 50163, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8002:28:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50164, + "nodeType": "RevertStatement", + "src": "7995:35:40" + } + ] + } + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "id": 50170, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "8065:4:40", + "typeDescriptions": { + "typeIdentifier": "t_contract$_CoinbaseSmartWallet_$50482", + "typeString": "contract CoinbaseSmartWallet" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_CoinbaseSmartWallet_$50482", + "typeString": "contract CoinbaseSmartWallet" + } + ], + "id": 50169, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "8057:7:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 50168, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "8057:7:40", + "typeDescriptions": {} + } + }, + "id": 50171, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8057:13:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "hexValue": "30", + "id": 50172, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "8072:1:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + { + "id": 50173, + "name": "data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50142, + "src": "8075:4:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 50167, + "name": "_call", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50339, + "src": "8051:5:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (address,uint256,bytes memory)" + } + }, + "id": 50174, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8051:29:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50175, + "nodeType": "ExpressionStatement", + "src": "8051:29:40" + } + ] + }, + "documentation": { + "id": 50140, + "nodeType": "StructuredDocumentation", + "src": "7111:669:40", + "text": "@notice Execute the given call from this account to this account (i.e., self call).\n @dev Can only be called by the Entrypoint.\n @dev Reverts if the given call is not authorized to skip the chain ID validtion.\n @dev `validateUserOp()` will recompute the `userOpHash` without the chain ID before validating\n it if the `UserOperation` aims at executing this function. This allows certain operations\n to be replayed for all accounts sharing the same address across chains. E.g. This may be\n useful for syncing owner changes.\n @param data The `UserOperation` raw call data of the execute." + }, + "functionSelector": "bf6ba1fc", + "implemented": true, + "kind": "function", + "modifiers": [ + { + "id": 50145, + "kind": "modifierInvocation", + "modifierName": { + "id": 50144, + "name": "onlyEntryPoint", + "nameLocations": [ + "7870:14:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 49984, + "src": "7870:14:40" + }, + "nodeType": "ModifierInvocation", + "src": "7870:14:40" + } + ], + "name": "executeWithoutChainIdValidation", + "nameLocation": "7794:31:40", + "parameters": { + "id": 50143, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50142, + "mutability": "mutable", + "name": "data", + "nameLocation": "7841:4:40", + "nodeType": "VariableDeclaration", + "scope": 50177, + "src": "7826:19:40", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 50141, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "7826:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "7825:21:40" + }, + "returnParameters": { + "id": 50146, + "nodeType": "ParameterList", + "parameters": [], + "src": "7885:0:40" + }, + "scope": 50482, + "stateMutability": "payable", + "virtual": true, + "visibility": "public" + }, + { + "id": 50196, + "nodeType": "FunctionDefinition", + "src": "8399:157:40", + "nodes": [], + "body": { + "id": 50195, + "nodeType": "Block", + "src": "8513:43:40", + "nodes": [], + "statements": [ + { + "expression": { + "arguments": [ + { + "id": 50190, + "name": "target", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50180, + "src": "8529:6:40", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 50191, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50182, + "src": "8537:5:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 50192, + "name": "data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50184, + "src": "8544:4:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 50189, + "name": "_call", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50339, + "src": "8523:5:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (address,uint256,bytes memory)" + } + }, + "id": 50193, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8523:26:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50194, + "nodeType": "ExpressionStatement", + "src": "8523:26:40" + } + ] + }, + "documentation": { + "id": 50178, + "nodeType": "StructuredDocumentation", + "src": "8093:301:40", + "text": "@notice Execute the given call from this account.\n @dev Can only be called by the Entrypoint or an owner of this account (including itself).\n @param target The target call address.\n @param value The call value to user.\n @param data The raw call data." + }, + "functionSelector": "b61d27f6", + "implemented": true, + "kind": "function", + "modifiers": [ + { + "id": 50187, + "kind": "modifierInvocation", + "modifierName": { + "id": 50186, + "name": "onlyEntryPointOrOwner", + "nameLocations": [ + "8491:21:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 49999, + "src": "8491:21:40" + }, + "nodeType": "ModifierInvocation", + "src": "8491:21:40" + } + ], + "name": "execute", + "nameLocation": "8408:7:40", + "parameters": { + "id": 50185, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50180, + "mutability": "mutable", + "name": "target", + "nameLocation": "8424:6:40", + "nodeType": "VariableDeclaration", + "scope": 50196, + "src": "8416:14:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 50179, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "8416:7:40", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50182, + "mutability": "mutable", + "name": "value", + "nameLocation": "8440:5:40", + "nodeType": "VariableDeclaration", + "scope": 50196, + "src": "8432:13:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 50181, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8432:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50184, + "mutability": "mutable", + "name": "data", + "nameLocation": "8462:4:40", + "nodeType": "VariableDeclaration", + "scope": 50196, + "src": "8447:19:40", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 50183, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "8447:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "8415:52:40" + }, + "returnParameters": { + "id": 50188, + "nodeType": "ParameterList", + "parameters": [], + "src": "8513:0:40" + }, + "scope": 50482, + "stateMutability": "payable", + "virtual": true, + "visibility": "public" + }, + { + "id": 50235, + "nodeType": "FunctionDefinition", + "src": "8796:278:40", + "nodes": [], + "body": { + "id": 50234, + "nodeType": "Block", + "src": "8886:188:40", + "nodes": [], + "statements": [ + { + "body": { + "id": 50232, + "nodeType": "Block", + "src": "8931:137:40", + "statements": [ + { + "expression": { + "arguments": [ + { + "expression": { + "baseExpression": { + "id": 50214, + "name": "calls", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50201, + "src": "8951:5:40", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Call_$49952_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct CoinbaseSmartWallet.Call calldata[] calldata" + } + }, + "id": 50216, + "indexExpression": { + "id": 50215, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50207, + "src": "8957:1:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "8951:8:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Call_$49952_calldata_ptr", + "typeString": "struct CoinbaseSmartWallet.Call calldata" + } + }, + "id": 50217, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "8960:6:40", + "memberName": "target", + "nodeType": "MemberAccess", + "referencedDeclaration": 49945, + "src": "8951:15:40", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": { + "baseExpression": { + "id": 50218, + "name": "calls", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50201, + "src": "8968:5:40", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Call_$49952_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct CoinbaseSmartWallet.Call calldata[] calldata" + } + }, + "id": 50220, + "indexExpression": { + "id": 50219, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50207, + "src": "8974:1:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "8968:8:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Call_$49952_calldata_ptr", + "typeString": "struct CoinbaseSmartWallet.Call calldata" + } + }, + "id": 50221, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "8977:5:40", + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": 49948, + "src": "8968:14:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "expression": { + "baseExpression": { + "id": 50222, + "name": "calls", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50201, + "src": "8984:5:40", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Call_$49952_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct CoinbaseSmartWallet.Call calldata[] calldata" + } + }, + "id": 50224, + "indexExpression": { + "id": 50223, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50207, + "src": "8990:1:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "8984:8:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Call_$49952_calldata_ptr", + "typeString": "struct CoinbaseSmartWallet.Call calldata" + } + }, + "id": 50225, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "8993:4:40", + "memberName": "data", + "nodeType": "MemberAccess", + "referencedDeclaration": 49951, + "src": "8984:13:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 50213, + "name": "_call", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50339, + "src": "8945:5:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (address,uint256,bytes memory)" + } + }, + "id": 50226, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8945:53:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50227, + "nodeType": "ExpressionStatement", + "src": "8945:53:40" + }, + { + "id": 50231, + "nodeType": "UncheckedBlock", + "src": "9012:46:40", + "statements": [ + { + "expression": { + "id": 50229, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": true, + "src": "9040:3:40", + "subExpression": { + "id": 50228, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50207, + "src": "9042:1:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 50230, + "nodeType": "ExpressionStatement", + "src": "9040:3:40" + } + ] + } + ] + }, + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 50212, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 50209, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50207, + "src": "8912:1:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "expression": { + "id": 50210, + "name": "calls", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50201, + "src": "8916:5:40", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Call_$49952_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct CoinbaseSmartWallet.Call calldata[] calldata" + } + }, + "id": 50211, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "8922:6:40", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "8916:12:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "8912:16:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50233, + "initializationExpression": { + "assignments": [ + 50207 + ], + "declarations": [ + { + "constant": false, + "id": 50207, + "mutability": "mutable", + "name": "i", + "nameLocation": "8909:1:40", + "nodeType": "VariableDeclaration", + "scope": 50233, + "src": "8901:9:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 50206, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8901:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 50208, + "nodeType": "VariableDeclarationStatement", + "src": "8901:9:40" + }, + "isSimpleCounterLoop": false, + "nodeType": "ForStatement", + "src": "8896:172:40" + } + ] + }, + "documentation": { + "id": 50197, + "nodeType": "StructuredDocumentation", + "src": "8562:229:40", + "text": "@notice Execute the given list of calls from this account.\n @dev Can only be called by the Entrypoint or an owner of this account (including itself).\n @param calls The list of `Call`s to execute." + }, + "functionSelector": "34fcd5be", + "implemented": true, + "kind": "function", + "modifiers": [ + { + "id": 50204, + "kind": "modifierInvocation", + "modifierName": { + "id": 50203, + "name": "onlyEntryPointOrOwner", + "nameLocations": [ + "8864:21:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 49999, + "src": "8864:21:40" + }, + "nodeType": "ModifierInvocation", + "src": "8864:21:40" + } + ], + "name": "executeBatch", + "nameLocation": "8805:12:40", + "parameters": { + "id": 50202, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50201, + "mutability": "mutable", + "name": "calls", + "nameLocation": "8834:5:40", + "nodeType": "VariableDeclaration", + "scope": 50235, + "src": "8818:21:40", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Call_$49952_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct CoinbaseSmartWallet.Call[]" + }, + "typeName": { + "baseType": { + "id": 50199, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 50198, + "name": "Call", + "nameLocations": [ + "8818:4:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 49952, + "src": "8818:4:40" + }, + "referencedDeclaration": 49952, + "src": "8818:4:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Call_$49952_storage_ptr", + "typeString": "struct CoinbaseSmartWallet.Call" + } + }, + "id": 50200, + "nodeType": "ArrayTypeName", + "src": "8818:6:40", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Call_$49952_storage_$dyn_storage_ptr", + "typeString": "struct CoinbaseSmartWallet.Call[]" + } + }, + "visibility": "internal" + } + ], + "src": "8817:23:40" + }, + "returnParameters": { + "id": 50205, + "nodeType": "ParameterList", + "parameters": [], + "src": "8886:0:40" + }, + "scope": 50482, + "stateMutability": "payable", + "virtual": true, + "visibility": "public" + }, + { + "id": 50244, + "nodeType": "FunctionDefinition", + "src": "9199:126:40", + "nodes": [], + "body": { + "id": 50243, + "nodeType": "Block", + "src": "9259:66:40", + "nodes": [], + "statements": [ + { + "expression": { + "hexValue": "307835464631333744346230464443443439446341333063374346353745353738613032366432373839", + "id": 50241, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9276:42:40", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "value": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" + }, + "functionReturnParameters": 50240, + "id": 50242, + "nodeType": "Return", + "src": "9269:49:40" + } + ] + }, + "documentation": { + "id": 50236, + "nodeType": "StructuredDocumentation", + "src": "9080:114:40", + "text": "@notice Returns the address of the EntryPoint v0.6.\n @return The address of the EntryPoint v0.6" + }, + "functionSelector": "b0d691fe", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "entryPoint", + "nameLocation": "9208:10:40", + "parameters": { + "id": 50237, + "nodeType": "ParameterList", + "parameters": [], + "src": "9218:2:40" + }, + "returnParameters": { + "id": 50240, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50239, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 50244, + "src": "9250:7:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 50238, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "9250:7:40", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "9249:9:40" + }, + "scope": 50482, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 50266, + "nodeType": "FunctionDefinition", + "src": "9723:243:40", + "nodes": [], + "body": { + "id": 50265, + "nodeType": "Block", + "src": "9876:90:40", + "nodes": [], + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "id": 50258, + "name": "userOp", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50248, + "src": "9936:6:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_UserOperation_$2402_calldata_ptr", + "typeString": "struct UserOperation calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_struct$_UserOperation_$2402_calldata_ptr", + "typeString": "struct UserOperation calldata" + } + ], + "expression": { + "id": 50256, + "name": "UserOperationLib", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2572, + "src": "9914:16:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_UserOperationLib_$2572_$", + "typeString": "type(library UserOperationLib)" + } + }, + "id": 50257, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "9931:4:40", + "memberName": "hash", + "nodeType": "MemberAccess", + "referencedDeclaration": 2554, + "src": "9914:21:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_struct$_UserOperation_$2402_calldata_ptr_$returns$_t_bytes32_$", + "typeString": "function (struct UserOperation calldata) pure returns (bytes32)" + } + }, + "id": 50259, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9914:29:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 50260, + "name": "entryPoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50244, + "src": "9945:10:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_address_$", + "typeString": "function () view returns (address)" + } + }, + "id": 50261, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9945:12:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "id": 50254, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "9903:3:40", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 50255, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "9907:6:40", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "9903:10:40", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 50262, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9903:55:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 50253, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -8, + "src": "9893:9:40", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 50263, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9893:66:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 50252, + "id": 50264, + "nodeType": "Return", + "src": "9886:73:40" + } + ] + }, + "documentation": { + "id": 50245, + "nodeType": "StructuredDocumentation", + "src": "9331:387:40", + "text": "@notice Computes the hash of the `UserOperation` in the same way as EntryPoint v0.6, but\n leaves out the chain ID.\n @dev This allows accounts to sign a hash that can be used on many chains.\n @param userOp The `UserOperation` to compute the hash for.\n @return userOpHash The `UserOperation` hash, not including the chain ID." + }, + "functionSelector": "4f6e7f22", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "getUserOpHashWithoutChainId", + "nameLocation": "9732:27:40", + "parameters": { + "id": 50249, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50248, + "mutability": "mutable", + "name": "userOp", + "nameLocation": "9783:6:40", + "nodeType": "VariableDeclaration", + "scope": 50266, + "src": "9760:29:40", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_struct$_UserOperation_$2402_calldata_ptr", + "typeString": "struct UserOperation" + }, + "typeName": { + "id": 50247, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 50246, + "name": "UserOperation", + "nameLocations": [ + "9760:13:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2402, + "src": "9760:13:40" + }, + "referencedDeclaration": 2402, + "src": "9760:13:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_UserOperation_$2402_storage_ptr", + "typeString": "struct UserOperation" + } + }, + "visibility": "internal" + } + ], + "src": "9759:31:40" + }, + "returnParameters": { + "id": 50252, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50251, + "mutability": "mutable", + "name": "userOpHash", + "nameLocation": "9860:10:40", + "nodeType": "VariableDeclaration", + "scope": 50266, + "src": "9852:18:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 50250, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "9852:7:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "9851:20:40" + }, + "scope": 50482, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 50274, + "nodeType": "FunctionDefinition", + "src": "10106:153:40", + "nodes": [], + "body": { + "id": 50273, + "nodeType": "Block", + "src": "10167:92:40", + "nodes": [], + "statements": [ + { + "AST": { + "nativeSrc": "10186:67:40", + "nodeType": "YulBlock", + "src": "10186:67:40", + "statements": [ + { + "nativeSrc": "10200:43:40", + "nodeType": "YulAssignment", + "src": "10200:43:40", + "value": { + "arguments": [ + { + "name": "_ERC1967_IMPLEMENTATION_SLOT", + "nativeSrc": "10214:28:40", + "nodeType": "YulIdentifier", + "src": "10214:28:40" + } + ], + "functionName": { + "name": "sload", + "nativeSrc": "10208:5:40", + "nodeType": "YulIdentifier", + "src": "10208:5:40" + }, + "nativeSrc": "10208:35:40", + "nodeType": "YulFunctionCall", + "src": "10208:35:40" + }, + "variableNames": [ + { + "name": "addr", + "nativeSrc": "10200:4:40", + "nodeType": "YulIdentifier", + "src": "10200:4:40" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 49428, + "isOffset": false, + "isSlot": false, + "src": "10214:28:40", + "valueSize": 1 + }, + { + "declaration": 50270, + "isOffset": false, + "isSlot": false, + "src": "10200:4:40", + "valueSize": 1 + } + ], + "id": 50272, + "nodeType": "InlineAssembly", + "src": "10177:76:40" + } + ] + }, + "documentation": { + "id": 50267, + "nodeType": "StructuredDocumentation", + "src": "9972:129:40", + "text": "@notice Returns the implementation of the ERC1967 proxy.\n @return addr The address of implementation contract." + }, + "functionSelector": "5c60da1b", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "implementation", + "nameLocation": "10115:14:40", + "parameters": { + "id": 50268, + "nodeType": "ParameterList", + "parameters": [], + "src": "10129:2:40" + }, + "returnParameters": { + "id": 50271, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50270, + "mutability": "mutable", + "name": "addr", + "nameLocation": "10161:4:40", + "nodeType": "VariableDeclaration", + "scope": 50274, + "src": "10153:12:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 50269, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "10153:7:40", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "10152:14:40" + }, + "scope": 50482, + "stateMutability": "view", + "virtual": false, + "visibility": "public" + }, + { + "id": 50312, + "nodeType": "FunctionDefinition", + "src": "10557:485:40", + "nodes": [], + "body": { + "id": 50311, + "nodeType": "Block", + "src": "10643:399:40", + "nodes": [], + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 50304, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 50298, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 50292, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "commonType": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "id": 50286, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 50282, + "name": "functionSelector", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50277, + "src": "10670:16:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "expression": { + "id": 50283, + "name": "MultiOwnable", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 51215, + "src": "10690:12:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_MultiOwnable_$51215_$", + "typeString": "type(contract MultiOwnable)" + } + }, + "id": 50284, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "10703:17:40", + "memberName": "addOwnerPublicKey", + "nodeType": "MemberAccess", + "referencedDeclaration": 50924, + "src": "10690:30:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$returns$__$", + "typeString": "function (bytes32,bytes32)" + } + }, + "id": 50285, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "10721:8:40", + "memberName": "selector", + "nodeType": "MemberAccess", + "src": "10690:39:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "src": "10670:59:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "commonType": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "id": 50291, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 50287, + "name": "functionSelector", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50277, + "src": "10749:16:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "expression": { + "id": 50288, + "name": "MultiOwnable", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 51215, + "src": "10769:12:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_MultiOwnable_$51215_$", + "typeString": "type(contract MultiOwnable)" + } + }, + "id": 50289, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "10782:15:40", + "memberName": "addOwnerAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 50905, + "src": "10769:28:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 50290, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "10798:8:40", + "memberName": "selector", + "nodeType": "MemberAccess", + "src": "10769:37:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "src": "10749:57:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "10670:136:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "commonType": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "id": 50297, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 50293, + "name": "functionSelector", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50277, + "src": "10826:16:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "expression": { + "id": 50294, + "name": "MultiOwnable", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 51215, + "src": "10846:12:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_MultiOwnable_$51215_$", + "typeString": "type(contract MultiOwnable)" + } + }, + "id": 50295, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "10859:18:40", + "memberName": "removeOwnerAtIndex", + "nodeType": "MemberAccess", + "referencedDeclaration": 50967, + "src": "10846:31:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$returns$__$", + "typeString": "function (uint256)" + } + }, + "id": 50296, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "10878:8:40", + "memberName": "selector", + "nodeType": "MemberAccess", + "src": "10846:40:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "src": "10826:60:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "10670:216:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "commonType": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "id": 50303, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 50299, + "name": "functionSelector", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50277, + "src": "10906:16:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "expression": { + "id": 50300, + "name": "UUPSUpgradeable", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49482, + "src": "10926:15:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_UUPSUpgradeable_$49482_$", + "typeString": "type(contract UUPSUpgradeable)" + } + }, + "id": 50301, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "10942:16:40", + "memberName": "upgradeToAndCall", + "nodeType": "MemberAccess", + "referencedDeclaration": 49461, + "src": "10926:32:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_bytes_calldata_ptr_$returns$__$", + "typeString": "function (address,bytes calldata)" + } + }, + "id": 50302, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "10959:8:40", + "memberName": "selector", + "nodeType": "MemberAccess", + "src": "10926:41:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "src": "10906:61:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "10670:297:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50308, + "nodeType": "IfStatement", + "src": "10653:361:40", + "trueBody": { + "id": 50307, + "nodeType": "Block", + "src": "10978:36:40", + "statements": [ + { + "expression": { + "hexValue": "74727565", + "id": 50305, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "10999:4:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 50281, + "id": 50306, + "nodeType": "Return", + "src": "10992:11:40" + } + ] + } + }, + { + "expression": { + "hexValue": "66616c7365", + "id": 50309, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "11030:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "functionReturnParameters": 50281, + "id": 50310, + "nodeType": "Return", + "src": "11023:12:40" + } + ] + }, + "documentation": { + "id": 50275, + "nodeType": "StructuredDocumentation", + "src": "10447:105:40", + "text": "@return `true` is the function selector is whitelisted to skip the chain ID validation, else `false`." + }, + "functionSelector": "9f9bcb34", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "canSkipChainIdValidation", + "nameLocation": "10566:24:40", + "parameters": { + "id": 50278, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50277, + "mutability": "mutable", + "name": "functionSelector", + "nameLocation": "10598:16:40", + "nodeType": "VariableDeclaration", + "scope": 50312, + "src": "10591:23:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 50276, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "10591:6:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "visibility": "internal" + } + ], + "src": "10590:25:40" + }, + "returnParameters": { + "id": 50281, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50280, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 50312, + "src": "10637:4:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 50279, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "10637:4:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "10636:6:40" + }, + "scope": 50482, + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + }, + { + "id": 50339, + "nodeType": "FunctionDefinition", + "src": "11413:302:40", + "nodes": [], + "body": { + "id": 50338, + "nodeType": "Block", + "src": "11487:228:40", + "nodes": [], + "statements": [ + { + "assignments": [ + 50323, + 50325 + ], + "declarations": [ + { + "constant": false, + "id": 50323, + "mutability": "mutable", + "name": "success", + "nameLocation": "11503:7:40", + "nodeType": "VariableDeclaration", + "scope": 50338, + "src": "11498:12:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 50322, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "11498:4:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50325, + "mutability": "mutable", + "name": "result", + "nameLocation": "11525:6:40", + "nodeType": "VariableDeclaration", + "scope": 50338, + "src": "11512:19:40", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 50324, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "11512:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 50332, + "initialValue": { + "arguments": [ + { + "id": 50330, + "name": "data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50319, + "src": "11561:4:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": { + "id": 50326, + "name": "target", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50315, + "src": "11535:6:40", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 50327, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "11542:4:40", + "memberName": "call", + "nodeType": "MemberAccess", + "src": "11535:11:40", + "typeDescriptions": { + "typeIdentifier": "t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "function (bytes memory) payable returns (bool,bytes memory)" + } + }, + "id": 50329, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "names": [ + "value" + ], + "nodeType": "FunctionCallOptions", + "options": [ + { + "id": 50328, + "name": "value", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50317, + "src": "11554:5:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "src": "11535:25:40", + "typeDescriptions": { + "typeIdentifier": "t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$value", + "typeString": "function (bytes memory) payable returns (bool,bytes memory)" + } + }, + "id": 50331, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "11535:31:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bool_$_t_bytes_memory_ptr_$", + "typeString": "tuple(bool,bytes memory)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "11497:69:40" + }, + { + "condition": { + "id": 50334, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "11580:8:40", + "subExpression": { + "id": 50333, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50323, + "src": "11581:7:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50337, + "nodeType": "IfStatement", + "src": "11576:133:40", + "trueBody": { + "id": 50336, + "nodeType": "Block", + "src": "11590:119:40", + "statements": [ + { + "AST": { + "nativeSrc": "11629:70:40", + "nodeType": "YulBlock", + "src": "11629:70:40", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "result", + "nativeSrc": "11658:6:40", + "nodeType": "YulIdentifier", + "src": "11658:6:40" + }, + { + "kind": "number", + "nativeSrc": "11666:2:40", + "nodeType": "YulLiteral", + "src": "11666:2:40", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "11654:3:40", + "nodeType": "YulIdentifier", + "src": "11654:3:40" + }, + "nativeSrc": "11654:15:40", + "nodeType": "YulFunctionCall", + "src": "11654:15:40" + }, + { + "arguments": [ + { + "name": "result", + "nativeSrc": "11677:6:40", + "nodeType": "YulIdentifier", + "src": "11677:6:40" + } + ], + "functionName": { + "name": "mload", + "nativeSrc": "11671:5:40", + "nodeType": "YulIdentifier", + "src": "11671:5:40" + }, + "nativeSrc": "11671:13:40", + "nodeType": "YulFunctionCall", + "src": "11671:13:40" + } + ], + "functionName": { + "name": "revert", + "nativeSrc": "11647:6:40", + "nodeType": "YulIdentifier", + "src": "11647:6:40" + }, + "nativeSrc": "11647:38:40", + "nodeType": "YulFunctionCall", + "src": "11647:38:40" + }, + "nativeSrc": "11647:38:40", + "nodeType": "YulExpressionStatement", + "src": "11647:38:40" + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 50325, + "isOffset": false, + "isSlot": false, + "src": "11658:6:40", + "valueSize": 1 + }, + { + "declaration": 50325, + "isOffset": false, + "isSlot": false, + "src": "11677:6:40", + "valueSize": 1 + } + ], + "flags": [ + "memory-safe" + ], + "id": 50335, + "nodeType": "InlineAssembly", + "src": "11604:95:40" + } + ] + } + } + ] + }, + "documentation": { + "id": 50313, + "nodeType": "StructuredDocumentation", + "src": "11048:360:40", + "text": "@notice Execute the given call from this account.\n @dev Reverts if the call reverted.\n @dev Impl taken from https://github.com/alchemyplatform/light-account/blob/main/src/LightAccount.sol#L347\n @param target The target call address.\n @param value The call value to user.\n @param data The raw call data." + }, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_call", + "nameLocation": "11422:5:40", + "parameters": { + "id": 50320, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50315, + "mutability": "mutable", + "name": "target", + "nameLocation": "11436:6:40", + "nodeType": "VariableDeclaration", + "scope": 50339, + "src": "11428:14:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 50314, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "11428:7:40", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50317, + "mutability": "mutable", + "name": "value", + "nameLocation": "11452:5:40", + "nodeType": "VariableDeclaration", + "scope": 50339, + "src": "11444:13:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 50316, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11444:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50319, + "mutability": "mutable", + "name": "data", + "nameLocation": "11472:4:40", + "nodeType": "VariableDeclaration", + "scope": 50339, + "src": "11459:17:40", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 50318, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "11459:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "11427:50:40" + }, + "returnParameters": { + "id": 50321, + "nodeType": "ParameterList", + "parameters": [], + "src": "11487:0:40" + }, + "scope": 50482, + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "id": 50455, + "nodeType": "FunctionDefinition", + "src": "12316:1469:40", + "nodes": [], + "body": { + "id": 50454, + "nodeType": "Block", + "src": "12477:1308:40", + "nodes": [], + "statements": [ + { + "assignments": [ + 50352 + ], + "declarations": [ + { + "constant": false, + "id": 50352, + "mutability": "mutable", + "name": "sigWrapper", + "nameLocation": "12511:10:40", + "nodeType": "VariableDeclaration", + "scope": 50454, + "src": "12487:34:40", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_struct$_SignatureWrapper_$49941_memory_ptr", + "typeString": "struct CoinbaseSmartWallet.SignatureWrapper" + }, + "typeName": { + "id": 50351, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 50350, + "name": "SignatureWrapper", + "nameLocations": [ + "12487:16:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 49941, + "src": "12487:16:40" + }, + "referencedDeclaration": 49941, + "src": "12487:16:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_SignatureWrapper_$49941_storage_ptr", + "typeString": "struct CoinbaseSmartWallet.SignatureWrapper" + } + }, + "visibility": "internal" + } + ], + "id": 50359, + "initialValue": { + "arguments": [ + { + "id": 50355, + "name": "signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50344, + "src": "12535:9:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + { + "components": [ + { + "id": 50356, + "name": "SignatureWrapper", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49941, + "src": "12547:16:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_SignatureWrapper_$49941_storage_ptr_$", + "typeString": "type(struct CoinbaseSmartWallet.SignatureWrapper storage pointer)" + } + } + ], + "id": 50357, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "12546:18:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_SignatureWrapper_$49941_storage_ptr_$", + "typeString": "type(struct CoinbaseSmartWallet.SignatureWrapper storage pointer)" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + }, + { + "typeIdentifier": "t_type$_t_struct$_SignatureWrapper_$49941_storage_ptr_$", + "typeString": "type(struct CoinbaseSmartWallet.SignatureWrapper storage pointer)" + } + ], + "expression": { + "id": 50353, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "12524:3:40", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 50354, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "12528:6:40", + "memberName": "decode", + "nodeType": "MemberAccess", + "src": "12524:10:40", + "typeDescriptions": { + "typeIdentifier": "t_function_abidecode_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 50358, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "12524:41:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_struct$_SignatureWrapper_$49941_memory_ptr", + "typeString": "struct CoinbaseSmartWallet.SignatureWrapper memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "12487:78:40" + }, + { + "assignments": [ + 50361 + ], + "declarations": [ + { + "constant": false, + "id": 50361, + "mutability": "mutable", + "name": "ownerBytes", + "nameLocation": "12588:10:40", + "nodeType": "VariableDeclaration", + "scope": 50454, + "src": "12575:23:40", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 50360, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "12575:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "id": 50366, + "initialValue": { + "arguments": [ + { + "expression": { + "id": 50363, + "name": "sigWrapper", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50352, + "src": "12614:10:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_SignatureWrapper_$49941_memory_ptr", + "typeString": "struct CoinbaseSmartWallet.SignatureWrapper memory" + } + }, + "id": 50364, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "12625:10:40", + "memberName": "ownerIndex", + "nodeType": "MemberAccess", + "referencedDeclaration": 49937, + "src": "12614:21:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 50362, + "name": "ownerAtIndex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 51036, + "src": "12601:12:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_bytes_memory_ptr_$", + "typeString": "function (uint256) view returns (bytes memory)" + } + }, + "id": 50365, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "12601:35:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "12575:61:40" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 50370, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 50367, + "name": "ownerBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50361, + "src": "12651:10:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 50368, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "12662:6:40", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "12651:17:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "3332", + "id": 50369, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "12672:2:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_32_by_1", + "typeString": "int_const 32" + }, + "value": "32" + }, + "src": "12651:23:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50403, + "nodeType": "IfStatement", + "src": "12647:607:40", + "trueBody": { + "id": 50402, + "nodeType": "Block", + "src": "12676:578:40", + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 50383, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "arguments": [ + { + "arguments": [ + { + "id": 50375, + "name": "ownerBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50361, + "src": "12710:10:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 50374, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "12702:7:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 50373, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12702:7:40", + "typeDescriptions": {} + } + }, + "id": 50376, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "12702:19:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 50372, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "12694:7:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 50371, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "12694:7:40", + "typeDescriptions": {} + } + }, + "id": 50377, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "12694:28:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "expression": { + "arguments": [ + { + "id": 50380, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "12730:7:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint160_$", + "typeString": "type(uint160)" + }, + "typeName": { + "id": 50379, + "name": "uint160", + "nodeType": "ElementaryTypeName", + "src": "12730:7:40", + "typeDescriptions": {} + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_type$_t_uint160_$", + "typeString": "type(uint160)" + } + ], + "id": 50378, + "name": "type", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -27, + "src": "12725:4:40", + "typeDescriptions": { + "typeIdentifier": "t_function_metatype_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 50381, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "12725:13:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_magic_meta_type_t_uint160", + "typeString": "type(uint160)" + } + }, + "id": 50382, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "12739:3:40", + "memberName": "max", + "nodeType": "MemberAccess", + "src": "12725:17:40", + "typeDescriptions": { + "typeIdentifier": "t_uint160", + "typeString": "uint160" + } + }, + "src": "12694:48:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50389, + "nodeType": "IfStatement", + "src": "12690:318:40", + "trueBody": { + "id": 50388, + "nodeType": "Block", + "src": "12744:264:40", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "id": 50385, + "name": "ownerBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50361, + "src": "12982:10:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 50384, + "name": "InvalidEthereumAddressOwner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50867, + "src": "12954:27:40", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (bytes memory) pure" + } + }, + "id": 50386, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "12954:39:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50387, + "nodeType": "RevertStatement", + "src": "12947:46:40" + } + ] + } + }, + { + "assignments": [ + 50391 + ], + "declarations": [ + { + "constant": false, + "id": 50391, + "mutability": "mutable", + "name": "owner", + "nameLocation": "13030:5:40", + "nodeType": "VariableDeclaration", + "scope": 50402, + "src": "13022:13:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 50390, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "13022:7:40", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "id": 50392, + "nodeType": "VariableDeclarationStatement", + "src": "13022:13:40" + }, + { + "AST": { + "nativeSrc": "13074:67:40", + "nodeType": "YulBlock", + "src": "13074:67:40", + "statements": [ + { + "nativeSrc": "13092:35:40", + "nodeType": "YulAssignment", + "src": "13092:35:40", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "ownerBytes", + "nativeSrc": "13111:10:40", + "nodeType": "YulIdentifier", + "src": "13111:10:40" + }, + { + "kind": "number", + "nativeSrc": "13123:2:40", + "nodeType": "YulLiteral", + "src": "13123:2:40", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "13107:3:40", + "nodeType": "YulIdentifier", + "src": "13107:3:40" + }, + "nativeSrc": "13107:19:40", + "nodeType": "YulFunctionCall", + "src": "13107:19:40" + } + ], + "functionName": { + "name": "mload", + "nativeSrc": "13101:5:40", + "nodeType": "YulIdentifier", + "src": "13101:5:40" + }, + "nativeSrc": "13101:26:40", + "nodeType": "YulFunctionCall", + "src": "13101:26:40" + }, + "variableNames": [ + { + "name": "owner", + "nativeSrc": "13092:5:40", + "nodeType": "YulIdentifier", + "src": "13092:5:40" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 50391, + "isOffset": false, + "isSlot": false, + "src": "13092:5:40", + "valueSize": 1 + }, + { + "declaration": 50361, + "isOffset": false, + "isSlot": false, + "src": "13111:10:40", + "valueSize": 1 + } + ], + "flags": [ + "memory-safe" + ], + "id": 50393, + "nodeType": "InlineAssembly", + "src": "13049:92:40" + }, + { + "expression": { + "arguments": [ + { + "id": 50396, + "name": "owner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50391, + "src": "13202:5:40", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 50397, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50342, + "src": "13209:7:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "expression": { + "id": 50398, + "name": "sigWrapper", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50352, + "src": "13218:10:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_SignatureWrapper_$49941_memory_ptr", + "typeString": "struct CoinbaseSmartWallet.SignatureWrapper memory" + } + }, + "id": 50399, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "13229:13:40", + "memberName": "signatureData", + "nodeType": "MemberAccess", + "referencedDeclaration": 49940, + "src": "13218:24:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "expression": { + "id": 50394, + "name": "SignatureCheckerLib", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49393, + "src": "13162:19:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SignatureCheckerLib_$49393_$", + "typeString": "type(library SignatureCheckerLib)" + } + }, + "id": 50395, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "13182:19:40", + "memberName": "isValidSignatureNow", + "nodeType": "MemberAccess", + "referencedDeclaration": 49254, + "src": "13162:39:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_address_$_t_bytes32_$_t_bytes_memory_ptr_$returns$_t_bool_$", + "typeString": "function (address,bytes32,bytes memory) view returns (bool)" + } + }, + "id": 50400, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13162:81:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 50349, + "id": 50401, + "nodeType": "Return", + "src": "13155:88:40" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 50407, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 50404, + "name": "ownerBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50361, + "src": "13268:10:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + "id": 50405, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "13279:6:40", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "13268:17:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "3634", + "id": 50406, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13289:2:40", + "typeDescriptions": { + "typeIdentifier": "t_rational_64_by_1", + "typeString": "int_const 64" + }, + "value": "64" + }, + "src": "13268:23:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50449, + "nodeType": "IfStatement", + "src": "13264:462:40", + "trueBody": { + "id": 50448, + "nodeType": "Block", + "src": "13293:433:40", + "statements": [ + { + "assignments": [ + 50409, + 50411 + ], + "declarations": [ + { + "constant": false, + "id": 50409, + "mutability": "mutable", + "name": "x", + "nameLocation": "13316:1:40", + "nodeType": "VariableDeclaration", + "scope": 50448, + "src": "13308:9:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 50408, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13308:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50411, + "mutability": "mutable", + "name": "y", + "nameLocation": "13327:1:40", + "nodeType": "VariableDeclaration", + "scope": 50448, + "src": "13319:9:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 50410, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13319:7:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 50421, + "initialValue": { + "arguments": [ + { + "id": 50414, + "name": "ownerBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50361, + "src": "13343:10:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + { + "components": [ + { + "id": 50416, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "13356:7:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 50415, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13356:7:40", + "typeDescriptions": {} + } + }, + { + "id": 50418, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "13365:7:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 50417, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "13365:7:40", + "typeDescriptions": {} + } + } + ], + "id": 50419, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13355:18:40", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_type$_t_uint256_$_$_t_type$_t_uint256_$_$", + "typeString": "tuple(type(uint256),type(uint256))" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + }, + { + "typeIdentifier": "t_tuple$_t_type$_t_uint256_$_$_t_type$_t_uint256_$_$", + "typeString": "tuple(type(uint256),type(uint256))" + } + ], + "expression": { + "id": 50412, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "13332:3:40", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 50413, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "13336:6:40", + "memberName": "decode", + "nodeType": "MemberAccess", + "src": "13332:10:40", + "typeDescriptions": { + "typeIdentifier": "t_function_abidecode_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 50420, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13332:42:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$", + "typeString": "tuple(uint256,uint256)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "13307:67:40" + }, + { + "assignments": [ + 50426 + ], + "declarations": [ + { + "constant": false, + "id": 50426, + "mutability": "mutable", + "name": "auth", + "nameLocation": "13418:4:40", + "nodeType": "VariableDeclaration", + "scope": 50448, + "src": "13389:33:40", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WebAuthnAuth_$49585_memory_ptr", + "typeString": "struct WebAuthn.WebAuthnAuth" + }, + "typeName": { + "id": 50425, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 50424, + "name": "WebAuthn.WebAuthnAuth", + "nameLocations": [ + "13389:8:40", + "13398:12:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 49585, + "src": "13389:21:40" + }, + "referencedDeclaration": 49585, + "src": "13389:21:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WebAuthnAuth_$49585_storage_ptr", + "typeString": "struct WebAuthn.WebAuthnAuth" + } + }, + "visibility": "internal" + } + ], + "id": 50435, + "initialValue": { + "arguments": [ + { + "expression": { + "id": 50429, + "name": "sigWrapper", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50352, + "src": "13436:10:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_SignatureWrapper_$49941_memory_ptr", + "typeString": "struct CoinbaseSmartWallet.SignatureWrapper memory" + } + }, + "id": 50430, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "memberLocation": "13447:13:40", + "memberName": "signatureData", + "nodeType": "MemberAccess", + "referencedDeclaration": 49940, + "src": "13436:24:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + { + "components": [ + { + "expression": { + "id": 50431, + "name": "WebAuthn", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49808, + "src": "13463:8:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_WebAuthn_$49808_$", + "typeString": "type(library WebAuthn)" + } + }, + "id": 50432, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "13472:12:40", + "memberName": "WebAuthnAuth", + "nodeType": "MemberAccess", + "referencedDeclaration": 49585, + "src": "13463:21:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_WebAuthnAuth_$49585_storage_ptr_$", + "typeString": "type(struct WebAuthn.WebAuthnAuth storage pointer)" + } + } + ], + "id": 50433, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "13462:23:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_struct$_WebAuthnAuth_$49585_storage_ptr_$", + "typeString": "type(struct WebAuthn.WebAuthnAuth storage pointer)" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + }, + { + "typeIdentifier": "t_type$_t_struct$_WebAuthnAuth_$49585_storage_ptr_$", + "typeString": "type(struct WebAuthn.WebAuthnAuth storage pointer)" + } + ], + "expression": { + "id": 50427, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "13425:3:40", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 50428, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "13429:6:40", + "memberName": "decode", + "nodeType": "MemberAccess", + "src": "13425:10:40", + "typeDescriptions": { + "typeIdentifier": "t_function_abidecode_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 50434, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13425:61:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_struct$_WebAuthnAuth_$49585_memory_ptr", + "typeString": "struct WebAuthn.WebAuthnAuth memory" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "13389:97:40" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "id": 50440, + "name": "message", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50342, + "src": "13564:7:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 50438, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "13553:3:40", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 50439, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "13557:6:40", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "13553:10:40", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 50441, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13553:19:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + }, + { + "hexValue": "66616c7365", + "id": 50442, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "13615:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + { + "id": 50443, + "name": "auth", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50426, + "src": "13652:4:40", + "typeDescriptions": { + "typeIdentifier": "t_struct$_WebAuthnAuth_$49585_memory_ptr", + "typeString": "struct WebAuthn.WebAuthnAuth memory" + } + }, + { + "id": 50444, + "name": "x", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50409, + "src": "13677:1:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 50445, + "name": "y", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50411, + "src": "13699:1:40", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_struct$_WebAuthnAuth_$49585_memory_ptr", + "typeString": "struct WebAuthn.WebAuthnAuth memory" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 50436, + "name": "WebAuthn", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 49808, + "src": "13508:8:40", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_WebAuthn_$49808_$", + "typeString": "type(library WebAuthn)" + } + }, + "id": 50437, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "13517:6:40", + "memberName": "verify", + "nodeType": "MemberAccess", + "referencedDeclaration": 49807, + "src": "13508:15:40", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes_memory_ptr_$_t_bool_$_t_struct$_WebAuthnAuth_$49585_memory_ptr_$_t_uint256_$_t_uint256_$returns$_t_bool_$", + "typeString": "function (bytes memory,bool,struct WebAuthn.WebAuthnAuth memory,uint256,uint256) view returns (bool)" + } + }, + "id": 50446, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [ + "13542:9:40", + "13590:23:40", + "13638:12:40", + "13674:1:40", + "13696:1:40" + ], + "names": [ + "challenge", + "requireUserVerification", + "webAuthnAuth", + "x", + "y" + ], + "nodeType": "FunctionCall", + "src": "13508:207:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 50349, + "id": 50447, + "nodeType": "Return", + "src": "13501:214:40" + } + ] + } + }, + { + "errorCall": { + "arguments": [ + { + "id": 50451, + "name": "ownerBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50361, + "src": "13767:10:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 50450, + "name": "InvalidOwnerBytesLength", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50862, + "src": "13743:23:40", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (bytes memory) pure" + } + }, + "id": 50452, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "13743:35:40", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50453, + "nodeType": "RevertStatement", + "src": "13736:42:40" + } + ] + }, + "baseFunctions": [ + 50821 + ], + "documentation": { + "id": 50340, + "nodeType": "StructuredDocumentation", + "src": "11721:590:40", + "text": "@inheritdoc ERC1271\n @dev Used both for classic ERC-1271 signature AND `UserOperation` validations.\n @dev Reverts if the signer (based on the `ownerIndex`) is not compatible with the signature.\n @dev Reverts if the signature does not correspond to an ERC-1271 signature or to the abi\n encoded version of a `WebAuthnAuth` struct.\n @dev Does NOT revert if the signature verification fails to allow making a \"simulation call\"\n without a valid signature.\n @param signature The abi encoded `SignatureWrapper` struct." + }, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_validateSignature", + "nameLocation": "12325:18:40", + "overrides": { + "id": 50346, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "12441:8:40" + }, + "parameters": { + "id": 50345, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50342, + "mutability": "mutable", + "name": "message", + "nameLocation": "12352:7:40", + "nodeType": "VariableDeclaration", + "scope": 50455, + "src": "12344:15:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 50341, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "12344:7:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50344, + "mutability": "mutable", + "name": "signature", + "nameLocation": "12376:9:40", + "nodeType": "VariableDeclaration", + "scope": 50455, + "src": "12361:24:40", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 50343, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "12361:5:40", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "12343:43:40" + }, + "returnParameters": { + "id": 50349, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50348, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 50455, + "src": "12467:4:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 50347, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "12467:4:40", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "12466:6:40" + }, + "scope": 50482, + "stateMutability": "view", + "virtual": true, + "visibility": "internal" + }, + { + "id": 50466, + "nodeType": "FunctionDefinition", + "src": "13928:96:40", + "nodes": [], + "body": { + "id": 50465, + "nodeType": "Block", + "src": "14022:2:40", + "nodes": [], + "statements": [] + }, + "baseFunctions": [ + 49434 + ], + "documentation": { + "id": 50456, + "nodeType": "StructuredDocumentation", + "src": "13791:132:40", + "text": "@inheritdoc UUPSUpgradeable\n @dev Authorization logic is only based on the sender being an owner of this account." + }, + "implemented": true, + "kind": "function", + "modifiers": [ + { + "id": 50463, + "kind": "modifierInvocation", + "modifierName": { + "id": 50462, + "name": "onlyOwner", + "nameLocations": [ + "14012:9:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 50889, + "src": "14012:9:40" + }, + "nodeType": "ModifierInvocation", + "src": "14012:9:40" + } + ], + "name": "_authorizeUpgrade", + "nameLocation": "13937:17:40", + "overrides": { + "id": 50461, + "nodeType": "OverrideSpecifier", + "overrides": [ + { + "id": 50460, + "name": "UUPSUpgradeable", + "nameLocations": [ + "13995:15:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 49482, + "src": "13995:15:40" + } + ], + "src": "13986:25:40" + }, + "parameters": { + "id": 50459, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50458, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 50466, + "src": "13955:7:40", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 50457, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "13955:7:40", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "13954:9:40" + }, + "returnParameters": { + "id": 50464, + "nodeType": "ParameterList", + "parameters": [], + "src": "14022:0:40" + }, + "scope": 50482, + "stateMutability": "view", + "virtual": true, + "visibility": "internal" + }, + { + "id": 50481, + "nodeType": "FunctionDefinition", + "src": "14058:158:40", + "nodes": [], + "body": { + "id": 50480, + "nodeType": "Block", + "src": "14162:54:40", + "nodes": [], + "statements": [ + { + "expression": { + "components": [ + { + "hexValue": "436f696e6261736520536d6172742057616c6c6574", + "id": 50476, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14180:23:40", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_65342b33652b3c0bc173049ed7496b7322db7ff8abfc0752044a5a592bdde64e", + "typeString": "literal_string \"Coinbase Smart Wallet\"" + }, + "value": "Coinbase Smart Wallet" + }, + { + "hexValue": "31", + "id": 50477, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "14205:3:40", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", + "typeString": "literal_string \"1\"" + }, + "value": "1" + } + ], + "id": 50478, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "14179:30:40", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_stringliteral_65342b33652b3c0bc173049ed7496b7322db7ff8abfc0752044a5a592bdde64e_$_t_stringliteral_c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6_$", + "typeString": "tuple(literal_string \"Coinbase Smart Wallet\",literal_string \"1\")" + } + }, + "functionReturnParameters": 50475, + "id": 50479, + "nodeType": "Return", + "src": "14172:37:40" + } + ] + }, + "baseFunctions": [ + 50811 + ], + "documentation": { + "id": 50467, + "nodeType": "StructuredDocumentation", + "src": "14030:23:40", + "text": "@inheritdoc ERC1271" + }, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_domainNameAndVersion", + "nameLocation": "14067:21:40", + "overrides": { + "id": 50470, + "nodeType": "OverrideSpecifier", + "overrides": [ + { + "id": 50469, + "name": "ERC1271", + "nameLocations": [ + "14114:7:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 50822, + "src": "14114:7:40" + } + ], + "src": "14105:17:40" + }, + "parameters": { + "id": 50468, + "nodeType": "ParameterList", + "parameters": [], + "src": "14088:2:40" + }, + "returnParameters": { + "id": 50475, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50472, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 50481, + "src": "14132:13:40", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 50471, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "14132:6:40", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50474, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 50481, + "src": "14147:13:40", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": { + "id": 50473, + "name": "string", + "nodeType": "ElementaryTypeName", + "src": "14147:6:40", + "typeDescriptions": { + "typeIdentifier": "t_string_storage_ptr", + "typeString": "string" + } + }, + "visibility": "internal" + } + ], + "src": "14131:30:40" + }, + "scope": 50482, + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + } + ], + "abstract": false, + "baseContracts": [ + { + "baseName": { + "id": 49926, + "name": "MultiOwnable", + "nameLocations": [ + "906:12:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 51215, + "src": "906:12:40" + }, + "id": 49927, + "nodeType": "InheritanceSpecifier", + "src": "906:12:40" + }, + { + "baseName": { + "id": 49928, + "name": "UUPSUpgradeable", + "nameLocations": [ + "920:15:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 49482, + "src": "920:15:40" + }, + "id": 49929, + "nodeType": "InheritanceSpecifier", + "src": "920:15:40" + }, + { + "baseName": { + "id": 49930, + "name": "Receiver", + "nameLocations": [ + "937:8:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 47844, + "src": "937:8:40" + }, + "id": 49931, + "nodeType": "InheritanceSpecifier", + "src": "937:8:40" + }, + { + "baseName": { + "id": 49932, + "name": "ERC1271", + "nameLocations": [ + "947:7:40" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 50822, + "src": "947:7:40" + }, + "id": 49933, + "nodeType": "InheritanceSpecifier", + "src": "947:7:40" + } + ], + "canonicalName": "CoinbaseSmartWallet", + "contractDependencies": [], + "contractKind": "contract", + "documentation": { + "id": 49925, + "nodeType": "StructuredDocumentation", + "src": "492:382:40", + "text": "@title Coinbase Smart Wallet\n @notice ERC4337-compatible smart contract wallet, based on Solady ERC4337 account implementation\n with inspiration from Alchemy's LightAccount and Daimo's DaimoAccount.\n @author Coinbase (https://github.com/coinbase/smart-wallet)\n @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/ERC4337.sol)" + }, + "fullyImplemented": true, + "internalFunctionIDs": { + "49461": 1, + "50905": 2, + "50924": 3, + "50967": 4 + }, + "linearizedBaseContracts": [ + 50482, + 50822, + 47844, + 49482, + 51215 + ], + "name": "CoinbaseSmartWallet", + "nameLocation": "883:19:40", + "scope": 50483, + "usedErrors": [ + 49399, + 49402, + 49959, + 49964, + 49969, + 50847, + 50852, + 50857, + 50862, + 50867 + ], + "usedEvents": [ + 49420, + 50874, + 50881 + ] + } + ], + "license": "MIT" + }, + "id": 40 +} \ No newline at end of file diff --git a/xmtp_id/artifact/CoinbaseSmartWalletFactory.json b/xmtp_id/artifact/CoinbaseSmartWalletFactory.json new file mode 100644 index 000000000..ea2806a34 --- /dev/null +++ b/xmtp_id/artifact/CoinbaseSmartWalletFactory.json @@ -0,0 +1,2278 @@ +{ + "abi": [ + { + "type": "constructor", + "inputs": [ + { + "name": "erc4337", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "createAccount", + "inputs": [ + { + "name": "owners", + "type": "bytes[]", + "internalType": "bytes[]" + }, + { + "name": "nonce", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "account", + "type": "address", + "internalType": "contract CoinbaseSmartWallet" + } + ], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "getAddress", + "inputs": [ + { + "name": "owners", + "type": "bytes[]", + "internalType": "bytes[]" + }, + { + "name": "nonce", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "predicted", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "implementation", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initCodeHash", + "inputs": [], + "outputs": [ + { + "name": "result", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "error", + "name": "OwnerRequired", + "inputs": [] + } + ], + "bytecode": { + "object": "0x60a06040526040516105eb3803806105eb83398101604081905261002291610033565b6001600160a01b0316608052610063565b60006020828403121561004557600080fd5b81516001600160a01b038116811461005c57600080fd5b9392505050565b60805161056061008b6000396000818160a60152818161013c015261023b01526105606000f3fe60806040526004361061003f5760003560e01c8063250b1b41146100445780633ffba36f146100815780635c60da1b14610094578063db4c545e146100c8575b600080fd5b34801561005057600080fd5b5061006461005f3660046103b7565b6100eb565b6040516001600160a01b0390911681526020015b60405180910390f35b61006461008f3660046103b7565b610111565b3480156100a057600080fd5b506100647f000000000000000000000000000000000000000000000000000000000000000081565b3480156100d457600080fd5b506100dd6101e6565b604051908152602001610078565b60006101096100f86101e6565b61010386868661027b565b306102b1565b949350505050565b600082810361013357604051633c776be160e01b815260040160405180910390fd5b60008061016b347f000000000000000000000000000000000000000000000000000000000000000061016689898961027b565b6102d3565b935091508290508115156000036101dd57604051633796f38760e11b81526001600160a01b03841690636f2de70e906101aa90899089906004016104f2565b600060405180830381600087803b1580156101c457600080fd5b505af11580156101d8573d6000803e3d6000fd5b505050505b50509392505050565b604080517fcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f360609081527f5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e207683526160096020527f0000000000000000000000000000000000000000000000000000000000000000601e5268603d3d8160223d3973600a52605f60212091909252600090915290565b600083838360405160200161029293929190610506565b6040516020818303038152906040528051906020012090509392505050565b600060ff60005350603592835260601b60015260155260556000908120915290565b6000806040517fcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f36060527f5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e207660405261600960205284601e5268603d3d8160223d3973600a52605f60212060358201523060581b815260ff8153836015820152605581209150813b61037f5783605f602188f591508161037a5763301164256000526004601cfd5b6103a5565b6001925085156103a55760003860003889865af16103a55763b12d13eb6000526004601cfd5b80604052506000606052935093915050565b6000806000604084860312156103cc57600080fd5b833567ffffffffffffffff808211156103e457600080fd5b818601915086601f8301126103f857600080fd5b81358181111561040757600080fd5b8760208260051b850101111561041c57600080fd5b6020928301989097509590910135949350505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000838385526020808601955060208560051b8301018460005b878110156104e557848303601f19018952813536889003601e1901811261049b57600080fd5b8701848101903567ffffffffffffffff8111156104b757600080fd5b8036038213156104c657600080fd5b6104d1858284610432565b9a86019a9450505090830190600101610475565b5090979650505050505050565b60208152600061010960208301848661045b565b60408152600061051a60408301858761045b565b905082602083015294935050505056fea264697066735822122098bae64e62859ac8d5ed01c4927e5fce406f632b517c86f038f06fef8355dba164736f6c63430008170033", + "sourceMap": "461:3187:41:-:0;;;1029:78;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;1076:24:41;;;461:3187;;14:290:69;84:6;137:2;125:9;116:7;112:23;108:32;105:52;;;153:1;150;143:12;105:52;179:16;;-1:-1:-1;;;;;224:31:69;;214:42;;204:70;;270:1;267;260:12;204:70;293:5;14:290;-1:-1:-1;;;14:290:69:o;:::-;461:3187:41;;;;;;;;;;;;;;;;;;;;;;", + "linkReferences": {} + }, + "deployedBytecode": { + "object": "0x60806040526004361061003f5760003560e01c8063250b1b41146100445780633ffba36f146100815780635c60da1b14610094578063db4c545e146100c8575b600080fd5b34801561005057600080fd5b5061006461005f3660046103b7565b6100eb565b6040516001600160a01b0390911681526020015b60405180910390f35b61006461008f3660046103b7565b610111565b3480156100a057600080fd5b506100647f000000000000000000000000000000000000000000000000000000000000000081565b3480156100d457600080fd5b506100dd6101e6565b604051908152602001610078565b60006101096100f86101e6565b61010386868661027b565b306102b1565b949350505050565b600082810361013357604051633c776be160e01b815260040160405180910390fd5b60008061016b347f000000000000000000000000000000000000000000000000000000000000000061016689898961027b565b6102d3565b935091508290508115156000036101dd57604051633796f38760e11b81526001600160a01b03841690636f2de70e906101aa90899089906004016104f2565b600060405180830381600087803b1580156101c457600080fd5b505af11580156101d8573d6000803e3d6000fd5b505050505b50509392505050565b604080517fcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f360609081527f5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e207683526160096020527f0000000000000000000000000000000000000000000000000000000000000000601e5268603d3d8160223d3973600a52605f60212091909252600090915290565b600083838360405160200161029293929190610506565b6040516020818303038152906040528051906020012090509392505050565b600060ff60005350603592835260601b60015260155260556000908120915290565b6000806040517fcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f36060527f5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e207660405261600960205284601e5268603d3d8160223d3973600a52605f60212060358201523060581b815260ff8153836015820152605581209150813b61037f5783605f602188f591508161037a5763301164256000526004601cfd5b6103a5565b6001925085156103a55760003860003889865af16103a55763b12d13eb6000526004601cfd5b80604052506000606052935093915050565b6000806000604084860312156103cc57600080fd5b833567ffffffffffffffff808211156103e457600080fd5b818601915086601f8301126103f857600080fd5b81358181111561040757600080fd5b8760208260051b850101111561041c57600080fd5b6020928301989097509590910135949350505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6000838385526020808601955060208560051b8301018460005b878110156104e557848303601f19018952813536889003601e1901811261049b57600080fd5b8701848101903567ffffffffffffffff8111156104b757600080fd5b8036038213156104c657600080fd5b6104d1858284610432565b9a86019a9450505090830190600101610475565b5090979650505050505050565b60208152600061010960208301848661045b565b60408152600061051a60408301858761045b565b905082602083015294935050505056fea264697066735822122098bae64e62859ac8d5ed01c4927e5fce406f632b517c86f038f06fef8355dba164736f6c63430008170033", + "sourceMap": "461:3187:41:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2672:223;;;;;;;;;;-1:-1:-1;2672:223:41;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;883:32:69;;;865:51;;853:2;838:18;2672:223:41;;;;;;;;1782:562;;;;;;:::i;:::-;;:::i;599:39::-;;;;;;;;;;;;;;;3057:139;;;;;;;;;;;;;:::i;:::-;;;1318:25:69;;;1306:2;1291:18;3057:139:41;1172:177:69;2672:223:41;2755:17;2796:92;2833:14;:12;:14::i;:::-;2849:23;2858:6;;2866:5;2849:8;:23::i;:::-;2882:4;2796:36;:92::i;:::-;2784:104;2672:223;-1:-1:-1;;;;2672:223:41:o;1782:562::-;1909:27;1956:18;;;1952:71;;1997:15;;-1:-1:-1;;;1997:15:41;;;;;;;;;;;1952:71;2034:20;2056:22;2094:87;2130:9;2141:14;2157:23;2166:6;;2174:5;2157:8;:23::i;:::-;2094:35;:87::i;:::-;2033:148;-1:-1:-1;2033:148:41;-1:-1:-1;2033:148:41;;-1:-1:-1;2261:24:41;;;2280:5;2261:24;2257:81;;2301:26;;-1:-1:-1;;;2301:26:41;;-1:-1:-1;;;;;2301:18:41;;;;;:26;;2320:6;;;;2301:26;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2257:81;1942:402;;1782:562;;;;;:::o;3057:139::-;54044:4:33;54038:11;;54109:66;54103:4;54096:80;;;54202:66;54189:80;;54295:6;-1:-1:-1;54282:20:33;3174:14:41;54322:4:33;54315:28;54369:20;54363:4;54356:34;54427:4;54421;54411:21;54445:15;;;;-1:-1:-1;54509:15:33;;;54411:21;3057:139:41:o;3491:155::-;3572:12;3624:6;;3632:5;3613:25;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;3603:36;;;;;;3596:43;;3491:155;;;;;:::o;71932:578:33:-;72062:17;72227:4;72221;72213:19;-1:-1:-1;72273:4:33;72266:18;;;72314:2;72310:17;72304:4;72297:31;72348:4;72341:18;72401:4;72395;72385:21;;;72419:15;;72385:21;71932:578::o;51105:1725::-;51228:20;51250:16;51363:4;51357:11;51428:66;51422:4;51415:80;51521:66;51515:4;51508:80;51614:6;51608:4;51601:20;51647:14;51641:4;51634:28;51688:20;51682:4;51675:34;51811:4;51805;51795:21;51788:4;51785:1;51781:12;51774:43;51848:9;51844:2;51840:18;51837:1;51830:29;51883:4;51880:1;51872:16;51943:4;51936;51933:1;51929:12;51922:26;51986:4;51983:1;51973:18;51961:30;;52056:8;52044:21;52034:324;;52128:4;52122;52116;52109:5;52101:32;52089:44;;52164:8;52154:160;;52213:10;52207:4;52200:24;52287:4;52281;52274:18;52154:160;52335:5;;52034:324;52394:1;52375:20;;52422:5;52412:26;52431:5;52412:26;52524:4;52512:10;52506:4;52494:10;52487:5;52477:8;52470:5;52465:64;52455:205;;52566:10;52560:4;52553:24;52637:4;52631;52624:18;52455:205;52722:1;52716:4;52709:15;;52786:1;52780:4;52773:15;51105:1725;;;;;;:::o;14:700:69:-;120:6;128;136;189:2;177:9;168:7;164:23;160:32;157:52;;;205:1;202;195:12;157:52;245:9;232:23;274:18;315:2;307:6;304:14;301:34;;;331:1;328;321:12;301:34;369:6;358:9;354:22;344:32;;414:7;407:4;403:2;399:13;395:27;385:55;;436:1;433;426:12;385:55;476:2;463:16;502:2;494:6;491:14;488:34;;;518:1;515;508:12;488:34;573:7;566:4;556:6;553:1;549:14;545:2;541:23;537:34;534:47;531:67;;;594:1;591;584:12;531:67;625:4;617:13;;;;649:6;;-1:-1:-1;687:20:69;;;;674:34;;14:700;-1:-1:-1;;;;14:700:69:o;1354:266::-;1442:6;1437:3;1430:19;1494:6;1487:5;1480:4;1475:3;1471:14;1458:43;-1:-1:-1;1546:1:69;1521:16;;;1539:4;1517:27;;;1510:38;;;;1602:2;1581:15;;;-1:-1:-1;;1577:29:69;1568:39;;;1564:50;;1354:266::o;1625:1047::-;1702:3;1733;1757:6;1752:3;1745:19;1783:4;1812;1807:3;1803:14;1796:21;;1870:4;1860:6;1857:1;1853:14;1846:5;1842:26;1838:37;1898:5;1921:1;1931:715;1945:6;1942:1;1939:13;1931:715;;;2010:16;;;-1:-1:-1;;2006:30:69;1994:43;;2076:20;;2151:14;2147:26;;;-1:-1:-1;;2143:40:69;2119:65;;2109:93;;2198:1;2195;2188:12;2109:93;2230:30;;2338:16;;;;2289:21;2383:18;2370:32;;2367:52;;;2415:1;2412;2405:12;2367:52;2468:8;2452:14;2448:29;2439:7;2435:43;2432:63;;;2491:1;2488;2481:12;2432:63;2516:50;2561:4;2551:8;2542:7;2516:50;:::i;:::-;2624:12;;;;2508:58;-1:-1:-1;;;2589:15:69;;;;1967:1;1960:9;1931:715;;;-1:-1:-1;2662:4:69;;1625:1047;-1:-1:-1;;;;;;;1625:1047:69:o;2677:315::-;2886:2;2875:9;2868:21;2849:4;2906:80;2982:2;2971:9;2967:18;2959:6;2951;2906:80;:::i;2997:386::-;3234:2;3223:9;3216:21;3197:4;3254:80;3330:2;3319:9;3315:18;3307:6;3299;3254:80;:::i;:::-;3246:88;;3370:6;3365:2;3354:9;3350:18;3343:34;2997:386;;;;;;:::o", + "linkReferences": {}, + "immutableReferences": { + "50492": [ + { + "start": 166, + "length": 32 + }, + { + "start": 316, + "length": 32 + }, + { + "start": 571, + "length": 32 + } + ] + } + }, + "methodIdentifiers": { + "createAccount(bytes[],uint256)": "3ffba36f", + "getAddress(bytes[],uint256)": "250b1b41", + "implementation()": "5c60da1b", + "initCodeHash()": "db4c545e" + }, + "rawMetadata": "{\"compiler\":{\"version\":\"0.8.23+commit.f704f362\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"erc4337\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"OwnerRequired\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"owners\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract CoinbaseSmartWallet\",\"name\":\"account\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"owners\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"predicted\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"initCodeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"result\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Coinbase (https://github.com/coinbase/smart-wallet)Solady (https://github.com/vectorized/solady/blob/main/src/accounts/ERC4337Factory.sol)\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"erc4337\":\"The address of the ERC-4337 implementation used to deploy new cloned accounts.\"}},\"createAccount(bytes[],uint256)\":{\"details\":\"The account is deployed behind a minimal ERC1967 proxy whose implementation points to the registered ERC-4337 `implementation`.The `owners` parameter is a set of addresses and/or public keys depending on the signature scheme used (respectively ERC-1271 or Webauthn authentication).\",\"params\":{\"nonce\":\"The nonce of the account, allowing multiple accounts with the same set of initial owners to exist.\",\"owners\":\"The initial set of owners that should be able to control the account.\"}},\"getAddress(bytes[],uint256)\":{\"params\":{\"nonce\":\"The nonce provided to `createAccount()`.\",\"owners\":\"The initial set of owners provided to `createAccount()`.\"},\"returns\":{\"predicted\":\"The predicted account deployment address.\"}},\"initCodeHash()\":{\"returns\":{\"result\":\"The initialization code hash.\"}}},\"title\":\"Coinbase Smart Wallet Factory\",\"version\":1},\"userdoc\":{\"errors\":{\"OwnerRequired()\":[{\"notice\":\"Thrown when trying to create a new `CoinbaseSmartWallet` account without any owner.\"}]},\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Factory constructor used to initialize the implementation address to use for future ERC-4337 account deployments.\"},\"createAccount(bytes[],uint256)\":{\"notice\":\"Deploys an ERC-4337 account and returns its deterministic address.\"},\"getAddress(bytes[],uint256)\":{\"notice\":\"Returns the deterministic address of the account created via `createAccount()`.\"},\"implementation()\":{\"notice\":\"Address of the ERC-4337 implementation used as implementation for new accounts.\"},\"initCodeHash()\":{\"notice\":\"Returns the initialization code hash of the account (a minimal ERC1967 proxy).\"}},\"notice\":\"CoinbaseSmartWallet factory, based on Solady's ERC4337Factory.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/CoinbaseSmartWalletFactory.sol\":\"CoinbaseSmartWalletFactory\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@openzeppelin/contracts/=lib/p256-verifier/lib/openzeppelin-contracts/contracts/\",\":FreshCryptoLib/=lib/FreshCryptoLib/solidity/src/\",\":account-abstraction/=lib/account-abstraction/contracts/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/p256-verifier/lib/openzeppelin-contracts/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts/=lib/p256-verifier/lib/openzeppelin-contracts/\",\":p256-verifier/=lib/p256-verifier/\",\":solady/=lib/solady/src/\",\":webauthn-sol/=lib/webauthn-sol/src/\"]},\"sources\":{\"lib/FreshCryptoLib/solidity/src/FCL_ecdsa.sol\":{\"keccak256\":\"0x679d2e9a655cd7e156a0cfc24de0aca88d4e0b34a8e0dfe6a599f23af092f5a2\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://db31eb84c6f854f076d2501e3d8b5a606fb4924168bdfc6fc3de84e67ed8a80d\",\"dweb:/ipfs/QmWGAmc7B4aT6Ki52uF9QmPQKWipaptit7r3JknBHjUGfe\"]},\"lib/FreshCryptoLib/solidity/src/FCL_elliptic.sol\":{\"keccak256\":\"0x097f137d52dc9bd97d6fee7426b2d6d809ad3684767df288d58ffd76f7924e5b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://30ffae5b57f2e0fcabcc1642eb7c60e1b4369151d58a78034bb372187fdffa8e\",\"dweb:/ipfs/Qma8RXPxaV52ZMuR5HaoFWqMGSAo7g2u3qG6poguDbFsL4\"]},\"lib/account-abstraction/contracts/core/Helpers.sol\":{\"keccak256\":\"0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://69643e83f68e6a13d5075c7565bfce326673b0bd98c432033c4603ea84835746\",\"dweb:/ipfs/QmSwSzjYyV7qudi5vvsmzHMG2Z4YJZxX51RRXXVCLaNcEU\"]},\"lib/account-abstraction/contracts/interfaces/UserOperation.sol\":{\"keccak256\":\"0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://6ff83c59432e733bf6304dda27cd4b0f34401917dd535e2669cc842d2d26568c\",\"dweb:/ipfs/QmPJbHU5TAjHqUTZzAcicEeG2nknmwCN43L4EW9LHbknTN\"]},\"lib/solady/src/accounts/Receiver.sol\":{\"keccak256\":\"0x9bf48dca73f428c20a0878a5a97d2d66626f835b077c012fd5b1ba6389feb2d0\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://15cb4c81e6c5b2f609e5c6ba13d3241b5c017f9997cab5cebc0572c2dd7f34da\",\"dweb:/ipfs/QmQr7sWaqW27XhyCVGx4wED1rMmFKGhSHPjSGVLz45dbeD\"]},\"lib/solady/src/utils/Base64.sol\":{\"keccak256\":\"0x07dcf983a86bc961e4cc0b57a2cfc3e46b20a50fed9b2092c7497e5fe3715a93\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://65c6c0a8a29cfc5b757abe84635c83e62a177a48c2ad0be24de6b0fba1a60ea2\",\"dweb:/ipfs/QmYuYwxHiBoUt6vaLTLbs2bZamRzqrTfA4BsNZ1TApTfrm\"]},\"lib/solady/src/utils/LibClone.sol\":{\"keccak256\":\"0x6ba469171b7d79d0e2bb3999210353e89dced6c85ac2c06bb58e2ef09ac48f26\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://778a87e2973196e0f2f7b716cd28646a901290998f73c053c984fac052ca1620\",\"dweb:/ipfs/QmcYg5fQyCHw7sZHmdHZtGwKEguthWjNd87oU9DWHtCLsN\"]},\"lib/solady/src/utils/LibString.sol\":{\"keccak256\":\"0x4fc555fe1ceb29162b143ce1564ac936099071c853065efc289f6c30c712f125\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8f9d3fdb7c03ed63323ae27e0176e080f27ca453f91bacb73f8d59b09da94cf7\",\"dweb:/ipfs/Qmcix9BzxupvYYLX3t8wf4Wsf1yp1b2q65CJb5agaFPtQ9\"]},\"lib/solady/src/utils/SignatureCheckerLib.sol\":{\"keccak256\":\"0x7a7acc59723ed291f24d9a2ed019109c8be69f32701f35f8a61dc7fff6652379\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7bab15a03dfca0567d7472933ee4e776fc21f9dfb6c4dbc06934fa75eceeff5e\",\"dweb:/ipfs/QmPUuKsRwpZXz15DpsoJMMPN9DtZiRvMfwjqJScxkppNsP\"]},\"lib/solady/src/utils/UUPSUpgradeable.sol\":{\"keccak256\":\"0x0f4da34fe99caf063e6d3a09d0a4ce783fdcd955b475d46ba00be48f7fda348f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5f8e8e92e7b781a8b0d3fdb720915964f46354395a806e87aa7d0a355a024a83\",\"dweb:/ipfs/QmdDmVgUstEYpVQn97jDdaACoqoqiEvcXjxtEhC8b6vmFC\"]},\"lib/webauthn-sol/src/WebAuthn.sol\":{\"keccak256\":\"0x2441d1c9cd3ed38f53ad8920db4ccf1dfc4e081f91138432fd1a91f9a94d46c7\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f6613c0ab26c03824b4db51d5d00a7fd665599ec1c4a20cc559c8fa19e885294\",\"dweb:/ipfs/QmaWPGM1ogH4nrxFYReaBoB7kA7AWy176kmLXFAZVEDTQp\"]},\"src/CoinbaseSmartWallet.sol\":{\"keccak256\":\"0x708d7985699d68185e35ca3359b8d973419725d9127d162b78e1131c000e92ec\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://95b890219a1067a9e43df42b5f5bb6e0d1748ade87d9714d204c4720b6febcd2\",\"dweb:/ipfs/QmPFAuxYAGhxdZqfCNbpa3Vc587fMBhFLQA1BtmCppVhYf\"]},\"src/CoinbaseSmartWalletFactory.sol\":{\"keccak256\":\"0xacedcda501e79257e7c73808e92c582be98f5648e7aa077da1c87c0dce3ca075\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://900f4c4fe156d307d1f6676d82779b7b821f96bd5600115e5d533c77f443dfee\",\"dweb:/ipfs/QmUM9GCLESCcZkJbLvFuDTrcedWMfZvgLSmpspgbqVErtw\"]},\"src/ERC1271.sol\":{\"keccak256\":\"0x670872019ca67ef9156017aaf0ec80c6be75258f3bcd6a21df270c45f8af3871\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://fad973b58b631f72cf53f54caf736f8100942d51c632f1c5c486d5b7228d4593\",\"dweb:/ipfs/QmaxTVxCvEwe1cBoxw3TNtssBaFejnjcACdymZrYhgEeSj\"]},\"src/MultiOwnable.sol\":{\"keccak256\":\"0x9c0a57f9fd802e3ff10383257b10bea2637a01bda9986fc18a06246155fdbe6e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://0efe6691756a2bb0357caa1bdbd0dcc08407cd30ded5efee3fdffa4f99885c8a\",\"dweb:/ipfs/QmVz9YQaUsH4NLv47JDcVQCmUWstrgzwTTEGv7cNQTjXyg\"]}},\"version\":1}", + "metadata": { + "compiler": { + "version": "0.8.23+commit.f704f362" + }, + "language": "Solidity", + "output": { + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "erc4337", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [], + "type": "error", + "name": "OwnerRequired" + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "owners", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function", + "name": "createAccount", + "outputs": [ + { + "internalType": "contract CoinbaseSmartWallet", + "name": "account", + "type": "address" + } + ] + }, + { + "inputs": [ + { + "internalType": "bytes[]", + "name": "owners", + "type": "bytes[]" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function", + "name": "getAddress", + "outputs": [ + { + "internalType": "address", + "name": "predicted", + "type": "address" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ] + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "initCodeHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "result", + "type": "bytes32" + } + ] + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "constructor": { + "params": { + "erc4337": "The address of the ERC-4337 implementation used to deploy new cloned accounts." + } + }, + "createAccount(bytes[],uint256)": { + "details": "The account is deployed behind a minimal ERC1967 proxy whose implementation points to the registered ERC-4337 `implementation`.The `owners` parameter is a set of addresses and/or public keys depending on the signature scheme used (respectively ERC-1271 or Webauthn authentication).", + "params": { + "nonce": "The nonce of the account, allowing multiple accounts with the same set of initial owners to exist.", + "owners": "The initial set of owners that should be able to control the account." + } + }, + "getAddress(bytes[],uint256)": { + "params": { + "nonce": "The nonce provided to `createAccount()`.", + "owners": "The initial set of owners provided to `createAccount()`." + }, + "returns": { + "predicted": "The predicted account deployment address." + } + }, + "initCodeHash()": { + "returns": { + "result": "The initialization code hash." + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Factory constructor used to initialize the implementation address to use for future ERC-4337 account deployments." + }, + "createAccount(bytes[],uint256)": { + "notice": "Deploys an ERC-4337 account and returns its deterministic address." + }, + "getAddress(bytes[],uint256)": { + "notice": "Returns the deterministic address of the account created via `createAccount()`." + }, + "implementation()": { + "notice": "Address of the ERC-4337 implementation used as implementation for new accounts." + }, + "initCodeHash()": { + "notice": "Returns the initialization code hash of the account (a minimal ERC1967 proxy)." + } + }, + "version": 1 + } + }, + "settings": { + "remappings": [ + "@openzeppelin/contracts/=lib/p256-verifier/lib/openzeppelin-contracts/contracts/", + "FreshCryptoLib/=lib/FreshCryptoLib/solidity/src/", + "account-abstraction/=lib/account-abstraction/contracts/", + "ds-test/=lib/forge-std/lib/ds-test/src/", + "erc4626-tests/=lib/p256-verifier/lib/openzeppelin-contracts/lib/erc4626-tests/", + "forge-std/=lib/forge-std/src/", + "openzeppelin-contracts/=lib/p256-verifier/lib/openzeppelin-contracts/", + "p256-verifier/=lib/p256-verifier/", + "solady/=lib/solady/src/", + "webauthn-sol/=lib/webauthn-sol/src/" + ], + "optimizer": { + "enabled": true, + "runs": 200 + }, + "metadata": { + "bytecodeHash": "ipfs" + }, + "compilationTarget": { + "src/CoinbaseSmartWalletFactory.sol": "CoinbaseSmartWalletFactory" + }, + "evmVersion": "paris", + "libraries": {} + }, + "sources": { + "lib/FreshCryptoLib/solidity/src/FCL_ecdsa.sol": { + "keccak256": "0x679d2e9a655cd7e156a0cfc24de0aca88d4e0b34a8e0dfe6a599f23af092f5a2", + "urls": [ + "bzz-raw://db31eb84c6f854f076d2501e3d8b5a606fb4924168bdfc6fc3de84e67ed8a80d", + "dweb:/ipfs/QmWGAmc7B4aT6Ki52uF9QmPQKWipaptit7r3JknBHjUGfe" + ], + "license": "MIT" + }, + "lib/FreshCryptoLib/solidity/src/FCL_elliptic.sol": { + "keccak256": "0x097f137d52dc9bd97d6fee7426b2d6d809ad3684767df288d58ffd76f7924e5b", + "urls": [ + "bzz-raw://30ffae5b57f2e0fcabcc1642eb7c60e1b4369151d58a78034bb372187fdffa8e", + "dweb:/ipfs/Qma8RXPxaV52ZMuR5HaoFWqMGSAo7g2u3qG6poguDbFsL4" + ], + "license": "MIT" + }, + "lib/account-abstraction/contracts/core/Helpers.sol": { + "keccak256": "0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a", + "urls": [ + "bzz-raw://69643e83f68e6a13d5075c7565bfce326673b0bd98c432033c4603ea84835746", + "dweb:/ipfs/QmSwSzjYyV7qudi5vvsmzHMG2Z4YJZxX51RRXXVCLaNcEU" + ], + "license": "GPL-3.0" + }, + "lib/account-abstraction/contracts/interfaces/UserOperation.sol": { + "keccak256": "0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c", + "urls": [ + "bzz-raw://6ff83c59432e733bf6304dda27cd4b0f34401917dd535e2669cc842d2d26568c", + "dweb:/ipfs/QmPJbHU5TAjHqUTZzAcicEeG2nknmwCN43L4EW9LHbknTN" + ], + "license": "GPL-3.0" + }, + "lib/solady/src/accounts/Receiver.sol": { + "keccak256": "0x9bf48dca73f428c20a0878a5a97d2d66626f835b077c012fd5b1ba6389feb2d0", + "urls": [ + "bzz-raw://15cb4c81e6c5b2f609e5c6ba13d3241b5c017f9997cab5cebc0572c2dd7f34da", + "dweb:/ipfs/QmQr7sWaqW27XhyCVGx4wED1rMmFKGhSHPjSGVLz45dbeD" + ], + "license": "MIT" + }, + "lib/solady/src/utils/Base64.sol": { + "keccak256": "0x07dcf983a86bc961e4cc0b57a2cfc3e46b20a50fed9b2092c7497e5fe3715a93", + "urls": [ + "bzz-raw://65c6c0a8a29cfc5b757abe84635c83e62a177a48c2ad0be24de6b0fba1a60ea2", + "dweb:/ipfs/QmYuYwxHiBoUt6vaLTLbs2bZamRzqrTfA4BsNZ1TApTfrm" + ], + "license": "MIT" + }, + "lib/solady/src/utils/LibClone.sol": { + "keccak256": "0x6ba469171b7d79d0e2bb3999210353e89dced6c85ac2c06bb58e2ef09ac48f26", + "urls": [ + "bzz-raw://778a87e2973196e0f2f7b716cd28646a901290998f73c053c984fac052ca1620", + "dweb:/ipfs/QmcYg5fQyCHw7sZHmdHZtGwKEguthWjNd87oU9DWHtCLsN" + ], + "license": "MIT" + }, + "lib/solady/src/utils/LibString.sol": { + "keccak256": "0x4fc555fe1ceb29162b143ce1564ac936099071c853065efc289f6c30c712f125", + "urls": [ + "bzz-raw://8f9d3fdb7c03ed63323ae27e0176e080f27ca453f91bacb73f8d59b09da94cf7", + "dweb:/ipfs/Qmcix9BzxupvYYLX3t8wf4Wsf1yp1b2q65CJb5agaFPtQ9" + ], + "license": "MIT" + }, + "lib/solady/src/utils/SignatureCheckerLib.sol": { + "keccak256": "0x7a7acc59723ed291f24d9a2ed019109c8be69f32701f35f8a61dc7fff6652379", + "urls": [ + "bzz-raw://7bab15a03dfca0567d7472933ee4e776fc21f9dfb6c4dbc06934fa75eceeff5e", + "dweb:/ipfs/QmPUuKsRwpZXz15DpsoJMMPN9DtZiRvMfwjqJScxkppNsP" + ], + "license": "MIT" + }, + "lib/solady/src/utils/UUPSUpgradeable.sol": { + "keccak256": "0x0f4da34fe99caf063e6d3a09d0a4ce783fdcd955b475d46ba00be48f7fda348f", + "urls": [ + "bzz-raw://5f8e8e92e7b781a8b0d3fdb720915964f46354395a806e87aa7d0a355a024a83", + "dweb:/ipfs/QmdDmVgUstEYpVQn97jDdaACoqoqiEvcXjxtEhC8b6vmFC" + ], + "license": "MIT" + }, + "lib/webauthn-sol/src/WebAuthn.sol": { + "keccak256": "0x2441d1c9cd3ed38f53ad8920db4ccf1dfc4e081f91138432fd1a91f9a94d46c7", + "urls": [ + "bzz-raw://f6613c0ab26c03824b4db51d5d00a7fd665599ec1c4a20cc559c8fa19e885294", + "dweb:/ipfs/QmaWPGM1ogH4nrxFYReaBoB7kA7AWy176kmLXFAZVEDTQp" + ], + "license": "MIT" + }, + "src/CoinbaseSmartWallet.sol": { + "keccak256": "0x708d7985699d68185e35ca3359b8d973419725d9127d162b78e1131c000e92ec", + "urls": [ + "bzz-raw://95b890219a1067a9e43df42b5f5bb6e0d1748ade87d9714d204c4720b6febcd2", + "dweb:/ipfs/QmPFAuxYAGhxdZqfCNbpa3Vc587fMBhFLQA1BtmCppVhYf" + ], + "license": "MIT" + }, + "src/CoinbaseSmartWalletFactory.sol": { + "keccak256": "0xacedcda501e79257e7c73808e92c582be98f5648e7aa077da1c87c0dce3ca075", + "urls": [ + "bzz-raw://900f4c4fe156d307d1f6676d82779b7b821f96bd5600115e5d533c77f443dfee", + "dweb:/ipfs/QmUM9GCLESCcZkJbLvFuDTrcedWMfZvgLSmpspgbqVErtw" + ], + "license": "MIT" + }, + "src/ERC1271.sol": { + "keccak256": "0x670872019ca67ef9156017aaf0ec80c6be75258f3bcd6a21df270c45f8af3871", + "urls": [ + "bzz-raw://fad973b58b631f72cf53f54caf736f8100942d51c632f1c5c486d5b7228d4593", + "dweb:/ipfs/QmaxTVxCvEwe1cBoxw3TNtssBaFejnjcACdymZrYhgEeSj" + ], + "license": "MIT" + }, + "src/MultiOwnable.sol": { + "keccak256": "0x9c0a57f9fd802e3ff10383257b10bea2637a01bda9986fc18a06246155fdbe6e", + "urls": [ + "bzz-raw://0efe6691756a2bb0357caa1bdbd0dcc08407cd30ded5efee3fdffa4f99885c8a", + "dweb:/ipfs/QmVz9YQaUsH4NLv47JDcVQCmUWstrgzwTTEGv7cNQTjXyg" + ], + "license": "MIT" + } + }, + "version": 1 + }, + "ast": { + "absolutePath": "src/CoinbaseSmartWalletFactory.sol", + "id": 50629, + "exportedSymbols": { + "CoinbaseSmartWallet": [ + 50482 + ], + "CoinbaseSmartWalletFactory": [ + 50628 + ], + "LibClone": [ + 48580 + ] + }, + "nodeType": "SourceUnit", + "src": "32:3617:41", + "nodes": [ + { + "id": 50484, + "nodeType": "PragmaDirective", + "src": "32:23:41", + "nodes": [], + "literals": [ + "solidity", + "^", + "0.8", + ".4" + ] + }, + { + "id": 50486, + "nodeType": "ImportDirective", + "src": "57:51:41", + "nodes": [], + "absolutePath": "lib/solady/src/utils/LibClone.sol", + "file": "solady/utils/LibClone.sol", + "nameLocation": "-1:-1:-1", + "scope": 50629, + "sourceUnit": 48581, + "symbolAliases": [ + { + "foreign": { + "id": 50485, + "name": "LibClone", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 48580, + "src": "65:8:41", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 50488, + "nodeType": "ImportDirective", + "src": "109:62:41", + "nodes": [], + "absolutePath": "src/CoinbaseSmartWallet.sol", + "file": "./CoinbaseSmartWallet.sol", + "nameLocation": "-1:-1:-1", + "scope": 50629, + "sourceUnit": 50483, + "symbolAliases": [ + { + "foreign": { + "id": 50487, + "name": "CoinbaseSmartWallet", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50482, + "src": "117:19:41", + "typeDescriptions": {} + }, + "nameLocation": "-1:-1:-1" + } + ], + "unitAlias": "" + }, + { + "id": 50628, + "nodeType": "ContractDefinition", + "src": "461:3187:41", + "nodes": [ + { + "id": 50492, + "nodeType": "VariableDeclaration", + "src": "599:39:41", + "nodes": [], + "constant": false, + "documentation": { + "id": 50490, + "nodeType": "StructuredDocumentation", + "src": "503:91:41", + "text": "@notice Address of the ERC-4337 implementation used as implementation for new accounts." + }, + "functionSelector": "5c60da1b", + "mutability": "immutable", + "name": "implementation", + "nameLocation": "624:14:41", + "scope": 50628, + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 50491, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "599:7:41", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "public" + }, + { + "id": 50495, + "nodeType": "ErrorDefinition", + "src": "745:22:41", + "nodes": [], + "documentation": { + "id": 50493, + "nodeType": "StructuredDocumentation", + "src": "645:95:41", + "text": "@notice Thrown when trying to create a new `CoinbaseSmartWallet` account without any owner." + }, + "errorSelector": "3c776be1", + "name": "OwnerRequired", + "nameLocation": "751:13:41", + "parameters": { + "id": 50494, + "nodeType": "ParameterList", + "parameters": [], + "src": "764:2:41" + } + }, + { + "id": 50506, + "nodeType": "FunctionDefinition", + "src": "1029:78:41", + "nodes": [], + "body": { + "id": 50505, + "nodeType": "Block", + "src": "1066:41:41", + "nodes": [], + "statements": [ + { + "expression": { + "id": 50503, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 50501, + "name": "implementation", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50492, + "src": "1076:14:41", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 50502, + "name": "erc4337", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50498, + "src": "1093:7:41", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "1076:24:41", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 50504, + "nodeType": "ExpressionStatement", + "src": "1076:24:41" + } + ] + }, + "documentation": { + "id": 50496, + "nodeType": "StructuredDocumentation", + "src": "773:251:41", + "text": "@notice Factory constructor used to initialize the implementation address to use for future\n ERC-4337 account deployments.\n @param erc4337 The address of the ERC-4337 implementation used to deploy new cloned accounts." + }, + "implemented": true, + "kind": "constructor", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "parameters": { + "id": 50499, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50498, + "mutability": "mutable", + "name": "erc4337", + "nameLocation": "1049:7:41", + "nodeType": "VariableDeclaration", + "scope": 50506, + "src": "1041:15:41", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 50497, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1041:7:41", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "1040:17:41" + }, + "returnParameters": { + "id": 50500, + "nodeType": "ParameterList", + "parameters": [], + "src": "1066:0:41" + }, + "scope": 50628, + "stateMutability": "payable", + "virtual": false, + "visibility": "public" + }, + { + "id": 50563, + "nodeType": "FunctionDefinition", + "src": "1782:562:41", + "nodes": [], + "body": { + "id": 50562, + "nodeType": "Block", + "src": "1942:402:41", + "nodes": [], + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 50521, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 50518, + "name": "owners", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50510, + "src": "1956:6:41", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + } + }, + "id": 50519, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1963:6:41", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "1956:13:41", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "30", + "id": 50520, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1973:1:41", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "1956:18:41", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50526, + "nodeType": "IfStatement", + "src": "1952:71:41", + "trueBody": { + "id": 50525, + "nodeType": "Block", + "src": "1976:47:41", + "statements": [ + { + "errorCall": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 50522, + "name": "OwnerRequired", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50495, + "src": "1997:13:41", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 50523, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1997:15:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50524, + "nodeType": "RevertStatement", + "src": "1990:22:41" + } + ] + } + }, + { + "assignments": [ + 50528, + 50530 + ], + "declarations": [ + { + "constant": false, + "id": 50528, + "mutability": "mutable", + "name": "alreadyDeployed", + "nameLocation": "2039:15:41", + "nodeType": "VariableDeclaration", + "scope": 50562, + "src": "2034:20:41", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 50527, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2034:4:41", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50530, + "mutability": "mutable", + "name": "accountAddress", + "nameLocation": "2064:14:41", + "nodeType": "VariableDeclaration", + "scope": 50562, + "src": "2056:22:41", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 50529, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2056:7:41", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "id": 50541, + "initialValue": { + "arguments": [ + { + "expression": { + "id": 50533, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -15, + "src": "2130:3:41", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 50534, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2134:5:41", + "memberName": "value", + "nodeType": "MemberAccess", + "src": "2130:9:41", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 50535, + "name": "implementation", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50492, + "src": "2141:14:41", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "arguments": [ + { + "id": 50537, + "name": "owners", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50510, + "src": "2166:6:41", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + } + }, + { + "id": 50538, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50512, + "src": "2174:5:41", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 50536, + "name": "_getSalt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50627, + "src": "2157:8:41", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr_$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (bytes calldata[] calldata,uint256) pure returns (bytes32)" + } + }, + "id": 50539, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2157:23:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 50531, + "name": "LibClone", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 48580, + "src": "2094:8:41", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibClone_$48580_$", + "typeString": "type(library LibClone)" + } + }, + "id": 50532, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2103:26:41", + "memberName": "createDeterministicERC1967", + "nodeType": "MemberAccess", + "referencedDeclaration": 48365, + "src": "2094:35:41", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_address_$_t_bytes32_$returns$_t_bool_$_t_address_$", + "typeString": "function (uint256,address,bytes32) returns (bool,address)" + } + }, + "id": 50540, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2094:87:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bool_$_t_address_$", + "typeString": "tuple(bool,address)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2033:148:41" + }, + { + "expression": { + "id": 50549, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 50542, + "name": "account", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50516, + "src": "2192:7:41", + "typeDescriptions": { + "typeIdentifier": "t_contract$_CoinbaseSmartWallet_$50482", + "typeString": "contract CoinbaseSmartWallet" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "arguments": [ + { + "id": 50546, + "name": "accountAddress", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50530, + "src": "2230:14:41", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 50545, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "2222:8:41", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_payable_$", + "typeString": "type(address payable)" + }, + "typeName": { + "id": 50544, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2222:8:41", + "stateMutability": "payable", + "typeDescriptions": {} + } + }, + "id": 50547, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2222:23:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + ], + "id": 50543, + "name": "CoinbaseSmartWallet", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50482, + "src": "2202:19:41", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_CoinbaseSmartWallet_$50482_$", + "typeString": "type(contract CoinbaseSmartWallet)" + } + }, + "id": 50548, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2202:44:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_contract$_CoinbaseSmartWallet_$50482", + "typeString": "contract CoinbaseSmartWallet" + } + }, + "src": "2192:54:41", + "typeDescriptions": { + "typeIdentifier": "t_contract$_CoinbaseSmartWallet_$50482", + "typeString": "contract CoinbaseSmartWallet" + } + }, + "id": 50550, + "nodeType": "ExpressionStatement", + "src": "2192:54:41" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 50553, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 50551, + "name": "alreadyDeployed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50528, + "src": "2261:15:41", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "66616c7365", + "id": 50552, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2280:5:41", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "src": "2261:24:41", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 50561, + "nodeType": "IfStatement", + "src": "2257:81:41", + "trueBody": { + "id": 50560, + "nodeType": "Block", + "src": "2287:51:41", + "statements": [ + { + "expression": { + "arguments": [ + { + "id": 50557, + "name": "owners", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50510, + "src": "2320:6:41", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + } + ], + "expression": { + "id": 50554, + "name": "account", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50516, + "src": "2301:7:41", + "typeDescriptions": { + "typeIdentifier": "t_contract$_CoinbaseSmartWallet_$50482", + "typeString": "contract CoinbaseSmartWallet" + } + }, + "id": 50556, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2309:10:41", + "memberName": "initialize", + "nodeType": "MemberAccess", + "referencedDeclaration": 50059, + "src": "2301:18:41", + "typeDescriptions": { + "typeIdentifier": "t_function_external_payable$_t_array$_t_bytes_memory_ptr_$dyn_memory_ptr_$returns$__$", + "typeString": "function (bytes memory[] memory) payable external" + } + }, + "id": 50558, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2301:26:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 50559, + "nodeType": "ExpressionStatement", + "src": "2301:26:41" + } + ] + } + } + ] + }, + "documentation": { + "id": 50507, + "nodeType": "StructuredDocumentation", + "src": "1113:664:41", + "text": "@notice Deploys an ERC-4337 account and returns its deterministic address.\n @dev The account is deployed behind a minimal ERC1967 proxy whose implementation points to\n the registered ERC-4337 `implementation`.\n @dev The `owners` parameter is a set of addresses and/or public keys depending on the signature\n scheme used (respectively ERC-1271 or Webauthn authentication).\n @param owners The initial set of owners that should be able to control the account.\n @param nonce The nonce of the account, allowing multiple accounts with the same set of initial\n owners to exist." + }, + "functionSelector": "3ffba36f", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "createAccount", + "nameLocation": "1791:13:41", + "parameters": { + "id": 50513, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50510, + "mutability": "mutable", + "name": "owners", + "nameLocation": "1822:6:41", + "nodeType": "VariableDeclaration", + "scope": 50563, + "src": "1805:23:41", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes[]" + }, + "typeName": { + "baseType": { + "id": 50508, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1805:5:41", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "id": 50509, + "nodeType": "ArrayTypeName", + "src": "1805:7:41", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_storage_$dyn_storage_ptr", + "typeString": "bytes[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50512, + "mutability": "mutable", + "name": "nonce", + "nameLocation": "1838:5:41", + "nodeType": "VariableDeclaration", + "scope": 50563, + "src": "1830:13:41", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 50511, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1830:7:41", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1804:40:41" + }, + "returnParameters": { + "id": 50517, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50516, + "mutability": "mutable", + "name": "account", + "nameLocation": "1929:7:41", + "nodeType": "VariableDeclaration", + "scope": 50563, + "src": "1909:27:41", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_contract$_CoinbaseSmartWallet_$50482", + "typeString": "contract CoinbaseSmartWallet" + }, + "typeName": { + "id": 50515, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 50514, + "name": "CoinbaseSmartWallet", + "nameLocations": [ + "1909:19:41" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 50482, + "src": "1909:19:41" + }, + "referencedDeclaration": 50482, + "src": "1909:19:41", + "typeDescriptions": { + "typeIdentifier": "t_contract$_CoinbaseSmartWallet_$50482", + "typeString": "contract CoinbaseSmartWallet" + } + }, + "visibility": "internal" + } + ], + "src": "1908:29:41" + }, + "scope": 50628, + "stateMutability": "payable", + "virtual": true, + "visibility": "public" + }, + { + "id": 50591, + "nodeType": "FunctionDefinition", + "src": "2672:223:41", + "nodes": [], + "body": { + "id": 50590, + "nodeType": "Block", + "src": "2774:121:41", + "nodes": [], + "statements": [ + { + "expression": { + "id": 50588, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 50574, + "name": "predicted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50572, + "src": "2784:9:41", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 50577, + "name": "initCodeHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50605, + "src": "2833:12:41", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$__$returns$_t_bytes32_$", + "typeString": "function () view returns (bytes32)" + } + }, + "id": 50578, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2833:14:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [ + { + "id": 50580, + "name": "owners", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50567, + "src": "2858:6:41", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + } + }, + { + "id": 50581, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50569, + "src": "2866:5:41", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 50579, + "name": "_getSalt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50627, + "src": "2849:8:41", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr_$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (bytes calldata[] calldata,uint256) pure returns (bytes32)" + } + }, + "id": 50582, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2849:23:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [ + { + "id": 50585, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -28, + "src": "2882:4:41", + "typeDescriptions": { + "typeIdentifier": "t_contract$_CoinbaseSmartWalletFactory_$50628", + "typeString": "contract CoinbaseSmartWalletFactory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_CoinbaseSmartWalletFactory_$50628", + "typeString": "contract CoinbaseSmartWalletFactory" + } + ], + "id": 50584, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "2874:7:41", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 50583, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2874:7:41", + "typeDescriptions": {} + } + }, + "id": 50586, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2874:13:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "id": 50575, + "name": "LibClone", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 48580, + "src": "2796:8:41", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibClone_$48580_$", + "typeString": "type(library LibClone)" + } + }, + "id": 50576, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2805:27:41", + "memberName": "predictDeterministicAddress", + "nodeType": "MemberAccess", + "referencedDeclaration": 48569, + "src": "2796:36:41", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$_t_address_$returns$_t_address_$", + "typeString": "function (bytes32,bytes32,address) pure returns (address)" + } + }, + "id": 50587, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2796:92:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "2784:104:41", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 50589, + "nodeType": "ExpressionStatement", + "src": "2784:104:41" + } + ] + }, + "documentation": { + "id": 50564, + "nodeType": "StructuredDocumentation", + "src": "2350:317:41", + "text": "@notice Returns the deterministic address of the account created via `createAccount()`.\n @param owners The initial set of owners provided to `createAccount()`.\n @param nonce The nonce provided to `createAccount()`.\n @return predicted The predicted account deployment address." + }, + "functionSelector": "250b1b41", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "getAddress", + "nameLocation": "2681:10:41", + "parameters": { + "id": 50570, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50567, + "mutability": "mutable", + "name": "owners", + "nameLocation": "2709:6:41", + "nodeType": "VariableDeclaration", + "scope": 50591, + "src": "2692:23:41", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes[]" + }, + "typeName": { + "baseType": { + "id": 50565, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "2692:5:41", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "id": 50566, + "nodeType": "ArrayTypeName", + "src": "2692:7:41", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_storage_$dyn_storage_ptr", + "typeString": "bytes[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50569, + "mutability": "mutable", + "name": "nonce", + "nameLocation": "2725:5:41", + "nodeType": "VariableDeclaration", + "scope": 50591, + "src": "2717:13:41", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 50568, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2717:7:41", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2691:40:41" + }, + "returnParameters": { + "id": 50573, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50572, + "mutability": "mutable", + "name": "predicted", + "nameLocation": "2763:9:41", + "nodeType": "VariableDeclaration", + "scope": 50591, + "src": "2755:17:41", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 50571, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2755:7:41", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "2754:19:41" + }, + "scope": 50628, + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "id": 50605, + "nodeType": "FunctionDefinition", + "src": "3057:139:41", + "nodes": [], + "body": { + "id": 50604, + "nodeType": "Block", + "src": "3126:70:41", + "nodes": [], + "statements": [ + { + "expression": { + "id": 50602, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 50597, + "name": "result", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50595, + "src": "3136:6:41", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 50600, + "name": "implementation", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50492, + "src": "3174:14:41", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "expression": { + "id": 50598, + "name": "LibClone", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 48580, + "src": "3145:8:41", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibClone_$48580_$", + "typeString": "type(library LibClone)" + } + }, + "id": 50599, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3154:19:41", + "memberName": "initCodeHashERC1967", + "nodeType": "MemberAccess", + "referencedDeclaration": 48385, + "src": "3145:28:41", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_address_$returns$_t_bytes32_$", + "typeString": "function (address) pure returns (bytes32)" + } + }, + "id": 50601, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3145:44:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "3136:53:41", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 50603, + "nodeType": "ExpressionStatement", + "src": "3136:53:41" + } + ] + }, + "documentation": { + "id": 50592, + "nodeType": "StructuredDocumentation", + "src": "2901:151:41", + "text": "@notice Returns the initialization code hash of the account (a minimal ERC1967 proxy).\n @return result The initialization code hash." + }, + "functionSelector": "db4c545e", + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "initCodeHash", + "nameLocation": "3066:12:41", + "parameters": { + "id": 50593, + "nodeType": "ParameterList", + "parameters": [], + "src": "3078:2:41" + }, + "returnParameters": { + "id": 50596, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50595, + "mutability": "mutable", + "name": "result", + "nameLocation": "3118:6:41", + "nodeType": "VariableDeclaration", + "scope": 50605, + "src": "3110:14:41", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 50594, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3110:7:41", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "3109:16:41" + }, + "scope": 50628, + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "id": 50627, + "nodeType": "FunctionDefinition", + "src": "3491:155:41", + "nodes": [], + "body": { + "id": 50626, + "nodeType": "Block", + "src": "3586:60:41", + "nodes": [], + "statements": [ + { + "expression": { + "id": 50624, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 50616, + "name": "salt", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50614, + "src": "3596:4:41", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "arguments": [ + { + "id": 50620, + "name": "owners", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50609, + "src": "3624:6:41", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + } + }, + { + "id": 50621, + "name": "nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 50611, + "src": "3632:5:41", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes calldata[] calldata" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 50618, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -1, + "src": "3613:3:41", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 50619, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "3617:6:41", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "3613:10:41", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 50622, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3613:25:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 50617, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": -8, + "src": "3603:9:41", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 50623, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3603:36:41", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "3596:43:41", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 50625, + "nodeType": "ExpressionStatement", + "src": "3596:43:41" + } + ] + }, + "documentation": { + "id": 50606, + "nodeType": "StructuredDocumentation", + "src": "3202:284:41", + "text": "@notice Returns the deterministic salt for a specific set of `owners` and `nonce`.\n @param owners The initial set of owners provided to `createAccount()`.\n @param nonce The nonce provided to `createAccount()`.\n @return salt The computed salt." + }, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_getSalt", + "nameLocation": "3500:8:41", + "parameters": { + "id": 50612, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50609, + "mutability": "mutable", + "name": "owners", + "nameLocation": "3526:6:41", + "nodeType": "VariableDeclaration", + "scope": 50627, + "src": "3509:23:41", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_calldata_ptr_$dyn_calldata_ptr", + "typeString": "bytes[]" + }, + "typeName": { + "baseType": { + "id": 50607, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3509:5:41", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "id": 50608, + "nodeType": "ArrayTypeName", + "src": "3509:7:41", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_bytes_storage_$dyn_storage_ptr", + "typeString": "bytes[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 50611, + "mutability": "mutable", + "name": "nonce", + "nameLocation": "3542:5:41", + "nodeType": "VariableDeclaration", + "scope": 50627, + "src": "3534:13:41", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 50610, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3534:7:41", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3508:40:41" + }, + "returnParameters": { + "id": 50615, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 50614, + "mutability": "mutable", + "name": "salt", + "nameLocation": "3580:4:41", + "nodeType": "VariableDeclaration", + "scope": 50627, + "src": "3572:12:41", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 50613, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3572:7:41", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "3571:14:41" + }, + "scope": 50628, + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + } + ], + "abstract": false, + "baseContracts": [], + "canonicalName": "CoinbaseSmartWalletFactory", + "contractDependencies": [], + "contractKind": "contract", + "documentation": { + "id": 50489, + "nodeType": "StructuredDocumentation", + "src": "173:288:41", + "text": "@title Coinbase Smart Wallet Factory\n @notice CoinbaseSmartWallet factory, based on Solady's ERC4337Factory.\n @author Coinbase (https://github.com/coinbase/smart-wallet)\n @author Solady (https://github.com/vectorized/solady/blob/main/src/accounts/ERC4337Factory.sol)" + }, + "fullyImplemented": true, + "linearizedBaseContracts": [ + 50628 + ], + "name": "CoinbaseSmartWalletFactory", + "nameLocation": "470:26:41", + "scope": 50629, + "usedErrors": [ + 50495 + ], + "usedEvents": [] + } + ], + "license": "MIT" + }, + "id": 41 +} \ No newline at end of file diff --git a/xmtp_id/src/associations/association_log.rs b/xmtp_id/src/associations/association_log.rs new file mode 100644 index 000000000..d0c8dde72 --- /dev/null +++ b/xmtp_id/src/associations/association_log.rs @@ -0,0 +1,394 @@ +use super::hashes::generate_inbox_id; +use super::member::{Member, MemberIdentifier, MemberKind}; +use super::signature::{Signature, SignatureError, SignatureKind}; +use super::state::AssociationState; + +use thiserror::Error; + +#[derive(Debug, Error, PartialEq)] +pub enum AssociationError { + #[error("Error creating association {0}")] + Generic(String), + #[error("Multiple create operations detected")] + MultipleCreate, + #[error("XID not yet created")] + NotCreated, + #[error("Signature validation failed {0}")] + Signature(#[from] SignatureError), + #[error("Member of kind {0} not allowed to add {1}")] + MemberNotAllowed(String, String), + #[error("Missing existing member")] + MissingExistingMember, + #[error("Legacy key is only allowed to be associated using a legacy signature with nonce 0")] + LegacySignatureReuse, + #[error("The new member identifier does not match the signer")] + NewMemberIdSignatureMismatch, + #[error("Signature not allowed for role {0:?} {1:?}")] + SignatureNotAllowed(String, String), + #[error("Replay detected")] + Replay, +} + +pub trait IdentityAction { + fn update_state( + &self, + existing_state: Option, + ) -> Result; + fn signatures(&self) -> Vec>; + fn replay_check(&self, state: &AssociationState) -> Result<(), AssociationError> { + let signatures = self.signatures(); + for signature in signatures { + if state.has_seen(&signature) { + return Err(AssociationError::Replay); + } + } + + Ok(()) + } +} + +/// CreateInbox Action +pub struct CreateInbox { + pub nonce: u64, + pub account_address: String, + pub initial_address_signature: Box, +} + +impl IdentityAction for CreateInbox { + fn update_state( + &self, + existing_state: Option, + ) -> Result { + if existing_state.is_some() { + return Err(AssociationError::MultipleCreate); + } + + let account_address = self.account_address.clone(); + let recovered_signer = self.initial_address_signature.recover_signer()?; + if recovered_signer.ne(&MemberIdentifier::Address(account_address.clone())) { + return Err(AssociationError::MissingExistingMember); + } + + allowed_signature_for_kind( + &MemberKind::Address, + &self.initial_address_signature.signature_kind(), + )?; + + if self.initial_address_signature.signature_kind() == SignatureKind::LegacyDelegated + && self.nonce != 0 + { + return Err(AssociationError::LegacySignatureReuse); + } + + Ok(AssociationState::new(account_address, self.nonce)) + } + + fn signatures(&self) -> Vec> { + vec![self.initial_address_signature.bytes()] + } +} + +/// AddAssociation Action +pub struct AddAssociation { + pub new_member_signature: Box, + pub new_member_identifier: MemberIdentifier, + pub existing_member_signature: Box, +} + +impl IdentityAction for AddAssociation { + fn update_state( + &self, + maybe_existing_state: Option, + ) -> Result { + let existing_state = maybe_existing_state.ok_or(AssociationError::NotCreated)?; + self.replay_check(&existing_state)?; + + // Validate the new member signature and get the recovered signer + let new_member_address = self.new_member_signature.recover_signer()?; + // Validate the existing member signature and get the recovedred signer + let existing_member_identifier = self.existing_member_signature.recover_signer()?; + + if new_member_address.ne(&self.new_member_identifier) { + return Err(AssociationError::NewMemberIdSignatureMismatch); + } + + // You cannot add yourself + if new_member_address == existing_member_identifier { + return Err(AssociationError::Generic("tried to add self".to_string())); + } + + // Only allow LegacyDelegated signatures on XIDs with a nonce of 0 + // Otherwise the client should use the regular wallet signature to create + if (is_legacy_signature(&self.new_member_signature) + || is_legacy_signature(&self.existing_member_signature)) + && existing_state.inbox_id().ne(&generate_inbox_id( + &existing_member_identifier.to_string(), + &0, + )) + { + return Err(AssociationError::LegacySignatureReuse); + } + + allowed_signature_for_kind( + &self.new_member_identifier.kind(), + &self.new_member_signature.signature_kind(), + )?; + + let existing_member = existing_state.get(&existing_member_identifier); + + let existing_entity_id = match existing_member { + // If there is an existing member of the XID, use that member's ID + Some(member) => member.identifier, + None => { + // Get the recovery address from the state as a MemberIdentifier + let recovery_identifier: MemberIdentifier = + existing_state.recovery_address().clone().into(); + + // Check if it is a signature from the recovery address, which is allowed to add members + if existing_member_identifier.ne(&recovery_identifier) { + return Err(AssociationError::MissingExistingMember); + } + // BUT, the recovery address has to be used with a real wallet signature, can't be delegated + if is_legacy_signature(&self.existing_member_signature) { + return Err(AssociationError::LegacySignatureReuse); + } + // If it is a real wallet signature, then it is allowed to add members + recovery_identifier + } + }; + + // Ensure that the existing member signature is correct for the existing member type + allowed_signature_for_kind( + &existing_entity_id.kind(), + &self.existing_member_signature.signature_kind(), + )?; + + // Ensure that the new member signature is correct for the new member type + allowed_association( + &existing_member_identifier.kind(), + &self.new_member_identifier.kind(), + )?; + + let new_member = Member::new(new_member_address, Some(existing_entity_id)); + + println!("Adding new entity to state {:?}", &new_member); + + Ok(existing_state.add(new_member)) + } + + fn signatures(&self) -> Vec> { + vec![ + self.existing_member_signature.bytes(), + self.new_member_signature.bytes(), + ] + } +} + +/// RevokeAssociation Action +pub struct RevokeAssociation { + pub recovery_address_signature: Box, + pub revoked_member: MemberIdentifier, +} + +impl IdentityAction for RevokeAssociation { + fn update_state( + &self, + maybe_existing_state: Option, + ) -> Result { + let existing_state = maybe_existing_state.ok_or(AssociationError::NotCreated)?; + self.replay_check(&existing_state)?; + + if is_legacy_signature(&self.recovery_address_signature) { + return Err(AssociationError::SignatureNotAllowed( + MemberKind::Address.to_string(), + SignatureKind::LegacyDelegated.to_string(), + )); + } + // Don't need to check for replay here since revocation is idempotent + let recovery_signer = self.recovery_address_signature.recover_signer()?; + // Make sure there is a recovery address set on the state + let state_recovery_address = existing_state.recovery_address(); + + // Ensure this message is signed by the recovery address + if recovery_signer.ne(&MemberIdentifier::Address(state_recovery_address.clone())) { + return Err(AssociationError::MissingExistingMember); + } + + let installations_to_remove: Vec = existing_state + .members_by_parent(&self.revoked_member) + .into_iter() + // Only remove children if they are installations + .filter(|child| child.kind() == MemberKind::Installation) + .collect(); + + // Actually apply the revocation to the parent + let new_state = existing_state.remove(&self.revoked_member); + + Ok(installations_to_remove + .iter() + .fold(new_state, |state, installation| { + state.remove(&installation.identifier) + })) + } + + fn signatures(&self) -> Vec> { + vec![self.recovery_address_signature.bytes()] + } +} + +/// ChangeRecoveryAddress Action +pub struct ChangeRecoveryAddress { + pub recovery_address_signature: Box, + pub new_recovery_address: String, +} + +impl IdentityAction for ChangeRecoveryAddress { + fn update_state( + &self, + existing_state: Option, + ) -> Result { + let existing_state = existing_state.ok_or(AssociationError::NotCreated)?; + self.replay_check(&existing_state)?; + + if is_legacy_signature(&self.recovery_address_signature) { + return Err(AssociationError::SignatureNotAllowed( + MemberKind::Address.to_string(), + SignatureKind::LegacyDelegated.to_string(), + )); + } + + let recovery_signer = self.recovery_address_signature.recover_signer()?; + if recovery_signer.ne(&existing_state.recovery_address().clone().into()) { + return Err(AssociationError::MissingExistingMember); + } + + Ok(existing_state.set_recovery_address(self.new_recovery_address.clone())) + } + + fn signatures(&self) -> Vec> { + vec![self.recovery_address_signature.bytes()] + } +} + +/// All possible Action types that can be used inside an `IdentityUpdate` +pub enum Action { + CreateInbox(CreateInbox), + AddAssociation(AddAssociation), + RevokeAssociation(RevokeAssociation), + ChangeRecoveryAddress(ChangeRecoveryAddress), +} + +impl IdentityAction for Action { + fn update_state( + &self, + existing_state: Option, + ) -> Result { + match self { + Action::CreateInbox(event) => event.update_state(existing_state), + Action::AddAssociation(event) => event.update_state(existing_state), + Action::RevokeAssociation(event) => event.update_state(existing_state), + Action::ChangeRecoveryAddress(event) => event.update_state(existing_state), + } + } + + fn signatures(&self) -> Vec> { + match self { + Action::CreateInbox(event) => event.signatures(), + Action::AddAssociation(event) => event.signatures(), + Action::RevokeAssociation(event) => event.signatures(), + Action::ChangeRecoveryAddress(event) => event.signatures(), + } + } +} + +/// An `IdentityUpdate` contains one or more Actions that can be applied to the AssociationState +pub struct IdentityUpdate { + pub client_timestamp_ns: u64, + pub actions: Vec, +} + +impl IdentityUpdate { + pub fn new(actions: Vec, client_timestamp_ns: u64) -> Self { + Self { + actions, + client_timestamp_ns, + } + } +} + +impl IdentityAction for IdentityUpdate { + fn update_state( + &self, + existing_state: Option, + ) -> Result { + let mut state = existing_state.clone(); + for action in &self.actions { + state = Some(action.update_state(state)?); + } + + let new_state = state.ok_or(AssociationError::NotCreated)?; + + // After all the updates in the LogEntry have been processed, add the list of signatures to the state + // so that the signatures can not be re-used in subsequent updates + Ok(new_state.add_seen_signatures(self.signatures())) + } + + fn signatures(&self) -> Vec> { + self.actions + .iter() + .flat_map(|action| action.signatures()) + .collect() + } +} + +#[allow(clippy::borrowed_box)] +fn is_legacy_signature(signature: &Box) -> bool { + signature.signature_kind() == SignatureKind::LegacyDelegated +} + +fn allowed_association( + existing_member_kind: &MemberKind, + new_member_kind: &MemberKind, +) -> Result<(), AssociationError> { + // The only disallowed association is an installation adding an installation + if existing_member_kind.eq(&MemberKind::Installation) + && new_member_kind.eq(&MemberKind::Installation) + { + return Err(AssociationError::MemberNotAllowed( + existing_member_kind.to_string(), + new_member_kind.to_string(), + )); + } + + Ok(()) +} + +// Ensure that the type of signature matches the new entity's role. +fn allowed_signature_for_kind( + role: &MemberKind, + signature_kind: &SignatureKind, +) -> Result<(), AssociationError> { + let is_ok = match role { + MemberKind::Address => match signature_kind { + SignatureKind::Erc191 => true, + SignatureKind::Erc1271 => true, + SignatureKind::InstallationKey => false, + SignatureKind::LegacyDelegated => true, + }, + MemberKind::Installation => match signature_kind { + SignatureKind::Erc191 => false, + SignatureKind::Erc1271 => false, + SignatureKind::InstallationKey => true, + SignatureKind::LegacyDelegated => false, + }, + }; + + if !is_ok { + return Err(AssociationError::SignatureNotAllowed( + role.to_string(), + signature_kind.to_string(), + )); + } + + Ok(()) +} diff --git a/xmtp_id/src/associations/builder.rs b/xmtp_id/src/associations/builder.rs new file mode 100644 index 000000000..90d63a9b3 --- /dev/null +++ b/xmtp_id/src/associations/builder.rs @@ -0,0 +1,442 @@ +use std::collections::{HashMap, HashSet}; + +use thiserror::Error; +use xmtp_mls::utils::time::now_ns; + +use super::{ + association_log::{AddAssociation, ChangeRecoveryAddress, CreateInbox, RevokeAssociation}, + unsigned_actions::{ + SignatureTextCreator, UnsignedAction, UnsignedAddAssociation, + UnsignedChangeRecoveryAddress, UnsignedCreateInbox, UnsignedIdentityUpdate, + UnsignedRevokeAssociation, + }, + Action, IdentityUpdate, MemberIdentifier, Signature, SignatureError, +}; + +#[derive(Error, Debug)] +pub enum IdentityBuilderError { + #[error("Missing signer")] + MissingSigner, +} + +#[derive(Clone, PartialEq, Hash, Eq)] +enum SignatureField { + InitialAddress, + ExistingMember, + NewMember, + RecoveryAddress, +} + +#[derive(Clone)] +pub struct PendingIdentityAction { + unsigned_action: UnsignedAction, + pending_signatures: HashMap, +} + +pub struct IdentityUpdateBuilder { + inbox_id: String, + client_timestamp_ns: u64, + actions: Vec, +} + +impl IdentityUpdateBuilder { + /// Create a new IdentityUpdateBuilder for the given `inbox_id` + pub fn new(inbox_id: String) -> Self { + Self { + inbox_id, + client_timestamp_ns: now_ns() as u64, + actions: vec![], + } + } + + /// Create a new inbox. This method must be called before any other methods or the IdentityUpdate will fail + pub fn create_inbox(mut self, signer_identity: MemberIdentifier, nonce: u64) -> Self { + let pending_action = PendingIdentityAction { + unsigned_action: UnsignedAction::CreateInbox(UnsignedCreateInbox { + account_address: signer_identity.to_string(), + nonce, + }), + pending_signatures: HashMap::from([( + SignatureField::InitialAddress, + signer_identity.clone(), + )]), + }; + // Save the `PendingIdentityAction` for later + self.actions.push(pending_action); + + self + } + + /// Add an AddAssociation action. + pub fn add_association( + mut self, + new_member_identifier: MemberIdentifier, + existing_member_identifier: MemberIdentifier, + ) -> Self { + self.actions.push(PendingIdentityAction { + unsigned_action: UnsignedAction::AddAssociation(UnsignedAddAssociation { + new_member_identifier: new_member_identifier.clone(), + inbox_id: self.inbox_id.clone(), + }), + pending_signatures: HashMap::from([ + ( + SignatureField::ExistingMember, + existing_member_identifier.clone(), + ), + (SignatureField::NewMember, new_member_identifier.clone()), + ]), + }); + + self + } + + pub fn revoke_association( + mut self, + recovery_address_identifier: MemberIdentifier, + revoked_member: MemberIdentifier, + ) -> Self { + self.actions.push(PendingIdentityAction { + pending_signatures: HashMap::from([( + SignatureField::RecoveryAddress, + recovery_address_identifier.clone(), + )]), + unsigned_action: UnsignedAction::RevokeAssociation(UnsignedRevokeAssociation { + inbox_id: self.inbox_id.clone(), + revoked_member, + }), + }); + + self + } + + pub fn change_recovery_address( + mut self, + recovery_address_identifier: MemberIdentifier, + new_recovery_address: String, + ) -> Self { + self.actions.push(PendingIdentityAction { + pending_signatures: HashMap::from([( + SignatureField::RecoveryAddress, + recovery_address_identifier.clone(), + )]), + unsigned_action: UnsignedAction::ChangeRecoveryAddress(UnsignedChangeRecoveryAddress { + inbox_id: self.inbox_id.clone(), + new_recovery_address, + }), + }); + + self + } + + pub fn to_signature_request(self) -> SignatureRequest { + let unsigned_actions: Vec = self + .actions + .iter() + .map(|pending_action| pending_action.unsigned_action.clone()) + .collect(); + + let signature_text = get_signature_text(unsigned_actions, self.client_timestamp_ns); + + SignatureRequest::new(self.actions, signature_text, self.client_timestamp_ns) + } +} + +#[derive(Debug, Error, PartialEq)] +pub enum SignatureRequestError { + #[error("Unknown signer")] + UnknownSigner, + #[error("Required signature was not provided")] + MissingSigner, + #[error("Signature error {0}")] + Signature(#[from] SignatureError), +} + +/// A signature request is meant to be sent over the FFI barrier (wrapped in a mutex) to platform SDKs. +/// `xmtp_mls` can add any InstallationKey signatures first, so that the platform SDK does not need to worry about those. +/// The platform SDK can then fill in any missing signatures and convert it to an IdentityUpdate that is ready to be published +/// to the network +#[derive(Clone)] +pub struct SignatureRequest { + pending_actions: Vec, + signature_text: String, + signatures: HashMap>, + client_timestamp_ns: u64, +} + +impl SignatureRequest { + pub fn new( + pending_actions: Vec, + signature_text: String, + client_timestamp_ns: u64, + ) -> Self { + Self { + pending_actions, + signature_text, + signatures: HashMap::new(), + client_timestamp_ns, + } + } + + pub fn missing_signatures(&self) -> Vec { + let signers: HashSet = self + .pending_actions + .iter() + .flat_map(|pending_action| { + pending_action + .pending_signatures + .values() + .cloned() + .collect::>() + }) + .collect(); + + let signatures: HashSet = self.signatures.keys().cloned().collect(); + + signers.difference(&signatures).cloned().collect() + } + + pub fn add_signature( + &mut self, + signature: Box, + ) -> Result<(), SignatureRequestError> { + let signer_identity = signature.recover_signer()?; + let missing_signatures = self.missing_signatures(); + + // Make sure the signer is someone actually in the request + if !missing_signatures.contains(&signer_identity) { + return Err(SignatureRequestError::UnknownSigner); + } + + self.signatures.insert(signer_identity, signature); + + Ok(()) + } + + pub fn is_ready(&self) -> bool { + self.missing_signatures().is_empty() + } + + pub fn signature_text(&self) -> String { + self.signature_text.clone() + } + + pub fn build_identity_update(&self) -> Result { + if !self.is_ready() { + return Err(SignatureRequestError::MissingSigner); + } + + let actions = self + .pending_actions + .clone() + .into_iter() + .map(|pending_action| build_action(pending_action, &self.signatures)) + .collect::, SignatureRequestError>>()?; + + Ok(IdentityUpdate::new(actions, self.client_timestamp_ns)) + } +} + +fn build_action( + pending_action: PendingIdentityAction, + signatures: &HashMap>, +) -> Result { + match pending_action.unsigned_action { + UnsignedAction::CreateInbox(unsigned_action) => { + let signer_identity = pending_action + .pending_signatures + .get(&SignatureField::InitialAddress) + .ok_or(SignatureRequestError::MissingSigner)?; + let initial_address_signature = signatures + .get(signer_identity) + .cloned() + .ok_or(SignatureRequestError::MissingSigner)?; + + Ok(Action::CreateInbox(CreateInbox { + nonce: unsigned_action.nonce, + account_address: unsigned_action.account_address, + initial_address_signature, + })) + } + UnsignedAction::AddAssociation(unsigned_action) => { + let existing_member_signer_identity = pending_action + .pending_signatures + .get(&SignatureField::ExistingMember) + .ok_or(SignatureRequestError::MissingSigner)?; + let new_member_signer_identity = pending_action + .pending_signatures + .get(&SignatureField::NewMember) + .ok_or(SignatureRequestError::MissingSigner)?; + + let existing_member_signature = signatures + .get(existing_member_signer_identity) + .cloned() + .ok_or(SignatureRequestError::MissingSigner)?; + + let new_member_signature = signatures + .get(new_member_signer_identity) + .cloned() + .ok_or(SignatureRequestError::MissingSigner)?; + + Ok(Action::AddAssociation(AddAssociation { + new_member_identifier: unsigned_action.new_member_identifier, + existing_member_signature, + new_member_signature, + })) + } + UnsignedAction::RevokeAssociation(unsigned_action) => { + let signer_identity = pending_action + .pending_signatures + .get(&SignatureField::RecoveryAddress) + .ok_or(SignatureRequestError::MissingSigner)?; + let recovery_address_signature = signatures + .get(signer_identity) + .cloned() + .ok_or(SignatureRequestError::MissingSigner)?; + + Ok(Action::RevokeAssociation(RevokeAssociation { + recovery_address_signature, + revoked_member: unsigned_action.revoked_member, + })) + } + UnsignedAction::ChangeRecoveryAddress(unsigned_action) => { + let signer_identity = pending_action + .pending_signatures + .get(&SignatureField::RecoveryAddress) + .ok_or(SignatureRequestError::MissingSigner)?; + + let recovery_address_signature = signatures + .get(signer_identity) + .cloned() + .ok_or(SignatureRequestError::MissingSigner)?; + + Ok(Action::ChangeRecoveryAddress(ChangeRecoveryAddress { + recovery_address_signature, + new_recovery_address: unsigned_action.new_recovery_address, + })) + } + } +} + +fn get_signature_text(actions: Vec, client_timestamp_ns: u64) -> String { + let identity_update = UnsignedIdentityUpdate { + client_timestamp_ns, + actions, + }; + + identity_update.signature_text() +} + +#[cfg(test)] +mod tests { + use crate::associations::{ + get_state, + hashes::generate_inbox_id, + test_utils::{rand_string, rand_vec, MockSignature}, + MemberKind, SignatureKind, + }; + + use super::*; + + // Helper function to add all the missing signatures + fn add_missing_signatures_to_request(signature_request: &mut SignatureRequest) { + let missing_signatures = signature_request.missing_signatures(); + for member_identifier in missing_signatures { + let signature_kind = match member_identifier.kind() { + MemberKind::Address => SignatureKind::Erc191, + MemberKind::Installation => SignatureKind::InstallationKey, + }; + + signature_request + .add_signature(MockSignature::new_boxed( + true, + member_identifier.clone(), + signature_kind, + Some(signature_request.signature_text()), + )) + .expect("should succeed"); + } + } + + #[test] + fn create_inbox() { + let account_address = "account_address".to_string(); + let nonce = 0; + let inbox_id = generate_inbox_id(&account_address, &nonce); + let mut signature_request = IdentityUpdateBuilder::new(inbox_id) + .create_inbox(account_address.into(), nonce) + .to_signature_request(); + + add_missing_signatures_to_request(&mut signature_request); + + let identity_update = signature_request + .build_identity_update() + .expect("should be valid"); + + get_state(vec![identity_update]).expect("should be valid"); + } + + #[test] + fn create_and_add_identity() { + let account_address = "account_address".to_string(); + let nonce = 0; + let inbox_id = generate_inbox_id(&account_address, &nonce); + let existing_member_identifier: MemberIdentifier = account_address.into(); + let new_member_identifier: MemberIdentifier = rand_vec().into(); + + let mut signature_request = IdentityUpdateBuilder::new(inbox_id) + .create_inbox(existing_member_identifier.clone(), nonce) + .add_association(new_member_identifier, existing_member_identifier) + .to_signature_request(); + + add_missing_signatures_to_request(&mut signature_request); + + let identity_update = signature_request + .build_identity_update() + .expect("should be valid"); + + let state = get_state(vec![identity_update]).expect("should be valid"); + assert_eq!(state.members().len(), 2); + } + + #[test] + fn create_and_revoke() { + let account_address = "account_address".to_string(); + let nonce = 0; + let inbox_id = generate_inbox_id(&account_address, &nonce); + let existing_member_identifier: MemberIdentifier = account_address.clone().into(); + + let mut signature_request = IdentityUpdateBuilder::new(inbox_id) + .create_inbox(existing_member_identifier.clone(), nonce) + .revoke_association(existing_member_identifier.clone(), account_address.into()) + .to_signature_request(); + + add_missing_signatures_to_request(&mut signature_request); + + let identity_update = signature_request + .build_identity_update() + .expect("should be valid"); + + let state = get_state(vec![identity_update]).expect("should be valid"); + + assert_eq!(state.members().len(), 0); + } + + #[test] + fn attempt_adding_unknown_signer() { + let account_address = "account_address".to_string(); + let nonce = 0; + let inbox_id = generate_inbox_id(&account_address, &nonce); + let mut signature_request = IdentityUpdateBuilder::new(inbox_id) + .create_inbox(account_address.into(), nonce) + .to_signature_request(); + + let attempt_to_add_random_member = signature_request.add_signature( + MockSignature::new_boxed(true, rand_string().into(), SignatureKind::Erc191, None), + ); + + assert_eq!( + attempt_to_add_random_member, + Err(SignatureRequestError::UnknownSigner) + ); + } +} diff --git a/xmtp_id/src/associations/hashes.rs b/xmtp_id/src/associations/hashes.rs new file mode 100644 index 000000000..fe000e037 --- /dev/null +++ b/xmtp_id/src/associations/hashes.rs @@ -0,0 +1,12 @@ +use sha2::{Digest, Sha256}; + +pub fn sha256_string(input: String) -> String { + let mut hasher = Sha256::new(); + hasher.update(input.as_bytes()); + let result = hasher.finalize(); + format!("{:x}", result) +} + +pub fn generate_inbox_id(account_address: &String, nonce: &u64) -> String { + sha256_string(format!("{}{}", account_address, nonce)) +} diff --git a/xmtp_id/src/associations/member.rs b/xmtp_id/src/associations/member.rs new file mode 100644 index 000000000..8efc76049 --- /dev/null +++ b/xmtp_id/src/associations/member.rs @@ -0,0 +1,122 @@ +#[derive(Clone, Debug, PartialEq)] +pub enum MemberKind { + Installation, + Address, +} + +impl std::fmt::Display for MemberKind { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + MemberKind::Installation => write!(f, "installation"), + MemberKind::Address => write!(f, "address"), + } + } +} + +/// A MemberIdentifier can be either an Address or an Installation Public Key +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub enum MemberIdentifier { + Address(String), + Installation(Vec), +} + +impl MemberIdentifier { + pub fn kind(&self) -> MemberKind { + match self { + MemberIdentifier::Address(_) => MemberKind::Address, + MemberIdentifier::Installation(_) => MemberKind::Installation, + } + } +} + +impl std::fmt::Display for MemberIdentifier { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let as_string = match self { + MemberIdentifier::Address(address) => address.to_string(), + MemberIdentifier::Installation(installation) => hex::encode(installation), + }; + + write!(f, "{}", as_string) + } +} + +impl From for MemberIdentifier { + fn from(address: String) -> Self { + MemberIdentifier::Address(address) + } +} + +impl From> for MemberIdentifier { + fn from(installation: Vec) -> Self { + MemberIdentifier::Installation(installation) + } +} + +/// A Member of Inbox +#[derive(Clone, Debug, PartialEq)] +pub struct Member { + pub identifier: MemberIdentifier, + pub added_by_entity: Option, +} + +impl Member { + pub fn new(identifier: MemberIdentifier, added_by_entity: Option) -> Self { + Self { + identifier, + added_by_entity, + } + } + + pub fn kind(&self) -> MemberKind { + self.identifier.kind() + } +} + +impl PartialEq for Member { + fn eq(&self, other: &MemberIdentifier) -> bool { + self.identifier.eq(other) + } +} + +#[cfg(test)] +mod tests { + use crate::associations::test_utils; + + use super::*; + + use test_utils::rand_string; + + impl Default for MemberIdentifier { + fn default() -> Self { + MemberIdentifier::Address(rand_string()) + } + } + + impl Default for Member { + fn default() -> Self { + Self { + identifier: MemberIdentifier::default(), + added_by_entity: None, + } + } + } + + #[test] + fn test_identifier_comparisons() { + let address_1 = MemberIdentifier::Address("0x123".to_string()); + let address_2 = MemberIdentifier::Address("0x456".to_string()); + let address_1_copy = MemberIdentifier::Address("0x123".to_string()); + + assert!(address_1 != address_2); + assert!(address_1.ne(&address_2)); + assert!(address_1 == address_1_copy); + + let installation_1 = MemberIdentifier::Installation(vec![1, 2, 3]); + let installation_2 = MemberIdentifier::Installation(vec![4, 5, 6]); + let installation_1_copy = MemberIdentifier::Installation(vec![1, 2, 3]); + + assert!(installation_1 != installation_2); + assert!(installation_1.ne(&installation_2)); + assert!(installation_1 == installation_1_copy); + } +} diff --git a/xmtp_id/src/associations/mod.rs b/xmtp_id/src/associations/mod.rs new file mode 100644 index 000000000..2f2680761 --- /dev/null +++ b/xmtp_id/src/associations/mod.rs @@ -0,0 +1,578 @@ +mod association_log; +pub mod builder; +mod hashes; +mod member; +mod signature; +mod state; +#[cfg(test)] +mod test_utils; +mod unsigned_actions; + +pub use self::association_log::*; +pub use self::member::{Member, MemberIdentifier, MemberKind}; +pub use self::signature::{Signature, SignatureError, SignatureKind}; +pub use self::state::AssociationState; + +// Apply a single IdentityUpdate to an existing AssociationState +pub fn apply_update( + initial_state: AssociationState, + update: IdentityUpdate, +) -> Result { + update.update_state(Some(initial_state)) +} + +// Get the current state from an array of `IdentityUpdate`s. Entire operation fails if any operation fails +pub fn get_state(updates: Vec) -> Result { + let new_state = updates.iter().try_fold( + None, + |state, update| -> Result, AssociationError> { + let updated_state = update.update_state(state)?; + Ok(Some(updated_state)) + }, + )?; + + new_state.ok_or(AssociationError::NotCreated) +} + +#[cfg(test)] +mod tests { + use self::test_utils::{rand_string, rand_u64, rand_vec, MockSignature}; + + use super::*; + + impl IdentityUpdate { + pub fn new_test(actions: Vec) -> Self { + Self::new(actions, rand_u64()) + } + } + + impl Default for AddAssociation { + fn default() -> Self { + let existing_member = rand_string(); + let new_member = rand_vec(); + return Self { + existing_member_signature: MockSignature::new_boxed( + true, + existing_member.into(), + SignatureKind::Erc191, + None, + ), + new_member_signature: MockSignature::new_boxed( + true, + new_member.clone().into(), + SignatureKind::InstallationKey, + None, + ), + new_member_identifier: new_member.into(), + }; + } + } + + // Default will create an inbox with a ERC-191 signature + impl Default for CreateInbox { + fn default() -> Self { + let signer = rand_string(); + return Self { + nonce: rand_u64(), + account_address: signer.clone(), + initial_address_signature: MockSignature::new_boxed( + true, + signer.into(), + SignatureKind::Erc191, + None, + ), + }; + } + } + + impl Default for RevokeAssociation { + fn default() -> Self { + let signer = rand_string(); + return Self { + recovery_address_signature: MockSignature::new_boxed( + true, + signer.into(), + SignatureKind::Erc191, + None, + ), + revoked_member: rand_string().into(), + }; + } + } + + fn new_test_inbox() -> AssociationState { + let create_request = CreateInbox::default(); + let identity_update = IdentityUpdate::new_test(vec![Action::CreateInbox(create_request)]); + + get_state(vec![identity_update]).unwrap() + } + + fn new_test_inbox_with_installation() -> AssociationState { + let initial_state = new_test_inbox(); + let initial_wallet_address: MemberIdentifier = + initial_state.recovery_address().clone().into(); + + let update = Action::AddAssociation(AddAssociation { + existing_member_signature: MockSignature::new_boxed( + true, + initial_wallet_address.clone(), + SignatureKind::Erc191, + None, + ), + ..Default::default() + }); + + apply_update(initial_state, IdentityUpdate::new_test(vec![update])).unwrap() + } + + #[test] + fn test_create_inbox() { + let create_request = CreateInbox::default(); + let account_address = create_request.account_address.clone(); + let identity_update = IdentityUpdate::new_test(vec![Action::CreateInbox(create_request)]); + let state = get_state(vec![identity_update]).unwrap(); + assert_eq!(state.members().len(), 1); + + let existing_entity = state.get(&account_address.clone().into()).unwrap(); + assert!(existing_entity.identifier.eq(&account_address.into())); + } + + #[test] + fn create_and_add_separately() { + let initial_state = new_test_inbox(); + let new_installation_identifier: MemberIdentifier = rand_vec().into(); + let first_member: MemberIdentifier = initial_state.recovery_address().clone().into(); + + let update = Action::AddAssociation(AddAssociation { + new_member_identifier: new_installation_identifier.clone(), + new_member_signature: MockSignature::new_boxed( + true, + new_installation_identifier.clone(), + SignatureKind::InstallationKey, + None, + ), + existing_member_signature: MockSignature::new_boxed( + true, + first_member.clone(), + SignatureKind::Erc191, + None, + ), + ..Default::default() + }); + + let new_state = + apply_update(initial_state, IdentityUpdate::new_test(vec![update])).unwrap(); + assert_eq!(new_state.members().len(), 2); + + let new_member = new_state.get(&new_installation_identifier).unwrap(); + assert_eq!(new_member.added_by_entity, Some(first_member)); + } + + #[test] + fn create_and_add_together() { + let create_action = CreateInbox::default(); + let account_address = create_action.account_address.clone(); + let new_member_identifier: MemberIdentifier = rand_vec().into(); + let add_action = AddAssociation { + existing_member_signature: MockSignature::new_boxed( + true, + account_address.clone().into(), + SignatureKind::Erc191, + None, + ), + // Add an installation ID + new_member_signature: MockSignature::new_boxed( + true, + new_member_identifier.clone(), + SignatureKind::InstallationKey, + None, + ), + new_member_identifier: new_member_identifier.clone(), + ..Default::default() + }; + let identity_update = IdentityUpdate::new_test(vec![ + Action::CreateInbox(create_action), + Action::AddAssociation(add_action), + ]); + let state = get_state(vec![identity_update]).unwrap(); + assert_eq!(state.members().len(), 2); + assert_eq!( + state.get(&new_member_identifier).unwrap().added_by_entity, + Some(account_address.into()) + ); + } + + #[test] + fn create_from_legacy_key() { + let member_identifier: MemberIdentifier = rand_string().into(); + let create_action = CreateInbox { + nonce: 0, + account_address: member_identifier.to_string(), + initial_address_signature: MockSignature::new_boxed( + true, + member_identifier.clone(), + SignatureKind::LegacyDelegated, + Some("0".to_string()), + ), + }; + let state = get_state(vec![IdentityUpdate::new_test(vec![Action::CreateInbox( + create_action, + )])]) + .unwrap(); + assert_eq!(state.members().len(), 1); + + // The legacy key can only be used once. After this, subsequent updates should fail + let update = Action::AddAssociation(AddAssociation { + existing_member_signature: MockSignature::new_boxed( + true, + member_identifier, + SignatureKind::LegacyDelegated, + // All requests from the same legacy key will have the same signature nonce + Some("0".to_string()), + ), + ..Default::default() + }); + let update_result = apply_update(state, IdentityUpdate::new_test(vec![update])); + assert!(update_result.is_err()); + assert_eq!(update_result.err().unwrap(), AssociationError::Replay); + } + + #[test] + fn add_wallet_from_installation_key() { + let initial_state = new_test_inbox_with_installation(); + let installation_id = initial_state + .members_by_kind(MemberKind::Installation) + .first() + .cloned() + .unwrap() + .identifier; + + let new_wallet_address: MemberIdentifier = rand_string().into(); + let add_association = Action::AddAssociation(AddAssociation { + new_member_identifier: new_wallet_address.clone(), + new_member_signature: MockSignature::new_boxed( + true, + new_wallet_address.clone(), + SignatureKind::Erc191, + None, + ), + existing_member_signature: MockSignature::new_boxed( + true, + installation_id.clone(), + SignatureKind::InstallationKey, + None, + ), + ..Default::default() + }); + + let new_state = apply_update( + initial_state, + IdentityUpdate::new_test(vec![add_association]), + ) + .expect("expected update to succeed"); + assert_eq!(new_state.members().len(), 3); + } + + #[test] + fn reject_invalid_signature_on_create() { + let bad_signature = + MockSignature::new_boxed(false, rand_string().into(), SignatureKind::Erc191, None); + let action = CreateInbox { + initial_address_signature: bad_signature.clone(), + ..Default::default() + }; + + let state_result = get_state(vec![IdentityUpdate::new_test(vec![Action::CreateInbox( + action, + )])]); + assert!(state_result.is_err()); + assert_eq!( + state_result.err().unwrap(), + AssociationError::Signature(SignatureError::Invalid) + ); + } + + #[test] + fn reject_invalid_signature_on_update() { + let initial_state = new_test_inbox(); + let bad_signature = + MockSignature::new_boxed(false, rand_string().into(), SignatureKind::Erc191, None); + + let update_with_bad_existing_member = Action::AddAssociation(AddAssociation { + existing_member_signature: bad_signature.clone(), + ..Default::default() + }); + + let update_result = apply_update( + initial_state.clone(), + IdentityUpdate::new_test(vec![update_with_bad_existing_member]), + ); + assert!(update_result.is_err()); + assert_eq!( + update_result.err().unwrap(), + AssociationError::Signature(SignatureError::Invalid) + ); + + let update_with_bad_new_member = Action::AddAssociation(AddAssociation { + new_member_signature: bad_signature.clone(), + existing_member_signature: MockSignature::new_boxed( + true, + initial_state.recovery_address().clone().into(), + SignatureKind::Erc191, + None, + ), + ..Default::default() + }); + + let update_result_2 = apply_update( + initial_state, + IdentityUpdate::new_test(vec![update_with_bad_new_member]), + ); + assert!(update_result_2.is_err()); + assert_eq!( + update_result_2.err().unwrap(), + AssociationError::Signature(SignatureError::Invalid) + ); + } + + #[test] + fn reject_if_signer_not_existing_member() { + let create_request = Action::CreateInbox(CreateInbox::default()); + // The default here will create an AddAssociation from a random wallet + let update = Action::AddAssociation(AddAssociation { + // Existing member signature is coming from a random wallet + existing_member_signature: MockSignature::new_boxed( + true, + rand_string().into(), + SignatureKind::Erc191, + None, + ), + ..Default::default() + }); + + let state_result = get_state(vec![IdentityUpdate::new_test(vec![create_request, update])]); + assert!(state_result.is_err()); + assert_eq!( + state_result.err().unwrap(), + AssociationError::MissingExistingMember + ); + } + + #[test] + fn reject_if_installation_adding_installation() { + let existing_state = new_test_inbox_with_installation(); + let existing_installations = existing_state.members_by_kind(MemberKind::Installation); + let existing_installation = existing_installations.first().unwrap(); + let new_installation_id: MemberIdentifier = rand_vec().into(); + + let update = Action::AddAssociation(AddAssociation { + existing_member_signature: MockSignature::new_boxed( + true, + existing_installation.identifier.clone(), + SignatureKind::InstallationKey, + None, + ), + new_member_identifier: new_installation_id.clone(), + new_member_signature: MockSignature::new_boxed( + true, + new_installation_id.clone(), + SignatureKind::InstallationKey, + None, + ), + ..Default::default() + }); + + let update_result = apply_update(existing_state, IdentityUpdate::new_test(vec![update])); + assert!(update_result.is_err()); + assert_eq!( + update_result.err().unwrap(), + AssociationError::MemberNotAllowed( + MemberKind::Installation.to_string(), + MemberKind::Installation.to_string() + ) + ); + } + + #[test] + fn revoke() { + let initial_state = new_test_inbox_with_installation(); + let installation_id = initial_state + .members_by_kind(MemberKind::Installation) + .first() + .cloned() + .unwrap() + .identifier; + let update = Action::RevokeAssociation(RevokeAssociation { + recovery_address_signature: MockSignature::new_boxed( + true, + initial_state.recovery_address().clone().into(), + SignatureKind::Erc191, + None, + ), + revoked_member: installation_id.clone(), + ..Default::default() + }); + + let new_state = apply_update(initial_state, IdentityUpdate::new_test(vec![update])) + .expect("expected update to succeed"); + assert!(new_state.get(&installation_id).is_none()); + } + + #[test] + fn revoke_children() { + let initial_state = new_test_inbox_with_installation(); + let wallet_address = initial_state + .members_by_kind(MemberKind::Address) + .first() + .cloned() + .unwrap() + .identifier; + + let add_second_installation = Action::AddAssociation(AddAssociation { + existing_member_signature: MockSignature::new_boxed( + true, + wallet_address.clone(), + SignatureKind::Erc191, + None, + ), + ..Default::default() + }); + + let new_state = apply_update( + initial_state, + IdentityUpdate::new_test(vec![add_second_installation]), + ) + .expect("expected update to succeed"); + assert_eq!(new_state.members().len(), 3); + + let revocation = Action::RevokeAssociation(RevokeAssociation { + recovery_address_signature: MockSignature::new_boxed( + true, + wallet_address.clone(), + SignatureKind::Erc191, + None, + ), + revoked_member: wallet_address.clone(), + ..Default::default() + }); + + // With this revocation the original wallet + both installations should be gone + let new_state = apply_update(new_state, IdentityUpdate::new_test(vec![revocation])) + .expect("expected update to succeed"); + assert_eq!(new_state.members().len(), 0); + } + + #[test] + fn revoke_and_re_add() { + let initial_state = new_test_inbox(); + let wallet_address = initial_state + .members_by_kind(MemberKind::Address) + .first() + .cloned() + .unwrap() + .identifier; + + let second_wallet_address: MemberIdentifier = rand_string().into(); + let add_second_wallet = Action::AddAssociation(AddAssociation { + new_member_identifier: second_wallet_address.clone(), + new_member_signature: MockSignature::new_boxed( + true, + second_wallet_address.clone(), + SignatureKind::Erc191, + None, + ), + existing_member_signature: MockSignature::new_boxed( + true, + wallet_address.clone(), + SignatureKind::Erc191, + None, + ), + ..Default::default() + }); + + let revoke_second_wallet = Action::RevokeAssociation(RevokeAssociation { + recovery_address_signature: MockSignature::new_boxed( + true, + wallet_address.clone(), + SignatureKind::Erc191, + None, + ), + revoked_member: second_wallet_address.clone(), + ..Default::default() + }); + + let state_after_remove = apply_update( + initial_state, + IdentityUpdate::new_test(vec![add_second_wallet, revoke_second_wallet]), + ) + .expect("expected update to succeed"); + assert_eq!(state_after_remove.members().len(), 1); + + let add_second_wallet_again = Action::AddAssociation(AddAssociation { + new_member_identifier: second_wallet_address.clone(), + new_member_signature: MockSignature::new_boxed( + true, + second_wallet_address.clone(), + SignatureKind::Erc191, + None, + ), + existing_member_signature: MockSignature::new_boxed( + true, + wallet_address, + SignatureKind::Erc191, + None, + ), + ..Default::default() + }); + + let state_after_re_add = apply_update( + state_after_remove, + IdentityUpdate::new_test(vec![add_second_wallet_again]), + ) + .expect("expected update to succeed"); + assert_eq!(state_after_re_add.members().len(), 2); + } + + #[test] + fn change_recovery_address() { + let initial_state = new_test_inbox_with_installation(); + let initial_recovery_address: MemberIdentifier = + initial_state.recovery_address().clone().into(); + let new_recovery_address = rand_string(); + let update_recovery = Action::ChangeRecoveryAddress(ChangeRecoveryAddress { + new_recovery_address: new_recovery_address.clone(), + recovery_address_signature: MockSignature::new_boxed( + true, + initial_state.recovery_address().clone().into(), + SignatureKind::Erc191, + None, + ), + }); + + let new_state = apply_update( + initial_state, + IdentityUpdate::new_test(vec![update_recovery]), + ) + .expect("expected update to succeed"); + assert_eq!(new_state.recovery_address(), &new_recovery_address); + + let attempted_revoke = Action::RevokeAssociation(RevokeAssociation { + recovery_address_signature: MockSignature::new_boxed( + true, + initial_recovery_address.clone(), + SignatureKind::Erc191, + None, + ), + revoked_member: initial_recovery_address.clone(), + ..Default::default() + }); + + let revoke_result = + apply_update(new_state, IdentityUpdate::new_test(vec![attempted_revoke])); + assert!(revoke_result.is_err()); + assert_eq!( + revoke_result.err().unwrap(), + AssociationError::MissingExistingMember + ); + } +} diff --git a/xmtp_id/src/associations/signature.rs b/xmtp_id/src/associations/signature.rs new file mode 100644 index 000000000..d71bec608 --- /dev/null +++ b/xmtp_id/src/associations/signature.rs @@ -0,0 +1,54 @@ +use thiserror::Error; + +use super::MemberIdentifier; + +#[derive(Debug, Error, PartialEq)] +pub enum SignatureError { + #[error("Signature validation failed")] + Invalid, +} + +#[derive(Clone, Debug, PartialEq)] +pub enum SignatureKind { + // We might want to have some sort of LegacyErc191 Signature Kind for the `CreateIdentity` signatures only + Erc191, + Erc1271, + InstallationKey, + LegacyDelegated, +} + +impl std::fmt::Display for SignatureKind { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + SignatureKind::Erc191 => write!(f, "erc-191"), + SignatureKind::Erc1271 => write!(f, "erc-1271"), + SignatureKind::InstallationKey => write!(f, "installation-key"), + SignatureKind::LegacyDelegated => write!(f, "legacy-delegated"), + } + } +} + +pub trait Signature: SignatureClone { + fn recover_signer(&self) -> Result; + fn signature_kind(&self) -> SignatureKind; + fn bytes(&self) -> Vec; +} + +pub trait SignatureClone { + fn clone_box(&self) -> Box; +} + +impl SignatureClone for T +where + T: 'static + Signature + Clone, +{ + fn clone_box(&self) -> Box { + Box::new(self.clone()) + } +} + +impl Clone for Box { + fn clone(&self) -> Box { + self.clone_box() + } +} diff --git a/xmtp_id/src/associations/state.rs b/xmtp_id/src/associations/state.rs new file mode 100644 index 000000000..0e1246fa1 --- /dev/null +++ b/xmtp_id/src/associations/state.rs @@ -0,0 +1,109 @@ +use std::collections::{HashMap, HashSet}; + +use super::{hashes::generate_inbox_id, member::Member, MemberIdentifier, MemberKind}; + +#[derive(Clone, Debug)] +pub struct AssociationState { + inbox_id: String, + members: HashMap, + recovery_address: String, + seen_signatures: HashSet>, +} + +impl AssociationState { + pub fn add(&self, member: Member) -> Self { + let mut new_state = self.clone(); + let _ = new_state.members.insert(member.identifier.clone(), member); + + new_state + } + + pub fn remove(&self, identifier: &MemberIdentifier) -> Self { + let mut new_state = self.clone(); + let _ = new_state.members.remove(identifier); + + new_state + } + + pub fn set_recovery_address(&self, recovery_address: String) -> Self { + let mut new_state = self.clone(); + new_state.recovery_address = recovery_address; + + new_state + } + + pub fn get(&self, identifier: &MemberIdentifier) -> Option { + self.members.get(identifier).cloned() + } + + pub fn add_seen_signatures(&self, signatures: Vec>) -> Self { + let mut new_state = self.clone(); + new_state.seen_signatures.extend(signatures); + + new_state + } + + pub fn has_seen(&self, signature: &Vec) -> bool { + self.seen_signatures.contains(signature) + } + + pub fn members(&self) -> Vec { + self.members.values().cloned().collect() + } + + pub fn inbox_id(&self) -> &String { + &self.inbox_id + } + + pub fn recovery_address(&self) -> &String { + &self.recovery_address + } + + pub fn members_by_parent(&self, parent_id: &MemberIdentifier) -> Vec { + self.members + .values() + .filter(|e| e.added_by_entity.eq(&Some(parent_id.clone()))) + .cloned() + .collect() + } + + pub fn members_by_kind(&self, kind: MemberKind) -> Vec { + self.members + .values() + .filter(|e| e.kind() == kind) + .cloned() + .collect() + } + + pub fn new(account_address: String, nonce: u64) -> Self { + let inbox_id = generate_inbox_id(&account_address, &nonce); + let identifier = MemberIdentifier::Address(account_address.clone()); + let new_member = Member::new(identifier.clone(), None); + Self { + members: { + let mut members = HashMap::new(); + members.insert(identifier, new_member); + members + }, + seen_signatures: HashSet::new(), + recovery_address: account_address, + inbox_id, + } + } +} + +#[cfg(test)] +mod tests { + use crate::associations::test_utils::rand_string; + + use super::*; + + #[test] + fn can_add_remove() { + let starting_state = AssociationState::new(rand_string(), 0); + let new_entity = Member::default(); + let with_add = starting_state.add(new_entity.clone()); + assert!(with_add.get(&new_entity.identifier).is_some()); + assert!(starting_state.get(&new_entity.identifier).is_none()); + } +} diff --git a/xmtp_id/src/associations/test_utils.rs b/xmtp_id/src/associations/test_utils.rs new file mode 100644 index 000000000..3fd06ab1f --- /dev/null +++ b/xmtp_id/src/associations/test_utils.rs @@ -0,0 +1,68 @@ +use rand::{distributions::Alphanumeric, Rng}; + +use super::{MemberIdentifier, Signature, SignatureError, SignatureKind}; + +pub fn rand_string() -> String { + let v: String = rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(32) + .map(char::from) + .collect(); + + v +} + +pub fn rand_u64() -> u64 { + rand::thread_rng().gen() +} + +pub fn rand_vec() -> Vec { + let mut buf = [0u8; 32]; + rand::thread_rng().fill(&mut buf[..]); + buf.to_vec() +} + +#[derive(Clone)] +pub struct MockSignature { + is_valid: bool, + signer_identity: MemberIdentifier, + signature_kind: SignatureKind, + signature_nonce: String, +} + +impl MockSignature { + pub fn new_boxed( + is_valid: bool, + signer_identity: MemberIdentifier, + signature_kind: SignatureKind, + // Signature nonce is used to control what the signature bytes are + // Defaults to random + signature_nonce: Option, + ) -> Box { + let nonce = signature_nonce.unwrap_or(rand_string()); + Box::new(Self { + is_valid, + signer_identity, + signature_kind, + signature_nonce: nonce, + }) + } +} + +impl Signature for MockSignature { + fn signature_kind(&self) -> SignatureKind { + self.signature_kind.clone() + } + + fn recover_signer(&self) -> Result { + match self.is_valid { + true => Ok(self.signer_identity.clone()), + false => Err(SignatureError::Invalid), + } + } + + fn bytes(&self) -> Vec { + let sig = format!("{}{}", self.signer_identity, self.signature_nonce); + sig.as_bytes().to_vec() + } +} diff --git a/xmtp_id/src/associations/unsigned_actions.rs b/xmtp_id/src/associations/unsigned_actions.rs new file mode 100644 index 000000000..ce6523e94 --- /dev/null +++ b/xmtp_id/src/associations/unsigned_actions.rs @@ -0,0 +1,167 @@ +use crate::associations::hashes::generate_inbox_id; + +use super::MemberIdentifier; + +pub trait SignatureTextCreator { + fn signature_text(&self) -> String; +} + +#[derive(Clone)] +pub struct UnsignedCreateInbox { + pub nonce: u64, + pub account_address: String, +} + +impl SignatureTextCreator for UnsignedCreateInbox { + fn signature_text(&self) -> String { + format!( + // TODO: Finalize text + "Create Inbox: {}", + generate_inbox_id(&self.account_address, &self.nonce) + ) + } +} + +#[derive(Clone)] +pub struct UnsignedAddAssociation { + pub inbox_id: String, + pub new_member_identifier: MemberIdentifier, +} + +impl SignatureTextCreator for UnsignedAddAssociation { + fn signature_text(&self) -> String { + format!( + // TODO: Finalize text + "Add {} to Inbox {}", + self.new_member_identifier, self.inbox_id + ) + } +} + +#[derive(Clone)] +pub struct UnsignedRevokeAssociation { + pub inbox_id: String, + pub revoked_member: MemberIdentifier, +} + +impl SignatureTextCreator for UnsignedRevokeAssociation { + fn signature_text(&self) -> String { + format!( + // TODO: Finalize text + "Remove {} from Inbox {}", + self.revoked_member, self.inbox_id + ) + } +} + +#[derive(Clone)] +pub struct UnsignedChangeRecoveryAddress { + pub inbox_id: String, + pub new_recovery_address: String, +} + +impl SignatureTextCreator for UnsignedChangeRecoveryAddress { + fn signature_text(&self) -> String { + format!( + // TODO: Finalize text + "Change Recovery Address for Inbox {} to {}", + self.inbox_id, self.new_recovery_address + ) + } +} + +#[allow(dead_code)] +#[derive(Clone)] +pub enum UnsignedAction { + CreateInbox(UnsignedCreateInbox), + AddAssociation(UnsignedAddAssociation), + RevokeAssociation(UnsignedRevokeAssociation), + ChangeRecoveryAddress(UnsignedChangeRecoveryAddress), +} + +impl SignatureTextCreator for UnsignedAction { + fn signature_text(&self) -> String { + match self { + UnsignedAction::CreateInbox(action) => action.signature_text(), + UnsignedAction::AddAssociation(action) => action.signature_text(), + UnsignedAction::RevokeAssociation(action) => action.signature_text(), + UnsignedAction::ChangeRecoveryAddress(action) => action.signature_text(), + } + } +} + +#[derive(Clone)] +pub struct UnsignedIdentityUpdate { + pub client_timestamp_ns: u64, + pub actions: Vec, +} + +impl SignatureTextCreator for UnsignedIdentityUpdate { + fn signature_text(&self) -> String { + let all_signatures = self + .actions + .iter() + .map(|action| action.signature_text()) + .collect::>(); + format!( + "I authorize the following actions on XMTP:\n\n{}\n\nAuthorized at: {}", + all_signatures.join("\n\n"), + // TODO: Pretty up date + self.client_timestamp_ns + ) + } +} + +#[cfg(test)] +mod tests { + use crate::associations::test_utils::{rand_string, rand_u64}; + + use super::*; + + #[test] + fn create_signatures() { + let create_inbox = UnsignedCreateInbox { + nonce: rand_u64(), + account_address: rand_string(), + }; + let inbox_id = generate_inbox_id(&create_inbox.account_address, &create_inbox.nonce); + + let add_association = UnsignedAddAssociation { + inbox_id: inbox_id.clone(), + new_member_identifier: MemberIdentifier::Address(rand_string()), + }; + + let revoke_association = UnsignedRevokeAssociation { + inbox_id: inbox_id.clone(), + revoked_member: MemberIdentifier::Address(rand_string()), + }; + + let change_recovery_address = UnsignedChangeRecoveryAddress { + inbox_id: inbox_id.clone(), + new_recovery_address: rand_string(), + }; + + let identity_update = UnsignedIdentityUpdate { + client_timestamp_ns: rand_u64(), + actions: vec![ + UnsignedAction::CreateInbox(create_inbox.clone()), + UnsignedAction::AddAssociation(add_association.clone()), + UnsignedAction::RevokeAssociation(revoke_association.clone()), + UnsignedAction::ChangeRecoveryAddress(change_recovery_address.clone()), + ], + }; + + let signature_text = identity_update.signature_text(); + let expected_text = format!("I authorize the following actions on XMTP:\n\nCreate Inbox: {}\n\nAdd {} to Inbox {}\n\nRemove {} from Inbox {}\n\nChange Recovery Address for Inbox {} to {}\n\nAuthorized at: {}", + inbox_id, + add_association.new_member_identifier, + inbox_id, + revoke_association.revoked_member, + inbox_id, + inbox_id, + change_recovery_address.new_recovery_address, + identity_update.client_timestamp_ns, + ); + assert_eq!(signature_text, expected_text) + } +} diff --git a/xmtp_id/src/erc1271_verifier.rs b/xmtp_id/src/erc1271_verifier.rs new file mode 100644 index 000000000..1c098e66b --- /dev/null +++ b/xmtp_id/src/erc1271_verifier.rs @@ -0,0 +1,214 @@ +use ethers::contract::abigen; +use ethers::providers::{Http, Provider}; +use ethers::types::{Address, BlockNumber, Bytes}; +use std::convert::TryFrom; +use std::sync::Arc; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum VerifierError {} + +const EIP1271_MAGIC_VALUE: [u8; 4] = [0x16, 0x26, 0xba, 0x7e]; + +abigen!( + ERC1271, + r#"[ + function isValidSignature(bytes32 hash, bytes calldata signature) public view virtual returns (bytes4 result) + ]"#, + derives(serde::Serialize, serde::Deserialize) +); + +pub struct ERC1271Verifier { + pub provider: Arc>, +} + +impl ERC1271Verifier { + pub fn new(url: String) -> Self { + let provider = Arc::new(Provider::::try_from(url).unwrap()); + Self { provider } + } + + /// Verifies an ERC-1271(https://eips.ethereum.org/EIPS/eip-1271) signature. + /// + /// # Arguments + /// + /// * `contract_address` - Address of the ERC1271 wallet. + /// * `block_number` - Block number to verify the signature at. + /// * `hash`, `signature` - Inputs to ERC-1271, used for signer verification. + pub async fn is_valid_signature( + &self, + contract_address: Address, + block_number: Option, + hash: [u8; 32], + signature: Bytes, + ) -> Result { + let erc1271 = ERC1271::new(contract_address, self.provider.clone()); + + let res: [u8; 4] = erc1271 + .is_valid_signature(hash, signature) + .block(block_number.unwrap_or_default()) + .call() + .await?; + + Ok(res == EIP1271_MAGIC_VALUE) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use ethers::{ + abi::{self, Token}, + providers::{Http, Middleware, Provider}, + types::{Bytes, H256, U256}, + }; + + use ethers::{ + core::utils::Anvil, + middleware::SignerMiddleware, + signers::{LocalWallet, Signer as _}, + }; + use std::{convert::TryFrom, sync::Arc}; + + abigen!( + CoinbaseSmartWallet, + "artifact/CoinbaseSmartWallet.json", + derives(serde::Serialize, serde::Deserialize) + ); + + abigen!( + CoinbaseSmartWalletFactory, + "artifact/CoinbaseSmartWalletFactory.json", + derives(serde::Serialize, serde::Deserialize) + ); + + #[tokio::test] + async fn test_coinbase_smart_wallet() { + let anvil = Anvil::new().args(vec!["--base-fee", "100"]).spawn(); + let owner0: LocalWallet = anvil.keys()[1].clone().into(); + let owner1: LocalWallet = anvil.keys()[2].clone().into(); + let owners = vec![ + Bytes::from(H256::from(owner0.address()).0.to_vec()), + Bytes::from(H256::from(owner1.address()).0.to_vec()), + ]; + let nonce = U256::from(0); // needed when creating a smart wallet + let provider = Provider::::try_from(anvil.endpoint()).unwrap(); + let client = Arc::new(SignerMiddleware::new( + provider.clone(), + owner0.clone().with_chain_id(anvil.chain_id()), + )); + let verifier = ERC1271Verifier::new(anvil.endpoint()); + + // deploy a coinbase smart wallet as the implementation for factory + let implementation = CoinbaseSmartWallet::deploy(client.clone(), ()) + .unwrap() + .gas_price(100) + .send() + .await + .unwrap(); + + // Deploy the factory + let factory = CoinbaseSmartWalletFactory::deploy(client.clone(), implementation.address()) + .unwrap() + .gas_price(100) + .send() + .await + .unwrap(); + + let smart_wallet_address = factory.get_address(owners.clone(), nonce).await.unwrap(); + let tx = factory.create_account(owners.clone(), nonce); + let pending_tx = tx.send().await.unwrap(); + let _ = pending_tx.await.unwrap(); + + // Generate signatures from owners and verify them. + let smart_wallet = CoinbaseSmartWallet::new(smart_wallet_address, client.clone()); + let hash: [u8; 32] = H256::random().into(); + let replay_safe_hash = smart_wallet.replay_safe_hash(hash).call().await.unwrap(); + // owner 0 + let sig0 = owner0.sign_hash(replay_safe_hash.into()).unwrap(); + + let res = verifier + .is_valid_signature( + smart_wallet_address, + None, + hash, + abi::encode(&[Token::Tuple(vec![ + Token::Uint(U256::from(0)), + Token::Bytes(sig0.to_vec()), + ])]) + .into(), + ) + .await + .unwrap(); + assert_eq!(res, true); + // owner1 + let sig1 = owner1.sign_hash(replay_safe_hash.into()).unwrap(); + let res = verifier + .is_valid_signature( + smart_wallet_address, + None, + hash, + abi::encode(&[Token::Tuple(vec![ + Token::Uint(U256::from(1)), + Token::Bytes(sig1.to_vec()), + ])]) + .into(), + ) + .await + .unwrap(); + assert_eq!(res, true); + // owner0 siganture won't be deemed as signed by owner1 + let res = verifier + .is_valid_signature( + smart_wallet_address, + None, + hash, + abi::encode(&[Token::Tuple(vec![ + Token::Uint(U256::from(1)), + Token::Bytes(sig0.to_vec()), + ])]) + .into(), + ) + .await + .unwrap(); + assert_eq!(res, false); + + // get block number before removing + let block_number = provider.get_block_number().await.unwrap(); + + // remove owner1 and check their signature + let tx = smart_wallet.remove_owner_at_index(1.into()); + let pending_tx = tx.send().await.unwrap(); + let _ = pending_tx.await.unwrap(); + + let res = verifier + .is_valid_signature( + smart_wallet_address, + None, + hash, + abi::encode(&[Token::Tuple(vec![ + Token::Uint(U256::from(1)), + Token::Bytes(sig1.to_vec()), + ])]) + .into(), + ) + .await; + assert!(res.is_err()); // when verify a non-existing owner, it errors + + // use pre-removal block number to verify owner1 signature + let res = verifier + .is_valid_signature( + smart_wallet_address, + Some(BlockNumber::Number(block_number)), + hash, + abi::encode(&[Token::Tuple(vec![ + Token::Uint(U256::from(1)), + Token::Bytes(sig1.to_vec()), + ])]) + .into(), + ) + .await + .unwrap(); + assert_eq!(res, true); + } +} diff --git a/xmtp_id/src/lib.rs b/xmtp_id/src/lib.rs index bb7549e9b..4a9668223 100644 --- a/xmtp_id/src/lib.rs +++ b/xmtp_id/src/lib.rs @@ -1,5 +1,6 @@ +pub mod associations; pub mod credential_verifier; -pub mod verified_key_package; +pub mod erc1271_verifier; use std::sync::RwLock; diff --git a/xmtp_mls/Cargo.toml b/xmtp_mls/Cargo.toml index 73c2bc0d5..20378a2e9 100644 --- a/xmtp_mls/Cargo.toml +++ b/xmtp_mls/Cargo.toml @@ -47,7 +47,7 @@ xmtp_cryptography = { workspace = true } xmtp_v2 = { path = "../xmtp_v2" } [dev-dependencies] -ctor = "0.2" +ctor.workspace = true flume = "0.11" mockall = "0.11.4" tempfile = "3.5.0" diff --git a/xmtp_mls/src/groups/members.rs b/xmtp_mls/src/groups/members.rs index 6f80650c2..1cc79cd92 100644 --- a/xmtp_mls/src/groups/members.rs +++ b/xmtp_mls/src/groups/members.rs @@ -38,9 +38,7 @@ pub fn aggregate_member_list(openmls_group: &OpenMlsGroup) -> Result = openmls_group .members() .filter_map(|member| { - let basic_credential = BasicCredential::try_from(&member.credential) - .ok() - .map(|basic_credential| (basic_credential))?; + let basic_credential = BasicCredential::try_from(&member.credential).ok()?; Identity::get_validated_account_address( basic_credential.identity(), &member.signature_key,